aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-06-05 15:17:01 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-06-05 15:17:01 -0300
commit762d059a13d83eb367238a6115bbb4f5f13fcb49 (patch)
treef35fdf0675b791865d0d4800522b172903b34803 /lvm.c
parent572a69b6afbd368beab8844bc876b0f9690b5253 (diff)
downloadlua-762d059a13d83eb367238a6115bbb4f5f13fcb49.tar.gz
lua-762d059a13d83eb367238a6115bbb4f5f13fcb49.tar.bz2
lua-762d059a13d83eb367238a6115bbb4f5f13fcb49.zip
new implementation for the Virtual Machine
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c476
1 files changed, 231 insertions, 245 deletions
diff --git a/lvm.c b/lvm.c
index 9c1b13d0..4cead1d9 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.177 2001/03/26 14:31:49 roberto Exp roberto $ 2** $Id: lvm.c,v 1.178 2001/04/06 18:25:00 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*/
@@ -28,15 +28,14 @@
28 28
29 29
30 30
31int luaV_tonumber (TObject *obj) { 31const TObject *luaV_tonumber (const TObject *obj, TObject *n) {
32 if (ttype(obj) != LUA_TSTRING) 32 if (ttype(obj) == LUA_TNUMBER) return obj;
33 return 1; 33 if (ttype(obj) == LUA_TSTRING && luaO_str2d(svalue(obj), &nvalue(n))) {
34 else { 34 ttype(n) = LUA_TNUMBER;
35 if (!luaO_str2d(svalue(obj), &nvalue(obj))) 35 return n;
36 return 2;
37 ttype(obj) = LUA_TNUMBER;
38 return 0;
39 } 36 }
37 else
38 return NULL;
40} 39}
41 40
42 41
@@ -148,8 +147,7 @@ void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) {
148 } 147 }
149 } 148 }
150 /* else will call the tag method */ 149 /* else will call the tag method */
151 } 150 } else { /* not a table; try a `gettable' tag method */
152 else { /* not a table; try a `gettable' tag method */
153 tm = luaT_gettmbyObj(G(L), t, TM_GETTABLE); 151 tm = luaT_gettmbyObj(G(L), t, TM_GETTABLE);
154 if (tm == NULL) /* no tag method? */ 152 if (tm == NULL) /* no tag method? */
155 luaG_typeerror(L, t, l_s("index")); 153 luaG_typeerror(L, t, l_s("index"));
@@ -162,7 +160,7 @@ void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) {
162/* 160/*
163** Receives table at `t', key at `key' and value at `val'. 161** Receives table at `t', key at `key' and value at `val'.
164*/ 162*/
165void luaV_settable (lua_State *L, StkId t, StkId key, StkId val) { 163void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) {
166 Closure *tm; 164 Closure *tm;
167 if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */ 165 if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */
168 int tg = hvalue(t)->htag; 166 int tg = hvalue(t)->htag;
@@ -172,8 +170,7 @@ void luaV_settable (lua_State *L, StkId t, StkId key, StkId val) {
172 return; 170 return;
173 } 171 }
174 /* else will call the tag method */ 172 /* else will call the tag method */
175 } 173 } else { /* not a table; try a `settable' tag method */
176 else { /* not a table; try a `settable' tag method */
177 tm = luaT_gettmbyObj(G(L), t, TM_SETTABLE); 174 tm = luaT_gettmbyObj(G(L), t, TM_SETTABLE);
178 if (tm == NULL) /* no tag method? */ 175 if (tm == NULL) /* no tag method? */
179 luaG_typeerror(L, t, l_s("index")); 176 luaG_typeerror(L, t, l_s("index"));
@@ -188,8 +185,7 @@ void luaV_getglobal (lua_State *L, TString *name, StkId res) {
188 if (!HAS_TM_GETGLOBAL(L, ttype(value)) || /* is there a tag method? */ 185 if (!HAS_TM_GETGLOBAL(L, ttype(value)) || /* is there a tag method? */
189 (tm = luaT_gettmbyObj(G(L), value, TM_GETGLOBAL)) == NULL) { 186 (tm = luaT_gettmbyObj(G(L), value, TM_GETGLOBAL)) == NULL) {
190 setobj(res, value); /* default behavior */ 187 setobj(res, value); /* default behavior */
191 } 188 } else
192 else
193 callTM(L, l_s("csor"), tm, name, value, res); 189 callTM(L, l_s("csor"), tm, name, value, res);
194} 190}
195 191
@@ -200,8 +196,7 @@ void luaV_setglobal (lua_State *L, TString *name, StkId val) {
200 if (!HAS_TM_SETGLOBAL(L, ttype(oldvalue)) || /* no tag methods? */ 196 if (!HAS_TM_SETGLOBAL(L, ttype(oldvalue)) || /* no tag methods? */
201 (tm = luaT_gettmbyObj(G(L), oldvalue, TM_SETGLOBAL)) == NULL) { 197 (tm = luaT_gettmbyObj(G(L), oldvalue, TM_SETGLOBAL)) == NULL) {
202 setobj(oldvalue, val); /* raw set */ 198 setobj(oldvalue, val); /* raw set */
203 } 199 } else
204 else
205 callTM(L, l_s("csoo"), tm, name, oldvalue, val); 200 callTM(L, l_s("csoo"), tm, name, oldvalue, val);
206} 201}
207 202
@@ -224,9 +219,10 @@ static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2,
224} 219}
225 220
226 221
227static void call_arith (lua_State *L, StkId p1, TMS event) { 222static void call_arith (lua_State *L, StkId p1, TObject *p2,
228 if (!call_binTM(L, p1, p1+1, p1, event)) 223 StkId res, TMS event) {
229 luaG_binerror(L, p1, LUA_TNUMBER, l_s("perform arithmetic on")); 224 if (!call_binTM(L, p1, p2, res, event))
225 luaG_aritherror(L, p1, p2);
230} 226}
231 227
232 228
@@ -270,9 +266,8 @@ void luaV_strconc (lua_State *L, int total, StkId top) {
270 int n = 2; /* number of elements handled in this pass (at least 2) */ 266 int n = 2; /* number of elements handled in this pass (at least 2) */
271 if (tostring(L, top-2) || tostring(L, top-1)) { 267 if (tostring(L, top-2) || tostring(L, top-1)) {
272 if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) 268 if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
273 luaG_binerror(L, top-2, LUA_TSTRING, l_s("concat")); 269 luaG_concaterror(L, top-2, top-1);
274 } 270 } else if (tsvalue(top-1)->len > 0) { /* if len=0, do nothing */
275 else if (tsvalue(top-1)->len > 0) { /* if len=0, do nothing */
276 /* at least two string values; get as many as possible */ 271 /* at least two string values; get as many as possible */
277 lu_mem tl = (lu_mem)tsvalue(top-1)->len + (lu_mem)tsvalue(top-2)->len; 272 lu_mem tl = (lu_mem)tsvalue(top-1)->len + (lu_mem)tsvalue(top-2)->len;
278 l_char *buffer; 273 l_char *buffer;
@@ -321,7 +316,32 @@ static void adjust_varargs (lua_State *L, StkId base, int nfixargs) {
321 316
322 317
323 318
324#define dojump(pc, i) ((pc) += GETARG_S(i)) 319/*
320** some macros for common tasks in `luaV_execute'
321*/
322
323#define runtime_check(L, c) { if (!(c)) return L->top; }
324
325#define RA(i) (base+GETARG_A(i))
326#define RB(i) (base+GETARG_B(i))
327#define RC(i) (base+GETARG_C(i))
328#define RKC(i) ((GETARG_C(i) < MAXSTACK) ? \
329 base+GETARG_C(i) : \
330 tf->k+GETARG_C(i)-MAXSTACK)
331#define KBc(i) (tf->k+GETARG_Bc(i))
332
333#define Arith(op, optm) { \
334 const TObject *b = RB(i); const TObject *c = RKC(i); \
335 TObject tempb, tempc; \
336 if ((ttype(b) == LUA_TNUMBER || (b = luaV_tonumber(b, &tempb)) != NULL) && \
337 (ttype(c) == LUA_TNUMBER || (c = luaV_tonumber(c, &tempc)) != NULL)) { \
338 setnvalue(RA(i), nvalue(b) op nvalue(c)); \
339 } else \
340 call_arith(L, RB(i), RKC(i), RA(i), optm); \
341}
342
343
344#define dojump(pc, i) ((pc) += GETARG_sBc(i))
325 345
326/* 346/*
327** Executes the given Lua function. Parameters are between [base,top). 347** Executes the given Lua function. Parameters are between [base,top).
@@ -329,328 +349,294 @@ static void adjust_varargs (lua_State *L, StkId base, int nfixargs) {
329*/ 349*/
330StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { 350StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
331 const Proto *const tf = cl->f.l; 351 const Proto *const tf = cl->f.l;
332 StkId top; /* keep top local, for performance */ 352 const Instruction *pc;
333 const Instruction *pc = tf->code; 353 lua_Hook linehook;
334 const lua_Hook linehook = L->linehook;
335 L->ci->pc = &pc;
336 if (tf->is_vararg) /* varargs? */ 354 if (tf->is_vararg) /* varargs? */
337 adjust_varargs(L, base, tf->numparams); 355 adjust_varargs(L, base, tf->numparams);
338 luaD_adjusttop(L, base, tf->maxstacksize); 356 luaD_adjusttop(L, base, tf->maxstacksize);
339 top = base+tf->numparams+tf->is_vararg; 357 pc = tf->code;
358 L->ci->pc = &pc;
359 linehook = L->linehook;
340 /* main loop of interpreter */ 360 /* main loop of interpreter */
341 for (;;) { 361 for (;;) {
342 const Instruction i = *pc++; 362 const Instruction i = *pc++;
343 lua_assert(L->top == base+tf->maxstacksize);
344 if (linehook) 363 if (linehook)
345 traceexec(L, linehook); 364 traceexec(L, linehook);
346 switch (GET_OPCODE(i)) { 365 switch (GET_OPCODE(i)) {
347 case OP_RETURN: { 366 case OP_MOVE: {
348 L->top = top; 367 setobj(RA(i), RB(i));
349 return base+GETARG_U(i);
350 }
351 case OP_CALL: {
352 int nres = GETARG_B(i);
353 if (nres == MULT_RET) nres = LUA_MULTRET;
354 L->top = top;
355 luaD_call(L, base+GETARG_A(i), nres);
356 top = L->top;
357 L->top = base+tf->maxstacksize;
358 break;
359 }
360 case OP_PUSHNIL: {
361 int n = GETARG_U(i);
362 lua_assert(n>0);
363 do {
364 setnilvalue(top++);
365 } while (--n > 0);
366 break;
367 }
368 case OP_POP: {
369 top -= GETARG_U(i);
370 break;
371 }
372 case OP_PUSHINT: {
373 setnvalue(top, (lua_Number)GETARG_S(i));
374 top++;
375 break;
376 }
377 case OP_PUSHSTRING: {
378 setsvalue(top, tf->kstr[GETARG_U(i)]);
379 top++;
380 break; 368 break;
381 } 369 }
382 case OP_PUSHNUM: { 370 case OP_LOADK: {
383 setnvalue(top, tf->knum[GETARG_U(i)]); 371 setobj(RA(i), KBc(i));
384 top++;
385 break; 372 break;
386 } 373 }
387 case OP_PUSHNEGNUM: { 374 case OP_LOADINT: {
388 setnvalue(top, -tf->knum[GETARG_U(i)]); 375 setnvalue(RA(i), (lua_Number)GETARG_sBc(i));
389 top++;
390 break; 376 break;
391 } 377 }
392 case OP_PUSHUPVALUE: { 378 case OP_LOADUPVAL: {
393 setobj(top++, &cl->upvalue[GETARG_U(i)]); 379 setobj(RA(i), cl->upvalue+GETARG_Bc(i));
394 break; 380 break;
395 } 381 }
396 case OP_GETLOCAL: { 382 case OP_LOADNIL: {
397 setobj(top++, base+GETARG_U(i)); 383 TObject *ra = RA(i);
384 TObject *rb = RB(i);
385 do {
386 setnilvalue(ra++);
387 } while (ra <= rb);
398 break; 388 break;
399 } 389 }
400 case OP_GETGLOBAL: { 390 case OP_GETGLOBAL: {
401 luaV_getglobal(L, tf->kstr[GETARG_U(i)], top); 391 lua_assert(ttype(KBc(i)) == LUA_TSTRING);
402 top++; 392 luaV_getglobal(L, tsvalue(KBc(i)), RA(i));
403 break; 393 break;
404 } 394 }
405 case OP_GETTABLE: { 395 case OP_GETTABLE: {
406 top--; 396 luaV_gettable(L, RB(i), RKC(i), RA(i));
407 luaV_gettable(L, top-1, top, top-1);
408 break;
409 }
410 case OP_GETDOTTED: {
411 setsvalue(top, tf->kstr[GETARG_U(i)]);
412 luaV_gettable(L, top-1, top, top-1);
413 break;
414 }
415 case OP_GETINDEXED: {
416 luaV_gettable(L, top-1, base+GETARG_U(i), top-1);
417 break;
418 }
419 case OP_PUSHSELF: {
420 setobj(top, top-1);
421 setsvalue(top+1, tf->kstr[GETARG_U(i)]);
422 luaV_gettable(L, top-1, top+1, top-1);
423 top++;
424 break;
425 }
426 case OP_CREATETABLE: {
427 luaC_checkGC(L);
428 sethvalue(top, luaH_new(L, GETARG_U(i)));
429 top++;
430 break;
431 }
432 case OP_SETLOCAL: {
433 setobj(base+GETARG_U(i), --top);
434 break; 397 break;
435 } 398 }
436 case OP_SETGLOBAL: { 399 case OP_SETGLOBAL: {
437 top--; 400 lua_assert(ttype(KBc(i)) == LUA_TSTRING);
438 luaV_setglobal(L, tf->kstr[GETARG_U(i)], top); 401 luaV_setglobal(L, tsvalue(KBc(i)), RA(i));
439 break; 402 break;
440 } 403 }
441 case OP_SETTABLE: { 404 case OP_SETTABLE: {
442 StkId t = top-GETARG_A(i); 405 luaV_settable(L, RB(i), RKC(i), RA(i));
443 luaV_settable(L, t, t+1, top-1);
444 top -= GETARG_B(i); /* pop values */
445 break; 406 break;
446 } 407 }
447 case OP_SETLIST: { 408 case OP_NEWTABLE: {
448 int aux = GETARG_A(i) * LFIELDS_PER_FLUSH; 409 luaC_checkGC(L);
449 TObject *t = base+GETARG_B(i); 410 sethvalue(RA(i), luaH_new(L, GETARG_Bc(i)));
450 Hash *h = hvalue(t);
451 int n;
452 for (n = top-t-1; n; n--)
453 setobj(luaH_setnum(L, h, n+aux), --top);
454 break; 411 break;
455 } 412 }
456 case OP_SETMAP: { 413 case OP_SELF: {
457 TObject *t = base+GETARG_U(i); 414 StkId ra = RA(i);
458 Hash *h = hvalue(t); 415 StkId rb = RB(i);
459 while (top-1 > t) { 416 setobj(ra+1, rb);
460 top-=2; 417 luaV_gettable(L, rb, RKC(i), ra);
461 setobj(luaH_set(L, h, top), top+1);
462 }
463 break; 418 break;
464 } 419 }
465 case OP_ADD: { 420 case OP_ADD: {
466 if (tonumber(top-2) || tonumber(top-1)) 421 Arith( + , TM_ADD);
467 call_arith(L, top-2, TM_ADD);
468 else
469 nvalue(top-2) += nvalue(top-1);
470 top--;
471 break;
472 }
473 case OP_ADDI: {
474 if (tonumber(top-1)) {
475 setnvalue(top, (lua_Number)GETARG_S(i));
476 call_arith(L, top-1, TM_ADD);
477 }
478 else
479 nvalue(top-1) += (lua_Number)GETARG_S(i);
480 break; 422 break;
481 } 423 }
482 case OP_SUB: { 424 case OP_SUB: {
483 if (tonumber(top-2) || tonumber(top-1)) 425 Arith( - , TM_SUB);
484 call_arith(L, top-2, TM_SUB);
485 else
486 nvalue(top-2) -= nvalue(top-1);
487 top--;
488 break; 426 break;
489 } 427 }
490 case OP_MULT: { 428 case OP_MUL: {
491 if (tonumber(top-2) || tonumber(top-1)) 429 Arith( * , TM_MUL);
492 call_arith(L, top-2, TM_MUL);
493 else
494 nvalue(top-2) *= nvalue(top-1);
495 top--;
496 break; 430 break;
497 } 431 }
498 case OP_DIV: { 432 case OP_DIV: {
499 if (tonumber(top-2) || tonumber(top-1)) 433 Arith( / , TM_DIV);
500 call_arith(L, top-2, TM_DIV);
501 else
502 nvalue(top-2) /= nvalue(top-1);
503 top--;
504 break; 434 break;
505 } 435 }
506 case OP_POW: { 436 case OP_POW: {
507 if (!call_binTM(L, top-2, top-1, top-2, TM_POW)) 437 call_arith(L, RB(i), RKC(i), RA(i), TM_POW);
508 luaD_error(L, l_s("undefined operation"));
509 top--;
510 break; 438 break;
511 } 439 }
512 case OP_CONCAT: { 440 case OP_UNM: {
513 int n = GETARG_U(i); 441 const TObject *rb = RB(i);
514 luaV_strconc(L, n, top); 442 StkId ra = RA(i);
515 top -= n-1; 443 if (ttype(rb) == LUA_TNUMBER || (rb=luaV_tonumber(rb, ra)) != NULL) {
516 luaC_checkGC(L); 444 setnvalue(ra, -nvalue(rb));
517 break; 445 }
518 } 446 else {
519 case OP_MINUS: { 447 TObject temp;
520 if (tonumber(top-1)) { 448 setnilvalue(&temp);
521 setnilvalue(top); 449 call_arith(L, RB(i), &temp, ra, TM_UNM);
522 call_arith(L, top-1, TM_UNM);
523 } 450 }
524 else
525 nvalue(top-1) = -nvalue(top-1);
526 break; 451 break;
527 } 452 }
528 case OP_NOT: { 453 case OP_NOT: {
529 ttype(top-1) = 454 if (ttype(RB(i)) == LUA_TNIL) {
530 (ttype(top-1) == LUA_TNIL) ? LUA_TNUMBER : LUA_TNIL; 455 setnvalue(RA(i), 1);
531 nvalue(top-1) = 1; 456 } else {
457 setnilvalue(RA(i));
458 }
532 break; 459 break;
533 } 460 }
534 case OP_JMPNE: { 461 case OP_CONCAT: {
535 top -= 2; 462 StkId top = RC(i)+1;
536 if (!luaO_equalObj(top, top+1)) dojump(pc, i); 463 StkId rb = RB(i);
464 luaV_strconc(L, top-rb, top);
465 setobj(RA(i), rb);
466 luaC_checkGC(L);
537 break; 467 break;
538 } 468 }
539 case OP_JMPEQ: { 469 case OP_CJMP:
540 top -= 2; 470 case OP_JMP: {
541 if (luaO_equalObj(top, top+1)) dojump(pc, i); 471 dojump(pc, i);
542 break; 472 break;
543 } 473 }
544 case OP_JMPLT: { 474 case OP_TESTEQ: {
545 top -= 2; 475 lua_assert(GET_OPCODE(*pc) == OP_CJMP);
546 if (luaV_lessthan(L, top, top+1)) dojump(pc, i); 476 if (luaO_equalObj(RB(i), RKC(i))) dojump(pc, *pc);
477 pc++;
547 break; 478 break;
548 } 479 }
549 case OP_JMPLE: { /* a <= b === !(b<a) */ 480 case OP_TESTNE: {
550 top -= 2; 481 lua_assert(GET_OPCODE(*pc) == OP_CJMP);
551 if (!luaV_lessthan(L, top+1, top)) dojump(pc, i); 482 if (!luaO_equalObj(RB(i), RKC(i))) dojump(pc, *pc);
483 pc++;
552 break; 484 break;
553 } 485 }
554 case OP_JMPGT: { /* a > b === (b<a) */ 486 case OP_TESTLT: {
555 top -= 2; 487 lua_assert(GET_OPCODE(*pc) == OP_CJMP);
556 if (luaV_lessthan(L, top+1, top)) dojump(pc, i); 488 if (luaV_lessthan(L, RB(i), RKC(i))) dojump(pc, *pc);
489 pc++;
557 break; 490 break;
558 } 491 }
559 case OP_JMPGE: { /* a >= b === !(a<b) */ 492 case OP_TESTLE: { /* b <= c === !(c<b) */
560 top -= 2; 493 lua_assert(GET_OPCODE(*pc) == OP_CJMP);
561 if (!luaV_lessthan(L, top, top+1)) dojump(pc, i); 494 if (!luaV_lessthan(L, RKC(i), RB(i))) dojump(pc, *pc);
495 pc++;
562 break; 496 break;
563 } 497 }
564 case OP_JMPT: { 498 case OP_TESTGT: { /* b > c === (c<b) */
565 if (ttype(--top) != LUA_TNIL) dojump(pc, i); 499 lua_assert(GET_OPCODE(*pc) == OP_CJMP);
500 if (luaV_lessthan(L, RKC(i), RB(i))) dojump(pc, *pc);
501 pc++;
566 break; 502 break;
567 } 503 }
568 case OP_JMPF: { 504 case OP_TESTGE: { /* b >= c === !(b<c) */
569 if (ttype(--top) == LUA_TNIL) dojump(pc, i); 505 lua_assert(GET_OPCODE(*pc) == OP_CJMP);
506 if (!luaV_lessthan(L, RB(i), RKC(i))) dojump(pc, *pc);
507 pc++;
570 break; 508 break;
571 } 509 }
572 case OP_JMPONT: { 510 case OP_TESTT: {
573 if (ttype(top-1) == LUA_TNIL) top--; 511 StkId rb = RB(i);
574 else dojump(pc, i); 512 lua_assert(GET_OPCODE(*pc) == OP_CJMP);
513 if (ttype(rb) != LUA_TNIL) {
514 int a = GETARG_A(i);
515 if (a != NO_REG) setobj(base+a, rb);
516 dojump(pc, *pc);
517 }
518 pc++;
575 break; 519 break;
576 } 520 }
577 case OP_JMPONF: { 521 case OP_TESTF: {
578 if (ttype(top-1) != LUA_TNIL) top--; 522 lua_assert(GET_OPCODE(*pc) == OP_CJMP);
579 else dojump(pc, i); 523 if (ttype(RB(i)) == LUA_TNIL) {
524 int a = GETARG_A(i);
525 if (a != NO_REG) setnilvalue(base+a);
526 dojump(pc, *pc);
527 }
528 pc++;
580 break; 529 break;
581 } 530 }
582 case OP_JMP: { 531 case OP_NILJMP: {
583 dojump(pc, i); 532 setnilvalue(RA(i));
533 pc++;
584 break; 534 break;
585 } 535 }
586 case OP_PUSHNILJMP: { 536 case OP_CALL: {
587 setnilvalue(top++); 537 int nres;
588 pc++; 538 int b = GETARG_B(i);
539 if (b != NO_REG)
540 L->top = base+b;
541 nres = GETARG_C(i);
542 if (nres == NO_REG) nres = LUA_MULTRET;
543 luaD_call(L, RA(i), nres);
544 if (nres != LUA_MULTRET) {
545 lua_assert(L->top == RA(i)+nres);
546 L->top = base+tf->maxstacksize;
547 }
589 break; 548 break;
590 } 549 }
550 case OP_RETURN: {
551 int b = GETARG_B(i);
552 if (b != NO_REG)
553 L->top = base+b;
554 return RA(i);
555 }
591 case OP_FORPREP: { 556 case OP_FORPREP: {
592 int jmp = GETARG_S(i); 557 int jmp = GETARG_sBc(i);
593 if (tonumber(top-1)) 558 StkId breg = RA(i);
594 luaD_error(L, l_s("`for' step must be a number")); 559 if (luaV_tonumber(breg, breg) == NULL)
595 if (tonumber(top-2))
596 luaD_error(L, l_s("`for' limit must be a number"));
597 if (tonumber(top-3))
598 luaD_error(L, l_s("`for' initial value must be a number")); 560 luaD_error(L, l_s("`for' initial value must be a number"));
561 if (luaV_tonumber(breg+1, breg+1) == NULL)
562 luaD_error(L, l_s("`for' limit must be a number"));
563 if (luaV_tonumber(breg+2, breg+2) == NULL)
564 luaD_error(L, l_s("`for' step must be a number"));
599 pc += -jmp; /* `jump' to loop end (delta is negated here) */ 565 pc += -jmp; /* `jump' to loop end (delta is negated here) */
600 goto forloop; /* do not increment index */ 566 nvalue(breg) -= nvalue(breg+2);/* decrement index (to be incremented) */
567 /* go through */
601 } 568 }
602 case OP_FORLOOP: { 569 case OP_FORLOOP: {
603 lua_assert(ttype(top-1) == LUA_TNUMBER); 570 StkId breg = RA(i);
604 lua_assert(ttype(top-2) == LUA_TNUMBER); 571 if (ttype(breg) != LUA_TNUMBER)
605 if (ttype(top-3) != LUA_TNUMBER)
606 luaD_error(L, l_s("`for' index must be a number")); 572 luaD_error(L, l_s("`for' index must be a number"));
607 nvalue(top-3) += nvalue(top-1); /* increment index */ 573 runtime_check(L, ttype(breg+1) == LUA_TNUMBER &&
608 forloop: 574 ttype(breg+2) == LUA_TNUMBER);
609 if (nvalue(top-1) > 0 ? 575 nvalue(breg) += nvalue(breg+2); /* increment index */
610 nvalue(top-3) > nvalue(top-2) : 576 if (nvalue(breg+2) > 0 ?
611 nvalue(top-3) < nvalue(top-2)) 577 nvalue(breg) <= nvalue(breg+1) :
612 top -= 3; /* end loop: remove control variables */ 578 nvalue(breg) >= nvalue(breg+1))
613 else
614 dojump(pc, i); /* repeat loop */ 579 dojump(pc, i); /* repeat loop */
615 break; 580 break;
616 } 581 }
617 case OP_LFORPREP: { 582 case OP_TFORPREP: {
618 int jmp = GETARG_S(i); 583 int jmp = GETARG_sBc(i);
619 if (ttype(top-1) != LUA_TTABLE) 584 StkId breg = RA(i);
585 if (ttype(breg) != LUA_TTABLE)
620 luaD_error(L, l_s("`for' table must be a table")); 586 luaD_error(L, l_s("`for' table must be a table"));
621 top += 3; /* index,key,value */ 587 setnvalue(breg+1, -1); /* initial index */
622 setnvalue(top-3, -1); /* initial index */ 588 setnilvalue(breg+2);
623 setnilvalue(top-2); 589 setnilvalue(breg+3);
624 setnilvalue(top-1);
625 pc += -jmp; /* `jump' to loop end (delta is negated here) */ 590 pc += -jmp; /* `jump' to loop end (delta is negated here) */
626 /* go through */ 591 /* go through */
627 } 592 }
628 case OP_LFORLOOP: { 593 case OP_TFORLOOP: {
629 Hash *t = hvalue(top-4); 594 StkId breg = RA(i);
630 int n = (int)nvalue(top-3); 595 Hash *t;
631 lua_assert(ttype(top-3) == LUA_TNUMBER); 596 int n;
632 lua_assert(ttype(top-4) == LUA_TTABLE); 597 runtime_check(L, ttype(breg) == LUA_TTABLE);
598 runtime_check(L, ttype(breg+1) == LUA_TNUMBER);
599 t = hvalue(breg);
600 n = (int)nvalue(breg+1);
633 n = luaH_nexti(t, n); 601 n = luaH_nexti(t, n);
634 if (n == -1) /* end loop? */ 602 if (n != -1) { /* repeat loop? */
635 top -= 4; /* remove table, index, key, and value */
636 else {
637 Node *node = node(t, n); 603 Node *node = node(t, n);
638 setnvalue(top-3, n); /* index */ 604 setnvalue(breg+1, n); /* index */
639 setkey2obj(top-2, node); 605 setkey2obj(breg+2, node);
640 setobj(top-1, val(node)); 606 setobj(breg+3, val(node));
641 dojump(pc, i); /* repeat loop */ 607 dojump(pc, i); /* repeat loop */
642 } 608 }
643 break; 609 break;
644 } 610 }
611 case OP_SETLIST:
612 case OP_SETLISTO: {
613 int bc;
614 int n;
615 Hash *h;
616 StkId ra = RA(i);
617 runtime_check(L, ttype(ra) == LUA_TTABLE);
618 h = hvalue(ra);
619 bc = GETARG_Bc(i);
620 if (GET_OPCODE(i) == OP_SETLIST)
621 n = (bc&(LFIELDS_PER_FLUSH-1)) + 1;
622 else
623 n = L->top - ra - 1;
624 bc &= ~(LFIELDS_PER_FLUSH-1); /* bc = bc - bc%FPF */
625 for (; n > 0; n--)
626 setobj(luaH_setnum(L, h, bc+n), ra+n);
627 break;
628 }
645 case OP_CLOSURE: { 629 case OP_CLOSURE: {
646 int nup = GETARG_B(i); 630 Proto *p = tf->kproto[GETARG_Bc(i)];
647 luaC_checkGC(L); 631 int nup = p->nupvalues;
648 L->top = top; 632 StkId ra = RA(i);
649 luaV_Lclosure(L, tf->kproto[GETARG_A(i)], nup); 633 L->top = ra+nup;
650 top -= (nup-1); 634 luaV_Lclosure(L, p, nup);
651 L->top = base+tf->maxstacksize; 635 L->top = base+tf->maxstacksize;
636 luaC_checkGC(L);
652 break; 637 break;
653 } 638 }
654 } 639 }
655 } 640 }
656} 641}
642