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 |
