diff options
| -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) */ |
