diff options
-rw-r--r-- | ldebug.c | 4 | ||||
-rw-r--r-- | lvm.c | 42 |
2 files changed, 32 insertions, 14 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldebug.c,v 1.102 2002/03/11 12:45:00 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 1.103 2002/03/19 12:45:25 roberto Exp roberto $ |
3 | ** Debug Interface | 3 | ** Debug Interface |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -296,6 +296,7 @@ static int checkopenop (const Proto *pt, int pc) { | |||
296 | Instruction i = pt->code[pc+1]; | 296 | Instruction i = pt->code[pc+1]; |
297 | switch (GET_OPCODE(i)) { | 297 | switch (GET_OPCODE(i)) { |
298 | case OP_CALL: | 298 | case OP_CALL: |
299 | case OP_TAILCALL: | ||
299 | case OP_RETURN: { | 300 | case OP_RETURN: { |
300 | check(GETARG_B(i) == 0); | 301 | check(GETARG_B(i) == 0); |
301 | return 1; | 302 | return 1; |
@@ -405,6 +406,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { | |||
405 | if (reg >= a) last = pc; /* affect all registers above base */ | 406 | if (reg >= a) last = pc; /* affect all registers above base */ |
406 | break; | 407 | break; |
407 | } | 408 | } |
409 | case OP_TAILCALL: | ||
408 | case OP_RETURN: { | 410 | case OP_RETURN: { |
409 | b--; /* b = num. returns */ | 411 | b--; /* b = num. returns */ |
410 | if (b > 0) checkreg(pt, a+b-1); | 412 | if (b > 0) checkreg(pt, a+b-1); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 1.220 2002/03/19 12:45:25 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.221 2002/03/20 12:52:32 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 | */ |
@@ -314,7 +314,7 @@ static void powOp (lua_State *L, StkId ra, StkId rb, StkId rc) { | |||
314 | } | 314 | } |
315 | 315 | ||
316 | 316 | ||
317 | #define dojump(pc, i) ((pc) += GETARG_sBc(i)) | 317 | #define dojump(pc, i) ((pc) += (i)) |
318 | 318 | ||
319 | /* | 319 | /* |
320 | ** Executes current Lua function. Parameters are between [base,top). | 320 | ** Executes current Lua function. Parameters are between [base,top). |
@@ -327,13 +327,13 @@ StkId luaV_execute (lua_State *L) { | |||
327 | const Instruction *pc; | 327 | const Instruction *pc; |
328 | lua_Hook linehook; | 328 | lua_Hook linehook; |
329 | reinit: | 329 | reinit: |
330 | base = L->ci->base; | ||
331 | cl = &clvalue(base - 1)->l; | ||
332 | k = cl->p->k; | ||
333 | linehook = L->linehook; | 330 | linehook = L->linehook; |
334 | L->ci->pc = &pc; | 331 | L->ci->pc = &pc; |
335 | L->ci->pb = &base; | ||
336 | pc = L->ci->savedpc; | 332 | pc = L->ci->savedpc; |
333 | L->ci->pb = &base; | ||
334 | base = L->ci->base; | ||
335 | cl = &clvalue(base - 1)->l; | ||
336 | k = cl->p->k; | ||
337 | /* main loop of interpreter */ | 337 | /* main loop of interpreter */ |
338 | for (;;) { | 338 | for (;;) { |
339 | const Instruction i = *pc++; | 339 | const Instruction i = *pc++; |
@@ -343,7 +343,8 @@ StkId luaV_execute (lua_State *L) { | |||
343 | ra = RA(i); | 343 | ra = RA(i); |
344 | lua_assert(L->top <= L->stack + L->stacksize && L->top >= L->ci->base); | 344 | lua_assert(L->top <= L->stack + L->stacksize && L->top >= L->ci->base); |
345 | lua_assert(L->top == L->ci->top || GET_OPCODE(i) == OP_CALL || | 345 | lua_assert(L->top == L->ci->top || GET_OPCODE(i) == OP_CALL || |
346 | GET_OPCODE(i) == OP_RETURN || GET_OPCODE(i) == OP_SETLISTO); | 346 | GET_OPCODE(i) == OP_TAILCALL || GET_OPCODE(i) == OP_RETURN || |
347 | GET_OPCODE(i) == OP_SETLISTO); | ||
347 | switch (GET_OPCODE(i)) { | 348 | switch (GET_OPCODE(i)) { |
348 | case OP_MOVE: { | 349 | case OP_MOVE: { |
349 | setobj(ra, RB(i)); | 350 | setobj(ra, RB(i)); |
@@ -452,7 +453,8 @@ StkId luaV_execute (lua_State *L) { | |||
452 | break; | 453 | break; |
453 | } | 454 | } |
454 | case OP_JMP: { | 455 | case OP_JMP: { |
455 | dojump(pc, i); | 456 | linehook = L->linehook; |
457 | dojump(pc, GETARG_sBc(i)); | ||
456 | break; | 458 | break; |
457 | } | 459 | } |
458 | case OP_TESTEQ: { /* skip next instruction if test fails */ | 460 | case OP_TESTEQ: { /* skip next instruction if test fails */ |
@@ -513,14 +515,26 @@ StkId luaV_execute (lua_State *L) { | |||
513 | } | 515 | } |
514 | break; | 516 | break; |
515 | } | 517 | } |
518 | case OP_TAILCALL: { | ||
519 | int b = GETARG_B(i); | ||
520 | if (L->openupval) luaF_close(L, base); | ||
521 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ | ||
522 | luaD_poscall(L, LUA_MULTRET, ra); /* move down function and args. */ | ||
523 | ra = luaD_precall(L, base-1); | ||
524 | if (ra == NULL) goto reinit; /* it is a Lua function */ | ||
525 | else if (ra > L->top) return NULL; /* yield??? */ | ||
526 | else goto ret; | ||
527 | } | ||
516 | case OP_RETURN: { | 528 | case OP_RETURN: { |
517 | CallInfo *ci; | ||
518 | int b; | 529 | int b; |
519 | if (L->openupval) luaF_close(L, base); | 530 | if (L->openupval) luaF_close(L, base); |
520 | b = GETARG_B(i); | 531 | b = GETARG_B(i); |
521 | if (b != 0) L->top = ra+b-1; | 532 | if (b != 0) L->top = ra+b-1; |
533 | lua_assert(L->ci->pc == &pc); | ||
534 | } | ||
535 | ret: { | ||
536 | CallInfo *ci; | ||
522 | ci = L->ci - 1; | 537 | ci = L->ci - 1; |
523 | lua_assert((ci+1)->pc == &pc); | ||
524 | if (ci->pc != &pc) /* previous function was running `here'? */ | 538 | if (ci->pc != &pc) /* previous function was running `here'? */ |
525 | return ra; /* no: return */ | 539 | return ra; /* no: return */ |
526 | else { /* yes: continue its execution */ | 540 | else { /* yes: continue its execution */ |
@@ -542,7 +556,7 @@ StkId luaV_execute (lua_State *L) { | |||
542 | int j = GETARG_sBc(i); | 556 | int j = GETARG_sBc(i); |
543 | const TObject *plimit = ra+1; | 557 | const TObject *plimit = ra+1; |
544 | const TObject *pstep = ra+2; | 558 | const TObject *pstep = ra+2; |
545 | pc += j; /* jump back before tests (for error messages) */ | 559 | dojump(pc, j); /* jump back before tests (for error messages) */ |
546 | if (ttype(ra) != LUA_TNUMBER) | 560 | if (ttype(ra) != LUA_TNUMBER) |
547 | luaD_error(L, "`for' initial value must be a number"); | 561 | luaD_error(L, "`for' initial value must be a number"); |
548 | if (!tonumber(plimit, ra+1)) | 562 | if (!tonumber(plimit, ra+1)) |
@@ -552,10 +566,12 @@ StkId luaV_execute (lua_State *L) { | |||
552 | step = nvalue(pstep); | 566 | step = nvalue(pstep); |
553 | index = nvalue(ra) + step; /* increment index */ | 567 | index = nvalue(ra) + step; /* increment index */ |
554 | limit = nvalue(plimit); | 568 | limit = nvalue(plimit); |
555 | if (step > 0 ? index <= limit : index >= limit) | 569 | if (step > 0 ? index <= limit : index >= limit) { |
556 | chgnvalue(ra, index); /* update index */ | 570 | chgnvalue(ra, index); /* update index */ |
571 | linehook = L->linehook; | ||
572 | } | ||
557 | else | 573 | else |
558 | pc -= j; /* undo jump */ | 574 | dojump(pc, -j); /* undo jump */ |
559 | break; | 575 | break; |
560 | } | 576 | } |
561 | case OP_TFORLOOP: { | 577 | case OP_TFORLOOP: { |