aboutsummaryrefslogtreecommitdiff
path: root/lcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'lcode.c')
-rw-r--r--lcode.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/lcode.c b/lcode.c
index 837253f4..74ff47de 100644
--- a/lcode.c
+++ b/lcode.c
@@ -68,6 +68,30 @@ static int tonumeral (const expdesc *e, TValue *v) {
68 68
69 69
70/* 70/*
71** If expression is a constant, fills 'v' with its value
72** and returns 1. Otherwise, returns 0.
73*/
74int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v) {
75 if (hasjumps(e))
76 return 0; /* not a constant */
77 switch (e->k) {
78 case VFALSE: case VTRUE:
79 setbvalue(v, e->k == VTRUE);
80 return 1;
81 case VNIL:
82 setnilvalue(v);
83 return 1;
84 case VK: {
85 TValue *k = &fs->f->k[e->u.info];
86 setobj(fs->ls->L, v, k);
87 return 1;
88 }
89 default: return tonumeral(e, v);
90 }
91}
92
93
94/*
71** Return the previous instruction of the current code. If there 95** Return the previous instruction of the current code. If there
72** may be a jump target between the current instruction and the 96** may be a jump target between the current instruction and the
73** previous one, return an invalid instruction (to avoid wrong 97** previous one, return an invalid instruction (to avoid wrong
@@ -630,6 +654,31 @@ static void luaK_float (FuncState *fs, int reg, lua_Number f) {
630 654
631 655
632/* 656/*
657** Convert a constant in 'v' into an expression description 'e'
658*/
659static void const2exp (FuncState *fs, TValue *v, expdesc *e) {
660 switch (ttypetag(v)) {
661 case LUA_TNUMINT:
662 e->k = VKINT; e->u.ival = ivalue(v);
663 break;
664 case LUA_TNUMFLT:
665 e->k = VKFLT; e->u.nval = fltvalue(v);
666 break;
667 case LUA_TBOOLEAN:
668 e->k = bvalue(v) ? VTRUE : VFALSE;
669 break;
670 case LUA_TNIL:
671 e->k = VNIL;
672 break;
673 case LUA_TSHRSTR: case LUA_TLNGSTR:
674 e->k = VK; e->u.info = luaK_stringK(fs, tsvalue(v));
675 break;
676 default: lua_assert(0);
677 }
678}
679
680
681/*
633** Fix an expression to return the number of results 'nresults'. 682** Fix an expression to return the number of results 'nresults'.
634** Either 'e' is a multi-ret expression (function call or vararg) 683** Either 'e' is a multi-ret expression (function call or vararg)
635** or 'nresults' is LUA_MULTRET (as any expression can satisfy that). 684** or 'nresults' is LUA_MULTRET (as any expression can satisfy that).
@@ -677,6 +726,11 @@ void luaK_setoneret (FuncState *fs, expdesc *e) {
677*/ 726*/
678void luaK_dischargevars (FuncState *fs, expdesc *e) { 727void luaK_dischargevars (FuncState *fs, expdesc *e) {
679 switch (e->k) { 728 switch (e->k) {
729 case VCONST: {
730 TValue *val = &fs->ls->dyd->actvar.arr[e->u.info].k;
731 const2exp(fs, val, e);
732 break;
733 }
680 case VLOCAL: { /* already in a register */ 734 case VLOCAL: { /* already in a register */
681 e->u.info = e->u.var.sidx; 735 e->u.info = e->u.var.sidx;
682 e->k = VNONRELOC; /* becomes a non-relocatable value */ 736 e->k = VNONRELOC; /* becomes a non-relocatable value */
@@ -1074,7 +1128,6 @@ void luaK_goiffalse (FuncState *fs, expdesc *e) {
1074** Code 'not e', doing constant folding. 1128** Code 'not e', doing constant folding.
1075*/ 1129*/
1076static void codenot (FuncState *fs, expdesc *e) { 1130static void codenot (FuncState *fs, expdesc *e) {
1077 luaK_dischargevars(fs, e);
1078 switch (e->k) { 1131 switch (e->k) {
1079 case VNIL: case VFALSE: { 1132 case VNIL: case VFALSE: {
1080 e->k = VTRUE; /* true == not nil == not false */ 1133 e->k = VTRUE; /* true == not nil == not false */
@@ -1447,6 +1500,7 @@ static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
1447*/ 1500*/
1448void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { 1501void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
1449 static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP}; 1502 static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP};
1503 luaK_dischargevars(fs, e);
1450 switch (op) { 1504 switch (op) {
1451 case OPR_MINUS: case OPR_BNOT: /* use 'ef' as fake 2nd operand */ 1505 case OPR_MINUS: case OPR_BNOT: /* use 'ef' as fake 2nd operand */
1452 if (constfolding(fs, op + LUA_OPUNM, e, &ef)) 1506 if (constfolding(fs, op + LUA_OPUNM, e, &ef))