aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-12-01 17:50:08 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-12-01 17:50:08 -0200
commitfe237ad8085f34e89fcd3610a9771215af63f03f (patch)
treef7ee5d8f7d1ffb74e94f049aa6f31eb03606cdf6
parent3181dfefee40b9a424b80aa779c671f5f458904c (diff)
downloadlua-fe237ad8085f34e89fcd3610a9771215af63f03f.tar.gz
lua-fe237ad8085f34e89fcd3610a9771215af63f03f.tar.bz2
lua-fe237ad8085f34e89fcd3610a9771215af63f03f.zip
fixed stack; first version.
-rw-r--r--lapi.c103
-rw-r--r--lbuiltin.c99
-rw-r--r--ldo.c171
-rw-r--r--ldo.h18
-rw-r--r--lgc.c8
-rw-r--r--lparser.c8
-rw-r--r--lstate.c7
-rw-r--r--lstate.h27
-rw-r--r--lvm.c351
-rw-r--r--lvm.h10
10 files changed, 400 insertions, 402 deletions
diff --git a/lapi.c b/lapi.c
index 50355b06..364179a4 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 1.59 1999/11/29 19:11:36 roberto Exp roberto $ 2** $Id: lapi.c,v 1.60 1999/11/29 19:31:29 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -63,28 +63,28 @@ static const TObject *luaA_protovalue (const TObject *o) {
63 63
64 64
65static void checkCparams (lua_State *L, int nParams) { 65static void checkCparams (lua_State *L, int nParams) {
66 if (L->stack.top-L->stack.stack < L->Cstack.base+nParams) 66 if (nParams > L->top-L->Cstack.base)
67 lua_error(L, "API error - wrong number of arguments in C2lua stack"); 67 lua_error(L, "API error - wrong number of arguments in C2lua stack");
68} 68}
69 69
70 70
71static lua_Object put_luaObject (lua_State *L, const TObject *o) { 71static lua_Object put_luaObject (lua_State *L, const TObject *o) {
72 luaD_openstack(L, (L->stack.top-L->stack.stack)-L->Cstack.base); 72 luaD_openstack(L, L->Cstack.base);
73 L->stack.stack[L->Cstack.base++] = *o; 73 *L->Cstack.base++ = *o;
74 return L->Cstack.base; /* this is +1 real position (see Ref) */ 74 return Ref(L, L->Cstack.base-1);
75} 75}
76 76
77 77
78lua_Object luaA_putObjectOnTop (lua_State *L) { 78lua_Object luaA_putObjectOnTop (lua_State *L) {
79 luaD_openstack(L, (L->stack.top-L->stack.stack)-L->Cstack.base); 79 luaD_openstack(L, L->Cstack.base);
80 L->stack.stack[L->Cstack.base++] = *(--L->stack.top); 80 *L->Cstack.base++ = *(--L->top);
81 return L->Cstack.base; /* this is +1 real position (see Ref) */ 81 return Ref(L, L->Cstack.base-1);
82} 82}
83 83
84 84
85static void top2LC (lua_State *L, int n) { 85static void top2LC (lua_State *L, int n) {
86 /* Put the 'n' elements on the top as the Lua2C contents */ 86 /* Put the 'n' elements on the top as the Lua2C contents */
87 L->Cstack.base = (L->stack.top-L->stack.stack); /* new base */ 87 L->Cstack.base = L->top; /* new base */
88 L->Cstack.lua2C = L->Cstack.base-n; /* position of the new results */ 88 L->Cstack.lua2C = L->Cstack.base-n; /* position of the new results */
89 L->Cstack.num = n; /* number of results */ 89 L->Cstack.num = n; /* number of results */
90} 90}
@@ -98,13 +98,11 @@ lua_Object lua_pop (lua_State *L) {
98 98
99/* 99/*
100** Get a parameter, returning the object handle or LUA_NOOBJECT on error. 100** Get a parameter, returning the object handle or LUA_NOOBJECT on error.
101** 'number' must be 1 to get the first parameter. 101** `number' must be 1 to get the first parameter.
102*/ 102*/
103lua_Object lua_lua2C (lua_State *L, int number) { 103lua_Object lua_lua2C (lua_State *L, int number) {
104 if (number <= 0 || number > L->Cstack.num) return LUA_NOOBJECT; 104 if (number <= 0 || number > L->Cstack.num) return LUA_NOOBJECT;
105 /* Ref(L, L->stack.stack+(L->Cstack.lua2C+number-1)) == 105 return Ref(L, L->Cstack.lua2C+number-1);
106 L->stack.stack+(L->Cstack.lua2C+number-1)-L->stack.stack+1 == */
107 return L->Cstack.lua2C+number;
108} 106}
109 107
110 108
@@ -112,8 +110,8 @@ int lua_callfunction (lua_State *L, lua_Object function) {
112 if (function == LUA_NOOBJECT) 110 if (function == LUA_NOOBJECT)
113 return 1; 111 return 1;
114 else { 112 else {
115 luaD_openstack(L, (L->stack.top-L->stack.stack)-L->Cstack.base); 113 luaD_openstack(L, L->Cstack.base);
116 set_normalized(L->stack.stack+L->Cstack.base, Address(L, function)); 114 set_normalized(L->Cstack.base, Address(L, function));
117 return luaD_protectedrun(L); 115 return luaD_protectedrun(L);
118 } 116 }
119} 117}
@@ -126,7 +124,7 @@ lua_Object lua_gettagmethod (lua_State *L, int tag, const char *event) {
126 124
127lua_Object lua_settagmethod (lua_State *L, int tag, const char *event) { 125lua_Object lua_settagmethod (lua_State *L, int tag, const char *event) {
128 checkCparams(L, 1); 126 checkCparams(L, 1);
129 luaT_settagmethod(L, tag, event, L->stack.top-1); 127 luaT_settagmethod(L, tag, event, L->top-1);
130 return luaA_putObjectOnTop(L); 128 return luaA_putObjectOnTop(L);
131} 129}
132 130
@@ -149,24 +147,24 @@ lua_Object lua_gettable (lua_State *L) {
149 147
150lua_Object lua_rawgettable (lua_State *L) { 148lua_Object lua_rawgettable (lua_State *L) {
151 checkCparams(L, 2); 149 checkCparams(L, 2);
152 if (ttype(L->stack.top-2) != LUA_T_ARRAY) 150 if (ttype(L->top-2) != LUA_T_ARRAY)
153 lua_error(L, "indexed expression not a table in rawgettable"); 151 lua_error(L, "indexed expression not a table in rawgettable");
154 *(L->stack.top-2) = *luaH_get(L, avalue(L->stack.top-2), L->stack.top-1); 152 *(L->top-2) = *luaH_get(L, avalue(L->top-2), L->top-1);
155 --L->stack.top; 153 --L->top;
156 return luaA_putObjectOnTop(L); 154 return luaA_putObjectOnTop(L);
157} 155}
158 156
159 157
160void lua_settable (lua_State *L) { 158void lua_settable (lua_State *L) {
161 checkCparams(L, 3); 159 checkCparams(L, 3);
162 luaV_settable(L, L->stack.top-3); 160 luaV_settable(L, L->top-3);
163 L->stack.top -= 2; /* pop table and index */ 161 L->top -= 2; /* pop table and index */
164} 162}
165 163
166 164
167void lua_rawsettable (lua_State *L) { 165void lua_rawsettable (lua_State *L) {
168 checkCparams(L, 3); 166 checkCparams(L, 3);
169 luaV_rawsettable(L, L->stack.top-3); 167 luaV_rawsettable(L, L->top-3);
170} 168}
171 169
172 170
@@ -202,7 +200,7 @@ void lua_setglobal (lua_State *L, const char *name) {
202void lua_rawsetglobal (lua_State *L, const char *name) { 200void lua_rawsetglobal (lua_State *L, const char *name) {
203 GlobalVar *gv = luaS_assertglobalbyname(L, name); 201 GlobalVar *gv = luaS_assertglobalbyname(L, name);
204 checkCparams(L, 1); 202 checkCparams(L, 1);
205 gv->value = *(--L->stack.top); 203 gv->value = *(--L->top);
206} 204}
207 205
208 206
@@ -280,19 +278,19 @@ lua_CFunction lua_getcfunction (lua_State *L, lua_Object obj) {
280 278
281 279
282void lua_pushnil (lua_State *L) { 280void lua_pushnil (lua_State *L) {
283 ttype(L->stack.top) = LUA_T_NIL; 281 ttype(L->top) = LUA_T_NIL;
284 incr_top; 282 incr_top;
285} 283}
286 284
287void lua_pushnumber (lua_State *L, double n) { 285void lua_pushnumber (lua_State *L, double n) {
288 ttype(L->stack.top) = LUA_T_NUMBER; 286 ttype(L->top) = LUA_T_NUMBER;
289 nvalue(L->stack.top) = n; 287 nvalue(L->top) = n;
290 incr_top; 288 incr_top;
291} 289}
292 290
293void lua_pushlstring (lua_State *L, const char *s, long len) { 291void lua_pushlstring (lua_State *L, const char *s, long len) {
294 tsvalue(L->stack.top) = luaS_newlstr(L, s, len); 292 tsvalue(L->top) = luaS_newlstr(L, s, len);
295 ttype(L->stack.top) = LUA_T_STRING; 293 ttype(L->top) = LUA_T_STRING;
296 incr_top; 294 incr_top;
297 luaC_checkGC(L); 295 luaC_checkGC(L);
298} 296}
@@ -308,8 +306,8 @@ void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
308 if (fn == NULL) 306 if (fn == NULL)
309 lua_error(L, "API error - attempt to push a NULL Cfunction"); 307 lua_error(L, "API error - attempt to push a NULL Cfunction");
310 checkCparams(L, n); 308 checkCparams(L, n);
311 ttype(L->stack.top) = LUA_T_CPROTO; 309 ttype(L->top) = LUA_T_CPROTO;
312 fvalue(L->stack.top) = fn; 310 fvalue(L->top) = fn;
313 incr_top; 311 incr_top;
314 luaV_closure(L, n); 312 luaV_closure(L, n);
315 luaC_checkGC(L); 313 luaC_checkGC(L);
@@ -318,21 +316,21 @@ void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
318void lua_pushusertag (lua_State *L, void *u, int tag) { 316void lua_pushusertag (lua_State *L, void *u, int tag) {
319 if (tag < 0 && tag != LUA_ANYTAG) 317 if (tag < 0 && tag != LUA_ANYTAG)
320 luaT_realtag(L, tag); /* error if tag is not valid */ 318 luaT_realtag(L, tag); /* error if tag is not valid */
321 tsvalue(L->stack.top) = luaS_createudata(L, u, tag); 319 tsvalue(L->top) = luaS_createudata(L, u, tag);
322 ttype(L->stack.top) = LUA_T_USERDATA; 320 ttype(L->top) = LUA_T_USERDATA;
323 incr_top; 321 incr_top;
324 luaC_checkGC(L); 322 luaC_checkGC(L);
325} 323}
326 324
327void luaA_pushobject (lua_State *L, const TObject *o) { 325void luaA_pushobject (lua_State *L, const TObject *o) {
328 *L->stack.top = *o; 326 *L->top = *o;
329 incr_top; 327 incr_top;
330} 328}
331 329
332void lua_pushobject (lua_State *L, lua_Object o) { 330void lua_pushobject (lua_State *L, lua_Object o) {
333 if (o == LUA_NOOBJECT) 331 if (o == LUA_NOOBJECT)
334 lua_error(L, "API error - attempt to push a NOOBJECT"); 332 lua_error(L, "API error - attempt to push a NOOBJECT");
335 set_normalized(L->stack.top, Address(L, o)); 333 set_normalized(L->top, Address(L, o));
336 incr_top; 334 incr_top;
337} 335}
338 336
@@ -368,18 +366,18 @@ int lua_tag (lua_State *L, lua_Object lo) {
368void lua_settag (lua_State *L, int tag) { 366void lua_settag (lua_State *L, int tag) {
369 checkCparams(L, 1); 367 checkCparams(L, 1);
370 luaT_realtag(L, tag); 368 luaT_realtag(L, tag);
371 switch (ttype(L->stack.top-1)) { 369 switch (ttype(L->top-1)) {
372 case LUA_T_ARRAY: 370 case LUA_T_ARRAY:
373 (L->stack.top-1)->value.a->htag = tag; 371 (L->top-1)->value.a->htag = tag;
374 break; 372 break;
375 case LUA_T_USERDATA: 373 case LUA_T_USERDATA:
376 (L->stack.top-1)->value.ts->u.d.tag = tag; 374 (L->top-1)->value.ts->u.d.tag = tag;
377 break; 375 break;
378 default: 376 default:
379 luaL_verror(L, "cannot change the tag of a %.20s", 377 luaL_verror(L, "cannot change the tag of a %.20s",
380 luaO_typename(L, L->stack.top-1)); 378 luaO_typename(L, L->top-1));
381 } 379 }
382 L->stack.top--; 380 L->top--;
383} 381}
384 382
385 383
@@ -395,7 +393,7 @@ GlobalVar *luaA_nextvar (lua_State *L, TaggedString *ts) {
395 while (gv && gv->value.ttype == LUA_T_NIL) /* skip globals with nil */ 393 while (gv && gv->value.ttype == LUA_T_NIL) /* skip globals with nil */
396 gv = gv->next; 394 gv = gv->next;
397 if (gv) { 395 if (gv) {
398 ttype(L->stack.top) = LUA_T_STRING; tsvalue(L->stack.top) = gv->name; 396 ttype(L->top) = LUA_T_STRING; tsvalue(L->top) = gv->name;
399 incr_top; 397 incr_top;
400 luaA_pushobject(L, &gv->value); 398 luaA_pushobject(L, &gv->value);
401 } 399 }
@@ -479,12 +477,12 @@ int lua_setdebug (lua_State *L, int debug) {
479 477
480 478
481lua_Function lua_stackedfunction (lua_State *L, int level) { 479lua_Function lua_stackedfunction (lua_State *L, int level) {
482 StkId i; 480 int i;
483 for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--) { 481 for (i = (L->top-1)-L->stack; i>=0; i--) {
484 int t = L->stack.stack[i].ttype; 482 int t = L->stack[i].ttype;
485 if (t == LUA_T_CLMARK || t == LUA_T_PMARK || t == LUA_T_CMARK) 483 if (t == LUA_T_CLMARK || t == LUA_T_PMARK || t == LUA_T_CMARK)
486 if (level-- == 0) 484 if (level-- == 0)
487 return Ref(L, L->stack.stack+i); 485 return Ref(L, L->stack+i);
488 } 486 }
489 return LUA_NOOBJECT; 487 return LUA_NOOBJECT;
490} 488}
@@ -498,8 +496,7 @@ int lua_nups (lua_State *L, lua_Function func) {
498 496
499int lua_currentline (lua_State *L, lua_Function func) { 497int lua_currentline (lua_State *L, lua_Function func) {
500 const TObject *f = Address(L, func); 498 const TObject *f = Address(L, func);
501 return (f+1 < L->stack.top && (f+1)->ttype == LUA_T_LINE) ? 499 return (f+1 < L->top && (f+1)->ttype == LUA_T_LINE) ? (f+1)->value.i : -1;
502 (f+1)->value.i : -1;
503} 500}
504 501
505 502
@@ -533,11 +530,11 @@ int lua_setlocal (lua_State *L, lua_Function func, int local_number) {
533 const char *name = luaF_getlocalname(fp, local_number, 530 const char *name = luaF_getlocalname(fp, local_number,
534 lua_currentline(L, func)); 531 lua_currentline(L, func));
535 checkCparams(L, 1); 532 checkCparams(L, 1);
536 --L->stack.top; 533 --L->top;
537 if (name) { 534 if (name) {
538 /* if "name", there must be a LUA_T_LINE */ 535 /* if "name", there must be a LUA_T_LINE */
539 /* therefore, f+2 points to function base */ 536 /* therefore, f+2 points to function base */
540 *((f+2)+(local_number-1)) = *L->stack.top; 537 *((f+2)+(local_number-1)) = *L->top;
541 return 1; 538 return 1;
542 } 539 }
543 else 540 else
@@ -565,14 +562,14 @@ void lua_funcinfo (lua_State *L, lua_Object func,
565 562
566 563
567static int checkfunc (lua_State *L, TObject *o) { 564static int checkfunc (lua_State *L, TObject *o) {
568 return luaO_equalObj(o, L->stack.top); 565 return luaO_equalObj(o, L->top);
569} 566}
570 567
571 568
572const char *lua_getobjname (lua_State *L, lua_Object o, const char **name) { 569const char *lua_getobjname (lua_State *L, lua_Object o, const char **name) {
573 /* try to find a name for given function */ 570 /* try to find a name for given function */
574 GlobalVar *g; 571 GlobalVar *g;
575 set_normalized(L->stack.top, Address(L, o)); /* to be used by `checkfunc' */ 572 set_normalized(L->top, Address(L, o)); /* to be used by `checkfunc' */
576 for (g=L->rootglobal; g; g=g->next) { 573 for (g=L->rootglobal; g; g=g->next) {
577 if (checkfunc(L, &g->value)) { 574 if (checkfunc(L, &g->value)) {
578 *name = g->name->str; 575 *name = g->name->str;
@@ -610,7 +607,7 @@ void lua_beginblock (lua_State *L) {
610void lua_endblock (lua_State *L) { 607void lua_endblock (lua_State *L) {
611 --L->numCblocks; 608 --L->numCblocks;
612 L->Cstack = L->Cblocks[L->numCblocks]; 609 L->Cstack = L->Cblocks[L->numCblocks];
613 luaD_adjusttop(L, L->Cstack.base); 610 L->top = L->Cstack.base;
614} 611}
615 612
616 613
@@ -618,8 +615,8 @@ void lua_endblock (lua_State *L) {
618int lua_ref (lua_State *L, int lock) { 615int lua_ref (lua_State *L, int lock) {
619 int ref; 616 int ref;
620 checkCparams(L, 1); 617 checkCparams(L, 1);
621 ref = luaR_ref(L, L->stack.top-1, lock); 618 ref = luaR_ref(L, L->top-1, lock);
622 L->stack.top--; 619 L->top--;
623 return ref; 620 return ref;
624} 621}
625 622
diff --git a/lbuiltin.c b/lbuiltin.c
index c9fefa35..28b64270 100644
--- a/lbuiltin.c
+++ b/lbuiltin.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbuiltin.c,v 1.77 1999/11/29 19:11:36 roberto Exp roberto $ 2** $Id: lbuiltin.c,v 1.78 1999/11/30 13:06:50 roberto Exp roberto $
3** Built-in functions 3** Built-in functions
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -37,8 +37,8 @@
37 37
38 38
39static void pushtagstring (lua_State *L, TaggedString *s) { 39static void pushtagstring (lua_State *L, TaggedString *s) {
40 ttype(L->stack.top) = LUA_T_STRING; 40 ttype(L->top) = LUA_T_STRING;
41 tsvalue(L->stack.top) = s; 41 tsvalue(L->top) = s;
42 incr_top; 42 incr_top;
43} 43}
44 44
@@ -303,7 +303,7 @@ static void luaB_call (lua_State *L) {
303 /* push arg[1...n] */ 303 /* push arg[1...n] */
304 luaD_checkstack(L, narg); 304 luaD_checkstack(L, narg);
305 for (i=0; i<narg; i++) 305 for (i=0; i<narg; i++)
306 *(L->stack.top++) = *luaH_getint(L, arg, i+1); 306 *(L->top++) = *luaH_getint(L, arg, i+1);
307 status = lua_callfunction(L, f); 307 status = lua_callfunction(L, f);
308 if (err != LUA_NOOBJECT) { /* restore old error method */ 308 if (err != LUA_NOOBJECT) { /* restore old error method */
309 lua_pushobject(L, err); 309 lua_pushobject(L, err);
@@ -319,7 +319,7 @@ static void luaB_call (lua_State *L) {
319 } 319 }
320 else { /* no errors */ 320 else { /* no errors */
321 if (strchr(options, 'p')) { /* pack results? */ 321 if (strchr(options, 'p')) { /* pack results? */
322 luaV_pack(L, L->Cstack.lua2C, L->Cstack.num, L->stack.top); 322 luaV_pack(L, L->Cstack.lua2C, L->Cstack.num, L->top);
323 incr_top; 323 incr_top;
324 } 324 }
325 else 325 else
@@ -414,65 +414,60 @@ static void luaB_assert (lua_State *L) {
414 414
415 415
416static void luaB_foreachi (lua_State *L) { 416static void luaB_foreachi (lua_State *L) {
417 struct Stack *S = &L->stack;
418 const Hash *t = gettable(L, 1); 417 const Hash *t = gettable(L, 1);
419 int n = (int)getnarg(L, t); 418 int n = (int)getnarg(L, t);
420 int i; 419 int i;
421 StkId f = luaA_Address(L, luaL_functionarg(L, 2)) - S->stack; 420 StkId f = luaA_Address(L, luaL_functionarg(L, 2));
422 /* 'f' cannot be a pointer to TObject, because it is on the stack, and the
423 stack may be reallocated by the call. */
424 luaD_checkstack(L, 3); /* for f, key, and val */ 421 luaD_checkstack(L, 3); /* for f, key, and val */
425 for (i=1; i<=n; i++) { 422 for (i=1; i<=n; i++) {
426 *(S->top++) = *(S->stack+f); 423 *(L->top++) = *f;
427 ttype(S->top) = LUA_T_NUMBER; nvalue(S->top++) = i; 424 ttype(L->top) = LUA_T_NUMBER; nvalue(L->top++) = i;
428 *(S->top++) = *luaH_getint(L, t, i); 425 *(L->top++) = *luaH_getint(L, t, i);
429 luaD_call(L, S->top-3, 1); 426 luaD_call(L, L->top-3, 1);
430 if (ttype(S->top-1) != LUA_T_NIL) 427 if (ttype(L->top-1) != LUA_T_NIL)
431 return; 428 return;
432 S->top--; 429 L->top--;
433 } 430 }
434} 431}
435 432
436 433
437static void luaB_foreach (lua_State *L) { 434static void luaB_foreach (lua_State *L) {
438 struct Stack *S = &L->stack;
439 const Hash *a = gettable(L, 1); 435 const Hash *a = gettable(L, 1);
440 StkId f = luaA_Address(L, luaL_functionarg(L, 2)) - S->stack; 436 StkId f = luaA_Address(L, luaL_functionarg(L, 2));
441 int i; 437 int i;
442 luaD_checkstack(L, 3); /* for f, key, and val */ 438 luaD_checkstack(L, 3); /* for f, key, and val */
443 for (i=0; i<a->size; i++) { 439 for (i=0; i<a->size; i++) {
444 const Node *nd = &(a->node[i]); 440 const Node *nd = &(a->node[i]);
445 if (ttype(val(nd)) != LUA_T_NIL) { 441 if (ttype(val(nd)) != LUA_T_NIL) {
446 *(S->top++) = *(S->stack+f); 442 *(L->top++) = *f;
447 *(S->top++) = *key(nd); 443 *(L->top++) = *key(nd);
448 *(S->top++) = *val(nd); 444 *(L->top++) = *val(nd);
449 luaD_call(L, S->top-3, 1); 445 luaD_call(L, L->top-3, 1);
450 if (ttype(S->top-1) != LUA_T_NIL) 446 if (ttype(L->top-1) != LUA_T_NIL)
451 return; 447 return;
452 S->top--; /* remove result */ 448 L->top--; /* remove result */
453 } 449 }
454 } 450 }
455} 451}
456 452
457 453
458static void luaB_foreachvar (lua_State *L) { 454static void luaB_foreachvar (lua_State *L) {
459 struct Stack *S = &L->stack; 455 StkId f = luaA_Address(L, luaL_functionarg(L, 1));
460 StkId f = luaA_Address(L, luaL_functionarg(L, 1)) - S->stack;
461 GlobalVar *gv; 456 GlobalVar *gv;
462 luaD_checkstack(L, 4); /* for extra var name, f, var name, and globalval */ 457 luaD_checkstack(L, 4); /* for extra var name, f, var name, and globalval */
463 for (gv = L->rootglobal; gv; gv = gv->next) { 458 for (gv = L->rootglobal; gv; gv = gv->next) {
464 if (gv->value.ttype != LUA_T_NIL) { 459 if (gv->value.ttype != LUA_T_NIL) {
465 pushtagstring(L, gv->name); /* keep (extra) name on stack to avoid GC */ 460 pushtagstring(L, gv->name); /* keep (extra) name on stack to avoid GC */
466 *(S->top++) = *(S->stack+f); 461 *(L->top++) = *f;
467 pushtagstring(L, gv->name); 462 pushtagstring(L, gv->name);
468 *(S->top++) = gv->value; 463 *(L->top++) = gv->value;
469 luaD_call(L, S->top-3, 1); 464 luaD_call(L, L->top-3, 1);
470 if (ttype(S->top-1) != LUA_T_NIL) { 465 if (ttype(L->top-1) != LUA_T_NIL) {
471 S->top--; 466 L->top--;
472 *(S->top-1) = *S->top; /* remove extra name */ 467 *(L->top-1) = *L->top; /* remove extra name */
473 return; 468 return;
474 } 469 }
475 S->top-=2; /* remove result and extra name */ 470 L->top-=2; /* remove result and extra name */
476 } 471 }
477 } 472 }
478} 473}
@@ -530,26 +525,24 @@ static int sort_comp (lua_State *L, lua_Object f, const TObject *a,
530 const TObject *b) { 525 const TObject *b) {
531 /* notice: the caller (auxsort) must check stack space */ 526 /* notice: the caller (auxsort) must check stack space */
532 if (f != LUA_NOOBJECT) { 527 if (f != LUA_NOOBJECT) {
533 *(L->stack.top) = *luaA_Address(L, f); 528 *(L->top) = *luaA_Address(L, f);
534 *(L->stack.top+1) = *a; 529 *(L->top+1) = *a;
535 *(L->stack.top+2) = *b; 530 *(L->top+2) = *b;
536 L->stack.top += 3; 531 L->top += 3;
537 luaD_call(L, L->stack.top-3, 1); 532 luaD_call(L, L->top-3, 1);
538 } 533 }
539 else { /* a < b? */ 534 else { /* a < b? */
540 *(L->stack.top) = *a; 535 *(L->top) = *a;
541 *(L->stack.top+1) = *b; 536 *(L->top+1) = *b;
542 L->stack.top += 2; 537 luaV_comparison(L, L->top+2, LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
543 luaV_comparison(L, LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT); 538 L->top++; /* result of comparison */
544 } 539 }
545 return ttype(--(L->stack.top)) != LUA_T_NIL; 540 return ttype(--(L->top)) != LUA_T_NIL;
546} 541}
547 542
548static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) { 543static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) {
549 struct Stack *S = &L->stack; 544 StkId P = L->top++; /* temporary place for pivot */
550 StkId P = S->top - S->stack; /* temporary place for pivot */ 545 ttype(P) = LUA_T_NIL;
551 S->top++;
552 ttype(S->stack+P) = LUA_T_NIL;
553 while (l < u) { /* for tail recursion */ 546 while (l < u) { /* for tail recursion */
554 int i, j; 547 int i, j;
555 /* sort elements a[l], a[(l+u)/2] and a[u] */ 548 /* sort elements a[l], a[(l+u)/2] and a[u] */
@@ -557,22 +550,22 @@ static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) {
557 swap(L, a, l, u); /* a[u]<a[l] */ 550 swap(L, a, l, u); /* a[u]<a[l] */
558 if (u-l == 1) break; /* only 2 elements */ 551 if (u-l == 1) break; /* only 2 elements */
559 i = (l+u)/2; 552 i = (l+u)/2;
560 *(S->stack+P) = *luaH_getint(L, a, i); /* P = a[i] */ 553 *P = *luaH_getint(L, a, i); /* P = a[i] */
561 if (sort_comp(L, f, S->stack+P, luaH_getint(L, a, l))) /* a[i]<a[l]? */ 554 if (sort_comp(L, f, P, luaH_getint(L, a, l))) /* a[i]<a[l]? */
562 swap(L, a, l, i); 555 swap(L, a, l, i);
563 else if (sort_comp(L, f, luaH_getint(L, a, u), S->stack+P)) /* a[u]<a[i]? */ 556 else if (sort_comp(L, f, luaH_getint(L, a, u), P)) /* a[u]<a[i]? */
564 swap(L, a, i, u); 557 swap(L, a, i, u);
565 if (u-l == 2) break; /* only 3 elements */ 558 if (u-l == 2) break; /* only 3 elements */
566 *(S->stack+P) = *luaH_getint(L, a, i); /* save pivot on stack (GC) */ 559 *P = *luaH_getint(L, a, i); /* save pivot on stack (GC) */
567 swap(L, a, i, u-1); /* put median element as pivot (a[u-1]) */ 560 swap(L, a, i, u-1); /* put median element as pivot (a[u-1]) */
568 /* a[l] <= P == a[u-1] <= a[u], only needs to sort from l+1 to u-2 */ 561 /* a[l] <= P == a[u-1] <= a[u], only needs to sort from l+1 to u-2 */
569 i = l; j = u-1; 562 i = l; j = u-1;
570 for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */ 563 for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
571 /* repeat i++ until a[i] >= P */ 564 /* repeat i++ until a[i] >= P */
572 while (sort_comp(L, f, luaH_getint(L, a, ++i), S->stack+P)) 565 while (sort_comp(L, f, luaH_getint(L, a, ++i), P))
573 if (i>u) lua_error(L, "invalid order function for sorting"); 566 if (i>u) lua_error(L, "invalid order function for sorting");
574 /* repeat j-- until a[j] <= P */ 567 /* repeat j-- until a[j] <= P */
575 while (sort_comp(L, f, (S->stack+P), luaH_getint(L, a, --j))) 568 while (sort_comp(L, f, P, luaH_getint(L, a, --j)))
576 if (j<l) lua_error(L, "invalid order function for sorting"); 569 if (j<l) lua_error(L, "invalid order function for sorting");
577 if (j<i) break; 570 if (j<i) break;
578 swap(L, a, i, j); 571 swap(L, a, i, j);
@@ -588,7 +581,7 @@ static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) {
588 } 581 }
589 auxsort(L, a, j, i, f); /* call recursively the smaller one */ 582 auxsort(L, a, j, i, f); /* call recursively the smaller one */
590 } /* repeat the routine for the larger one */ 583 } /* repeat the routine for the larger one */
591 S->top--; /* remove pivot from stack */ 584 L->top--; /* remove pivot from stack */
592} 585}
593 586
594static void luaB_sort (lua_State *L) { 587static void luaB_sort (lua_State *L) {
diff --git a/ldo.c b/ldo.c
index cadfd650..25632e4b 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.52 1999/11/22 13:12:07 roberto Exp roberto $ 2** $Id: ldo.c,v 1.53 1999/11/25 18:58:51 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -28,39 +28,40 @@
28 28
29 29
30 30
31#ifndef STACK_LIMIT 31#ifndef DEFAULT_STACK_SIZE
32#define STACK_LIMIT 6000 /* arbitrary limit */ 32#define DEFAULT_STACK_SIZE 1024
33#endif 33#endif
34 34
35#define EXTRA_STACK 32 /* space to handle stack overflow errors */
35 36
36 37/*
37#define STACK_UNIT 128 38** typical numer of recursive calls that fit in the stack
38 39** (only for error messages)
39 40*/
40#ifdef DEBUG 41#define REC_DEEP (DEFAULT_STACK_SIZE/20)
41#undef STACK_UNIT
42#define STACK_UNIT 2
43#endif
44 42
45 43
46void luaD_init (lua_State *L) { 44void luaD_init (lua_State *L) {
47 L->stack.stack = luaM_newvector(L, STACK_UNIT, TObject); 45 L->stack = luaM_newvector(L, DEFAULT_STACK_SIZE+EXTRA_STACK, TObject);
48 L->stack.top = L->stack.stack; 46 L->stack_last = L->stack+(DEFAULT_STACK_SIZE-1);
49 L->stack.last = L->stack.stack+(STACK_UNIT-1); 47 L->Cstack.base = L->Cstack.lua2C = L->top = L->stack;
48 L->Cstack.num = 0;
50} 49}
51 50
52 51
53void luaD_checkstack (lua_State *L, int n) { 52void luaD_checkstack (lua_State *L, int n) {
54 struct Stack *S = &L->stack; 53 if (L->stack_last-L->top <= n) { /* stack overflow? */
55 if (S->last-S->top <= n) { 54 if (L->stack_last-L->stack > (DEFAULT_STACK_SIZE-1)) {
56 StkId top = S->top-S->stack; 55 /* overflow while handling overflow: do what?? */
57 int stacksize = (S->last-S->stack)+STACK_UNIT+n; 56 L->top -= EXTRA_STACK;
58 luaM_reallocvector(L, S->stack, stacksize, TObject); 57 lua_error(L, "BAD STACK OVERFLOW! DATA CORRUPTED!!");
59 S->last = S->stack+(stacksize-1); 58 }
60 S->top = S->stack + top; 59 else {
61 if (stacksize >= STACK_LIMIT) { /* stack overflow? */ 60 L->stack_last += EXTRA_STACK; /* to be used by error message */
62 if (lua_stackedfunction(L, 100) == LUA_NOOBJECT) /* 100 funcs on stack? */ 61 if (lua_stackedfunction(L, REC_DEEP) == LUA_NOOBJECT) {
63 lua_error(L, "Lua2C - C2Lua overflow"); /* doesn't look like a rec. loop */ 62 /* less than REC_DEEP funcs on stack: doesn't look like a rec. loop */
63 lua_error(L, "Lua2C - C2Lua overflow");
64 }
64 else 65 else
65 lua_error(L, "stack size overflow"); 66 lua_error(L, "stack size overflow");
66 } 67 }
@@ -68,54 +69,62 @@ void luaD_checkstack (lua_State *L, int n) {
68} 69}
69 70
70 71
72static void restore_stack_limit (lua_State *L) {
73 if (L->top-L->stack < DEFAULT_STACK_SIZE-1)
74 L->stack_last = L->stack+(DEFAULT_STACK_SIZE-1);
75}
76
77
71/* 78/*
72** Adjust stack. Set top to the given value, pushing NILs if needed. 79** Adjust stack. Set top to base+extra, pushing NILs if needed.
80** (we cannot add base+extra unless we are sure it fits in the stack;
81** otherwise the result of such operation on pointers is undefined)
73*/ 82*/
74void luaD_adjusttop (lua_State *L, StkId newtop) { 83void luaD_adjusttop (lua_State *L, StkId base, int extra) {
75 int diff = newtop-(L->stack.top-L->stack.stack); 84 int diff = extra-(L->top-base);
76 if (diff <= 0) 85 if (diff <= 0)
77 L->stack.top += diff; 86 L->top = base+extra;
78 else { 87 else {
79 luaD_checkstack(L, diff); 88 luaD_checkstack(L, diff);
80 while (diff--) 89 while (diff--)
81 ttype(L->stack.top++) = LUA_T_NIL; 90 ttype(L->top++) = LUA_T_NIL;
82 } 91 }
83} 92}
84 93
85 94
86/* 95/*
87** Open a hole below "nelems" from the L->stack.top. 96** Open a hole inside the stack at `pos'
88*/ 97*/
89void luaD_openstack (lua_State *L, int nelems) { 98void luaD_openstack (lua_State *L, StkId pos) {
90 luaO_memup(L->stack.top-nelems+1, L->stack.top-nelems, 99 luaO_memup(pos+1, pos, (L->top-pos)*sizeof(TObject));
91 nelems*sizeof(TObject));
92 incr_top; 100 incr_top;
93} 101}
94 102
95 103
96void luaD_lineHook (lua_State *L, int line) { 104void luaD_lineHook (lua_State *L, int line) {
97 struct C_Lua_Stack oldCLS = L->Cstack; 105 struct C_Lua_Stack oldCLS = L->Cstack;
98 StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack; 106 StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top;
99 L->Cstack.num = 0; 107 L->Cstack.num = 0;
100 (*L->linehook)(L, line); 108 (*L->linehook)(L, line);
101 L->stack.top = L->stack.stack+old_top; 109 L->top = old_top;
102 L->Cstack = oldCLS; 110 L->Cstack = oldCLS;
103} 111}
104 112
105 113
106void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf, int isreturn) { 114void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf,
115 int isreturn) {
107 struct C_Lua_Stack oldCLS = L->Cstack; 116 struct C_Lua_Stack oldCLS = L->Cstack;
108 StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack; 117 StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top;
109 L->Cstack.num = 0; 118 L->Cstack.num = 0;
110 if (isreturn) 119 if (isreturn)
111 (*L->callhook)(L, LUA_NOOBJECT, "(return)", 0); 120 (*L->callhook)(L, LUA_NOOBJECT, "(return)", 0);
112 else { 121 else {
113 TObject *f = L->stack.stack+base-1; 122 TObject *f = base-1;
114 if (tf) 123 if (tf)
115 (*L->callhook)(L, Ref(L, f), tf->source->str, tf->lineDefined); 124 (*L->callhook)(L, Ref(L, f), tf->source->str, tf->lineDefined);
116 else (*L->callhook)(L, Ref(L, f), "(C)", -1); 125 else (*L->callhook)(L, Ref(L, f), "(C)", -1);
117 } 126 }
118 L->stack.top = L->stack.stack+old_top; 127 L->top = old_top;
119 L->Cstack = oldCLS; 128 L->Cstack = oldCLS;
120} 129}
121 130
@@ -126,43 +135,41 @@ void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf, int isreturn
126** first argument. Returns an index to the first result from C. 135** first argument. Returns an index to the first result from C.
127*/ 136*/
128static StkId callC (lua_State *L, lua_CFunction f, StkId base) { 137static StkId callC (lua_State *L, lua_CFunction f, StkId base) {
129 struct C_Lua_Stack *cls = &L->Cstack; 138 struct C_Lua_Stack oldCLS = L->Cstack;
130 struct C_Lua_Stack oldCLS = *cls;
131 StkId firstResult; 139 StkId firstResult;
132 int numarg = (L->stack.top-L->stack.stack) - base; 140 int numarg = L->top - base;
133 cls->num = numarg; 141 L->Cstack.num = numarg;
134 cls->lua2C = base; 142 L->Cstack.lua2C = base;
135 cls->base = base+numarg; /* == top-stack */ 143 L->Cstack.base = L->top;
136 if (L->callhook) 144 if (L->callhook)
137 luaD_callHook(L, base, NULL, 0); 145 luaD_callHook(L, base, NULL, 0);
138 (*f)(L); /* do the actual call */ 146 (*f)(L); /* do the actual call */
139 if (L->callhook) /* func may have changed callhook */ 147 if (L->callhook) /* test again: `func' may have changed callhook */
140 luaD_callHook(L, base, NULL, 1); 148 luaD_callHook(L, base, NULL, 1);
141 firstResult = cls->base; 149 firstResult = L->Cstack.base;
142 *cls = oldCLS; 150 L->Cstack = oldCLS;
143 return firstResult; 151 return firstResult;
144} 152}
145 153
146 154
147static StkId callCclosure (lua_State *L, const struct Closure *cl, 155static StkId callCclosure (lua_State *L, const struct Closure *cl,
148 lua_CFunction f, StkId base) { 156 lua_CFunction f, StkId base) {
149 TObject *pbase;
150 int nup = cl->nelems; /* number of upvalues */ 157 int nup = cl->nelems; /* number of upvalues */
151 luaD_checkstack(L, nup); 158 luaD_checkstack(L, nup);
152 pbase = L->stack.stack+base; /* care: previous call may change this */
153 /* open space for upvalues as extra arguments */ 159 /* open space for upvalues as extra arguments */
154 luaO_memup(pbase+nup, pbase, (L->stack.top-pbase)*sizeof(TObject)); 160 luaO_memup(base+nup, base, (L->top-base)*sizeof(TObject));
155 /* copy upvalues into stack */ 161 /* copy upvalues into stack */
156 memcpy(pbase, cl->consts+1, nup*sizeof(TObject)); 162 memcpy(base, cl->consts+1, nup*sizeof(TObject));
157 L->stack.top += nup; 163 L->top += nup;
158 return callC(L, f, base); 164 return callC(L, f, base);
159} 165}
160 166
161 167
162void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults) { 168void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults) {
163 luaD_openstack(L, nParams); 169 StkId base = L->top - nParams;
164 *(L->stack.top-nParams-1) = *f; 170 luaD_openstack(L, base);
165 luaD_call(L, L->stack.top-nParams-1, nResults); 171 *base = *f;
172 luaD_call(L, base, nResults);
166} 173}
167 174
168 175
@@ -173,26 +180,24 @@ void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults) {
173** function position. 180** function position.
174** The number of results is nResults, unless nResults=MULT_RET. 181** The number of results is nResults, unless nResults=MULT_RET.
175*/ 182*/
176void luaD_call (lua_State *L, TObject *func, int nResults) { 183void luaD_call (lua_State *L, StkId func, int nResults) {
177 struct Stack *S = &L->stack; /* to optimize */
178 StkId base = func - S->stack + 1; /* where is first argument */
179 StkId firstResult; 184 StkId firstResult;
180 switch (ttype(func)) { 185 switch (ttype(func)) {
181 case LUA_T_CPROTO: 186 case LUA_T_CPROTO:
182 ttype(func) = LUA_T_CMARK; 187 ttype(func) = LUA_T_CMARK;
183 firstResult = callC(L, fvalue(func), base); 188 firstResult = callC(L, fvalue(func), func+1);
184 break; 189 break;
185 case LUA_T_PROTO: 190 case LUA_T_PROTO:
186 ttype(func) = LUA_T_PMARK; 191 ttype(func) = LUA_T_PMARK;
187 firstResult = luaV_execute(L, NULL, tfvalue(func), base); 192 firstResult = luaV_execute(L, NULL, tfvalue(func), func+1);
188 break; 193 break;
189 case LUA_T_CLOSURE: { 194 case LUA_T_CLOSURE: {
190 Closure *c = clvalue(func); 195 Closure *c = clvalue(func);
191 TObject *proto = c->consts; 196 TObject *proto = c->consts;
192 ttype(func) = LUA_T_CLMARK; 197 ttype(func) = LUA_T_CLMARK;
193 firstResult = (ttype(proto) == LUA_T_CPROTO) ? 198 firstResult = (ttype(proto) == LUA_T_CPROTO) ?
194 callCclosure(L, c, fvalue(proto), base) : 199 callCclosure(L, c, fvalue(proto), func+1) :
195 luaV_execute(L, c, tfvalue(proto), base); 200 luaV_execute(L, c, tfvalue(proto), func+1);
196 break; 201 break;
197 } 202 }
198 default: { /* func is not a function */ 203 default: { /* func is not a function */
@@ -200,19 +205,18 @@ void luaD_call (lua_State *L, TObject *func, int nResults) {
200 const TObject *im = luaT_getimbyObj(L, func, IM_FUNCTION); 205 const TObject *im = luaT_getimbyObj(L, func, IM_FUNCTION);
201 if (ttype(im) == LUA_T_NIL) 206 if (ttype(im) == LUA_T_NIL)
202 lua_error(L, "call expression not a function"); 207 lua_error(L, "call expression not a function");
203 luaD_callTM(L, im, (S->top-S->stack)-(base-1), nResults); 208 luaD_callTM(L, im, L->top-func, nResults);
204 return; 209 return;
205 } 210 }
206 } 211 }
207 /* adjust the number of results */ 212 /* adjust the number of results */
208 if (nResults == MULT_RET) 213 if (nResults == MULT_RET)
209 nResults = (S->top-S->stack)-firstResult; 214 nResults = L->top - firstResult;
210 else 215 else
211 luaD_adjusttop(L, firstResult+nResults); 216 luaD_adjusttop(L, firstResult, nResults);
212 /* move results to base-1 (to erase parameters and function) */ 217 /* move results to func (to erase parameters and function) */
213 base--; 218 luaO_memdown(func, firstResult, nResults*sizeof(TObject));
214 luaO_memdown(S->stack+base, S->stack+firstResult, nResults*sizeof(TObject)); 219 L->top = func+nResults;
215 S->top -= firstResult-base;
216} 220}
217 221
218 222
@@ -220,10 +224,10 @@ static void message (lua_State *L, const char *s) {
220 const TObject *em = &(luaS_assertglobalbyname(L, "_ERRORMESSAGE")->value); 224 const TObject *em = &(luaS_assertglobalbyname(L, "_ERRORMESSAGE")->value);
221 if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO || 225 if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO ||
222 ttype(em) == LUA_T_CLOSURE) { 226 ttype(em) == LUA_T_CLOSURE) {
223 *L->stack.top = *em; 227 *L->top = *em;
224 incr_top; 228 incr_top;
225 lua_pushstring(L, s); 229 lua_pushstring(L, s);
226 luaD_call(L, L->stack.top-2, 0); 230 luaD_call(L, L->top-2, 0);
227 } 231 }
228} 232}
229 233
@@ -253,15 +257,16 @@ int luaD_protectedrun (lua_State *L) {
253 L->errorJmp = &myErrorJmp; 257 L->errorJmp = &myErrorJmp;
254 if (setjmp(myErrorJmp.b) == 0) { 258 if (setjmp(myErrorJmp.b) == 0) {
255 StkId base = L->Cstack.base; 259 StkId base = L->Cstack.base;
256 luaD_call(L, L->stack.stack+base, MULT_RET); 260 luaD_call(L, base, MULT_RET);
257 L->Cstack.lua2C = base; /* position of the new results */ 261 L->Cstack.lua2C = base; /* position of the new results */
258 L->Cstack.num = (L->stack.top-L->stack.stack) - base; 262 L->Cstack.num = L->top - base;
259 L->Cstack.base = base + L->Cstack.num; /* incorporate results on stack */ 263 L->Cstack.base = base + L->Cstack.num; /* incorporate results on stack */
260 status = 0; 264 status = 0;
261 } 265 }
262 else { /* an error occurred: restore L->Cstack and L->stack.top */ 266 else { /* an error occurred: restore the stack */
263 L->Cstack = oldCLS; 267 L->Cstack = oldCLS;
264 L->stack.top = L->stack.stack+L->Cstack.base; 268 L->top = L->Cstack.base;
269 restore_stack_limit(L);
265 status = 1; 270 status = 1;
266 } 271 }
267 L->errorJmp = oldErr; 272 L->errorJmp = oldErr;
@@ -283,18 +288,18 @@ static int protectedparser (lua_State *L, ZIO *z, int bin) {
283 tf = bin ? luaU_undump1(L, z) : luaY_parser(L, z); 288 tf = bin ? luaU_undump1(L, z) : luaY_parser(L, z);
284 status = 0; 289 status = 0;
285 } 290 }
286 else { /* an error occurred: restore L->Cstack and L->stack.top */ 291 else { /* an error occurred: restore L->Cstack and L->top */
287 L->Cstack = oldCLS; 292 L->Cstack = oldCLS;
288 L->stack.top = L->stack.stack+L->Cstack.base; 293 L->top = L->Cstack.base;
289 tf = NULL; 294 tf = NULL;
290 status = 1; 295 status = 1;
291 } 296 }
292 L->errorJmp = oldErr; 297 L->errorJmp = oldErr;
293 if (status) return 1; /* error code */ 298 if (status) return 1; /* error code */
294 if (tf == NULL) return 2; /* 'natural' end */ 299 if (tf == NULL) return 2; /* `natural' end */
295 luaD_adjusttop(L, L->Cstack.base+1); /* one slot for the pseudo-function */ 300 luaD_adjusttop(L, L->Cstack.base, 1); /* one slot for the pseudo-function */
296 L->stack.stack[L->Cstack.base].ttype = LUA_T_PROTO; 301 L->Cstack.base->ttype = LUA_T_PROTO;
297 L->stack.stack[L->Cstack.base].value.tf = tf; 302 L->Cstack.base->value.tf = tf;
298 luaV_closure(L, 0); 303 luaV_closure(L, 0);
299 return 0; 304 return 0;
300} 305}
@@ -323,7 +328,7 @@ static int do_main (lua_State *L, ZIO *z, int bin) {
323void luaD_gcIM (lua_State *L, const TObject *o) { 328void luaD_gcIM (lua_State *L, const TObject *o) {
324 const TObject *im = luaT_getimbyObj(L, o, IM_GC); 329 const TObject *im = luaT_getimbyObj(L, o, IM_GC);
325 if (ttype(im) != LUA_T_NIL) { 330 if (ttype(im) != LUA_T_NIL) {
326 *L->stack.top = *o; 331 *L->top = *o;
327 incr_top; 332 incr_top;
328 luaD_callTM(L, im, 1, 0); 333 luaD_callTM(L, im, 1, 0);
329 } 334 }
diff --git a/ldo.h b/ldo.h
index d08adbb5..163de9d5 100644
--- a/ldo.h
+++ b/ldo.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.h,v 1.10 1999/11/22 13:12:07 roberto Exp roberto $ 2** $Id: ldo.h,v 1.11 1999/11/25 18:58:51 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -20,22 +20,22 @@
20** macro to increment stack top. 20** macro to increment stack top.
21** There must be always an empty slot at the L->stack.top 21** There must be always an empty slot at the L->stack.top
22*/ 22*/
23#define incr_top { if (L->stack.top >= L->stack.last) luaD_checkstack(L, 1); \ 23#define incr_top {if (L->top == L->stack_last) luaD_checkstack(L, 1); L->top++;}
24 L->stack.top++; }
25 24
26 25
27/* macros to convert from lua_Object to (TObject *) and back */ 26/* macros to convert from lua_Object to (TObject *) and back */
28 27
29#define Address(L, lo) ((lo)+L->stack.stack-1) 28#define Address(L, lo) ((lo)+L->stack-1)
30#define Ref(L, st) ((st)-L->stack.stack+1) 29#define Ref(L, st) ((st)-L->stack+1)
31 30
32 31
33void luaD_init (lua_State *L); 32void luaD_init (lua_State *L);
34void luaD_adjusttop (lua_State *L, StkId newtop); 33void luaD_adjusttop (lua_State *L, StkId base, int extra);
35void luaD_openstack (lua_State *L, int nelems); 34void luaD_openstack (lua_State *L, StkId pos);
36void luaD_lineHook (lua_State *L, int line); 35void luaD_lineHook (lua_State *L, int line);
37void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf, int isreturn); 36void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf,
38void luaD_call (lua_State *L, TObject *func, int nResults); 37 int isreturn);
38void luaD_call (lua_State *L, StkId func, int nResults);
39void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults); 39void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults);
40int luaD_protectedrun (lua_State *L); 40int luaD_protectedrun (lua_State *L);
41void luaD_gcIM (lua_State *L, const TObject *o); 41void luaD_gcIM (lua_State *L, const TObject *o);
diff --git a/lgc.c b/lgc.c
index c3259421..14ef9539 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.33 1999/11/23 13:58:02 roberto Exp roberto $ 2** $Id: lgc.c,v 1.34 1999/11/26 18:59:20 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -77,9 +77,9 @@ static void travglobal (lua_State *L) {
77 77
78 78
79static void travstack (lua_State *L) { 79static void travstack (lua_State *L) {
80 StkId i; 80 int i;
81 for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--) 81 for (i = (L->top-1)-L->stack; i>=0; i--)
82 markobject(L, L->stack.stack+i); 82 markobject(L, L->stack+i);
83} 83}
84 84
85 85
diff --git a/lparser.c b/lparser.c
index 4305cc1d..df73fa31 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.43 1999/11/22 13:12:07 roberto Exp roberto $ 2** $Id: lparser.c,v 1.44 1999/11/25 18:59:43 roberto Exp roberto $
3** LL(1) Parser and code generator for Lua 3** LL(1) Parser and code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -581,8 +581,8 @@ static void init_state (LexState *ls, FuncState *fs, TaggedString *source) {
581 code_byte(ls, 0); /* to be filled with maxstacksize */ 581 code_byte(ls, 0); /* to be filled with maxstacksize */
582 code_byte(ls, 0); /* to be filled with arg information */ 582 code_byte(ls, 0); /* to be filled with arg information */
583 /* push function (to avoid GC) */ 583 /* push function (to avoid GC) */
584 tfvalue(L->stack.top) = f; 584 tfvalue(L->top) = f;
585 ttype(L->stack.top) = LUA_T_PROTO; 585 ttype(L->top) = LUA_T_PROTO;
586 incr_top; 586 incr_top;
587} 587}
588 588
@@ -599,7 +599,7 @@ static void close_func (LexState *ls) {
599 luaM_reallocvector(ls->L, f->locvars, fs->nvars, LocVar); 599 luaM_reallocvector(ls->L, f->locvars, fs->nvars, LocVar);
600 } 600 }
601 ls->fs = fs->prev; 601 ls->fs = fs->prev;
602 ls->L->stack.top--; /* pop function */ 602 ls->L->top--; /* pop function */
603} 603}
604 604
605 605
diff --git a/lstate.c b/lstate.c
index 26a7ae68..fe2b4830 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 1.17 1999/11/22 13:12:07 roberto Exp roberto $ 2** $Id: lstate.c,v 1.18 1999/11/29 19:12:07 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -23,9 +23,6 @@ lua_State *lua_state = NULL;
23 23
24lua_State *lua_newstate (void) { 24lua_State *lua_newstate (void) {
25 lua_State *L = luaM_new(NULL, lua_State); 25 lua_State *L = luaM_new(NULL, lua_State);
26 L->Cstack.base = 0;
27 L->Cstack.lua2C = 0;
28 L->Cstack.num = 0;
29 L->errorJmp = NULL; 26 L->errorJmp = NULL;
30 L->Mbuffer = NULL; 27 L->Mbuffer = NULL;
31 L->Mbuffbase = 0; 28 L->Mbuffbase = 0;
@@ -63,7 +60,7 @@ void lua_close (lua_State *L) {
63 LUA_ASSERT(L, L->rootglobal == NULL, "list should be empty"); 60 LUA_ASSERT(L, L->rootglobal == NULL, "list should be empty");
64 LUA_ASSERT(L, L->roottable == NULL, "list should be empty"); 61 LUA_ASSERT(L, L->roottable == NULL, "list should be empty");
65 luaS_freeall(L); 62 luaS_freeall(L);
66 luaM_free(L, L->stack.stack); 63 luaM_free(L, L->stack);
67 luaM_free(L, L->IMtable); 64 luaM_free(L, L->IMtable);
68 luaM_free(L, L->refArray); 65 luaM_free(L, L->refArray);
69 luaM_free(L, L->Mbuffer); 66 luaM_free(L, L->Mbuffer);
diff --git a/lstate.h b/lstate.h
index 2ee31840..1b946312 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 1.22 1999/11/10 15:39:35 roberto Exp roberto $ 2** $Id: lstate.h,v 1.23 1999/11/22 13:12:07 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -15,7 +15,7 @@
15 15
16 16
17 17
18typedef int StkId; /* index to stack elements */ 18typedef TObject *StkId; /* index to stack elements */
19 19
20 20
21/* 21/*
@@ -27,17 +27,16 @@ struct lua_longjmp {
27}; 27};
28 28
29 29
30struct Stack { 30/*
31 TObject *top; 31** stack layout for C point of view:
32 TObject *stack; 32** [lua2C, lua2C+num) - `array' lua2C
33 TObject *last; 33** [lua2C+num, base) - space for extra lua_Objects
34}; 34** [base, L->top) - `stack' C2Lua
35 35*/
36struct C_Lua_Stack { 36struct C_Lua_Stack {
37 StkId base; /* when Lua calls C or C calls Lua, points to */ 37 StkId base;
38 /* the first slot after the last parameter. */ 38 StkId lua2C;
39 StkId lua2C; /* points to first element of "array" lua2C */ 39 int num;
40 int num; /* size of "array" lua2C */
41}; 40};
42 41
43 42
@@ -51,7 +50,9 @@ typedef struct stringtable {
51 50
52struct lua_State { 51struct lua_State {
53 /* thread-specific state */ 52 /* thread-specific state */
54 struct Stack stack; /* Lua stack */ 53 StkId top; /* first free slot in the stack */
54 StkId stack; /* stack base */
55 StkId stack_last; /* last free slot in the stack */
55 struct C_Lua_Stack Cstack; /* C2lua struct */ 56 struct C_Lua_Stack Cstack; /* C2lua struct */
56 struct lua_longjmp *errorJmp; /* current error recover point */ 57 struct lua_longjmp *errorJmp; /* current error recover point */
57 char *Mbuffer; /* global buffer */ 58 char *Mbuffer; /* global buffer */
diff --git a/lvm.c b/lvm.c
index 32aa59f1..15349c64 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.67 1999/11/25 18:59:43 roberto Exp roberto $ 2** $Id: lvm.c,v 1.68 1999/11/29 18:27:49 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*/
@@ -83,13 +83,12 @@ void luaV_setn (lua_State *L, Hash *t, int val) {
83 83
84void luaV_closure (lua_State *L, int nelems) { 84void luaV_closure (lua_State *L, int nelems) {
85 if (nelems > 0) { 85 if (nelems > 0) {
86 struct Stack *S = &L->stack;
87 Closure *c = luaF_newclosure(L, nelems); 86 Closure *c = luaF_newclosure(L, nelems);
88 c->consts[0] = *(S->top-1); 87 c->consts[0] = *(L->top-1);
89 memcpy(&c->consts[1], S->top-(nelems+1), nelems*sizeof(TObject)); 88 L->top -= nelems;
90 S->top -= nelems; 89 memcpy(&c->consts[1], L->top-1, nelems*sizeof(TObject));
91 ttype(S->top-1) = LUA_T_CLOSURE; 90 ttype(L->top-1) = LUA_T_CLOSURE;
92 (S->top-1)->value.cl = c; 91 (L->top-1)->value.cl = c;
93 } 92 }
94} 93}
95 94
@@ -99,7 +98,7 @@ void luaV_closure (lua_State *L, int nelems) {
99** Receives the table at top-2 and the index at top-1. 98** Receives the table at top-2 and the index at top-1.
100*/ 99*/
101void luaV_gettable (lua_State *L) { 100void luaV_gettable (lua_State *L) {
102 TObject *table = L->stack.top-2; 101 TObject *table = L->top-2;
103 const TObject *im; 102 const TObject *im;
104 if (ttype(table) != LUA_T_ARRAY) { /* not a table, get gettable method */ 103 if (ttype(table) != LUA_T_ARRAY) { /* not a table, get gettable method */
105 im = luaT_getimbyObj(L, table, IM_GETTABLE); 104 im = luaT_getimbyObj(L, table, IM_GETTABLE);
@@ -117,7 +116,7 @@ void luaV_gettable (lua_State *L) {
117 luaD_callTM(L, im, 2, 1); /* calls it */ 116 luaD_callTM(L, im, 2, 1); /* calls it */
118 } 117 }
119 else { 118 else {
120 L->stack.top--; 119 L->top--;
121 *table = *h; /* "push" result into table position */ 120 *table = *h; /* "push" result into table position */
122 } 121 }
123 return; 122 return;
@@ -132,8 +131,7 @@ void luaV_gettable (lua_State *L) {
132/* 131/*
133** Receives table at *t, index at *(t+1) and value at top. 132** Receives table at *t, index at *(t+1) and value at top.
134*/ 133*/
135void luaV_settable (lua_State *L, const TObject *t) { 134void luaV_settable (lua_State *L, StkId t) {
136 struct Stack *S = &L->stack;
137 const TObject *im; 135 const TObject *im;
138 if (ttype(t) != LUA_T_ARRAY) { /* not a table, get "settable" method */ 136 if (ttype(t) != LUA_T_ARRAY) { /* not a table, get "settable" method */
139 im = luaT_getimbyObj(L, t, IM_SETTABLE); 137 im = luaT_getimbyObj(L, t, IM_SETTABLE);
@@ -143,29 +141,28 @@ void luaV_settable (lua_State *L, const TObject *t) {
143 else { /* object is a table... */ 141 else { /* object is a table... */
144 im = luaT_getim(L, avalue(t)->htag, IM_SETTABLE); 142 im = luaT_getim(L, avalue(t)->htag, IM_SETTABLE);
145 if (ttype(im) == LUA_T_NIL) { /* and does not have a "settable" method */ 143 if (ttype(im) == LUA_T_NIL) { /* and does not have a "settable" method */
146 luaH_set(L, avalue(t), t+1, S->top-1); 144 luaH_set(L, avalue(t), t+1, L->top-1);
147 S->top--; /* pop value */ 145 L->top--; /* pop value */
148 return; 146 return;
149 } 147 }
150 /* else it has a "settable" method, go through to next command */ 148 /* else it has a "settable" method, go through to next command */
151 } 149 }
152 /* object is not a table, or it has a "settable" method */ 150 /* object is not a table, or it has a "settable" method */
153 /* prepare arguments and call the tag method */ 151 /* prepare arguments and call the tag method */
154 *(S->top+1) = *(L->stack.top-1); 152 *(L->top+1) = *(L->top-1);
155 *(S->top) = *(t+1); 153 *(L->top) = *(t+1);
156 *(S->top-1) = *t; 154 *(L->top-1) = *t;
157 S->top += 2; /* WARNING: caller must assure stack space */ 155 L->top += 2; /* WARNING: caller must assure stack space */
158 luaD_callTM(L, im, 3, 0); 156 luaD_callTM(L, im, 3, 0);
159} 157}
160 158
161 159
162void luaV_rawsettable (lua_State *L, const TObject *t) { 160void luaV_rawsettable (lua_State *L, StkId t) {
163 if (ttype(t) != LUA_T_ARRAY) 161 if (ttype(t) != LUA_T_ARRAY)
164 lua_error(L, "indexed expression not a table"); 162 lua_error(L, "indexed expression not a table");
165 else { 163 else {
166 struct Stack *S = &L->stack; 164 luaH_set(L, avalue(t), t+1, L->top-1);
167 luaH_set(L, avalue(t), t+1, S->top-1); 165 L->top -= 3;
168 S->top -= 3;
169 } 166 }
170} 167}
171 168
@@ -178,17 +175,16 @@ void luaV_getglobal (lua_State *L, GlobalVar *gv) {
178 case LUA_T_USERDATA: case LUA_T_ARRAY: case LUA_T_NIL: { 175 case LUA_T_USERDATA: case LUA_T_ARRAY: case LUA_T_NIL: {
179 TObject *im = luaT_getimbyObj(L, value, IM_GETGLOBAL); 176 TObject *im = luaT_getimbyObj(L, value, IM_GETGLOBAL);
180 if (ttype(im) != LUA_T_NIL) { /* is there a tag method? */ 177 if (ttype(im) != LUA_T_NIL) { /* is there a tag method? */
181 struct Stack *S = &L->stack; 178 ttype(L->top) = LUA_T_STRING;
182 ttype(S->top) = LUA_T_STRING; 179 tsvalue(L->top) = gv->name; /* global name */
183 tsvalue(S->top) = gv->name; /* global name */ 180 L->top++;
184 S->top++; 181 *L->top++ = *value;
185 *S->top++ = *value;
186 luaD_callTM(L, im, 2, 1); 182 luaD_callTM(L, im, 2, 1);
187 return; 183 return;
188 } 184 }
189 /* else no tag method: go through to default behavior */ 185 /* else no tag method: go through to default behavior */
190 } 186 }
191 default: *L->stack.top++ = *value; /* default behavior */ 187 default: *L->top++ = *value; /* default behavior */
192 } 188 }
193} 189}
194 190
@@ -197,26 +193,26 @@ void luaV_setglobal (lua_State *L, GlobalVar *gv) {
197 const TObject *oldvalue = &gv->value; 193 const TObject *oldvalue = &gv->value;
198 const TObject *im = luaT_getimbyObj(L, oldvalue, IM_SETGLOBAL); 194 const TObject *im = luaT_getimbyObj(L, oldvalue, IM_SETGLOBAL);
199 if (ttype(im) == LUA_T_NIL) /* is there a tag method? */ 195 if (ttype(im) == LUA_T_NIL) /* is there a tag method? */
200 gv->value = *(--L->stack.top); 196 gv->value = *(--L->top);
201 else { 197 else {
202 /* WARNING: caller must assure stack space */ 198 /* WARNING: caller must assure stack space */
203 struct Stack *S = &L->stack;
204 TObject newvalue; 199 TObject newvalue;
205 newvalue = *(S->top-1); 200 newvalue = *(L->top-1);
206 ttype(S->top-1) = LUA_T_STRING; 201 ttype(L->top-1) = LUA_T_STRING;
207 tsvalue(S->top-1) = gv->name; 202 tsvalue(L->top-1) = gv->name;
208 *S->top++ = *oldvalue; 203 *L->top++ = *oldvalue;
209 *S->top++ = newvalue; 204 *L->top++ = newvalue;
210 luaD_callTM(L, im, 3, 0); 205 luaD_callTM(L, im, 3, 0);
211 } 206 }
212} 207}
213 208
214 209
215static void call_binTM (lua_State *L, IMS event, const char *msg) { 210static void call_binTM (lua_State *L, StkId top, IMS event, const char *msg) {
216 /* try first operand */ 211 /* try first operand */
217 const TObject *im = luaT_getimbyObj(L, L->stack.top-2, event); 212 const TObject *im = luaT_getimbyObj(L, top-2, event);
213 L->top = top;
218 if (ttype(im) == LUA_T_NIL) { 214 if (ttype(im) == LUA_T_NIL) {
219 im = luaT_getimbyObj(L, L->stack.top-1, event); /* try second operand */ 215 im = luaT_getimbyObj(L, top-1, event); /* try second operand */
220 if (ttype(im) == LUA_T_NIL) { 216 if (ttype(im) == LUA_T_NIL) {
221 im = luaT_getim(L, 0, event); /* try a 'global' i.m. */ 217 im = luaT_getim(L, 0, event); /* try a 'global' i.m. */
222 if (ttype(im) == LUA_T_NIL) 218 if (ttype(im) == LUA_T_NIL)
@@ -228,8 +224,8 @@ static void call_binTM (lua_State *L, IMS event, const char *msg) {
228} 224}
229 225
230 226
231static void call_arith (lua_State *L, IMS event) { 227static void call_arith (lua_State *L, StkId top, IMS event) {
232 call_binTM(L, event, "unexpected type in arithmetic operation"); 228 call_binTM(L, top, event, "unexpected type in arithmetic operation");
233} 229}
234 230
235 231
@@ -249,11 +245,10 @@ static int luaV_strcomp (const char *l, long ll, const char *r, long lr) {
249 } 245 }
250} 246}
251 247
252void luaV_comparison (lua_State *L, lua_Type ttype_less, lua_Type ttype_equal, 248void luaV_comparison (lua_State *L, StkId top, lua_Type ttype_less,
253 lua_Type ttype_great, IMS op) { 249 lua_Type ttype_equal, lua_Type ttype_great, IMS op) {
254 struct Stack *S = &L->stack; 250 const TObject *l = top-2;
255 const TObject *l = S->top-2; 251 const TObject *r = top-1;
256 const TObject *r = S->top-1;
257 real result; 252 real result;
258 if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER) 253 if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER)
259 result = nvalue(l)-nvalue(r); 254 result = nvalue(l)-nvalue(r);
@@ -261,39 +256,41 @@ void luaV_comparison (lua_State *L, lua_Type ttype_less, lua_Type ttype_equal,
261 result = luaV_strcomp(svalue(l), tsvalue(l)->u.s.len, 256 result = luaV_strcomp(svalue(l), tsvalue(l)->u.s.len,
262 svalue(r), tsvalue(r)->u.s.len); 257 svalue(r), tsvalue(r)->u.s.len);
263 else { 258 else {
264 call_binTM(L, op, "unexpected type in comparison"); 259 call_binTM(L, top, op, "unexpected type in comparison");
265 return; 260 return;
266 } 261 }
267 S->top--; 262 nvalue(top-2) = 1;
268 nvalue(S->top-1) = 1; 263 ttype(top-2) = (result < 0) ? ttype_less :
269 ttype(S->top-1) = (result < 0) ? ttype_less :
270 (result == 0) ? ttype_equal : ttype_great; 264 (result == 0) ? ttype_equal : ttype_great;
271} 265}
272 266
273 267
274void luaV_pack (lua_State *L, StkId firstel, int nvararg, TObject *tab) { 268void luaV_pack (lua_State *L, StkId firstelem, int nvararg, TObject *tab) {
275 TObject *firstelem = L->stack.stack+firstel;
276 int i; 269 int i;
277 Hash *htab; 270 Hash *htab;
278 if (nvararg < 0) nvararg = 0; 271 htab = avalue(tab) = luaH_new(L, nvararg+1); /* +1 for field `n' */
279 htab = avalue(tab) = luaH_new(L, nvararg+1); /* +1 for field 'n' */
280 ttype(tab) = LUA_T_ARRAY; 272 ttype(tab) = LUA_T_ARRAY;
281 for (i=0; i<nvararg; i++) 273 for (i=0; i<nvararg; i++)
282 luaH_setint(L, htab, i+1, firstelem+i); 274 luaH_setint(L, htab, i+1, firstelem+i);
283 luaV_setn(L, htab, nvararg); /* store counter in field "n" */ 275 luaV_setn(L, htab, nvararg); /* store counter in field `n' */
284} 276}
285 277
286 278
287static void adjust_varargs (lua_State *L, StkId first_extra_arg) { 279static void adjust_varargs (lua_State *L, StkId base, int nfixargs) {
288 TObject arg; 280 TObject arg;
289 luaV_pack(L, first_extra_arg, 281 int nvararg = (L->top-base) - nfixargs;
290 (L->stack.top-L->stack.stack)-first_extra_arg, &arg); 282 if (nvararg < 0) {
291 luaD_adjusttop(L, first_extra_arg); 283 luaV_pack(L, base, 0, &arg);
292 *L->stack.top++ = arg; 284 luaD_adjusttop(L, base, nfixargs);
285 }
286 else {
287 luaV_pack(L, base+nfixargs, nvararg, &arg);
288 L->top = base+nfixargs;
289 }
290 *L->top++ = arg;
293} 291}
294 292
295 293
296
297/* 294/*
298** Execute the given opcode, until a RET. Parameters are between 295** Execute the given opcode, until a RET. Parameters are between
299** [stack+base,top). Returns n such that the the results are between 296** [stack+base,top). Returns n such that the the results are between
@@ -301,25 +298,26 @@ static void adjust_varargs (lua_State *L, StkId first_extra_arg) {
301*/ 298*/
302StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, 299StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
303 StkId base) { 300 StkId base) {
304 struct Stack *S = &L->stack; /* to optimize */ 301 register StkId top; /* keep top local, for performance */
305 register const Byte *pc = tf->code; 302 register const Byte *pc = tf->code;
306 const TObject *consts = tf->consts; 303 const TObject *consts = tf->consts;
307 if (L->callhook) 304 if (L->callhook)
308 luaD_callHook(L, base, tf, 0); 305 luaD_callHook(L, base, tf, 0);
309 luaD_checkstack(L, (*pc++)+EXTRA_STACK); 306 luaD_checkstack(L, (*pc++)+EXTRA_STACK);
310 if (*pc < ZEROVARARG) 307 if (*pc < ZEROVARARG)
311 luaD_adjusttop(L, base+*(pc++)); 308 luaD_adjusttop(L, base, *(pc++));
312 else { /* varargs */ 309 else { /* varargs */
310 adjust_varargs(L, base, (*pc++)-ZEROVARARG);
313 luaC_checkGC(L); 311 luaC_checkGC(L);
314 adjust_varargs(L, base+(*pc++)-ZEROVARARG);
315 } 312 }
313 top = L->top;
316 for (;;) { 314 for (;;) {
317 register int aux = 0; 315 register int aux = 0;
318 switchentry: 316 switchentry:
319 switch ((OpCode)*pc++) { 317 switch ((OpCode)*pc++) {
320 318
321 case ENDCODE: 319 case ENDCODE:
322 S->top = S->stack + base; 320 top = base;
323 goto ret; 321 goto ret;
324 322
325 case RETCODE: 323 case RETCODE:
@@ -327,238 +325,240 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
327 goto ret; 325 goto ret;
328 326
329 case CALL: aux = *pc++; 327 case CALL: aux = *pc++;
330 luaD_call(L, (S->stack+base) + *pc++, aux); 328 L->top = top;
329 luaD_call(L, base+(*pc++), aux);
330 top = L->top;
331 break; 331 break;
332 332
333 case TAILCALL: aux = *pc++; 333 case TAILCALL: aux = *pc++;
334 luaD_call(L, (S->stack+base) + *pc++, MULT_RET); 334 L->top = top;
335 luaD_call(L, base+(*pc++), MULT_RET);
336 top = L->top;
335 base += aux; 337 base += aux;
336 goto ret; 338 goto ret;
337 339
338 case PUSHNIL: aux = *pc++; 340 case PUSHNIL: aux = *pc++;
339 do { 341 do {
340 ttype(S->top++) = LUA_T_NIL; 342 ttype(top++) = LUA_T_NIL;
341 } while (aux--); 343 } while (aux--);
342 break; 344 break;
343 345
344 case POP: aux = *pc++; 346 case POP: aux = *pc++;
345 S->top -= aux; 347 top -= aux;
346 break; 348 break;
347 349
348 case PUSHNUMBERW: aux += highbyte(L, *pc++); 350 case PUSHNUMBERW: aux += highbyte(L, *pc++);
349 case PUSHNUMBER: aux += *pc++; 351 case PUSHNUMBER: aux += *pc++;
350 ttype(S->top) = LUA_T_NUMBER; 352 ttype(top) = LUA_T_NUMBER;
351 nvalue(S->top) = aux; 353 nvalue(top) = aux;
352 S->top++; 354 top++;
353 break; 355 break;
354 356
355 case PUSHNUMBERNEGW: aux += highbyte(L, *pc++); 357 case PUSHNUMBERNEGW: aux += highbyte(L, *pc++);
356 case PUSHNUMBERNEG: aux += *pc++; 358 case PUSHNUMBERNEG: aux += *pc++;
357 ttype(S->top) = LUA_T_NUMBER; 359 ttype(top) = LUA_T_NUMBER;
358 nvalue(S->top) = -aux; 360 nvalue(top) = -aux;
359 S->top++; 361 top++;
360 break; 362 break;
361 363
362 case PUSHCONSTANTW: aux += highbyte(L, *pc++); 364 case PUSHCONSTANTW: aux += highbyte(L, *pc++);
363 case PUSHCONSTANT: aux += *pc++; 365 case PUSHCONSTANT: aux += *pc++;
364 *S->top++ = consts[aux]; 366 *top++ = consts[aux];
365 break; 367 break;
366 368
367 case PUSHUPVALUE: aux = *pc++; 369 case PUSHUPVALUE: aux = *pc++;
368 *S->top++ = cl->consts[aux+1]; 370 *top++ = cl->consts[aux+1];
369 break; 371 break;
370 372
371 case PUSHLOCAL: aux = *pc++; 373 case PUSHLOCAL: aux = *pc++;
372 *S->top++ = *((S->stack+base) + aux); 374 *top++ = *(base+aux);
373 break; 375 break;
374 376
375 case GETGLOBALW: aux += highbyte(L, *pc++); 377 case GETGLOBALW: aux += highbyte(L, *pc++);
376 case GETGLOBAL: aux += *pc++; 378 case GETGLOBAL: aux += *pc++;
379 L->top = top;
377 luaV_getglobal(L, tsvalue(&consts[aux])->u.s.gv); 380 luaV_getglobal(L, tsvalue(&consts[aux])->u.s.gv);
381 top++;
378 break; 382 break;
379 383
380 case GETTABLE: 384 case GETTABLE:
385 L->top = top;
381 luaV_gettable(L); 386 luaV_gettable(L);
387 top--;
382 break; 388 break;
383 389
384 case GETDOTTEDW: aux += highbyte(L, *pc++); 390 case GETDOTTEDW: aux += highbyte(L, *pc++);
385 case GETDOTTED: aux += *pc++; 391 case GETDOTTED: aux += *pc++;
386 *S->top++ = consts[aux]; 392 *top++ = consts[aux];
393 L->top = top;
387 luaV_gettable(L); 394 luaV_gettable(L);
395 top--;
388 break; 396 break;
389 397
390 case PUSHSELFW: aux += highbyte(L, *pc++); 398 case PUSHSELFW: aux += highbyte(L, *pc++);
391 case PUSHSELF: aux += *pc++; { 399 case PUSHSELF: aux += *pc++; {
392 TObject receiver; 400 TObject receiver;
393 receiver = *(S->top-1); 401 receiver = *(top-1);
394 *S->top++ = consts[aux]; 402 *top++ = consts[aux];
403 L->top = top;
395 luaV_gettable(L); 404 luaV_gettable(L);
396 *S->top++ = receiver; 405 *(top-1) = receiver;
397 break; 406 break;
398 } 407 }
399 408
400 case CREATEARRAYW: aux += highbyte(L, *pc++); 409 case CREATEARRAYW: aux += highbyte(L, *pc++);
401 case CREATEARRAY: aux += *pc++; 410 case CREATEARRAY: aux += *pc++;
411 L->top = top;
402 luaC_checkGC(L); 412 luaC_checkGC(L);
403 avalue(S->top) = luaH_new(L, aux); 413 avalue(top) = luaH_new(L, aux);
404 ttype(S->top) = LUA_T_ARRAY; 414 ttype(top) = LUA_T_ARRAY;
405 S->top++; 415 top++;
406 break; 416 break;
407 417
408 case SETLOCAL: aux = *pc++; 418 case SETLOCAL: aux = *pc++;
409 *((S->stack+base) + aux) = *(--S->top); 419 *(base+aux) = *(--top);
410 break; 420 break;
411 421
412 case SETGLOBALW: aux += highbyte(L, *pc++); 422 case SETGLOBALW: aux += highbyte(L, *pc++);
413 case SETGLOBAL: aux += *pc++; 423 case SETGLOBAL: aux += *pc++;
424 L->top = top;
414 luaV_setglobal(L, tsvalue(&consts[aux])->u.s.gv); 425 luaV_setglobal(L, tsvalue(&consts[aux])->u.s.gv);
426 top--;
415 break; 427 break;
416 428
417 case SETTABLEPOP: 429 case SETTABLEPOP:
418 luaV_settable(L, S->top-3); 430 L->top = top;
419 S->top -= 2; /* pop table and index */ 431 luaV_settable(L, top-3);
432 top -= 3; /* pop table, index, and value */
420 break; 433 break;
421 434
422 case SETTABLE: 435 case SETTABLE:
423 luaV_settable(L, S->top-3-(*pc++)); 436 L->top = top;
437 luaV_settable(L, top-3-(*pc++));
438 top--; /* pop value */
424 break; 439 break;
425 440
426 case SETLISTW: aux += highbyte(L, *pc++); 441 case SETLISTW: aux += highbyte(L, *pc++);
427 case SETLIST: aux += *pc++; { 442 case SETLIST: aux += *pc++; {
428 int n = *(pc++); 443 int n = *(pc++);
429 Hash *arr = avalue(S->top-n-1); 444 Hash *arr = avalue(top-n-1);
430 aux *= LFIELDS_PER_FLUSH; 445 aux *= LFIELDS_PER_FLUSH;
431 for (; n; n--) 446 for (; n; n--)
432 luaH_setint(L, arr, n+aux, --S->top); 447 luaH_setint(L, arr, n+aux, --top);
433 break; 448 break;
434 } 449 }
435 450
436 case SETMAP: aux = *pc++; { 451 case SETMAP: aux = *pc++; {
437 Hash *arr = avalue(S->top-(2*aux)-3); 452 Hash *arr = avalue(top-(2*aux)-3);
438 do { 453 do {
439 luaH_set(L, arr, S->top-2, S->top-1); 454 luaH_set(L, arr, top-2, top-1);
440 S->top-=2; 455 top-=2;
441 } while (aux--); 456 } while (aux--);
442 break; 457 break;
443 } 458 }
444 459
445 case NEQOP: aux = 1; 460 case NEQOP: aux = 1;
446 case EQOP: { 461 case EQOP: {
447 int res = luaO_equalObj(S->top-2, S->top-1); 462 int res = luaO_equalObj(top-2, top-1);
448 if (aux) res = !res; 463 if (aux) res = !res;
449 S->top--; 464 top--;
450 ttype(S->top-1) = res ? LUA_T_NUMBER : LUA_T_NIL; 465 ttype(top-1) = res ? LUA_T_NUMBER : LUA_T_NIL;
451 nvalue(S->top-1) = 1; 466 nvalue(top-1) = 1;
452 break; 467 break;
453 } 468 }
454 469
455 case LTOP: 470 case LTOP:
456 luaV_comparison(L, LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT); 471 luaV_comparison(L, top, LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
472 top--;
457 break; 473 break;
458 474
459 case LEOP: 475 case LEOP:
460 luaV_comparison(L, LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE); 476 luaV_comparison(L, top, LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE);
477 top--;
461 break; 478 break;
462 479
463 case GTOP: 480 case GTOP:
464 luaV_comparison(L, LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT); 481 luaV_comparison(L, top, LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT);
482 top--;
465 break; 483 break;
466 484
467 case GEOP: 485 case GEOP:
468 luaV_comparison(L, LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE); 486 luaV_comparison(L, top, LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE);
487 top--;
469 break; 488 break;
470 489
471 case ADDOP: { 490 case ADDOP:
472 TObject *l = S->top-2; 491 if (tonumber(top-1) || tonumber(top-2))
473 TObject *r = S->top-1; 492 call_arith(L, top, IM_ADD);
474 if (tonumber(r) || tonumber(l)) 493 else
475 call_arith(L, IM_ADD); 494 nvalue(top-2) += nvalue(top-1);
476 else { 495 top--;
477 nvalue(l) += nvalue(r);
478 --S->top;
479 }
480 break; 496 break;
481 }
482 497
483 case SUBOP: { 498 case SUBOP:
484 TObject *l = S->top-2; 499 if (tonumber(top-1) || tonumber(top-2))
485 TObject *r = S->top-1; 500 call_arith(L, top, IM_SUB);
486 if (tonumber(r) || tonumber(l)) 501 else
487 call_arith(L, IM_SUB); 502 nvalue(top-2) -= nvalue(top-1);
488 else { 503 top--;
489 nvalue(l) -= nvalue(r);
490 --S->top;
491 }
492 break; 504 break;
493 }
494 505
495 case MULTOP: { 506 case MULTOP:
496 TObject *l = S->top-2; 507 if (tonumber(top-1) || tonumber(top-2))
497 TObject *r = S->top-1; 508 call_arith(L, top, IM_MUL);
498 if (tonumber(r) || tonumber(l)) 509 else
499 call_arith(L, IM_MUL); 510 nvalue(top-2) *= nvalue(top-1);
500 else { 511 top--;
501 nvalue(l) *= nvalue(r);
502 --S->top;
503 }
504 break; 512 break;
505 }
506 513
507 case DIVOP: { 514 case DIVOP:
508 TObject *l = S->top-2; 515 if (tonumber(top-1) || tonumber(top-2))
509 TObject *r = S->top-1; 516 call_arith(L, top, IM_DIV);
510 if (tonumber(r) || tonumber(l)) 517 else
511 call_arith(L, IM_DIV); 518 nvalue(top-2) /= nvalue(top-1);
512 else { 519 top--;
513 nvalue(l) /= nvalue(r);
514 --S->top;
515 }
516 break; 520 break;
517 }
518 521
519 case POWOP: 522 case POWOP:
520 call_binTM(L, IM_POW, "undefined operation"); 523 call_binTM(L, top, IM_POW, "undefined operation");
524 top--;
521 break; 525 break;
522 526
523 case CONCOP: { 527 case CONCOP:
524 TObject *l = S->top-2; 528 if (tostring(L, top-2) || tostring(L, top-1))
525 TObject *r = S->top-1; 529 call_binTM(L, top, IM_CONCAT, "unexpected type for concatenation");
526 if (tostring(L, l) || tostring(L, r)) 530 else
527 call_binTM(L, IM_CONCAT, "unexpected type for concatenation"); 531 tsvalue(top-2) = strconc(L, tsvalue(top-2), tsvalue(top-1));
528 else { 532 L->top = top;
529 tsvalue(l) = strconc(L, tsvalue(l), tsvalue(r));
530 --S->top;
531 }
532 luaC_checkGC(L); 533 luaC_checkGC(L);
534 top--;
533 break; 535 break;
534 }
535 536
536 case MINUSOP: 537 case MINUSOP:
537 if (tonumber(S->top-1)) { 538 if (tonumber(top-1)) {
538 ttype(S->top) = LUA_T_NIL; 539 ttype(top) = LUA_T_NIL;
539 S->top++; 540 call_arith(L, top+1, IM_UNM);
540 call_arith(L, IM_UNM);
541 } 541 }
542 else 542 else
543 nvalue(S->top-1) = - nvalue(S->top-1); 543 nvalue(top-1) = - nvalue(top-1);
544 break; 544 break;
545 545
546 case NOTOP: 546 case NOTOP:
547 ttype(S->top-1) = 547 ttype(top-1) =
548 (ttype(S->top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL; 548 (ttype(top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL;
549 nvalue(S->top-1) = 1; 549 nvalue(top-1) = 1;
550 break; 550 break;
551 551
552 case ONTJMPW: aux += highbyte(L, *pc++); 552 case ONTJMPW: aux += highbyte(L, *pc++);
553 case ONTJMP: aux += *pc++; 553 case ONTJMP: aux += *pc++;
554 if (ttype(S->top-1) != LUA_T_NIL) pc += aux; 554 if (ttype(top-1) != LUA_T_NIL) pc += aux;
555 else S->top--; 555 else top--;
556 break; 556 break;
557 557
558 case ONFJMPW: aux += highbyte(L, *pc++); 558 case ONFJMPW: aux += highbyte(L, *pc++);
559 case ONFJMP: aux += *pc++; 559 case ONFJMP: aux += *pc++;
560 if (ttype(S->top-1) == LUA_T_NIL) pc += aux; 560 if (ttype(top-1) == LUA_T_NIL) pc += aux;
561 else S->top--; 561 else top--;
562 break; 562 break;
563 563
564 case JMPW: aux += highbyte(L, *pc++); 564 case JMPW: aux += highbyte(L, *pc++);
@@ -568,35 +568,40 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
568 568
569 case IFFJMPW: aux += highbyte(L, *pc++); 569 case IFFJMPW: aux += highbyte(L, *pc++);
570 case IFFJMP: aux += *pc++; 570 case IFFJMP: aux += *pc++;
571 if (ttype(--S->top) == LUA_T_NIL) pc += aux; 571 if (ttype(--top) == LUA_T_NIL) pc += aux;
572 break; 572 break;
573 573
574 case IFTUPJMPW: aux += highbyte(L, *pc++); 574 case IFTUPJMPW: aux += highbyte(L, *pc++);
575 case IFTUPJMP: aux += *pc++; 575 case IFTUPJMP: aux += *pc++;
576 if (ttype(--S->top) != LUA_T_NIL) pc -= aux; 576 if (ttype(--top) != LUA_T_NIL) pc -= aux;
577 break; 577 break;
578 578
579 case IFFUPJMPW: aux += highbyte(L, *pc++); 579 case IFFUPJMPW: aux += highbyte(L, *pc++);
580 case IFFUPJMP: aux += *pc++; 580 case IFFUPJMP: aux += *pc++;
581 if (ttype(--S->top) == LUA_T_NIL) pc -= aux; 581 if (ttype(--top) == LUA_T_NIL) pc -= aux;
582 break; 582 break;
583 583
584 case CLOSUREW: aux += highbyte(L, *pc++); 584 case CLOSUREW: aux += highbyte(L, *pc++);
585 case CLOSURE: aux += *pc++; 585 case CLOSURE: aux += *pc++;
586 *S->top++ = consts[aux]; 586 *top++ = consts[aux];
587 luaV_closure(L, *pc++); 587 L->top = top;
588 aux = *pc++;
589 luaV_closure(L, aux);
588 luaC_checkGC(L); 590 luaC_checkGC(L);
591 top -= aux;
589 break; 592 break;
590 593
591 case SETLINEW: aux += highbyte(L, *pc++); 594 case SETLINEW: aux += highbyte(L, *pc++);
592 case SETLINE: aux += *pc++; 595 case SETLINE: aux += *pc++;
593 if ((S->stack+base-1)->ttype != LUA_T_LINE) { 596 L->top = top;
597 if ((base-1)->ttype != LUA_T_LINE) {
594 /* open space for LINE value */ 598 /* open space for LINE value */
595 luaD_openstack(L, (S->top-S->stack)-base); 599 luaD_openstack(L, base);
600 base->ttype = LUA_T_LINE;
596 base++; 601 base++;
597 (S->stack+base-1)->ttype = LUA_T_LINE; 602 top++;
598 } 603 }
599 (S->stack+base-1)->value.i = aux; 604 (base-1)->value.i = aux;
600 if (L->linehook) 605 if (L->linehook)
601 luaD_lineHook(L, aux); 606 luaD_lineHook(L, aux);
602 break; 607 break;
@@ -608,8 +613,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
608 613
609 } 614 }
610 } ret: 615 } ret:
616 L->top = top;
611 if (L->callhook) 617 if (L->callhook)
612 luaD_callHook(L, 0, NULL, 1); 618 luaD_callHook(L, 0, NULL, 1);
613 return base; 619 return base;
614} 620}
615
diff --git a/lvm.h b/lvm.h
index 8ddfd361..0768e570 100644
--- a/lvm.h
+++ b/lvm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.h,v 1.11 1999/11/04 17:22:26 roberto Exp roberto $ 2** $Id: lvm.h,v 1.12 1999/11/22 13:12:07 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*/
@@ -22,13 +22,13 @@ int luaV_tonumber (TObject *obj);
22int luaV_tostring (lua_State *L, TObject *obj); 22int luaV_tostring (lua_State *L, TObject *obj);
23void luaV_setn (lua_State *L, Hash *t, int val); 23void luaV_setn (lua_State *L, Hash *t, int val);
24void luaV_gettable (lua_State *L); 24void luaV_gettable (lua_State *L);
25void luaV_settable (lua_State *L, const TObject *t); 25void luaV_settable (lua_State *L, StkId t);
26void luaV_rawsettable (lua_State *L, const TObject *t); 26void luaV_rawsettable (lua_State *L, StkId t);
27void luaV_getglobal (lua_State *L, GlobalVar *gv); 27void luaV_getglobal (lua_State *L, GlobalVar *gv);
28void luaV_setglobal (lua_State *L, GlobalVar *gv); 28void luaV_setglobal (lua_State *L, GlobalVar *gv);
29StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, StkId base); 29StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, StkId base);
30void luaV_closure (lua_State *L, int nelems); 30void luaV_closure (lua_State *L, int nelems);
31void luaV_comparison (lua_State *L, lua_Type ttype_less, lua_Type ttype_equal, 31void luaV_comparison (lua_State *L, StkId top, lua_Type ttype_less,
32 lua_Type ttype_great, IMS op); 32 lua_Type ttype_equal, lua_Type ttype_great, IMS op);
33 33
34#endif 34#endif