diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-12-20 13:13:38 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-12-20 13:13:38 -0200 |
commit | 18afb90349fc1b698d179e29fdc014589c2e1145 (patch) | |
tree | 0ebee0d47aa91ce4bdf580baa2e5639c361c9a9a /lvm.c | |
parent | 22dd271cbba22c0765eb45296a957ecacf68755e (diff) | |
download | lua-18afb90349fc1b698d179e29fdc014589c2e1145.tar.gz lua-18afb90349fc1b698d179e29fdc014589c2e1145.tar.bz2 lua-18afb90349fc1b698d179e29fdc014589c2e1145.zip |
first version of stackless Lua
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 87 |
1 files changed, 56 insertions, 31 deletions
@@ -97,14 +97,9 @@ static void callTM (lua_State *L, const TObject *f, | |||
97 | setobj(base+3, p3); /* 3th argument */ | 97 | setobj(base+3, p3); /* 3th argument */ |
98 | L->top++; | 98 | L->top++; |
99 | } | 99 | } |
100 | luaD_call(L, base); | 100 | luaD_call(L, base, (result ? 1 : 0)); |
101 | if (result) { /* need a result? */ | 101 | if (result) { /* need a result? */ |
102 | if (L->top == base) { /* are there valid results? */ | 102 | setobj(result, base); /* get it */ |
103 | setnilvalue(result); /* function had no results */ | ||
104 | } | ||
105 | else { | ||
106 | setobj(result, base); /* get first result */ | ||
107 | } | ||
108 | } | 103 | } |
109 | L->top = base; /* restore top */ | 104 | L->top = base; /* restore top */ |
110 | } | 105 | } |
@@ -140,7 +135,7 @@ void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) { | |||
140 | if (ttype(tm) == LUA_TFUNCTION) | 135 | if (ttype(tm) == LUA_TFUNCTION) |
141 | callTM(L, tm, t, key, NULL, res); | 136 | callTM(L, tm, t, key, NULL, res); |
142 | else { | 137 | else { |
143 | t = tm; | 138 | t = (StkId)tm; /* ?? */ |
144 | goto init; /* return luaV_gettable(L, tm, key, res); */ | 139 | goto init; /* return luaV_gettable(L, tm, key, res); */ |
145 | } | 140 | } |
146 | } | 141 | } |
@@ -169,7 +164,7 @@ void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) { | |||
169 | if (ttype(tm) == LUA_TFUNCTION) | 164 | if (ttype(tm) == LUA_TFUNCTION) |
170 | callTM(L, tm, t, key, val, NULL); | 165 | callTM(L, tm, t, key, val, NULL); |
171 | else { | 166 | else { |
172 | t = tm; | 167 | t = (StkId)tm; /* ?? */ |
173 | goto init; /* luaV_settable(L, tm, key, val); */ | 168 | goto init; /* luaV_settable(L, tm, key, val); */ |
174 | } | 169 | } |
175 | } | 170 | } |
@@ -311,15 +306,15 @@ static void powOp (lua_State *L, StkId ra, StkId rb, StkId rc) { | |||
311 | ** some macros for common tasks in `luaV_execute' | 306 | ** some macros for common tasks in `luaV_execute' |
312 | */ | 307 | */ |
313 | 308 | ||
314 | #define runtime_check(L, c) { if (!(c)) return L->top; } | 309 | #define runtime_check(L, c) { if (!(c)) return 0; } |
315 | 310 | ||
316 | #define RA(i) (base+GETARG_A(i)) | 311 | #define RA(i) (base+GETARG_A(i)) |
317 | #define RB(i) (base+GETARG_B(i)) | 312 | #define RB(i) (base+GETARG_B(i)) |
318 | #define RC(i) (base+GETARG_C(i)) | 313 | #define RC(i) (base+GETARG_C(i)) |
319 | #define RKC(i) ((GETARG_C(i) < MAXSTACK) ? \ | 314 | #define RKC(i) ((GETARG_C(i) < MAXSTACK) ? \ |
320 | base+GETARG_C(i) : \ | 315 | base+GETARG_C(i) : \ |
321 | tf->k+GETARG_C(i)-MAXSTACK) | 316 | cl->p->k+GETARG_C(i)-MAXSTACK) |
322 | #define KBc(i) (tf->k+GETARG_Bc(i)) | 317 | #define KBc(i) (cl->p->k+GETARG_Bc(i)) |
323 | 318 | ||
324 | #define Arith(op, optm) { \ | 319 | #define Arith(op, optm) { \ |
325 | const TObject *b = RB(i); const TObject *c = RKC(i); \ | 320 | const TObject *b = RB(i); const TObject *c = RKC(i); \ |
@@ -332,6 +327,16 @@ static void powOp (lua_State *L, StkId ra, StkId rb, StkId rc) { | |||
332 | } | 327 | } |
333 | 328 | ||
334 | 329 | ||
330 | #define luaV_poscall(L,c,f) \ | ||
331 | if (c != NO_REG) { \ | ||
332 | luaD_poscall(L, c, f); \ | ||
333 | L->top = base + cl->p->maxstacksize; \ | ||
334 | } \ | ||
335 | else { \ | ||
336 | luaD_poscall(L, LUA_MULTRET, f); \ | ||
337 | } | ||
338 | |||
339 | |||
335 | #define dojump(pc, i) ((pc) += GETARG_sBc(i)) | 340 | #define dojump(pc, i) ((pc) += GETARG_sBc(i)) |
336 | 341 | ||
337 | /* | 342 | /* |
@@ -339,17 +344,18 @@ static void powOp (lua_State *L, StkId ra, StkId rb, StkId rc) { | |||
339 | ** Returns n such that the results are between [n,top). | 344 | ** Returns n such that the results are between [n,top). |
340 | */ | 345 | */ |
341 | StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) { | 346 | StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) { |
342 | const Proto *const tf = cl->p; | ||
343 | const Instruction *pc; | 347 | const Instruction *pc; |
344 | lua_Hook linehook; | 348 | lua_Hook linehook; |
345 | if (tf->is_vararg) /* varargs? */ | 349 | reinit: |
346 | adjust_varargs(L, base, tf->numparams); | 350 | lua_assert(L->ci->savedpc == NULL); |
347 | if (base > L->stack_last - tf->maxstacksize) | 351 | if (cl->p->is_vararg) /* varargs? */ |
352 | adjust_varargs(L, base, cl->p->numparams); | ||
353 | if (base > L->stack_last - cl->p->maxstacksize) | ||
348 | luaD_stackerror(L); | 354 | luaD_stackerror(L); |
349 | luaD_adjusttop(L, base + tf->maxstacksize); | 355 | luaD_adjusttop(L, base + cl->p->maxstacksize); |
350 | pc = tf->code; | ||
351 | L->ci->pc = &pc; | 356 | L->ci->pc = &pc; |
352 | linehook = L->linehook; | 357 | linehook = L->ci->linehook = L->linehook; |
358 | pc = cl->p->code; | ||
353 | /* main loop of interpreter */ | 359 | /* main loop of interpreter */ |
354 | for (;;) { | 360 | for (;;) { |
355 | const Instruction i = *pc++; | 361 | const Instruction i = *pc++; |
@@ -528,25 +534,44 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) { | |||
528 | break; | 534 | break; |
529 | } | 535 | } |
530 | case OP_CALL: { | 536 | case OP_CALL: { |
531 | int c; | 537 | StkId firstResult; |
532 | int b = GETARG_B(i); | 538 | int b = GETARG_B(i); |
533 | if (b != NO_REG) | 539 | if (b != NO_REG) L->top = ra+b+1; |
534 | L->top = ra+b+1; | 540 | /* else previous instruction set top */ |
535 | luaD_call(L, ra); | 541 | firstResult = luaD_precall(L, ra); |
536 | c = GETARG_C(i); | 542 | if (firstResult) { |
537 | if (c != NO_REG) { | 543 | /* it was a C function (`precall' called it); adjust results */ |
538 | while (L->top < ra+c) setnilvalue(L->top++); | 544 | luaV_poscall(L, GETARG_C(i), firstResult); |
539 | L->top = base + tf->maxstacksize; | 545 | } |
546 | else { /* it is a Lua function: `call' it */ | ||
547 | CallInfo *ci = L->ci; | ||
548 | (ci-1)->savedpc = pc; | ||
549 | base = ci->base; | ||
550 | cl = &clvalue(base - 1)->l; | ||
551 | goto reinit; | ||
540 | } | 552 | } |
541 | break; | 553 | break; |
542 | } | 554 | } |
543 | case OP_RETURN: { | 555 | case OP_RETURN: { |
556 | CallInfo *ci; | ||
544 | int b; | 557 | int b; |
545 | luaF_close(L, base); | 558 | luaF_close(L, base); |
546 | b = GETARG_B(i); | 559 | b = GETARG_B(i); |
547 | if (b != NO_REG) | 560 | if (b != NO_REG) L->top = ra+b; |
548 | L->top = ra+b; | 561 | ci = L->ci - 1; |
549 | return ra; | 562 | if (ci->savedpc == NULL) |
563 | return ra; | ||
564 | else { /* previous function is Lua: continue its execution */ | ||
565 | lua_assert(ttype(ci->base-1) == LUA_TFUNCTION); | ||
566 | base = ci->base; /* restore previous values */ | ||
567 | linehook = ci->linehook; | ||
568 | cl = &clvalue(base - 1)->l; | ||
569 | pc = ci->savedpc; | ||
570 | ci->savedpc = NULL; | ||
571 | lua_assert(GET_OPCODE(*(pc-1)) == OP_CALL); | ||
572 | luaV_poscall(L, GETARG_C(*(pc-1)), ra); | ||
573 | } | ||
574 | break; | ||
550 | } | 575 | } |
551 | case OP_FORPREP: { | 576 | case OP_FORPREP: { |
552 | if (luaV_tonumber(ra, ra) == NULL) | 577 | if (luaV_tonumber(ra, ra) == NULL) |
@@ -623,7 +648,7 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) { | |||
623 | Closure *ncl; | 648 | Closure *ncl; |
624 | int nup, j; | 649 | int nup, j; |
625 | luaV_checkGC(L, L->top); | 650 | luaV_checkGC(L, L->top); |
626 | p = tf->p[GETARG_Bc(i)]; | 651 | p = cl->p->p[GETARG_Bc(i)]; |
627 | nup = p->nupvalues; | 652 | nup = p->nupvalues; |
628 | ncl = luaF_newLclosure(L, nup); | 653 | ncl = luaF_newLclosure(L, nup); |
629 | ncl->l.p = p; | 654 | ncl->l.p = p; |