diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-08-05 14:36:24 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-08-05 14:36:24 -0300 |
| commit | 4e23699aa647fd9dc04933bf5582217ca594c8ce (patch) | |
| tree | 03d4f407c2f8974a62837a7d71f417c833aedd99 /lvm.c | |
| parent | 1c0ac3c0f53720c53dcfae13308b11b29dca38e4 (diff) | |
| download | lua-4e23699aa647fd9dc04933bf5582217ca594c8ce.tar.gz lua-4e23699aa647fd9dc04933bf5582217ca594c8ce.tar.bz2 lua-4e23699aa647fd9dc04933bf5582217ca594c8ce.zip | |
new implementation for error handling
Diffstat (limited to 'lvm.c')
| -rw-r--r-- | lvm.c | 150 |
1 files changed, 77 insertions, 73 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 1.247 2002/07/16 14:26:56 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.248 2002/07/17 16:25:13 roberto Exp $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -24,6 +24,9 @@ | |||
| 24 | #include "lvm.h" | 24 | #include "lvm.h" |
| 25 | 25 | ||
| 26 | 26 | ||
| 27 | Instruction const *luaV_callingmark = NULL; | ||
| 28 | |||
| 29 | |||
| 27 | /* function to convert a lua_Number to a string */ | 30 | /* function to convert a lua_Number to a string */ |
| 28 | #ifndef lua_number2str | 31 | #ifndef lua_number2str |
| 29 | #include <stdio.h> | 32 | #include <stdio.h> |
| @@ -46,8 +49,8 @@ static void luaV_checkGC (lua_State *L, StkId top) { | |||
| 46 | 49 | ||
| 47 | const TObject *luaV_tonumber (const TObject *obj, TObject *n) { | 50 | const TObject *luaV_tonumber (const TObject *obj, TObject *n) { |
| 48 | lua_Number num; | 51 | lua_Number num; |
| 49 | if (ttype(obj) == LUA_TNUMBER) return obj; | 52 | if (ttisnumber(obj)) return obj; |
| 50 | if (ttype(obj) == LUA_TSTRING && luaO_str2d(svalue(obj), &num)) { | 53 | if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) { |
| 51 | setnvalue(n, num); | 54 | setnvalue(n, num); |
| 52 | return n; | 55 | return n; |
| 53 | } | 56 | } |
| @@ -57,7 +60,7 @@ const TObject *luaV_tonumber (const TObject *obj, TObject *n) { | |||
| 57 | 60 | ||
| 58 | 61 | ||
| 59 | int luaV_tostring (lua_State *L, TObject *obj) { | 62 | int luaV_tostring (lua_State *L, TObject *obj) { |
| 60 | if (ttype(obj) != LUA_TNUMBER) | 63 | if (!ttisnumber(obj)) |
| 61 | return 0; | 64 | return 0; |
| 62 | else { | 65 | else { |
| 63 | char s[32]; /* 16 digits, sign, point and \0 (+ some extra...) */ | 66 | char s[32]; /* 16 digits, sign, point and \0 (+ some extra...) */ |
| @@ -80,16 +83,16 @@ static void traceexec (lua_State *L) { | |||
| 80 | if (mask & LUA_MASKLINE) { | 83 | if (mask & LUA_MASKLINE) { |
| 81 | CallInfo *ci = L->ci; | 84 | CallInfo *ci = L->ci; |
| 82 | Proto *p = ci_func(ci)->l.p; | 85 | Proto *p = ci_func(ci)->l.p; |
| 83 | int newline = getline(p, pcRel(*ci->u.l.pc, p)); | 86 | int newline = getline(p, pcRel(*ci->pc, p)); |
| 84 | if (pcRel(*ci->u.l.pc, p) == 0) /* tracing may be starting now? */ | 87 | if (pcRel(*ci->pc, p) == 0) /* tracing may be starting now? */ |
| 85 | ci->savedpc = *ci->u.l.pc; /* initialize `savedpc' */ | 88 | ci->u.l.savedpc = *ci->pc; /* initialize `savedpc' */ |
| 86 | /* calls linehook when enters a new line or jumps back (loop) */ | 89 | /* calls linehook when enters a new line or jumps back (loop) */ |
| 87 | if (*ci->u.l.pc <= ci->savedpc || | 90 | if (*ci->pc <= ci->u.l.savedpc || |
| 88 | newline != getline(p, pcRel(ci->savedpc, p))) { | 91 | newline != getline(p, pcRel(ci->u.l.savedpc, p))) { |
| 89 | luaD_callhook(L, LUA_HOOKLINE, newline); | 92 | luaD_callhook(L, LUA_HOOKLINE, newline); |
| 90 | ci = L->ci; /* previous call may reallocate `ci' */ | 93 | ci = L->ci; /* previous call may reallocate `ci' */ |
| 91 | } | 94 | } |
| 92 | ci->savedpc = *ci->u.l.pc; | 95 | ci->u.l.savedpc = *ci->pc; |
| 93 | } | 96 | } |
| 94 | } | 97 | } |
| 95 | 98 | ||
| @@ -123,7 +126,7 @@ static const TObject *luaV_index (lua_State *L, const TObject *t, | |||
| 123 | TObject *key, int loop) { | 126 | TObject *key, int loop) { |
| 124 | const TObject *tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); | 127 | const TObject *tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); |
| 125 | if (tm == NULL) return &luaO_nilobject; /* no TM */ | 128 | if (tm == NULL) return &luaO_nilobject; /* no TM */ |
| 126 | if (ttype(tm) == LUA_TFUNCTION) { | 129 | if (ttisfunction(tm)) { |
| 127 | callTMres(L, tm, t, key); | 130 | callTMres(L, tm, t, key); |
| 128 | return L->top; | 131 | return L->top; |
| 129 | } | 132 | } |
| @@ -133,9 +136,9 @@ static const TObject *luaV_index (lua_State *L, const TObject *t, | |||
| 133 | static const TObject *luaV_getnotable (lua_State *L, const TObject *t, | 136 | static const TObject *luaV_getnotable (lua_State *L, const TObject *t, |
| 134 | TObject *key, int loop) { | 137 | TObject *key, int loop) { |
| 135 | const TObject *tm = luaT_gettmbyobj(L, t, TM_GETTABLE); | 138 | const TObject *tm = luaT_gettmbyobj(L, t, TM_GETTABLE); |
| 136 | if (ttype(tm) == LUA_TNIL) | 139 | if (ttisnil(tm)) |
| 137 | luaG_typeerror(L, t, "index"); | 140 | luaG_typeerror(L, t, "index"); |
| 138 | if (ttype(tm) == LUA_TFUNCTION) { | 141 | if (ttisfunction(tm)) { |
| 139 | callTMres(L, tm, t, key); | 142 | callTMres(L, tm, t, key); |
| 140 | return L->top; | 143 | return L->top; |
| 141 | } | 144 | } |
| @@ -152,10 +155,10 @@ const TObject *luaV_gettable (lua_State *L, const TObject *t, TObject *key, | |||
| 152 | int loop) { | 155 | int loop) { |
| 153 | if (loop > MAXTAGLOOP) | 156 | if (loop > MAXTAGLOOP) |
| 154 | luaG_runerror(L, "loop in gettable"); | 157 | luaG_runerror(L, "loop in gettable"); |
| 155 | if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */ | 158 | if (ttistable(t)) { /* `t' is a table? */ |
| 156 | Table *h = hvalue(t); | 159 | Table *h = hvalue(t); |
| 157 | const TObject *v = luaH_get(h, key); /* do a primitive get */ | 160 | const TObject *v = luaH_get(h, key); /* do a primitive get */ |
| 158 | if (ttype(v) != LUA_TNIL) return v; | 161 | if (!ttisnil(v)) return v; |
| 159 | else return luaV_index(L, t, key, loop+1); | 162 | else return luaV_index(L, t, key, loop+1); |
| 160 | } | 163 | } |
| 161 | else return luaV_getnotable(L, t, key, loop+1); | 164 | else return luaV_getnotable(L, t, key, loop+1); |
| @@ -169,19 +172,19 @@ void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val) { | |||
| 169 | const TObject *tm; | 172 | const TObject *tm; |
| 170 | int loop = 0; | 173 | int loop = 0; |
| 171 | do { | 174 | do { |
| 172 | if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */ | 175 | if (ttistable(t)) { /* `t' is a table? */ |
| 173 | Table *h = hvalue(t); | 176 | Table *h = hvalue(t); |
| 174 | TObject *oldval = luaH_set(L, h, key); /* do a primitive set */ | 177 | TObject *oldval = luaH_set(L, h, key); /* do a primitive set */ |
| 175 | if (ttype(oldval) != LUA_TNIL || /* result is no nil? */ | 178 | if (!ttisnil(oldval) || /* result is no nil? */ |
| 176 | (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ | 179 | (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ |
| 177 | setobj(oldval, val); | 180 | setobj(oldval, val); |
| 178 | return; | 181 | return; |
| 179 | } | 182 | } |
| 180 | /* else will try the tag method */ | 183 | /* else will try the tag method */ |
| 181 | } | 184 | } |
| 182 | else if (ttype(tm = luaT_gettmbyobj(L, t, TM_SETTABLE)) == LUA_TNIL) | 185 | else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_SETTABLE))) |
| 183 | luaG_typeerror(L, t, "index"); | 186 | luaG_typeerror(L, t, "index"); |
| 184 | if (ttype(tm) == LUA_TFUNCTION) { | 187 | if (ttisfunction(tm)) { |
| 185 | callTM(L, tm, t, key, val); | 188 | callTM(L, tm, t, key, val); |
| 186 | return; | 189 | return; |
| 187 | } | 190 | } |
| @@ -195,9 +198,9 @@ static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2, | |||
| 195 | TObject *res, TMS event) { | 198 | TObject *res, TMS event) { |
| 196 | ptrdiff_t result = savestack(L, res); | 199 | ptrdiff_t result = savestack(L, res); |
| 197 | const TObject *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ | 200 | const TObject *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ |
| 198 | if (ttype(tm) == LUA_TNIL) | 201 | if (ttisnil(tm)) |
| 199 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ | 202 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ |
| 200 | if (ttype(tm) != LUA_TFUNCTION) return 0; | 203 | if (!ttisfunction(tm)) return 0; |
| 201 | callTMres(L, tm, p1, p2); | 204 | callTMres(L, tm, p1, p2); |
| 202 | res = restorestack(L, result); /* previous call may change stack */ | 205 | res = restorestack(L, result); /* previous call may change stack */ |
| 203 | setobj(res, L->top); | 206 | setobj(res, L->top); |
| @@ -230,9 +233,9 @@ static int luaV_strcmp (const TString *ls, const TString *rs) { | |||
| 230 | int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r) { | 233 | int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r) { |
| 231 | if (ttype(l) != ttype(r)) | 234 | if (ttype(l) != ttype(r)) |
| 232 | return luaG_ordererror(L, l, r); | 235 | return luaG_ordererror(L, l, r); |
| 233 | else if (ttype(l) == LUA_TNUMBER) | 236 | else if (ttisnumber(l)) |
| 234 | return nvalue(l) < nvalue(r); | 237 | return nvalue(l) < nvalue(r); |
| 235 | else if (ttype(l) == LUA_TSTRING) | 238 | else if (ttisstring(l)) |
| 236 | return luaV_strcmp(tsvalue(l), tsvalue(r)) < 0; | 239 | return luaV_strcmp(tsvalue(l), tsvalue(r)) < 0; |
| 237 | else if (call_binTM(L, l, r, L->top, TM_LT)) | 240 | else if (call_binTM(L, l, r, L->top, TM_LT)) |
| 238 | return !l_isfalse(L->top); | 241 | return !l_isfalse(L->top); |
| @@ -243,9 +246,9 @@ int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r) { | |||
| 243 | static int luaV_lessequal (lua_State *L, const TObject *l, const TObject *r) { | 246 | static int luaV_lessequal (lua_State *L, const TObject *l, const TObject *r) { |
| 244 | if (ttype(l) != ttype(r)) | 247 | if (ttype(l) != ttype(r)) |
| 245 | return luaG_ordererror(L, l, r); | 248 | return luaG_ordererror(L, l, r); |
| 246 | else if (ttype(l) == LUA_TNUMBER) | 249 | else if (ttisnumber(l)) |
| 247 | return nvalue(l) <= nvalue(r); | 250 | return nvalue(l) <= nvalue(r); |
| 248 | else if (ttype(l) == LUA_TSTRING) | 251 | else if (ttisstring(l)) |
| 249 | return luaV_strcmp(tsvalue(l), tsvalue(r)) <= 0; | 252 | return luaV_strcmp(tsvalue(l), tsvalue(r)) <= 0; |
| 250 | else if (call_binTM(L, l, r, L->top, TM_LE)) /* first try `le' */ | 253 | else if (call_binTM(L, l, r, L->top, TM_LE)) /* first try `le' */ |
| 251 | return !l_isfalse(L->top); | 254 | return !l_isfalse(L->top); |
| @@ -330,7 +333,7 @@ static void Arith (lua_State *L, StkId ra, StkId rb, StkId rc, TMS op) { | |||
| 330 | const TObject *f = luaH_getstr(hvalue(registry(L)), | 333 | const TObject *f = luaH_getstr(hvalue(registry(L)), |
| 331 | G(L)->tmname[TM_POW]); | 334 | G(L)->tmname[TM_POW]); |
| 332 | ptrdiff_t res = savestack(L, ra); | 335 | ptrdiff_t res = savestack(L, ra); |
| 333 | if (ttype(f) != LUA_TFUNCTION) | 336 | if (!ttisfunction(f)) |
| 334 | luaG_runerror(L, "`pow' (for `^' operator) is not a function"); | 337 | luaG_runerror(L, "`pow' (for `^' operator) is not a function"); |
| 335 | callTMres(L, f, b, c); | 338 | callTMres(L, f, b, c); |
| 336 | ra = restorestack(L, res); /* previous call may change stack */ | 339 | ra = restorestack(L, res); /* previous call may change stack */ |
| @@ -370,9 +373,9 @@ StkId luaV_execute (lua_State *L) { | |||
| 370 | TObject *k; | 373 | TObject *k; |
| 371 | const Instruction *pc; | 374 | const Instruction *pc; |
| 372 | callentry: /* entry point when calling new functions */ | 375 | callentry: /* entry point when calling new functions */ |
| 373 | L->ci->u.l.pc = &pc; | ||
| 374 | L->ci->u.l.pb = &base; | 376 | L->ci->u.l.pb = &base; |
| 375 | pc = L->ci->savedpc; | 377 | L->ci->pc = &pc; |
| 378 | pc = L->ci->u.l.savedpc; | ||
| 376 | if (L->hookmask & LUA_MASKCALL) | 379 | if (L->hookmask & LUA_MASKCALL) |
| 377 | luaD_callhook(L, LUA_HOOKCALL, -1); | 380 | luaD_callhook(L, LUA_HOOKCALL, -1); |
| 378 | retentry: /* entry point when returning to old functions */ | 381 | retentry: /* entry point when returning to old functions */ |
| @@ -382,11 +385,10 @@ StkId luaV_execute (lua_State *L) { | |||
| 382 | /* main loop of interpreter */ | 385 | /* main loop of interpreter */ |
| 383 | for (;;) { | 386 | for (;;) { |
| 384 | const Instruction i = *pc++; | 387 | const Instruction i = *pc++; |
| 385 | StkId ra; | 388 | const StkId ra = RA(i); |
| 386 | if (L->hookmask >= LUA_MASKLINE && | 389 | if (L->hookmask >= LUA_MASKLINE && |
| 387 | (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) | 390 | (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) |
| 388 | traceexec(L); | 391 | traceexec(L); |
| 389 | ra = RA(i); | ||
| 390 | lua_assert(L->top <= L->stack + L->stacksize && L->top >= L->ci->base); | 392 | lua_assert(L->top <= L->stack + L->stacksize && L->top >= L->ci->base); |
| 391 | lua_assert(L->top == L->ci->top || | 393 | lua_assert(L->top == L->ci->top || |
| 392 | GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL || | 394 | GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL || |
| @@ -420,9 +422,9 @@ StkId luaV_execute (lua_State *L) { | |||
| 420 | case OP_GETGLOBAL: { | 422 | case OP_GETGLOBAL: { |
| 421 | StkId rb = KBx(i); | 423 | StkId rb = KBx(i); |
| 422 | const TObject *v; | 424 | const TObject *v; |
| 423 | lua_assert(ttype(rb) == LUA_TSTRING && ttype(&cl->g) == LUA_TTABLE); | 425 | lua_assert(ttisstring(rb) && ttistable(&cl->g)); |
| 424 | v = luaH_getstr(hvalue(&cl->g), tsvalue(rb)); | 426 | v = luaH_getstr(hvalue(&cl->g), tsvalue(rb)); |
| 425 | if (ttype(v) != LUA_TNIL) { setobj(ra, v); } | 427 | if (!ttisnil(v)) { setobj(ra, v); } |
| 426 | else | 428 | else |
| 427 | setobj(RA(i), luaV_index(L, &cl->g, rb, 0)); | 429 | setobj(RA(i), luaV_index(L, &cl->g, rb, 0)); |
| 428 | break; | 430 | break; |
| @@ -430,9 +432,9 @@ StkId luaV_execute (lua_State *L) { | |||
| 430 | case OP_GETTABLE: { | 432 | case OP_GETTABLE: { |
| 431 | StkId rb = RB(i); | 433 | StkId rb = RB(i); |
| 432 | TObject *rc = RKC(i); | 434 | TObject *rc = RKC(i); |
| 433 | if (ttype(rb) == LUA_TTABLE) { | 435 | if (ttistable(rb)) { |
| 434 | const TObject *v = luaH_get(hvalue(rb), rc); | 436 | const TObject *v = luaH_get(hvalue(rb), rc); |
| 435 | if (ttype(v) != LUA_TNIL) { setobj(ra, v); } | 437 | if (!ttisnil(v)) { setobj(ra, v); } |
| 436 | else | 438 | else |
| 437 | setobj(RA(i), luaV_index(L, rb, rc, 0)); | 439 | setobj(RA(i), luaV_index(L, rb, rc, 0)); |
| 438 | } | 440 | } |
| @@ -441,7 +443,7 @@ StkId luaV_execute (lua_State *L) { | |||
| 441 | break; | 443 | break; |
| 442 | } | 444 | } |
| 443 | case OP_SETGLOBAL: { | 445 | case OP_SETGLOBAL: { |
| 444 | lua_assert(ttype(KBx(i)) == LUA_TSTRING && ttype(&cl->g) == LUA_TTABLE); | 446 | lua_assert(ttisstring(KBx(i)) && ttistable(&cl->g)); |
| 445 | luaV_settable(L, &cl->g, KBx(i), ra); | 447 | luaV_settable(L, &cl->g, KBx(i), ra); |
| 446 | break; | 448 | break; |
| 447 | } | 449 | } |
| @@ -464,11 +466,11 @@ StkId luaV_execute (lua_State *L) { | |||
| 464 | case OP_SELF: { | 466 | case OP_SELF: { |
| 465 | StkId rb = RB(i); | 467 | StkId rb = RB(i); |
| 466 | TObject *rc = RKC(i); | 468 | TObject *rc = RKC(i); |
| 467 | runtime_check(L, ttype(rc) == LUA_TSTRING); | 469 | runtime_check(L, ttisstring(rc)); |
| 468 | setobj(ra+1, rb); | 470 | setobj(ra+1, rb); |
| 469 | if (ttype(rb) == LUA_TTABLE) { | 471 | if (ttistable(rb)) { |
| 470 | const TObject *v = luaH_getstr(hvalue(rb), tsvalue(rc)); | 472 | const TObject *v = luaH_getstr(hvalue(rb), tsvalue(rc)); |
| 471 | if (ttype(v) != LUA_TNIL) { setobj(ra, v); } | 473 | if (!ttisnil(v)) { setobj(ra, v); } |
| 472 | else | 474 | else |
| 473 | setobj(RA(i), luaV_index(L, rb, rc, 0)); | 475 | setobj(RA(i), luaV_index(L, rb, rc, 0)); |
| 474 | } | 476 | } |
| @@ -479,7 +481,7 @@ StkId luaV_execute (lua_State *L) { | |||
| 479 | case OP_ADD: { | 481 | case OP_ADD: { |
| 480 | StkId rb = RB(i); | 482 | StkId rb = RB(i); |
| 481 | StkId rc = RKC(i); | 483 | StkId rc = RKC(i); |
| 482 | if (ttype(rb) == LUA_TNUMBER && ttype(rc) == LUA_TNUMBER) { | 484 | if (ttisnumber(rb) && ttisnumber(rc)) { |
| 483 | setnvalue(ra, nvalue(rb) + nvalue(rc)); | 485 | setnvalue(ra, nvalue(rb) + nvalue(rc)); |
| 484 | } | 486 | } |
| 485 | else | 487 | else |
| @@ -489,7 +491,7 @@ StkId luaV_execute (lua_State *L) { | |||
| 489 | case OP_SUB: { | 491 | case OP_SUB: { |
| 490 | StkId rb = RB(i); | 492 | StkId rb = RB(i); |
| 491 | StkId rc = RKC(i); | 493 | StkId rc = RKC(i); |
| 492 | if (ttype(rb) == LUA_TNUMBER && ttype(rc) == LUA_TNUMBER) { | 494 | if (ttisnumber(rb) && ttisnumber(rc)) { |
| 493 | setnvalue(ra, nvalue(rb) - nvalue(rc)); | 495 | setnvalue(ra, nvalue(rb) - nvalue(rc)); |
| 494 | } | 496 | } |
| 495 | else | 497 | else |
| @@ -499,7 +501,7 @@ StkId luaV_execute (lua_State *L) { | |||
| 499 | case OP_MUL: { | 501 | case OP_MUL: { |
| 500 | StkId rb = RB(i); | 502 | StkId rb = RB(i); |
| 501 | StkId rc = RKC(i); | 503 | StkId rc = RKC(i); |
| 502 | if (ttype(rb) == LUA_TNUMBER && ttype(rc) == LUA_TNUMBER) { | 504 | if (ttisnumber(rb) && ttisnumber(rc)) { |
| 503 | setnvalue(ra, nvalue(rb) * nvalue(rc)); | 505 | setnvalue(ra, nvalue(rb) * nvalue(rc)); |
| 504 | } | 506 | } |
| 505 | else | 507 | else |
| @@ -509,7 +511,7 @@ StkId luaV_execute (lua_State *L) { | |||
| 509 | case OP_DIV: { | 511 | case OP_DIV: { |
| 510 | StkId rb = RB(i); | 512 | StkId rb = RB(i); |
| 511 | StkId rc = RKC(i); | 513 | StkId rc = RKC(i); |
| 512 | if (ttype(rb) == LUA_TNUMBER && ttype(rc) == LUA_TNUMBER) { | 514 | if (ttisnumber(rb) && ttisnumber(rc)) { |
| 513 | setnvalue(ra, nvalue(rb) / nvalue(rc)); | 515 | setnvalue(ra, nvalue(rb) / nvalue(rc)); |
| 514 | } | 516 | } |
| 515 | else | 517 | else |
| @@ -584,7 +586,8 @@ StkId luaV_execute (lua_State *L) { | |||
| 584 | } | 586 | } |
| 585 | break; | 587 | break; |
| 586 | } | 588 | } |
| 587 | case OP_CALL: { | 589 | case OP_CALL: |
| 590 | case OP_TAILCALL: { | ||
| 588 | StkId firstResult; | 591 | StkId firstResult; |
| 589 | int b = GETARG_B(i); | 592 | int b = GETARG_B(i); |
| 590 | int nresults; | 593 | int nresults; |
| @@ -593,46 +596,47 @@ StkId luaV_execute (lua_State *L) { | |||
| 593 | firstResult = luaD_precall(L, ra); | 596 | firstResult = luaD_precall(L, ra); |
| 594 | if (firstResult) { | 597 | if (firstResult) { |
| 595 | if (firstResult > L->top) { /* yield? */ | 598 | if (firstResult > L->top) { /* yield? */ |
| 596 | (L->ci-1)->savedpc = pc; | 599 | (L->ci - 1)->u.l.savedpc = pc; |
| 600 | (L->ci - 1)->pc = &luaV_callingmark; | ||
| 597 | return NULL; | 601 | return NULL; |
| 598 | } | 602 | } |
| 599 | /* it was a C function (`precall' called it); adjust results */ | 603 | /* it was a C function (`precall' called it); adjust results */ |
| 600 | luaD_poscall(L, nresults, firstResult); | 604 | luaD_poscall(L, nresults, firstResult); |
| 601 | if (nresults >= 0) L->top = L->ci->top; | 605 | if (nresults >= 0) L->top = L->ci->top; |
| 602 | } | 606 | } |
| 603 | else { /* it is a Lua function: `call' it */ | 607 | else { /* it is a Lua function */ |
| 604 | (L->ci-1)->savedpc = pc; | 608 | if (GET_OPCODE(i) == OP_CALL) { /* regular call? */ |
| 609 | (L->ci-1)->u.l.savedpc = pc; /* save `pc' to return later */ | ||
| 610 | (L->ci-1)->pc = &luaV_callingmark; /* function is calling */ | ||
| 611 | } | ||
| 612 | else { /* tail call: put new frame in place of previous one */ | ||
| 613 | int aux; | ||
| 614 | StkId ra1 = RA(i); /* `luaD_precall' may change the stack */ | ||
| 615 | if (L->openupval) luaF_close(L, base); | ||
| 616 | for (aux = 0; ra1+aux < L->top; aux++) /* move frame down */ | ||
| 617 | setobj(base+aux-1, ra1+aux); | ||
| 618 | (L->ci - 1)->top = L->top = base+aux; /* correct top */ | ||
| 619 | (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc; | ||
| 620 | L->ci--; /* remove previous frame */ | ||
| 621 | } | ||
| 605 | goto callentry; | 622 | goto callentry; |
| 606 | } | 623 | } |
| 607 | break; | 624 | break; |
| 608 | } | 625 | } |
| 609 | case OP_TAILCALL: { | ||
| 610 | int b = GETARG_B(i); | ||
| 611 | if (L->openupval) luaF_close(L, base); | ||
| 612 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ | ||
| 613 | luaD_poscall(L, LUA_MULTRET, ra); /* move down function and args. */ | ||
| 614 | ra = luaD_precall(L, base-1); | ||
| 615 | if (ra == NULL) goto callentry; /* it is a Lua function */ | ||
| 616 | else if (ra > L->top) return NULL; /* yield??? */ | ||
| 617 | else goto ret; | ||
| 618 | } | ||
| 619 | case OP_RETURN: { | 626 | case OP_RETURN: { |
| 620 | int b; | 627 | CallInfo *ci = L->ci - 1; |
| 621 | if (L->openupval) luaF_close(L, base); | 628 | int b = GETARG_B(i); |
| 622 | b = GETARG_B(i); | ||
| 623 | if (b != 0) L->top = ra+b-1; | 629 | if (b != 0) L->top = ra+b-1; |
| 624 | lua_assert(L->ci->u.l.pc == &pc); | 630 | lua_assert(L->ci->pc == &pc); |
| 625 | } | 631 | if (L->openupval) luaF_close(L, base); |
| 626 | ret: { | ||
| 627 | CallInfo *ci; | ||
| 628 | ci = L->ci - 1; | ||
| 629 | /* previous function was running `here'? */ | 632 | /* previous function was running `here'? */ |
| 630 | if (!isLua(ci) || ci->u.l.pc != &pc) | 633 | if (ci->pc != &luaV_callingmark) |
| 631 | return ra; /* no: return */ | 634 | return ra; /* no: return */ |
| 632 | else { /* yes: continue its execution */ | 635 | else { /* yes: continue its execution (go through) */ |
| 633 | int nresults; | 636 | int nresults; |
| 634 | lua_assert(ttype(ci->base-1) == LUA_TFUNCTION); | 637 | lua_assert(ttisfunction(ci->base-1)); |
| 635 | pc = ci->savedpc; | 638 | ci->pc = &pc; /* function is active again */ |
| 639 | pc = ci->u.l.savedpc; | ||
| 636 | lua_assert(GET_OPCODE(*(pc-1)) == OP_CALL); | 640 | lua_assert(GET_OPCODE(*(pc-1)) == OP_CALL); |
| 637 | nresults = GETARG_C(*(pc-1)) - 1; | 641 | nresults = GETARG_C(*(pc-1)) - 1; |
| 638 | luaD_poscall(L, nresults, ra); | 642 | luaD_poscall(L, nresults, ra); |
| @@ -644,7 +648,7 @@ StkId luaV_execute (lua_State *L) { | |||
| 644 | lua_Number step, index, limit; | 648 | lua_Number step, index, limit; |
| 645 | const TObject *plimit = ra+1; | 649 | const TObject *plimit = ra+1; |
| 646 | const TObject *pstep = ra+2; | 650 | const TObject *pstep = ra+2; |
| 647 | if (ttype(ra) != LUA_TNUMBER) | 651 | if (!ttisnumber(ra)) |
| 648 | luaG_runerror(L, "`for' initial value must be a number"); | 652 | luaG_runerror(L, "`for' initial value must be a number"); |
| 649 | if (!tonumber(plimit, ra+1)) | 653 | if (!tonumber(plimit, ra+1)) |
| 650 | luaG_runerror(L, "`for' limit must be a number"); | 654 | luaG_runerror(L, "`for' limit must be a number"); |
| @@ -666,12 +670,12 @@ StkId luaV_execute (lua_State *L) { | |||
| 666 | L->top = ra+5; | 670 | L->top = ra+5; |
| 667 | luaD_call(L, ra+2, GETARG_C(i) + 1); | 671 | luaD_call(L, ra+2, GETARG_C(i) + 1); |
| 668 | L->top = L->ci->top; | 672 | L->top = L->ci->top; |
| 669 | if (ttype(ra+2) == LUA_TNIL) pc++; /* skip jump (break loop) */ | 673 | if (ttisnil(ra+2)) pc++; /* skip jump (break loop) */ |
| 670 | else dojump(pc, GETARG_sBx(*pc) + 1); /* else jump back */ | 674 | else dojump(pc, GETARG_sBx(*pc) + 1); /* else jump back */ |
| 671 | break; | 675 | break; |
| 672 | } | 676 | } |
| 673 | case OP_TFORPREP: { /* for compatibility only */ | 677 | case OP_TFORPREP: { /* for compatibility only */ |
| 674 | if (ttype(ra) == LUA_TTABLE) { | 678 | if (ttistable(ra)) { |
| 675 | setobj(ra+1, ra); | 679 | setobj(ra+1, ra); |
| 676 | setobj(ra, luaH_getstr(hvalue(gt(L)), luaS_new(L, "next"))); | 680 | setobj(ra, luaH_getstr(hvalue(gt(L)), luaS_new(L, "next"))); |
| 677 | } | 681 | } |
| @@ -683,7 +687,7 @@ StkId luaV_execute (lua_State *L) { | |||
| 683 | int bc; | 687 | int bc; |
| 684 | int n; | 688 | int n; |
| 685 | Table *h; | 689 | Table *h; |
| 686 | runtime_check(L, ttype(ra) == LUA_TTABLE); | 690 | runtime_check(L, ttistable(ra)); |
| 687 | h = hvalue(ra); | 691 | h = hvalue(ra); |
| 688 | bc = GETARG_Bx(i); | 692 | bc = GETARG_Bx(i); |
| 689 | if (GET_OPCODE(i) == OP_SETLIST) | 693 | if (GET_OPCODE(i) == OP_SETLIST) |
