diff options
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 81 |
1 files changed, 45 insertions, 36 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.307 2017/11/07 17:20:42 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.308 2017/11/08 14:50:23 roberto Exp roberto $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -780,8 +780,7 @@ void luaV_finishOp (lua_State *L) { | |||
780 | ** Protect code that, in general, can raise errors, reallocate the | 780 | ** Protect code that, in general, can raise errors, reallocate the |
781 | ** stack, and change the hooks. | 781 | ** stack, and change the hooks. |
782 | */ | 782 | */ |
783 | #define Protect(code) \ | 783 | #define Protect(exp) (savepc(L), (exp), base = ci->func + 1, updatemask(L)) |
784 | { savepc(L); {code;}; base = ci->func + 1; updatemask(L); } | ||
785 | 784 | ||
786 | 785 | ||
787 | #define checkGC(L,c) \ | 786 | #define checkGC(L,c) \ |
@@ -881,7 +880,8 @@ void luaV_execute (lua_State *L) { | |||
881 | if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { | 880 | if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { |
882 | setobj2s(L, ra, slot); | 881 | setobj2s(L, ra, slot); |
883 | } | 882 | } |
884 | else Protect(luaV_finishget(L, upval, rc, ra, slot)); | 883 | else |
884 | Protect(luaV_finishget(L, upval, rc, ra, slot)); | ||
885 | vmbreak; | 885 | vmbreak; |
886 | } | 886 | } |
887 | vmcase(OP_GETTABLE) { | 887 | vmcase(OP_GETTABLE) { |
@@ -920,7 +920,8 @@ void luaV_execute (lua_State *L) { | |||
920 | if (luaV_fastget(L, rb, key, slot, luaH_getshortstr)) { | 920 | if (luaV_fastget(L, rb, key, slot, luaH_getshortstr)) { |
921 | setobj2s(L, ra, slot); | 921 | setobj2s(L, ra, slot); |
922 | } | 922 | } |
923 | else Protect(luaV_finishget(L, rb, rc, ra, slot)); | 923 | else |
924 | Protect(luaV_finishget(L, rb, rc, ra, slot)); | ||
924 | vmbreak; | 925 | vmbreak; |
925 | } | 926 | } |
926 | vmcase(OP_SETTABUP) { | 927 | vmcase(OP_SETTABUP) { |
@@ -997,7 +998,8 @@ void luaV_execute (lua_State *L) { | |||
997 | if (luaV_fastget(L, rb, key, slot, luaH_getstr)) { | 998 | if (luaV_fastget(L, rb, key, slot, luaH_getstr)) { |
998 | setobj2s(L, ra, slot); | 999 | setobj2s(L, ra, slot); |
999 | } | 1000 | } |
1000 | else Protect(luaV_finishget(L, rb, rc, ra, slot)); | 1001 | else |
1002 | Protect(luaV_finishget(L, rb, rc, ra, slot)); | ||
1001 | vmbreak; | 1003 | vmbreak; |
1002 | } | 1004 | } |
1003 | vmcase(OP_ADDI) { | 1005 | vmcase(OP_ADDI) { |
@@ -1109,7 +1111,8 @@ void luaV_execute (lua_State *L) { | |||
1109 | else if (tonumberns(rb, nb) && tonumberns(rc, nc)) { | 1111 | else if (tonumberns(rb, nb) && tonumberns(rc, nc)) { |
1110 | setfltvalue(s2v(ra), luai_numadd(L, nb, nc)); | 1112 | setfltvalue(s2v(ra), luai_numadd(L, nb, nc)); |
1111 | } | 1113 | } |
1112 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_ADD)); } | 1114 | else |
1115 | Protect(luaT_trybinTM(L, rb, rc, ra, TM_ADD)); | ||
1113 | vmbreak; | 1116 | vmbreak; |
1114 | } | 1117 | } |
1115 | vmcase(OP_SUB) { | 1118 | vmcase(OP_SUB) { |
@@ -1123,7 +1126,8 @@ void luaV_execute (lua_State *L) { | |||
1123 | else if (tonumberns(rb, nb) && tonumberns(rc, nc)) { | 1126 | else if (tonumberns(rb, nb) && tonumberns(rc, nc)) { |
1124 | setfltvalue(s2v(ra), luai_numsub(L, nb, nc)); | 1127 | setfltvalue(s2v(ra), luai_numsub(L, nb, nc)); |
1125 | } | 1128 | } |
1126 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SUB)); } | 1129 | else |
1130 | Protect(luaT_trybinTM(L, rb, rc, ra, TM_SUB)); | ||
1127 | vmbreak; | 1131 | vmbreak; |
1128 | } | 1132 | } |
1129 | vmcase(OP_MUL) { | 1133 | vmcase(OP_MUL) { |
@@ -1137,7 +1141,8 @@ void luaV_execute (lua_State *L) { | |||
1137 | else if (tonumberns(rb, nb) && tonumberns(rc, nc)) { | 1141 | else if (tonumberns(rb, nb) && tonumberns(rc, nc)) { |
1138 | setfltvalue(s2v(ra), luai_nummul(L, nb, nc)); | 1142 | setfltvalue(s2v(ra), luai_nummul(L, nb, nc)); |
1139 | } | 1143 | } |
1140 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_MUL)); } | 1144 | else |
1145 | Protect(luaT_trybinTM(L, rb, rc, ra, TM_MUL)); | ||
1141 | vmbreak; | 1146 | vmbreak; |
1142 | } | 1147 | } |
1143 | vmcase(OP_DIV) { /* float division (always with floats) */ | 1148 | vmcase(OP_DIV) { /* float division (always with floats) */ |
@@ -1147,7 +1152,8 @@ void luaV_execute (lua_State *L) { | |||
1147 | if (tonumberns(rb, nb) && tonumberns(rc, nc)) { | 1152 | if (tonumberns(rb, nb) && tonumberns(rc, nc)) { |
1148 | setfltvalue(s2v(ra), luai_numdiv(L, nb, nc)); | 1153 | setfltvalue(s2v(ra), luai_numdiv(L, nb, nc)); |
1149 | } | 1154 | } |
1150 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_DIV)); } | 1155 | else |
1156 | Protect(luaT_trybinTM(L, rb, rc, ra, TM_DIV)); | ||
1151 | vmbreak; | 1157 | vmbreak; |
1152 | } | 1158 | } |
1153 | vmcase(OP_BAND) { | 1159 | vmcase(OP_BAND) { |
@@ -1157,7 +1163,8 @@ void luaV_execute (lua_State *L) { | |||
1157 | if (tointegerns(rb, &ib) && tointegerns(rc, &ic)) { | 1163 | if (tointegerns(rb, &ib) && tointegerns(rc, &ic)) { |
1158 | setivalue(s2v(ra), intop(&, ib, ic)); | 1164 | setivalue(s2v(ra), intop(&, ib, ic)); |
1159 | } | 1165 | } |
1160 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BAND)); } | 1166 | else |
1167 | Protect(luaT_trybinTM(L, rb, rc, ra, TM_BAND)); | ||
1161 | vmbreak; | 1168 | vmbreak; |
1162 | } | 1169 | } |
1163 | vmcase(OP_BOR) { | 1170 | vmcase(OP_BOR) { |
@@ -1167,7 +1174,8 @@ void luaV_execute (lua_State *L) { | |||
1167 | if (tointegerns(rb, &ib) && tointegerns(rc, &ic)) { | 1174 | if (tointegerns(rb, &ib) && tointegerns(rc, &ic)) { |
1168 | setivalue(s2v(ra), intop(|, ib, ic)); | 1175 | setivalue(s2v(ra), intop(|, ib, ic)); |
1169 | } | 1176 | } |
1170 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BOR)); } | 1177 | else |
1178 | Protect(luaT_trybinTM(L, rb, rc, ra, TM_BOR)); | ||
1171 | vmbreak; | 1179 | vmbreak; |
1172 | } | 1180 | } |
1173 | vmcase(OP_BXOR) { | 1181 | vmcase(OP_BXOR) { |
@@ -1177,7 +1185,8 @@ void luaV_execute (lua_State *L) { | |||
1177 | if (tointegerns(rb, &ib) && tointegerns(rc, &ic)) { | 1185 | if (tointegerns(rb, &ib) && tointegerns(rc, &ic)) { |
1178 | setivalue(s2v(ra), intop(^, ib, ic)); | 1186 | setivalue(s2v(ra), intop(^, ib, ic)); |
1179 | } | 1187 | } |
1180 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BXOR)); } | 1188 | else |
1189 | Protect(luaT_trybinTM(L, rb, rc, ra, TM_BXOR)); | ||
1181 | vmbreak; | 1190 | vmbreak; |
1182 | } | 1191 | } |
1183 | vmcase(OP_SHL) { | 1192 | vmcase(OP_SHL) { |
@@ -1187,7 +1196,8 @@ void luaV_execute (lua_State *L) { | |||
1187 | if (tointegerns(rb, &ib) && tointegerns(rc, &ic)) { | 1196 | if (tointegerns(rb, &ib) && tointegerns(rc, &ic)) { |
1188 | setivalue(s2v(ra), luaV_shiftl(ib, ic)); | 1197 | setivalue(s2v(ra), luaV_shiftl(ib, ic)); |
1189 | } | 1198 | } |
1190 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); } | 1199 | else |
1200 | Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); | ||
1191 | vmbreak; | 1201 | vmbreak; |
1192 | } | 1202 | } |
1193 | vmcase(OP_SHR) { | 1203 | vmcase(OP_SHR) { |
@@ -1197,7 +1207,8 @@ void luaV_execute (lua_State *L) { | |||
1197 | if (tointegerns(rb, &ib) && tointegerns(rc, &ic)) { | 1207 | if (tointegerns(rb, &ib) && tointegerns(rc, &ic)) { |
1198 | setivalue(s2v(ra), luaV_shiftl(ib, -ic)); | 1208 | setivalue(s2v(ra), luaV_shiftl(ib, -ic)); |
1199 | } | 1209 | } |
1200 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHR)); } | 1210 | else |
1211 | Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHR)); | ||
1201 | vmbreak; | 1212 | vmbreak; |
1202 | } | 1213 | } |
1203 | vmcase(OP_MOD) { | 1214 | vmcase(OP_MOD) { |
@@ -1213,7 +1224,8 @@ void luaV_execute (lua_State *L) { | |||
1213 | luai_nummod(L, nb, nc, m); | 1224 | luai_nummod(L, nb, nc, m); |
1214 | setfltvalue(s2v(ra), m); | 1225 | setfltvalue(s2v(ra), m); |
1215 | } | 1226 | } |
1216 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_MOD)); } | 1227 | else |
1228 | Protect(luaT_trybinTM(L, rb, rc, ra, TM_MOD)); | ||
1217 | vmbreak; | 1229 | vmbreak; |
1218 | } | 1230 | } |
1219 | vmcase(OP_IDIV) { /* floor division */ | 1231 | vmcase(OP_IDIV) { /* floor division */ |
@@ -1227,7 +1239,8 @@ void luaV_execute (lua_State *L) { | |||
1227 | else if (tonumberns(rb, nb) && tonumberns(rc, nc)) { | 1239 | else if (tonumberns(rb, nb) && tonumberns(rc, nc)) { |
1228 | setfltvalue(s2v(ra), luai_numidiv(L, nb, nc)); | 1240 | setfltvalue(s2v(ra), luai_numidiv(L, nb, nc)); |
1229 | } | 1241 | } |
1230 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_IDIV)); } | 1242 | else |
1243 | Protect(luaT_trybinTM(L, rb, rc, ra, TM_IDIV)); | ||
1231 | vmbreak; | 1244 | vmbreak; |
1232 | } | 1245 | } |
1233 | vmcase(OP_POW) { | 1246 | vmcase(OP_POW) { |
@@ -1237,7 +1250,8 @@ void luaV_execute (lua_State *L) { | |||
1237 | if (tonumberns(rb, nb) && tonumberns(rc, nc)) { | 1250 | if (tonumberns(rb, nb) && tonumberns(rc, nc)) { |
1238 | setfltvalue(s2v(ra), luai_numpow(L, nb, nc)); | 1251 | setfltvalue(s2v(ra), luai_numpow(L, nb, nc)); |
1239 | } | 1252 | } |
1240 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_POW)); } | 1253 | else |
1254 | Protect(luaT_trybinTM(L, rb, rc, ra, TM_POW)); | ||
1241 | vmbreak; | 1255 | vmbreak; |
1242 | } | 1256 | } |
1243 | vmcase(OP_UNM) { | 1257 | vmcase(OP_UNM) { |
@@ -1250,9 +1264,8 @@ void luaV_execute (lua_State *L) { | |||
1250 | else if (tonumberns(rb, nb)) { | 1264 | else if (tonumberns(rb, nb)) { |
1251 | setfltvalue(s2v(ra), luai_numunm(L, nb)); | 1265 | setfltvalue(s2v(ra), luai_numunm(L, nb)); |
1252 | } | 1266 | } |
1253 | else { | 1267 | else |
1254 | Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM)); | 1268 | Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM)); |
1255 | } | ||
1256 | vmbreak; | 1269 | vmbreak; |
1257 | } | 1270 | } |
1258 | vmcase(OP_BNOT) { | 1271 | vmcase(OP_BNOT) { |
@@ -1261,9 +1274,8 @@ void luaV_execute (lua_State *L) { | |||
1261 | if (tointegerns(rb, &ib)) { | 1274 | if (tointegerns(rb, &ib)) { |
1262 | setivalue(s2v(ra), intop(^, ~l_castS2U(0), ib)); | 1275 | setivalue(s2v(ra), intop(^, ~l_castS2U(0), ib)); |
1263 | } | 1276 | } |
1264 | else { | 1277 | else |
1265 | Protect(luaT_trybinTM(L, rb, rb, ra, TM_BNOT)); | 1278 | Protect(luaT_trybinTM(L, rb, rb, ra, TM_BNOT)); |
1266 | } | ||
1267 | vmbreak; | 1279 | vmbreak; |
1268 | } | 1280 | } |
1269 | vmcase(OP_NOT) { | 1281 | vmcase(OP_NOT) { |
@@ -1300,12 +1312,12 @@ void luaV_execute (lua_State *L) { | |||
1300 | vmcase(OP_EQ) { | 1312 | vmcase(OP_EQ) { |
1301 | TValue *rb = vRB(i); | 1313 | TValue *rb = vRB(i); |
1302 | TValue *rc = vRC(i); | 1314 | TValue *rc = vRC(i); |
1303 | Protect( | 1315 | int res; |
1304 | if (luaV_equalobj(L, rb, rc) != GETARG_A(i)) | 1316 | Protect(res = luaV_equalobj(L, rb, rc)); |
1305 | pc++; | 1317 | if (res != GETARG_A(i)) |
1306 | else | 1318 | pc++; |
1307 | donextjump(ci); | 1319 | else |
1308 | ) | 1320 | donextjump(ci); |
1309 | vmbreak; | 1321 | vmbreak; |
1310 | } | 1322 | } |
1311 | vmcase(OP_LT) { | 1323 | vmcase(OP_LT) { |
@@ -1314,9 +1326,8 @@ void luaV_execute (lua_State *L) { | |||
1314 | int res; | 1326 | int res; |
1315 | if (ttisinteger(rb) && ttisinteger(rc)) | 1327 | if (ttisinteger(rb) && ttisinteger(rc)) |
1316 | res = (ivalue(rb) < ivalue(rc)); | 1328 | res = (ivalue(rb) < ivalue(rc)); |
1317 | else Protect( | 1329 | else |
1318 | res = luaV_lessthan(L, rb, rc); | 1330 | Protect(res = luaV_lessthan(L, rb, rc)); |
1319 | ) | ||
1320 | if (res != GETARG_A(i)) | 1331 | if (res != GETARG_A(i)) |
1321 | pc++; | 1332 | pc++; |
1322 | else | 1333 | else |
@@ -1329,9 +1340,8 @@ void luaV_execute (lua_State *L) { | |||
1329 | int res; | 1340 | int res; |
1330 | if (ttisinteger(rb) && ttisinteger(rc)) | 1341 | if (ttisinteger(rb) && ttisinteger(rc)) |
1331 | res = (ivalue(rb) <= ivalue(rc)); | 1342 | res = (ivalue(rb) <= ivalue(rc)); |
1332 | else Protect( | 1343 | else |
1333 | res = luaV_lessequal(L, rb, rc); | 1344 | Protect(res = luaV_lessequal(L, rb, rc)); |
1334 | ) | ||
1335 | if (res != GETARG_A(i)) | 1345 | if (res != GETARG_A(i)) |
1336 | pc++; | 1346 | pc++; |
1337 | else | 1347 | else |
@@ -1379,9 +1389,8 @@ void luaV_execute (lua_State *L) { | |||
1379 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ | 1389 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ |
1380 | lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); | 1390 | lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); |
1381 | savepc(L); | 1391 | savepc(L); |
1382 | if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */ | 1392 | if (luaD_precall(L, ra, LUA_MULTRET)) /* C function? */ |
1383 | Protect((void)0); /* update 'base' */ | 1393 | Protect((void)0); /* update 'base' */ |
1384 | } | ||
1385 | else { | 1394 | else { |
1386 | /* tail call: put called frame (n) in place of caller one (o) */ | 1395 | /* tail call: put called frame (n) in place of caller one (o) */ |
1387 | CallInfo *nci = L->ci; /* called frame (new) */ | 1396 | CallInfo *nci = L->ci; /* called frame (new) */ |