aboutsummaryrefslogtreecommitdiff
path: root/lcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'lcode.c')
-rw-r--r--lcode.c60
1 files changed, 13 insertions, 47 deletions
diff --git a/lcode.c b/lcode.c
index 1005f1b7..cb6ea0dc 100644
--- a/lcode.c
+++ b/lcode.c
@@ -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*/
55int luaK_tonumeral (FuncState *fs, const expdesc *e, TValue *v) { 55static 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*/
81static 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) {
708void luaK_dischargevars (FuncState *fs, expdesc *e) { 678void 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) {
1252static int constfolding (FuncState *fs, int op, expdesc *e1, 1220static 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,
1362static void codecommutative (FuncState *fs, OpCode op, 1328static 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;