diff options
-rw-r--r-- | lapi.c | 103 | ||||
-rw-r--r-- | lbuiltin.c | 99 | ||||
-rw-r--r-- | ldo.c | 171 | ||||
-rw-r--r-- | ldo.h | 18 | ||||
-rw-r--r-- | lgc.c | 8 | ||||
-rw-r--r-- | lparser.c | 8 | ||||
-rw-r--r-- | lstate.c | 7 | ||||
-rw-r--r-- | lstate.h | 27 | ||||
-rw-r--r-- | lvm.c | 351 | ||||
-rw-r--r-- | lvm.h | 10 |
10 files changed, 400 insertions, 402 deletions
@@ -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 | ||
65 | static void checkCparams (lua_State *L, int nParams) { | 65 | static 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 | ||
71 | static lua_Object put_luaObject (lua_State *L, const TObject *o) { | 71 | static 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 | ||
78 | lua_Object luaA_putObjectOnTop (lua_State *L) { | 78 | lua_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 | ||
85 | static void top2LC (lua_State *L, int n) { | 85 | static 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 | */ |
103 | lua_Object lua_lua2C (lua_State *L, int number) { | 103 | lua_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 | ||
127 | lua_Object lua_settagmethod (lua_State *L, int tag, const char *event) { | 125 | lua_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 | ||
150 | lua_Object lua_rawgettable (lua_State *L) { | 148 | lua_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 | ||
160 | void lua_settable (lua_State *L) { | 158 | void 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 | ||
167 | void lua_rawsettable (lua_State *L) { | 165 | void 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) { | |||
202 | void lua_rawsetglobal (lua_State *L, const char *name) { | 200 | void 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 | ||
282 | void lua_pushnil (lua_State *L) { | 280 | void 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 | ||
287 | void lua_pushnumber (lua_State *L, double n) { | 285 | void 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 | ||
293 | void lua_pushlstring (lua_State *L, const char *s, long len) { | 291 | void 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) { | |||
318 | void lua_pushusertag (lua_State *L, void *u, int tag) { | 316 | void 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 | ||
327 | void luaA_pushobject (lua_State *L, const TObject *o) { | 325 | void 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 | ||
332 | void lua_pushobject (lua_State *L, lua_Object o) { | 330 | void 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) { | |||
368 | void lua_settag (lua_State *L, int tag) { | 366 | void 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 | ||
481 | lua_Function lua_stackedfunction (lua_State *L, int level) { | 479 | lua_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 | ||
499 | int lua_currentline (lua_State *L, lua_Function func) { | 497 | int 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 | ||
567 | static int checkfunc (lua_State *L, TObject *o) { | 564 | static 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 | ||
572 | const char *lua_getobjname (lua_State *L, lua_Object o, const char **name) { | 569 | const 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) { | |||
610 | void lua_endblock (lua_State *L) { | 607 | void 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) { | |||
618 | int lua_ref (lua_State *L, int lock) { | 615 | int 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 | ||
@@ -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 | ||
39 | static void pushtagstring (lua_State *L, TaggedString *s) { | 39 | static 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 | ||
416 | static void luaB_foreachi (lua_State *L) { | 416 | static 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 | ||
437 | static void luaB_foreach (lua_State *L) { | 434 | static 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 | ||
458 | static void luaB_foreachvar (lua_State *L) { | 454 | static 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 | ||
548 | static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) { | 543 | static 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 | ||
594 | static void luaB_sort (lua_State *L) { | 587 | static void luaB_sort (lua_State *L) { |
@@ -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 | ||
46 | void luaD_init (lua_State *L) { | 44 | void 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 | ||
53 | void luaD_checkstack (lua_State *L, int n) { | 52 | void 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 | ||
72 | static 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 | */ |
74 | void luaD_adjusttop (lua_State *L, StkId newtop) { | 83 | void 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 | */ |
89 | void luaD_openstack (lua_State *L, int nelems) { | 98 | void 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 | ||
96 | void luaD_lineHook (lua_State *L, int line) { | 104 | void 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 | ||
106 | void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf, int isreturn) { | 114 | void 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 | */ |
128 | static StkId callC (lua_State *L, lua_CFunction f, StkId base) { | 137 | static 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 | ||
147 | static StkId callCclosure (lua_State *L, const struct Closure *cl, | 155 | static 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 | ||
162 | void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults) { | 168 | void 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 | */ |
176 | void luaD_call (lua_State *L, TObject *func, int nResults) { | 183 | void 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) { | |||
323 | void luaD_gcIM (lua_State *L, const TObject *o) { | 328 | void 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 | } |
@@ -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 | ||
33 | void luaD_init (lua_State *L); | 32 | void luaD_init (lua_State *L); |
34 | void luaD_adjusttop (lua_State *L, StkId newtop); | 33 | void luaD_adjusttop (lua_State *L, StkId base, int extra); |
35 | void luaD_openstack (lua_State *L, int nelems); | 34 | void luaD_openstack (lua_State *L, StkId pos); |
36 | void luaD_lineHook (lua_State *L, int line); | 35 | void luaD_lineHook (lua_State *L, int line); |
37 | void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf, int isreturn); | 36 | void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf, |
38 | void luaD_call (lua_State *L, TObject *func, int nResults); | 37 | int isreturn); |
38 | void luaD_call (lua_State *L, StkId func, int nResults); | ||
39 | void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults); | 39 | void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults); |
40 | int luaD_protectedrun (lua_State *L); | 40 | int luaD_protectedrun (lua_State *L); |
41 | void luaD_gcIM (lua_State *L, const TObject *o); | 41 | void luaD_gcIM (lua_State *L, const TObject *o); |
@@ -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 | ||
79 | static void travstack (lua_State *L) { | 79 | static 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 | ||
@@ -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 | ||
@@ -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 | ||
24 | lua_State *lua_newstate (void) { | 24 | lua_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); |
@@ -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 | ||
18 | typedef int StkId; /* index to stack elements */ | 18 | typedef 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 | ||
30 | struct 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 | */ | |
36 | struct C_Lua_Stack { | 36 | struct 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 | ||
52 | struct lua_State { | 51 | struct 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 */ |
@@ -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 | ||
84 | void luaV_closure (lua_State *L, int nelems) { | 84 | void 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 | */ |
101 | void luaV_gettable (lua_State *L) { | 100 | void 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 | */ |
135 | void luaV_settable (lua_State *L, const TObject *t) { | 134 | void 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 | ||
162 | void luaV_rawsettable (lua_State *L, const TObject *t) { | 160 | void 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 | ||
215 | static void call_binTM (lua_State *L, IMS event, const char *msg) { | 210 | static 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 | ||
231 | static void call_arith (lua_State *L, IMS event) { | 227 | static 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 | ||
252 | void luaV_comparison (lua_State *L, lua_Type ttype_less, lua_Type ttype_equal, | 248 | void 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 | ||
274 | void luaV_pack (lua_State *L, StkId firstel, int nvararg, TObject *tab) { | 268 | void 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 | ||
287 | static void adjust_varargs (lua_State *L, StkId first_extra_arg) { | 279 | static 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 | */ |
302 | StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, | 299 | StkId 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 | |||
@@ -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); | |||
22 | int luaV_tostring (lua_State *L, TObject *obj); | 22 | int luaV_tostring (lua_State *L, TObject *obj); |
23 | void luaV_setn (lua_State *L, Hash *t, int val); | 23 | void luaV_setn (lua_State *L, Hash *t, int val); |
24 | void luaV_gettable (lua_State *L); | 24 | void luaV_gettable (lua_State *L); |
25 | void luaV_settable (lua_State *L, const TObject *t); | 25 | void luaV_settable (lua_State *L, StkId t); |
26 | void luaV_rawsettable (lua_State *L, const TObject *t); | 26 | void luaV_rawsettable (lua_State *L, StkId t); |
27 | void luaV_getglobal (lua_State *L, GlobalVar *gv); | 27 | void luaV_getglobal (lua_State *L, GlobalVar *gv); |
28 | void luaV_setglobal (lua_State *L, GlobalVar *gv); | 28 | void luaV_setglobal (lua_State *L, GlobalVar *gv); |
29 | StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, StkId base); | 29 | StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, StkId base); |
30 | void luaV_closure (lua_State *L, int nelems); | 30 | void luaV_closure (lua_State *L, int nelems); |
31 | void luaV_comparison (lua_State *L, lua_Type ttype_less, lua_Type ttype_equal, | 31 | void 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 |