diff options
Diffstat (limited to 'lvm.c')
-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 | |||