diff options
Diffstat (limited to 'lcode.c')
-rw-r--r-- | lcode.c | 60 |
1 files changed, 13 insertions, 47 deletions
@@ -52,7 +52,7 @@ l_noret luaK_semerror (LexState *ls, const char *msg) { | |||
52 | ** If expression is a numeric constant, fills 'v' with its value | 52 | ** If expression is a numeric constant, fills 'v' with its value |
53 | ** and returns 1. Otherwise, returns 0. | 53 | ** and returns 1. Otherwise, returns 0. |
54 | */ | 54 | */ |
55 | int luaK_tonumeral (FuncState *fs, const expdesc *e, TValue *v) { | 55 | static int tonumeral (const expdesc *e, TValue *v) { |
56 | if (hasjumps(e)) | 56 | if (hasjumps(e)) |
57 | return 0; /* not a numeral */ | 57 | return 0; /* not a numeral */ |
58 | switch (e->k) { | 58 | switch (e->k) { |
@@ -62,42 +62,12 @@ int luaK_tonumeral (FuncState *fs, const expdesc *e, TValue *v) { | |||
62 | case VKFLT: | 62 | case VKFLT: |
63 | if (v) setfltvalue(v, e->u.nval); | 63 | if (v) setfltvalue(v, e->u.nval); |
64 | return 1; | 64 | return 1; |
65 | case VUPVAL: { /* may be a constant */ | ||
66 | Vardesc *vd = luaY_getvardesc(&fs, e); | ||
67 | if (v && vd && !ttisnil(&vd->val)) { | ||
68 | setobj(fs->ls->L, v, &vd->val); | ||
69 | return 1; | ||
70 | } /* else */ | ||
71 | } /* FALLTHROUGH */ | ||
72 | default: return 0; | 65 | default: return 0; |
73 | } | 66 | } |
74 | } | 67 | } |
75 | 68 | ||
76 | 69 | ||
77 | /* | 70 | /* |
78 | ** If expression 'e' is a constant, change 'e' to represent | ||
79 | ** the constant value. | ||
80 | */ | ||
81 | static int const2exp (FuncState *fs, expdesc *e) { | ||
82 | Vardesc *vd = luaY_getvardesc(&fs, e); | ||
83 | if (vd) { | ||
84 | TValue *v = &vd->val; | ||
85 | switch (ttypetag(v)) { | ||
86 | case LUA_TNUMINT: | ||
87 | e->k = VKINT; | ||
88 | e->u.ival = ivalue(v); | ||
89 | return 1; | ||
90 | case LUA_TNUMFLT: | ||
91 | e->k = VKFLT; | ||
92 | e->u.nval = fltvalue(v); | ||
93 | return 1; | ||
94 | } | ||
95 | } | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | |||
100 | /* | ||
101 | ** Return the previous instruction of the current code. If there | 71 | ** Return the previous instruction of the current code. If there |
102 | ** may be a jump target between the current instruction and the | 72 | ** may be a jump target between the current instruction and the |
103 | ** previous one, return an invalid instruction (to avoid wrong | 73 | ** previous one, return an invalid instruction (to avoid wrong |
@@ -708,15 +678,13 @@ void luaK_setoneret (FuncState *fs, expdesc *e) { | |||
708 | void luaK_dischargevars (FuncState *fs, expdesc *e) { | 678 | void luaK_dischargevars (FuncState *fs, expdesc *e) { |
709 | switch (e->k) { | 679 | switch (e->k) { |
710 | case VLOCAL: { /* already in a register */ | 680 | case VLOCAL: { /* already in a register */ |
711 | e->u.info = e->u.var.idx; | 681 | e->u.info = e->u.var.sidx; |
712 | e->k = VNONRELOC; /* becomes a non-relocatable value */ | 682 | e->k = VNONRELOC; /* becomes a non-relocatable value */ |
713 | break; | 683 | break; |
714 | } | 684 | } |
715 | case VUPVAL: { /* move value to some (pending) register */ | 685 | case VUPVAL: { /* move value to some (pending) register */ |
716 | if (!const2exp(fs, e)) { | 686 | e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0); |
717 | e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.var.idx, 0); | 687 | e->k = VRELOC; |
718 | e->k = VRELOC; | ||
719 | } | ||
720 | break; | 688 | break; |
721 | } | 689 | } |
722 | case VINDEXUP: { | 690 | case VINDEXUP: { |
@@ -971,12 +939,12 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { | |||
971 | switch (var->k) { | 939 | switch (var->k) { |
972 | case VLOCAL: { | 940 | case VLOCAL: { |
973 | freeexp(fs, ex); | 941 | freeexp(fs, ex); |
974 | exp2reg(fs, ex, var->u.var.idx); /* compute 'ex' into proper place */ | 942 | exp2reg(fs, ex, var->u.var.sidx); /* compute 'ex' into proper place */ |
975 | return; | 943 | return; |
976 | } | 944 | } |
977 | case VUPVAL: { | 945 | case VUPVAL: { |
978 | int e = luaK_exp2anyreg(fs, ex); | 946 | int e = luaK_exp2anyreg(fs, ex); |
979 | luaK_codeABC(fs, OP_SETUPVAL, e, var->u.var.idx, 0); | 947 | luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0); |
980 | break; | 948 | break; |
981 | } | 949 | } |
982 | case VINDEXUP: { | 950 | case VINDEXUP: { |
@@ -1203,13 +1171,13 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { | |||
1203 | if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non string? */ | 1171 | if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non string? */ |
1204 | luaK_exp2anyreg(fs, t); /* put it in a register */ | 1172 | luaK_exp2anyreg(fs, t); /* put it in a register */ |
1205 | if (t->k == VUPVAL) { | 1173 | if (t->k == VUPVAL) { |
1206 | t->u.ind.t = t->u.var.idx; /* upvalue index */ | 1174 | t->u.ind.t = t->u.info; /* upvalue index */ |
1207 | t->u.ind.idx = k->u.info; /* literal string */ | 1175 | t->u.ind.idx = k->u.info; /* literal string */ |
1208 | t->k = VINDEXUP; | 1176 | t->k = VINDEXUP; |
1209 | } | 1177 | } |
1210 | else { | 1178 | else { |
1211 | /* register index of the table */ | 1179 | /* register index of the table */ |
1212 | t->u.ind.t = (t->k == VLOCAL) ? t->u.var.idx: t->u.info; | 1180 | t->u.ind.t = (t->k == VLOCAL) ? t->u.var.sidx: t->u.info; |
1213 | if (isKstr(fs, k)) { | 1181 | if (isKstr(fs, k)) { |
1214 | t->u.ind.idx = k->u.info; /* literal string */ | 1182 | t->u.ind.idx = k->u.info; /* literal string */ |
1215 | t->k = VINDEXSTR; | 1183 | t->k = VINDEXSTR; |
@@ -1252,9 +1220,7 @@ static int validop (int op, TValue *v1, TValue *v2) { | |||
1252 | static int constfolding (FuncState *fs, int op, expdesc *e1, | 1220 | static int constfolding (FuncState *fs, int op, expdesc *e1, |
1253 | const expdesc *e2) { | 1221 | const expdesc *e2) { |
1254 | TValue v1, v2, res; | 1222 | TValue v1, v2, res; |
1255 | if (!luaK_tonumeral(fs, e1, &v1) || | 1223 | if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2)) |
1256 | !luaK_tonumeral(fs, e2, &v2) || | ||
1257 | !validop(op, &v1, &v2)) | ||
1258 | return 0; /* non-numeric operands or not safe to fold */ | 1224 | return 0; /* non-numeric operands or not safe to fold */ |
1259 | luaO_rawarith(fs->ls->L, op, &v1, &v2, &res); /* does operation */ | 1225 | luaO_rawarith(fs->ls->L, op, &v1, &v2, &res); /* does operation */ |
1260 | if (ttisinteger(&res)) { | 1226 | if (ttisinteger(&res)) { |
@@ -1341,7 +1307,7 @@ static void codearith (FuncState *fs, OpCode op, | |||
1341 | expdesc *e1, expdesc *e2, int flip, int line) { | 1307 | expdesc *e1, expdesc *e2, int flip, int line) { |
1342 | if (isSCint(e2)) /* immediate operand? */ | 1308 | if (isSCint(e2)) /* immediate operand? */ |
1343 | codebini(fs, cast(OpCode, op - OP_ADD + OP_ADDI), e1, e2, flip, line); | 1309 | codebini(fs, cast(OpCode, op - OP_ADD + OP_ADDI), e1, e2, flip, line); |
1344 | else if (luaK_tonumeral(fs, e2, NULL) && luaK_exp2K(fs, e2)) { /* K operand? */ | 1310 | else if (tonumeral(e2, NULL) && luaK_exp2K(fs, e2)) { /* K operand? */ |
1345 | int v2 = e2->u.info; /* K index */ | 1311 | int v2 = e2->u.info; /* K index */ |
1346 | op = cast(OpCode, op - OP_ADD + OP_ADDK); | 1312 | op = cast(OpCode, op - OP_ADD + OP_ADDK); |
1347 | finishbinexpval(fs, e1, e2, op, v2, flip, line); | 1313 | finishbinexpval(fs, e1, e2, op, v2, flip, line); |
@@ -1362,7 +1328,7 @@ static void codearith (FuncState *fs, OpCode op, | |||
1362 | static void codecommutative (FuncState *fs, OpCode op, | 1328 | static void codecommutative (FuncState *fs, OpCode op, |
1363 | expdesc *e1, expdesc *e2, int line) { | 1329 | expdesc *e1, expdesc *e2, int line) { |
1364 | int flip = 0; | 1330 | int flip = 0; |
1365 | if (luaK_tonumeral(fs, e1, NULL)) { /* is first operand a numeric constant? */ | 1331 | if (tonumeral(e1, NULL)) { /* is first operand a numeric constant? */ |
1366 | swapexps(e1, e2); /* change order */ | 1332 | swapexps(e1, e2); /* change order */ |
1367 | flip = 1; | 1333 | flip = 1; |
1368 | } | 1334 | } |
@@ -1519,13 +1485,13 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { | |||
1519 | case OPR_MOD: case OPR_POW: | 1485 | case OPR_MOD: case OPR_POW: |
1520 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: | 1486 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: |
1521 | case OPR_SHL: case OPR_SHR: { | 1487 | case OPR_SHL: case OPR_SHR: { |
1522 | if (!luaK_tonumeral(fs, v, NULL)) | 1488 | if (!tonumeral(v, NULL)) |
1523 | luaK_exp2anyreg(fs, v); | 1489 | luaK_exp2anyreg(fs, v); |
1524 | /* else keep numeral, which may be folded with 2nd operand */ | 1490 | /* else keep numeral, which may be folded with 2nd operand */ |
1525 | break; | 1491 | break; |
1526 | } | 1492 | } |
1527 | case OPR_EQ: case OPR_NE: { | 1493 | case OPR_EQ: case OPR_NE: { |
1528 | if (!luaK_tonumeral(fs, v, NULL)) | 1494 | if (!tonumeral(v, NULL)) |
1529 | luaK_exp2RK(fs, v); | 1495 | luaK_exp2RK(fs, v); |
1530 | /* else keep numeral, which may be an immediate operand */ | 1496 | /* else keep numeral, which may be an immediate operand */ |
1531 | break; | 1497 | break; |