diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-02-01 14:03:38 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-02-01 14:03:38 -0200 |
| commit | 4ab6acacdfdb5d5d29ed4d089aeda3ec6d82670b (patch) | |
| tree | 86b28ac2c82f1d69a29ec8c842e6b559ad2b9923 /lvm.c | |
| parent | 68587639945aa68844871fdd74a6729b653f523a (diff) | |
| download | lua-4ab6acacdfdb5d5d29ed4d089aeda3ec6d82670b.tar.gz lua-4ab6acacdfdb5d5d29ed4d089aeda3ec6d82670b.tar.bz2 lua-4ab6acacdfdb5d5d29ed4d089aeda3ec6d82670b.zip | |
better control of relationship top x L->top
Diffstat (limited to 'lvm.c')
| -rw-r--r-- | lvm.c | 138 |
1 files changed, 73 insertions, 65 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 1.160 2001/01/29 15:26:40 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.161 2001/01/29 17:16:58 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 | */ |
| @@ -111,36 +111,38 @@ void luaV_Lclosure (lua_State *L, Proto *l, int nelems) { | |||
| 111 | 111 | ||
| 112 | /* | 112 | /* |
| 113 | ** Function to index a table. | 113 | ** Function to index a table. |
| 114 | ** Receives the table at `t' and the key at top. | 114 | ** Receives the table at `t' and the key at the top (`top'-1), |
| 115 | ** leaves the result at `res'. | ||
| 115 | */ | 116 | */ |
| 116 | const TObject *luaV_gettable (lua_State *L, StkId t) { | 117 | void luaV_gettable (lua_State *L, StkId t, StkId top, StkId res) { |
| 117 | Closure *tm; | 118 | Closure *tm; |
| 118 | int tg; | 119 | int tg; |
| 119 | if (ttype(t) == LUA_TTABLE && /* `t' is a table? */ | 120 | if (ttype(t) == LUA_TTABLE && /* `t' is a table? */ |
| 120 | ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ | 121 | ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ |
| 121 | luaT_gettm(G(L), tg, TM_GETTABLE) == NULL)) { /* or no TM? */ | 122 | luaT_gettm(G(L), tg, TM_GETTABLE) == NULL)) { /* or no TM? */ |
| 122 | /* do a primitive get */ | 123 | /* do a primitive get */ |
| 123 | const TObject *h = luaH_get(hvalue(t), L->top-1); | 124 | const TObject *h = luaH_get(hvalue(t), top-1); |
| 124 | /* result is no nil or there is no `index' tag method? */ | 125 | /* result is no nil or there is no `index' tag method? */ |
| 125 | if (ttype(h) != LUA_TNIL || ((tm=luaT_gettm(G(L), tg, TM_INDEX)) == NULL)) | 126 | if (ttype(h) != LUA_TNIL || ((tm=luaT_gettm(G(L), tg, TM_INDEX)) == NULL)) { |
| 126 | return h; /* return result */ | 127 | setobj(res, h); |
| 128 | return; | ||
| 129 | } | ||
| 127 | /* else call `index' tag method */ | 130 | /* else call `index' tag method */ |
| 128 | } | 131 | } |
| 129 | else { /* try a `gettable' tag method */ | 132 | else { /* try a `gettable' tag method */ |
| 130 | tm = luaT_gettmbyObj(G(L), t, TM_GETTABLE); | 133 | tm = luaT_gettmbyObj(G(L), t, TM_GETTABLE); |
| 131 | } | 134 | } |
| 132 | if (tm != NULL) { /* is there a tag method? */ | 135 | L->top = top; |
| 133 | luaD_checkstack(L, 2); | 136 | if (tm == NULL) /* no tag method? */ |
| 134 | setobj(L->top+1, L->top-1); /* key */ | ||
| 135 | setobj(L->top, t); /* table */ | ||
| 136 | setclvalue(L->top-1, tm); /* tag method */ | ||
| 137 | L->top += 2; | ||
| 138 | luaD_call(L, L->top - 3, 1); | ||
| 139 | return L->top - 1; /* call result */ | ||
| 140 | } | ||
| 141 | else { /* no tag method */ | ||
| 142 | luaG_typeerror(L, t, "index"); | 137 | luaG_typeerror(L, t, "index"); |
| 143 | return NULL; /* to avoid warnings */ | 138 | else { /* call tag method */ |
| 139 | luaD_checkstack(L, 2); | ||
| 140 | setobj(res+2, top-1); /* key */ | ||
| 141 | setobj(res+1, t); /* table */ | ||
| 142 | setclvalue(res, tm); /* tag method */ | ||
| 143 | L->top = res+3; | ||
| 144 | luaD_call(L, res, 1); | ||
| 145 | L->top = top; /* will be decremented by the callee */ | ||
| 144 | } | 146 | } |
| 145 | } | 147 | } |
| 146 | 148 | ||
| @@ -148,63 +150,72 @@ const TObject *luaV_gettable (lua_State *L, StkId t) { | |||
| 148 | /* | 150 | /* |
| 149 | ** Receives table at `t', key at `key' and value at top. | 151 | ** Receives table at `t', key at `key' and value at top. |
| 150 | */ | 152 | */ |
| 151 | void luaV_settable (lua_State *L, StkId t, StkId key) { | 153 | void luaV_settable (lua_State *L, StkId t, StkId key, StkId top) { |
| 152 | int tg; | 154 | int tg; |
| 153 | if (ttype(t) == LUA_TTABLE && /* `t' is a table? */ | 155 | if (ttype(t) == LUA_TTABLE && /* `t' is a table? */ |
| 154 | ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ | 156 | ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ |
| 155 | luaT_gettm(G(L), tg, TM_SETTABLE) == NULL)) { /* or no TM? */ | 157 | luaT_gettm(G(L), tg, TM_SETTABLE) == NULL)) { /* or no TM? */ |
| 156 | setobj(luaH_set(L, hvalue(t), key), L->top-1); /* do a primitive set */ | 158 | setobj(luaH_set(L, hvalue(t), key), top-1); /* do a primitive set */ |
| 157 | } | 159 | } |
| 158 | else { /* try a `settable' tag method */ | 160 | else { /* try a `settable' tag method */ |
| 159 | Closure *tm = luaT_gettmbyObj(G(L), t, TM_SETTABLE); | 161 | Closure *tm = luaT_gettmbyObj(G(L), t, TM_SETTABLE); |
| 160 | if (tm != NULL) { | 162 | L->top = top; |
| 163 | if (tm == NULL) /* no tag method? */ | ||
| 164 | luaG_typeerror(L, t, "index"); | ||
| 165 | else { | ||
| 161 | luaD_checkstack(L, 3); | 166 | luaD_checkstack(L, 3); |
| 162 | setobj(L->top+2, L->top-1); | 167 | setobj(top+2, top-1); |
| 163 | setobj(L->top+1, key); | 168 | setobj(top+1, key); |
| 164 | setobj(L->top, t); | 169 | setobj(top, t); |
| 165 | setclvalue(L->top-1, tm); | 170 | setclvalue(top-1, tm); |
| 166 | L->top += 3; | 171 | L->top = top+3; |
| 167 | luaD_call(L, L->top - 4, 0); /* call `settable' tag method */ | 172 | luaD_call(L, top-1, 0); /* call `settable' tag method */ |
| 173 | lua_assert(L->top == top-1); | ||
| 174 | L->top = top; /* will be decremented by the callee */ | ||
| 168 | } | 175 | } |
| 169 | else /* no tag method... */ | ||
| 170 | luaG_typeerror(L, t, "index"); | ||
| 171 | } | 176 | } |
| 172 | } | 177 | } |
| 173 | 178 | ||
| 174 | 179 | ||
| 175 | const TObject *luaV_getglobal (lua_State *L, TString *s) { | 180 | void luaV_getglobal (lua_State *L, TString *s, StkId top) { |
| 176 | const TObject *value = luaH_getstr(L->gt, s); | 181 | const TObject *value = luaH_getstr(L->gt, s); |
| 177 | Closure *tm; | 182 | Closure *tm; |
| 178 | if (!HAS_TM_GETGLOBAL(L, ttype(value)) || /* is there a tag method? */ | 183 | if (!HAS_TM_GETGLOBAL(L, ttype(value)) || /* is there a tag method? */ |
| 179 | (tm = luaT_gettmbyObj(G(L), value, TM_GETGLOBAL)) == NULL) | 184 | (tm = luaT_gettmbyObj(G(L), value, TM_GETGLOBAL)) == NULL) { |
| 180 | return value; /* default behavior */ | 185 | setobj(top, value); /* default behavior */ |
| 181 | else { /* tag method */ | 186 | } |
| 187 | else { /* call tag method */ | ||
| 188 | L->top = top; | ||
| 182 | luaD_checkstack(L, 3); | 189 | luaD_checkstack(L, 3); |
| 183 | setclvalue(L->top, tm); | 190 | setclvalue(top, tm); |
| 184 | setsvalue(L->top+1, s); /* global name */ | 191 | setsvalue(top+1, s); /* global name */ |
| 185 | setobj(L->top+2, value); | 192 | setobj(top+2, value); |
| 186 | L->top += 3; | 193 | L->top = top+3; |
| 187 | luaD_call(L, L->top - 3, 1); | 194 | luaD_call(L, top, 1); |
| 188 | return L->top - 1; | 195 | lua_assert(L->top == top+1); |
| 196 | L->top = top; /* will be incremented by the callee */ | ||
| 189 | } | 197 | } |
| 190 | } | 198 | } |
| 191 | 199 | ||
| 192 | 200 | ||
| 193 | void luaV_setglobal (lua_State *L, TString *s) { | 201 | void luaV_setglobal (lua_State *L, TString *s, StkId top) { |
| 194 | TObject *oldvalue = luaH_setstr(L, L->gt, s); | 202 | TObject *oldvalue = luaH_setstr(L, L->gt, s); |
| 195 | Closure *tm; | 203 | Closure *tm; |
| 196 | if (!HAS_TM_SETGLOBAL(L, ttype(oldvalue)) || /* no tag methods? */ | 204 | if (!HAS_TM_SETGLOBAL(L, ttype(oldvalue)) || /* no tag methods? */ |
| 197 | (tm = luaT_gettmbyObj(G(L), oldvalue, TM_SETGLOBAL)) == NULL) { | 205 | (tm = luaT_gettmbyObj(G(L), oldvalue, TM_SETGLOBAL)) == NULL) { |
| 198 | setobj(oldvalue, L->top - 1); /* raw set */ | 206 | setobj(oldvalue, top-1); /* raw set */ |
| 199 | } | 207 | } |
| 200 | else { /* call tag method */ | 208 | else { /* call tag method */ |
| 209 | L->top = top; | ||
| 201 | luaD_checkstack(L, 3); | 210 | luaD_checkstack(L, 3); |
| 202 | setobj(L->top+2, L->top-1); /* new value */ | 211 | setobj(top+2, top-1); /* new value */ |
| 203 | setobj(L->top+1, oldvalue); /* old value */ | 212 | setobj(top+1, oldvalue); /* old value */ |
| 204 | setsvalue(L->top, s); /* var name */ | 213 | setsvalue(top, s); /* var name */ |
| 205 | setclvalue(L->top-1, tm); /* tag method */ | 214 | setclvalue(top-1, tm); /* tag method */ |
| 206 | L->top += 3; | 215 | L->top = top+3; |
| 207 | luaD_call(L, L->top - 4, 0); | 216 | luaD_call(L, top-1, 0); |
| 217 | lua_assert(L->top == top-1); | ||
| 218 | L->top = top; /* will be decremented by the callee */ | ||
| 208 | } | 219 | } |
| 209 | } | 220 | } |
| 210 | 221 | ||
| @@ -262,11 +273,12 @@ int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top) | |||
| 262 | else if (ttype(l) == LUA_TSTRING && ttype(r) == LUA_TSTRING) | 273 | else if (ttype(l) == LUA_TSTRING && ttype(r) == LUA_TSTRING) |
| 263 | return luaV_strlessthan(tsvalue(l), tsvalue(r)); | 274 | return luaV_strlessthan(tsvalue(l), tsvalue(r)); |
| 264 | else { /* call TM */ | 275 | else { /* call TM */ |
| 276 | L->top = top; | ||
| 265 | luaD_checkstack(L, 2); | 277 | luaD_checkstack(L, 2); |
| 266 | setobj(top++, l); | 278 | setobj(top++, l); |
| 267 | setobj(top++, r); | 279 | setobj(top++, r); |
| 268 | if (!call_binTM(L, top, TM_LT)) | 280 | if (!call_binTM(L, top, TM_LT)) |
| 269 | luaG_ordererror(L, top-2); | 281 | luaG_ordererror(L, top); |
| 270 | L->top--; | 282 | L->top--; |
| 271 | return (ttype(L->top) != LUA_TNIL); | 283 | return (ttype(L->top) != LUA_TNIL); |
| 272 | } | 284 | } |
| @@ -413,34 +425,31 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 413 | break; | 425 | break; |
| 414 | } | 426 | } |
| 415 | case OP_GETGLOBAL: { | 427 | case OP_GETGLOBAL: { |
| 416 | L->top = top; | 428 | luaV_getglobal(L, kstr[GETARG_U(i)], top); |
| 417 | setobj(top++, luaV_getglobal(L, kstr[GETARG_U(i)])); | 429 | top++; |
| 418 | break; | 430 | break; |
| 419 | } | 431 | } |
| 420 | case OP_GETTABLE: { | 432 | case OP_GETTABLE: { |
| 421 | L->top = top; | 433 | luaV_gettable(L, top-2, top, top-2); |
| 422 | top--; | 434 | top--; |
| 423 | setobj(top-1, luaV_gettable(L, top-1)); | ||
| 424 | break; | 435 | break; |
| 425 | } | 436 | } |
| 426 | case OP_GETDOTTED: { | 437 | case OP_GETDOTTED: { |
| 427 | setsvalue(top, kstr[GETARG_U(i)]); | 438 | setsvalue(top, kstr[GETARG_U(i)]); |
| 428 | L->top = top+1; | 439 | luaV_gettable(L, top-1, top+1, top-1); |
| 429 | setobj(top-1, luaV_gettable(L, top-1)); | ||
| 430 | break; | 440 | break; |
| 431 | } | 441 | } |
| 432 | case OP_GETINDEXED: { | 442 | case OP_GETINDEXED: { |
| 433 | setobj(top, base+GETARG_U(i)); | 443 | setobj(top, base+GETARG_U(i)); |
| 434 | L->top = top+1; | 444 | luaV_gettable(L, top-1, top+1, top-1); |
| 435 | setobj(top-1, luaV_gettable(L, top-1)); | ||
| 436 | break; | 445 | break; |
| 437 | } | 446 | } |
| 438 | case OP_PUSHSELF: { | 447 | case OP_PUSHSELF: { |
| 439 | TObject receiver; | 448 | TObject receiver; |
| 440 | setobj(&receiver, top-1); | 449 | setobj(&receiver, top-1); |
| 441 | setsvalue(top, kstr[GETARG_U(i)]); | 450 | setsvalue(top, kstr[GETARG_U(i)]); |
| 442 | L->top = ++top; | 451 | top++; |
| 443 | setobj(top-2, luaV_gettable(L, top-2)); | 452 | luaV_gettable(L, top-2, top, top-2); |
| 444 | setobj(top-1, &receiver); | 453 | setobj(top-1, &receiver); |
| 445 | break; | 454 | break; |
| 446 | } | 455 | } |
| @@ -456,14 +465,13 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 456 | break; | 465 | break; |
| 457 | } | 466 | } |
| 458 | case OP_SETGLOBAL: { | 467 | case OP_SETGLOBAL: { |
| 459 | L->top = top--; | 468 | luaV_setglobal(L, kstr[GETARG_U(i)], top); |
| 460 | luaV_setglobal(L, kstr[GETARG_U(i)]); | 469 | top--; |
| 461 | break; | 470 | break; |
| 462 | } | 471 | } |
| 463 | case OP_SETTABLE: { | 472 | case OP_SETTABLE: { |
| 464 | StkId t = top-GETARG_A(i); | 473 | StkId t = top-GETARG_A(i); |
| 465 | L->top = top; | 474 | luaV_settable(L, t, t+1, top); |
| 466 | luaV_settable(L, t, t+1); | ||
| 467 | top -= GETARG_B(i); /* pop values */ | 475 | top -= GETARG_B(i); /* pop values */ |
| 468 | break; | 476 | break; |
| 469 | } | 477 | } |
| @@ -471,7 +479,6 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 471 | int aux = GETARG_A(i) * LFIELDS_PER_FLUSH; | 479 | int aux = GETARG_A(i) * LFIELDS_PER_FLUSH; |
| 472 | int n = GETARG_B(i); | 480 | int n = GETARG_B(i); |
| 473 | Hash *arr = hvalue(top-n-1); | 481 | Hash *arr = hvalue(top-n-1); |
| 474 | L->top = top-n; /* final value of `top' (in case of errors) */ | ||
| 475 | for (; n; n--) | 482 | for (; n; n--) |
| 476 | setobj(luaH_setnum(L, arr, n+aux), --top); | 483 | setobj(luaH_setnum(L, arr, n+aux), --top); |
| 477 | break; | 484 | break; |
| @@ -480,7 +487,6 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 480 | int n = GETARG_U(i); | 487 | int n = GETARG_U(i); |
| 481 | StkId finaltop = top-2*n; | 488 | StkId finaltop = top-2*n; |
| 482 | Hash *arr = hvalue(finaltop-1); | 489 | Hash *arr = hvalue(finaltop-1); |
| 483 | L->top = finaltop; /* final value of `top' (in case of errors) */ | ||
| 484 | for (; n; n--) { | 490 | for (; n; n--) { |
| 485 | top-=2; | 491 | top-=2; |
| 486 | setobj(luaH_set(L, arr, top), top+1); | 492 | setobj(luaH_set(L, arr, top), top+1); |
| @@ -669,9 +675,11 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 669 | break; | 675 | break; |
| 670 | } | 676 | } |
| 671 | case OP_CLOSURE: { | 677 | case OP_CLOSURE: { |
| 678 | int nup = GETARG_B(i); | ||
| 672 | L->top = top; | 679 | L->top = top; |
| 673 | luaV_Lclosure(L, tf->kproto[GETARG_A(i)], GETARG_B(i)); | 680 | luaV_Lclosure(L, tf->kproto[GETARG_A(i)], nup); |
| 674 | top = L->top; | 681 | top -= (nup-1); |
| 682 | lua_assert(top == L->top); | ||
| 675 | luaC_checkGC(L); | 683 | luaC_checkGC(L); |
| 676 | break; | 684 | break; |
| 677 | } | 685 | } |
