diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-12-01 17:50:08 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-12-01 17:50:08 -0200 |
| commit | fe237ad8085f34e89fcd3610a9771215af63f03f (patch) | |
| tree | f7ee5d8f7d1ffb74e94f049aa6f31eb03606cdf6 /lvm.c | |
| parent | 3181dfefee40b9a424b80aa779c671f5f458904c (diff) | |
| download | lua-fe237ad8085f34e89fcd3610a9771215af63f03f.tar.gz lua-fe237ad8085f34e89fcd3610a9771215af63f03f.tar.bz2 lua-fe237ad8085f34e89fcd3610a9771215af63f03f.zip | |
fixed stack; first version.
Diffstat (limited to '')
| -rw-r--r-- | lvm.c | 351 |
1 files changed, 178 insertions, 173 deletions
| @@ -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 | |||
