aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-12-01 17:50:08 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-12-01 17:50:08 -0200
commitfe237ad8085f34e89fcd3610a9771215af63f03f (patch)
treef7ee5d8f7d1ffb74e94f049aa6f31eb03606cdf6 /lvm.c
parent3181dfefee40b9a424b80aa779c671f5f458904c (diff)
downloadlua-fe237ad8085f34e89fcd3610a9771215af63f03f.tar.gz
lua-fe237ad8085f34e89fcd3610a9771215af63f03f.tar.bz2
lua-fe237ad8085f34e89fcd3610a9771215af63f03f.zip
fixed stack; first version.
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c351
1 files changed, 178 insertions, 173 deletions
diff --git a/lvm.c b/lvm.c
index 32aa59f1..15349c64 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.67 1999/11/25 18:59:43 roberto Exp roberto $ 2** $Id: lvm.c,v 1.68 1999/11/29 18:27:49 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -83,13 +83,12 @@ void luaV_setn (lua_State *L, Hash *t, int val) {
83 83
84void luaV_closure (lua_State *L, int nelems) { 84void luaV_closure (lua_State *L, int nelems) {
85 if (nelems > 0) { 85 if (nelems > 0) {
86 struct Stack *S = &L->stack;
87 Closure *c = luaF_newclosure(L, nelems); 86 Closure *c = luaF_newclosure(L, nelems);
88 c->consts[0] = *(S->top-1); 87 c->consts[0] = *(L->top-1);
89 memcpy(&c->consts[1], S->top-(nelems+1), nelems*sizeof(TObject)); 88 L->top -= nelems;
90 S->top -= nelems; 89 memcpy(&c->consts[1], L->top-1, nelems*sizeof(TObject));
91 ttype(S->top-1) = LUA_T_CLOSURE; 90 ttype(L->top-1) = LUA_T_CLOSURE;
92 (S->top-1)->value.cl = c; 91 (L->top-1)->value.cl = c;
93 } 92 }
94} 93}
95 94
@@ -99,7 +98,7 @@ void luaV_closure (lua_State *L, int nelems) {
99** Receives the table at top-2 and the index at top-1. 98** Receives the table at top-2 and the index at top-1.
100*/ 99*/
101void luaV_gettable (lua_State *L) { 100void luaV_gettable (lua_State *L) {
102 TObject *table = L->stack.top-2; 101 TObject *table = L->top-2;
103 const TObject *im; 102 const TObject *im;
104 if (ttype(table) != LUA_T_ARRAY) { /* not a table, get gettable method */ 103 if (ttype(table) != LUA_T_ARRAY) { /* not a table, get gettable method */
105 im = luaT_getimbyObj(L, table, IM_GETTABLE); 104 im = luaT_getimbyObj(L, table, IM_GETTABLE);
@@ -117,7 +116,7 @@ void luaV_gettable (lua_State *L) {
117 luaD_callTM(L, im, 2, 1); /* calls it */ 116 luaD_callTM(L, im, 2, 1); /* calls it */
118 } 117 }
119 else { 118 else {
120 L->stack.top--; 119 L->top--;
121 *table = *h; /* "push" result into table position */ 120 *table = *h; /* "push" result into table position */
122 } 121 }
123 return; 122 return;
@@ -132,8 +131,7 @@ void luaV_gettable (lua_State *L) {
132/* 131/*
133** Receives table at *t, index at *(t+1) and value at top. 132** Receives table at *t, index at *(t+1) and value at top.
134*/ 133*/
135void luaV_settable (lua_State *L, const TObject *t) { 134void luaV_settable (lua_State *L, StkId t) {
136 struct Stack *S = &L->stack;
137 const TObject *im; 135 const TObject *im;
138 if (ttype(t) != LUA_T_ARRAY) { /* not a table, get "settable" method */ 136 if (ttype(t) != LUA_T_ARRAY) { /* not a table, get "settable" method */
139 im = luaT_getimbyObj(L, t, IM_SETTABLE); 137 im = luaT_getimbyObj(L, t, IM_SETTABLE);
@@ -143,29 +141,28 @@ void luaV_settable (lua_State *L, const TObject *t) {
143 else { /* object is a table... */ 141 else { /* object is a table... */
144 im = luaT_getim(L, avalue(t)->htag, IM_SETTABLE); 142 im = luaT_getim(L, avalue(t)->htag, IM_SETTABLE);
145 if (ttype(im) == LUA_T_NIL) { /* and does not have a "settable" method */ 143 if (ttype(im) == LUA_T_NIL) { /* and does not have a "settable" method */
146 luaH_set(L, avalue(t), t+1, S->top-1); 144 luaH_set(L, avalue(t), t+1, L->top-1);
147 S->top--; /* pop value */ 145 L->top--; /* pop value */
148 return; 146 return;
149 } 147 }
150 /* else it has a "settable" method, go through to next command */ 148 /* else it has a "settable" method, go through to next command */
151 } 149 }
152 /* object is not a table, or it has a "settable" method */ 150 /* object is not a table, or it has a "settable" method */
153 /* prepare arguments and call the tag method */ 151 /* prepare arguments and call the tag method */
154 *(S->top+1) = *(L->stack.top-1); 152 *(L->top+1) = *(L->top-1);
155 *(S->top) = *(t+1); 153 *(L->top) = *(t+1);
156 *(S->top-1) = *t; 154 *(L->top-1) = *t;
157 S->top += 2; /* WARNING: caller must assure stack space */ 155 L->top += 2; /* WARNING: caller must assure stack space */
158 luaD_callTM(L, im, 3, 0); 156 luaD_callTM(L, im, 3, 0);
159} 157}
160 158
161 159
162void luaV_rawsettable (lua_State *L, const TObject *t) { 160void luaV_rawsettable (lua_State *L, StkId t) {
163 if (ttype(t) != LUA_T_ARRAY) 161 if (ttype(t) != LUA_T_ARRAY)
164 lua_error(L, "indexed expression not a table"); 162 lua_error(L, "indexed expression not a table");
165 else { 163 else {
166 struct Stack *S = &L->stack; 164 luaH_set(L, avalue(t), t+1, L->top-1);
167 luaH_set(L, avalue(t), t+1, S->top-1); 165 L->top -= 3;
168 S->top -= 3;
169 } 166 }
170} 167}
171 168
@@ -178,17 +175,16 @@ void luaV_getglobal (lua_State *L, GlobalVar *gv) {
178 case LUA_T_USERDATA: case LUA_T_ARRAY: case LUA_T_NIL: { 175 case LUA_T_USERDATA: case LUA_T_ARRAY: case LUA_T_NIL: {
179 TObject *im = luaT_getimbyObj(L, value, IM_GETGLOBAL); 176 TObject *im = luaT_getimbyObj(L, value, IM_GETGLOBAL);
180 if (ttype(im) != LUA_T_NIL) { /* is there a tag method? */ 177 if (ttype(im) != LUA_T_NIL) { /* is there a tag method? */
181 struct Stack *S = &L->stack; 178 ttype(L->top) = LUA_T_STRING;
182 ttype(S->top) = LUA_T_STRING; 179 tsvalue(L->top) = gv->name; /* global name */
183 tsvalue(S->top) = gv->name; /* global name */ 180 L->top++;
184 S->top++; 181 *L->top++ = *value;
185 *S->top++ = *value;
186 luaD_callTM(L, im, 2, 1); 182 luaD_callTM(L, im, 2, 1);
187 return; 183 return;
188 } 184 }
189 /* else no tag method: go through to default behavior */ 185 /* else no tag method: go through to default behavior */
190 } 186 }
191 default: *L->stack.top++ = *value; /* default behavior */ 187 default: *L->top++ = *value; /* default behavior */
192 } 188 }
193} 189}
194 190
@@ -197,26 +193,26 @@ void luaV_setglobal (lua_State *L, GlobalVar *gv) {
197 const TObject *oldvalue = &gv->value; 193 const TObject *oldvalue = &gv->value;
198 const TObject *im = luaT_getimbyObj(L, oldvalue, IM_SETGLOBAL); 194 const TObject *im = luaT_getimbyObj(L, oldvalue, IM_SETGLOBAL);
199 if (ttype(im) == LUA_T_NIL) /* is there a tag method? */ 195 if (ttype(im) == LUA_T_NIL) /* is there a tag method? */
200 gv->value = *(--L->stack.top); 196 gv->value = *(--L->top);
201 else { 197 else {
202 /* WARNING: caller must assure stack space */ 198 /* WARNING: caller must assure stack space */
203 struct Stack *S = &L->stack;
204 TObject newvalue; 199 TObject newvalue;
205 newvalue = *(S->top-1); 200 newvalue = *(L->top-1);
206 ttype(S->top-1) = LUA_T_STRING; 201 ttype(L->top-1) = LUA_T_STRING;
207 tsvalue(S->top-1) = gv->name; 202 tsvalue(L->top-1) = gv->name;
208 *S->top++ = *oldvalue; 203 *L->top++ = *oldvalue;
209 *S->top++ = newvalue; 204 *L->top++ = newvalue;
210 luaD_callTM(L, im, 3, 0); 205 luaD_callTM(L, im, 3, 0);
211 } 206 }
212} 207}
213 208
214 209
215static void call_binTM (lua_State *L, IMS event, const char *msg) { 210static void call_binTM (lua_State *L, StkId top, IMS event, const char *msg) {
216 /* try first operand */ 211 /* try first operand */
217 const TObject *im = luaT_getimbyObj(L, L->stack.top-2, event); 212 const TObject *im = luaT_getimbyObj(L, top-2, event);
213 L->top = top;
218 if (ttype(im) == LUA_T_NIL) { 214 if (ttype(im) == LUA_T_NIL) {
219 im = luaT_getimbyObj(L, L->stack.top-1, event); /* try second operand */ 215 im = luaT_getimbyObj(L, top-1, event); /* try second operand */
220 if (ttype(im) == LUA_T_NIL) { 216 if (ttype(im) == LUA_T_NIL) {
221 im = luaT_getim(L, 0, event); /* try a 'global' i.m. */ 217 im = luaT_getim(L, 0, event); /* try a 'global' i.m. */
222 if (ttype(im) == LUA_T_NIL) 218 if (ttype(im) == LUA_T_NIL)
@@ -228,8 +224,8 @@ static void call_binTM (lua_State *L, IMS event, const char *msg) {
228} 224}
229 225
230 226
231static void call_arith (lua_State *L, IMS event) { 227static void call_arith (lua_State *L, StkId top, IMS event) {
232 call_binTM(L, event, "unexpected type in arithmetic operation"); 228 call_binTM(L, top, event, "unexpected type in arithmetic operation");
233} 229}
234 230
235 231
@@ -249,11 +245,10 @@ static int luaV_strcomp (const char *l, long ll, const char *r, long lr) {
249 } 245 }
250} 246}
251 247
252void luaV_comparison (lua_State *L, lua_Type ttype_less, lua_Type ttype_equal, 248void luaV_comparison (lua_State *L, StkId top, lua_Type ttype_less,
253 lua_Type ttype_great, IMS op) { 249 lua_Type ttype_equal, lua_Type ttype_great, IMS op) {
254 struct Stack *S = &L->stack; 250 const TObject *l = top-2;
255 const TObject *l = S->top-2; 251 const TObject *r = top-1;
256 const TObject *r = S->top-1;
257 real result; 252 real result;
258 if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER) 253 if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER)
259 result = nvalue(l)-nvalue(r); 254 result = nvalue(l)-nvalue(r);
@@ -261,39 +256,41 @@ void luaV_comparison (lua_State *L, lua_Type ttype_less, lua_Type ttype_equal,
261 result = luaV_strcomp(svalue(l), tsvalue(l)->u.s.len, 256 result = luaV_strcomp(svalue(l), tsvalue(l)->u.s.len,
262 svalue(r), tsvalue(r)->u.s.len); 257 svalue(r), tsvalue(r)->u.s.len);
263 else { 258 else {
264 call_binTM(L, op, "unexpected type in comparison"); 259 call_binTM(L, top, op, "unexpected type in comparison");
265 return; 260 return;
266 } 261 }
267 S->top--; 262 nvalue(top-2) = 1;
268 nvalue(S->top-1) = 1; 263 ttype(top-2) = (result < 0) ? ttype_less :
269 ttype(S->top-1) = (result < 0) ? ttype_less :
270 (result == 0) ? ttype_equal : ttype_great; 264 (result == 0) ? ttype_equal : ttype_great;
271} 265}
272 266
273 267
274void luaV_pack (lua_State *L, StkId firstel, int nvararg, TObject *tab) { 268void luaV_pack (lua_State *L, StkId firstelem, int nvararg, TObject *tab) {
275 TObject *firstelem = L->stack.stack+firstel;
276 int i; 269 int i;
277 Hash *htab; 270 Hash *htab;
278 if (nvararg < 0) nvararg = 0; 271 htab = avalue(tab) = luaH_new(L, nvararg+1); /* +1 for field `n' */
279 htab = avalue(tab) = luaH_new(L, nvararg+1); /* +1 for field 'n' */
280 ttype(tab) = LUA_T_ARRAY; 272 ttype(tab) = LUA_T_ARRAY;
281 for (i=0; i<nvararg; i++) 273 for (i=0; i<nvararg; i++)
282 luaH_setint(L, htab, i+1, firstelem+i); 274 luaH_setint(L, htab, i+1, firstelem+i);
283 luaV_setn(L, htab, nvararg); /* store counter in field "n" */ 275 luaV_setn(L, htab, nvararg); /* store counter in field `n' */
284} 276}
285 277
286 278
287static void adjust_varargs (lua_State *L, StkId first_extra_arg) { 279static void adjust_varargs (lua_State *L, StkId base, int nfixargs) {
288 TObject arg; 280 TObject arg;
289 luaV_pack(L, first_extra_arg, 281 int nvararg = (L->top-base) - nfixargs;
290 (L->stack.top-L->stack.stack)-first_extra_arg, &arg); 282 if (nvararg < 0) {
291 luaD_adjusttop(L, first_extra_arg); 283 luaV_pack(L, base, 0, &arg);
292 *L->stack.top++ = arg; 284 luaD_adjusttop(L, base, nfixargs);
285 }
286 else {
287 luaV_pack(L, base+nfixargs, nvararg, &arg);
288 L->top = base+nfixargs;
289 }
290 *L->top++ = arg;
293} 291}
294 292
295 293
296
297/* 294/*
298** Execute the given opcode, until a RET. Parameters are between 295** Execute the given opcode, until a RET. Parameters are between
299** [stack+base,top). Returns n such that the the results are between 296** [stack+base,top). Returns n such that the the results are between
@@ -301,25 +298,26 @@ static void adjust_varargs (lua_State *L, StkId first_extra_arg) {
301*/ 298*/
302StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, 299StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
303 StkId base) { 300 StkId base) {
304 struct Stack *S = &L->stack; /* to optimize */ 301 register StkId top; /* keep top local, for performance */
305 register const Byte *pc = tf->code; 302 register const Byte *pc = tf->code;
306 const TObject *consts = tf->consts; 303 const TObject *consts = tf->consts;
307 if (L->callhook) 304 if (L->callhook)
308 luaD_callHook(L, base, tf, 0); 305 luaD_callHook(L, base, tf, 0);
309 luaD_checkstack(L, (*pc++)+EXTRA_STACK); 306 luaD_checkstack(L, (*pc++)+EXTRA_STACK);
310 if (*pc < ZEROVARARG) 307 if (*pc < ZEROVARARG)
311 luaD_adjusttop(L, base+*(pc++)); 308 luaD_adjusttop(L, base, *(pc++));
312 else { /* varargs */ 309 else { /* varargs */
310 adjust_varargs(L, base, (*pc++)-ZEROVARARG);
313 luaC_checkGC(L); 311 luaC_checkGC(L);
314 adjust_varargs(L, base+(*pc++)-ZEROVARARG);
315 } 312 }
313 top = L->top;
316 for (;;) { 314 for (;;) {
317 register int aux = 0; 315 register int aux = 0;
318 switchentry: 316 switchentry:
319 switch ((OpCode)*pc++) { 317 switch ((OpCode)*pc++) {
320 318
321 case ENDCODE: 319 case ENDCODE:
322 S->top = S->stack + base; 320 top = base;
323 goto ret; 321 goto ret;
324 322
325 case RETCODE: 323 case RETCODE:
@@ -327,238 +325,240 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
327 goto ret; 325 goto ret;
328 326
329 case CALL: aux = *pc++; 327 case CALL: aux = *pc++;
330 luaD_call(L, (S->stack+base) + *pc++, aux); 328 L->top = top;
329 luaD_call(L, base+(*pc++), aux);
330 top = L->top;
331 break; 331 break;
332 332
333 case TAILCALL: aux = *pc++; 333 case TAILCALL: aux = *pc++;
334 luaD_call(L, (S->stack+base) + *pc++, MULT_RET); 334 L->top = top;
335 luaD_call(L, base+(*pc++), MULT_RET);
336 top = L->top;
335 base += aux; 337 base += aux;
336 goto ret; 338 goto ret;
337 339
338 case PUSHNIL: aux = *pc++; 340 case PUSHNIL: aux = *pc++;
339 do { 341 do {
340 ttype(S->top++) = LUA_T_NIL; 342 ttype(top++) = LUA_T_NIL;
341 } while (aux--); 343 } while (aux--);
342 break; 344 break;
343 345
344 case POP: aux = *pc++; 346 case POP: aux = *pc++;
345 S->top -= aux; 347 top -= aux;
346 break; 348 break;
347 349
348 case PUSHNUMBERW: aux += highbyte(L, *pc++); 350 case PUSHNUMBERW: aux += highbyte(L, *pc++);
349 case PUSHNUMBER: aux += *pc++; 351 case PUSHNUMBER: aux += *pc++;
350 ttype(S->top) = LUA_T_NUMBER; 352 ttype(top) = LUA_T_NUMBER;
351 nvalue(S->top) = aux; 353 nvalue(top) = aux;
352 S->top++; 354 top++;
353 break; 355 break;
354 356
355 case PUSHNUMBERNEGW: aux += highbyte(L, *pc++); 357 case PUSHNUMBERNEGW: aux += highbyte(L, *pc++);
356 case PUSHNUMBERNEG: aux += *pc++; 358 case PUSHNUMBERNEG: aux += *pc++;
357 ttype(S->top) = LUA_T_NUMBER; 359 ttype(top) = LUA_T_NUMBER;
358 nvalue(S->top) = -aux; 360 nvalue(top) = -aux;
359 S->top++; 361 top++;
360 break; 362 break;
361 363
362 case PUSHCONSTANTW: aux += highbyte(L, *pc++); 364 case PUSHCONSTANTW: aux += highbyte(L, *pc++);
363 case PUSHCONSTANT: aux += *pc++; 365 case PUSHCONSTANT: aux += *pc++;
364 *S->top++ = consts[aux]; 366 *top++ = consts[aux];
365 break; 367 break;
366 368
367 case PUSHUPVALUE: aux = *pc++; 369 case PUSHUPVALUE: aux = *pc++;
368 *S->top++ = cl->consts[aux+1]; 370 *top++ = cl->consts[aux+1];
369 break; 371 break;
370 372
371 case PUSHLOCAL: aux = *pc++; 373 case PUSHLOCAL: aux = *pc++;
372 *S->top++ = *((S->stack+base) + aux); 374 *top++ = *(base+aux);
373 break; 375 break;
374 376
375 case GETGLOBALW: aux += highbyte(L, *pc++); 377 case GETGLOBALW: aux += highbyte(L, *pc++);
376 case GETGLOBAL: aux += *pc++; 378 case GETGLOBAL: aux += *pc++;
379 L->top = top;
377 luaV_getglobal(L, tsvalue(&consts[aux])->u.s.gv); 380 luaV_getglobal(L, tsvalue(&consts[aux])->u.s.gv);
381 top++;
378 break; 382 break;
379 383
380 case GETTABLE: 384 case GETTABLE:
385 L->top = top;
381 luaV_gettable(L); 386 luaV_gettable(L);
387 top--;
382 break; 388 break;
383 389
384 case GETDOTTEDW: aux += highbyte(L, *pc++); 390 case GETDOTTEDW: aux += highbyte(L, *pc++);
385 case GETDOTTED: aux += *pc++; 391 case GETDOTTED: aux += *pc++;
386 *S->top++ = consts[aux]; 392 *top++ = consts[aux];
393 L->top = top;
387 luaV_gettable(L); 394 luaV_gettable(L);
395 top--;
388 break; 396 break;
389 397
390 case PUSHSELFW: aux += highbyte(L, *pc++); 398 case PUSHSELFW: aux += highbyte(L, *pc++);
391 case PUSHSELF: aux += *pc++; { 399 case PUSHSELF: aux += *pc++; {
392 TObject receiver; 400 TObject receiver;
393 receiver = *(S->top-1); 401 receiver = *(top-1);
394 *S->top++ = consts[aux]; 402 *top++ = consts[aux];
403 L->top = top;
395 luaV_gettable(L); 404 luaV_gettable(L);
396 *S->top++ = receiver; 405 *(top-1) = receiver;
397 break; 406 break;
398 } 407 }
399 408
400 case CREATEARRAYW: aux += highbyte(L, *pc++); 409 case CREATEARRAYW: aux += highbyte(L, *pc++);
401 case CREATEARRAY: aux += *pc++; 410 case CREATEARRAY: aux += *pc++;
411 L->top = top;
402 luaC_checkGC(L); 412 luaC_checkGC(L);
403 avalue(S->top) = luaH_new(L, aux); 413 avalue(top) = luaH_new(L, aux);
404 ttype(S->top) = LUA_T_ARRAY; 414 ttype(top) = LUA_T_ARRAY;
405 S->top++; 415 top++;
406 break; 416 break;
407 417
408 case SETLOCAL: aux = *pc++; 418 case SETLOCAL: aux = *pc++;
409 *((S->stack+base) + aux) = *(--S->top); 419 *(base+aux) = *(--top);
410 break; 420 break;
411 421
412 case SETGLOBALW: aux += highbyte(L, *pc++); 422 case SETGLOBALW: aux += highbyte(L, *pc++);
413 case SETGLOBAL: aux += *pc++; 423 case SETGLOBAL: aux += *pc++;
424 L->top = top;
414 luaV_setglobal(L, tsvalue(&consts[aux])->u.s.gv); 425 luaV_setglobal(L, tsvalue(&consts[aux])->u.s.gv);
426 top--;
415 break; 427 break;
416 428
417 case SETTABLEPOP: 429 case SETTABLEPOP:
418 luaV_settable(L, S->top-3); 430 L->top = top;
419 S->top -= 2; /* pop table and index */ 431 luaV_settable(L, top-3);
432 top -= 3; /* pop table, index, and value */
420 break; 433 break;
421 434
422 case SETTABLE: 435 case SETTABLE:
423 luaV_settable(L, S->top-3-(*pc++)); 436 L->top = top;
437 luaV_settable(L, top-3-(*pc++));
438 top--; /* pop value */
424 break; 439 break;
425 440
426 case SETLISTW: aux += highbyte(L, *pc++); 441 case SETLISTW: aux += highbyte(L, *pc++);
427 case SETLIST: aux += *pc++; { 442 case SETLIST: aux += *pc++; {
428 int n = *(pc++); 443 int n = *(pc++);
429 Hash *arr = avalue(S->top-n-1); 444 Hash *arr = avalue(top-n-1);
430 aux *= LFIELDS_PER_FLUSH; 445 aux *= LFIELDS_PER_FLUSH;
431 for (; n; n--) 446 for (; n; n--)
432 luaH_setint(L, arr, n+aux, --S->top); 447 luaH_setint(L, arr, n+aux, --top);
433 break; 448 break;
434 } 449 }
435 450
436 case SETMAP: aux = *pc++; { 451 case SETMAP: aux = *pc++; {
437 Hash *arr = avalue(S->top-(2*aux)-3); 452 Hash *arr = avalue(top-(2*aux)-3);
438 do { 453 do {
439 luaH_set(L, arr, S->top-2, S->top-1); 454 luaH_set(L, arr, top-2, top-1);
440 S->top-=2; 455 top-=2;
441 } while (aux--); 456 } while (aux--);
442 break; 457 break;
443 } 458 }
444 459
445 case NEQOP: aux = 1; 460 case NEQOP: aux = 1;
446 case EQOP: { 461 case EQOP: {
447 int res = luaO_equalObj(S->top-2, S->top-1); 462 int res = luaO_equalObj(top-2, top-1);
448 if (aux) res = !res; 463 if (aux) res = !res;
449 S->top--; 464 top--;
450 ttype(S->top-1) = res ? LUA_T_NUMBER : LUA_T_NIL; 465 ttype(top-1) = res ? LUA_T_NUMBER : LUA_T_NIL;
451 nvalue(S->top-1) = 1; 466 nvalue(top-1) = 1;
452 break; 467 break;
453 } 468 }
454 469
455 case LTOP: 470 case LTOP:
456 luaV_comparison(L, LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT); 471 luaV_comparison(L, top, LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
472 top--;
457 break; 473 break;
458 474
459 case LEOP: 475 case LEOP:
460 luaV_comparison(L, LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE); 476 luaV_comparison(L, top, LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE);
477 top--;
461 break; 478 break;
462 479
463 case GTOP: 480 case GTOP:
464 luaV_comparison(L, LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT); 481 luaV_comparison(L, top, LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT);
482 top--;
465 break; 483 break;
466 484
467 case GEOP: 485 case GEOP:
468 luaV_comparison(L, LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE); 486 luaV_comparison(L, top, LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE);
487 top--;
469 break; 488 break;
470 489
471 case ADDOP: { 490 case ADDOP:
472 TObject *l = S->top-2; 491 if (tonumber(top-1) || tonumber(top-2))
473 TObject *r = S->top-1; 492 call_arith(L, top, IM_ADD);
474 if (tonumber(r) || tonumber(l)) 493 else
475 call_arith(L, IM_ADD); 494 nvalue(top-2) += nvalue(top-1);
476 else { 495 top--;
477 nvalue(l) += nvalue(r);
478 --S->top;
479 }
480 break; 496 break;
481 }
482 497
483 case SUBOP: { 498 case SUBOP:
484 TObject *l = S->top-2; 499 if (tonumber(top-1) || tonumber(top-2))
485 TObject *r = S->top-1; 500 call_arith(L, top, IM_SUB);
486 if (tonumber(r) || tonumber(l)) 501 else
487 call_arith(L, IM_SUB); 502 nvalue(top-2) -= nvalue(top-1);
488 else { 503 top--;
489 nvalue(l) -= nvalue(r);
490 --S->top;
491 }
492 break; 504 break;
493 }
494 505
495 case MULTOP: { 506 case MULTOP:
496 TObject *l = S->top-2; 507 if (tonumber(top-1) || tonumber(top-2))
497 TObject *r = S->top-1; 508 call_arith(L, top, IM_MUL);
498 if (tonumber(r) || tonumber(l)) 509 else
499 call_arith(L, IM_MUL); 510 nvalue(top-2) *= nvalue(top-1);
500 else { 511 top--;
501 nvalue(l) *= nvalue(r);
502 --S->top;
503 }
504 break; 512 break;
505 }
506 513
507 case DIVOP: { 514 case DIVOP:
508 TObject *l = S->top-2; 515 if (tonumber(top-1) || tonumber(top-2))
509 TObject *r = S->top-1; 516 call_arith(L, top, IM_DIV);
510 if (tonumber(r) || tonumber(l)) 517 else
511 call_arith(L, IM_DIV); 518 nvalue(top-2) /= nvalue(top-1);
512 else { 519 top--;
513 nvalue(l) /= nvalue(r);
514 --S->top;
515 }
516 break; 520 break;
517 }
518 521
519 case POWOP: 522 case POWOP:
520 call_binTM(L, IM_POW, "undefined operation"); 523 call_binTM(L, top, IM_POW, "undefined operation");
524 top--;
521 break; 525 break;
522 526
523 case CONCOP: { 527 case CONCOP:
524 TObject *l = S->top-2; 528 if (tostring(L, top-2) || tostring(L, top-1))
525 TObject *r = S->top-1; 529 call_binTM(L, top, IM_CONCAT, "unexpected type for concatenation");
526 if (tostring(L, l) || tostring(L, r)) 530 else
527 call_binTM(L, IM_CONCAT, "unexpected type for concatenation"); 531 tsvalue(top-2) = strconc(L, tsvalue(top-2), tsvalue(top-1));
528 else { 532 L->top = top;
529 tsvalue(l) = strconc(L, tsvalue(l), tsvalue(r));
530 --S->top;
531 }
532 luaC_checkGC(L); 533 luaC_checkGC(L);
534 top--;
533 break; 535 break;
534 }
535 536
536 case MINUSOP: 537 case MINUSOP:
537 if (tonumber(S->top-1)) { 538 if (tonumber(top-1)) {
538 ttype(S->top) = LUA_T_NIL; 539 ttype(top) = LUA_T_NIL;
539 S->top++; 540 call_arith(L, top+1, IM_UNM);
540 call_arith(L, IM_UNM);
541 } 541 }
542 else 542 else
543 nvalue(S->top-1) = - nvalue(S->top-1); 543 nvalue(top-1) = - nvalue(top-1);
544 break; 544 break;
545 545
546 case NOTOP: 546 case NOTOP:
547 ttype(S->top-1) = 547 ttype(top-1) =
548 (ttype(S->top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL; 548 (ttype(top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL;
549 nvalue(S->top-1) = 1; 549 nvalue(top-1) = 1;
550 break; 550 break;
551 551
552 case ONTJMPW: aux += highbyte(L, *pc++); 552 case ONTJMPW: aux += highbyte(L, *pc++);
553 case ONTJMP: aux += *pc++; 553 case ONTJMP: aux += *pc++;
554 if (ttype(S->top-1) != LUA_T_NIL) pc += aux; 554 if (ttype(top-1) != LUA_T_NIL) pc += aux;
555 else S->top--; 555 else top--;
556 break; 556 break;
557 557
558 case ONFJMPW: aux += highbyte(L, *pc++); 558 case ONFJMPW: aux += highbyte(L, *pc++);
559 case ONFJMP: aux += *pc++; 559 case ONFJMP: aux += *pc++;
560 if (ttype(S->top-1) == LUA_T_NIL) pc += aux; 560 if (ttype(top-1) == LUA_T_NIL) pc += aux;
561 else S->top--; 561 else top--;
562 break; 562 break;
563 563
564 case JMPW: aux += highbyte(L, *pc++); 564 case JMPW: aux += highbyte(L, *pc++);
@@ -568,35 +568,40 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
568 568
569 case IFFJMPW: aux += highbyte(L, *pc++); 569 case IFFJMPW: aux += highbyte(L, *pc++);
570 case IFFJMP: aux += *pc++; 570 case IFFJMP: aux += *pc++;
571 if (ttype(--S->top) == LUA_T_NIL) pc += aux; 571 if (ttype(--top) == LUA_T_NIL) pc += aux;
572 break; 572 break;
573 573
574 case IFTUPJMPW: aux += highbyte(L, *pc++); 574 case IFTUPJMPW: aux += highbyte(L, *pc++);
575 case IFTUPJMP: aux += *pc++; 575 case IFTUPJMP: aux += *pc++;
576 if (ttype(--S->top) != LUA_T_NIL) pc -= aux; 576 if (ttype(--top) != LUA_T_NIL) pc -= aux;
577 break; 577 break;
578 578
579 case IFFUPJMPW: aux += highbyte(L, *pc++); 579 case IFFUPJMPW: aux += highbyte(L, *pc++);
580 case IFFUPJMP: aux += *pc++; 580 case IFFUPJMP: aux += *pc++;
581 if (ttype(--S->top) == LUA_T_NIL) pc -= aux; 581 if (ttype(--top) == LUA_T_NIL) pc -= aux;
582 break; 582 break;
583 583
584 case CLOSUREW: aux += highbyte(L, *pc++); 584 case CLOSUREW: aux += highbyte(L, *pc++);
585 case CLOSURE: aux += *pc++; 585 case CLOSURE: aux += *pc++;
586 *S->top++ = consts[aux]; 586 *top++ = consts[aux];
587 luaV_closure(L, *pc++); 587 L->top = top;
588 aux = *pc++;
589 luaV_closure(L, aux);
588 luaC_checkGC(L); 590 luaC_checkGC(L);
591 top -= aux;
589 break; 592 break;
590 593
591 case SETLINEW: aux += highbyte(L, *pc++); 594 case SETLINEW: aux += highbyte(L, *pc++);
592 case SETLINE: aux += *pc++; 595 case SETLINE: aux += *pc++;
593 if ((S->stack+base-1)->ttype != LUA_T_LINE) { 596 L->top = top;
597 if ((base-1)->ttype != LUA_T_LINE) {
594 /* open space for LINE value */ 598 /* open space for LINE value */
595 luaD_openstack(L, (S->top-S->stack)-base); 599 luaD_openstack(L, base);
600 base->ttype = LUA_T_LINE;
596 base++; 601 base++;
597 (S->stack+base-1)->ttype = LUA_T_LINE; 602 top++;
598 } 603 }
599 (S->stack+base-1)->value.i = aux; 604 (base-1)->value.i = aux;
600 if (L->linehook) 605 if (L->linehook)
601 luaD_lineHook(L, aux); 606 luaD_lineHook(L, aux);
602 break; 607 break;
@@ -608,8 +613,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
608 613
609 } 614 }
610 } ret: 615 } ret:
616 L->top = top;
611 if (L->callhook) 617 if (L->callhook)
612 luaD_callHook(L, 0, NULL, 1); 618 luaD_callHook(L, 0, NULL, 1);
613 return base; 619 return base;
614} 620}
615