aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-02-01 14:03:38 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-02-01 14:03:38 -0200
commit4ab6acacdfdb5d5d29ed4d089aeda3ec6d82670b (patch)
tree86b28ac2c82f1d69a29ec8c842e6b559ad2b9923 /lvm.c
parent68587639945aa68844871fdd74a6729b653f523a (diff)
downloadlua-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.c138
1 files changed, 73 insertions, 65 deletions
diff --git a/lvm.c b/lvm.c
index 5c00648e..f0f6df31 100644
--- a/lvm.c
+++ b/lvm.c
@@ -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*/
116const TObject *luaV_gettable (lua_State *L, StkId t) { 117void 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*/
151void luaV_settable (lua_State *L, StkId t, StkId key) { 153void 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
175const TObject *luaV_getglobal (lua_State *L, TString *s) { 180void 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
193void luaV_setglobal (lua_State *L, TString *s) { 201void 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 }