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 | } |