aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-01-09 20:02:47 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-01-09 20:02:47 -0200
commitf083812c020186d0d919833100c1a0b6eda8c2c0 (patch)
tree29c2e1d25f05af62277aab03e8e070aaa1a0d664 /lvm.c
parent3533382a1ed7ba21f0233057c886be2dd8a71d92 (diff)
downloadlua-f083812c020186d0d919833100c1a0b6eda8c2c0.tar.gz
lua-f083812c020186d0d919833100c1a0b6eda8c2c0.tar.bz2
lua-f083812c020186d0d919833100c1a0b6eda8c2c0.zip
first implementation of coroutines
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c86
1 files changed, 29 insertions, 57 deletions
diff --git a/lvm.c b/lvm.c
index a073d39d..bec488f1 100644
--- a/lvm.c
+++ b/lvm.c
@@ -254,29 +254,6 @@ void luaV_strconc (lua_State *L, int total, StkId top) {
254} 254}
255 255
256 256
257static void adjust_varargs (lua_State *L, StkId base, int nfixargs) {
258 int i;
259 Table *htab;
260 TObject n, nname;
261 StkId firstvar = base + nfixargs; /* position of first vararg */
262 if (L->top < firstvar) {
263 luaD_checkstack(L, firstvar - L->top);
264 while (L->top < firstvar)
265 setnilvalue(L->top++);
266 }
267 htab = luaH_new(L, 0, 0);
268 for (i=0; firstvar+i<L->top; i++)
269 luaH_setnum(L, htab, i+1, firstvar+i);
270 /* store counter in field `n' */
271 setnvalue(&n, i);
272 setsvalue(&nname, luaS_newliteral(L, "n"));
273 luaH_set(L, htab, &nname, &n);
274 L->top = firstvar; /* remove elements from the stack */
275 sethvalue(L->top, htab);
276 incr_top;
277}
278
279
280static void powOp (lua_State *L, StkId ra, StkId rb, StkId rc) { 257static void powOp (lua_State *L, StkId ra, StkId rb, StkId rc) {
281 const TObject *b = rb; 258 const TObject *b = rb;
282 const TObject *c = rc; 259 const TObject *c = rc;
@@ -307,8 +284,8 @@ static void powOp (lua_State *L, StkId ra, StkId rb, StkId rc) {
307#define RC(i) (base+GETARG_C(i)) 284#define RC(i) (base+GETARG_C(i))
308#define RKC(i) ((GETARG_C(i) < MAXSTACK) ? \ 285#define RKC(i) ((GETARG_C(i) < MAXSTACK) ? \
309 base+GETARG_C(i) : \ 286 base+GETARG_C(i) : \
310 cl->p->k+GETARG_C(i)-MAXSTACK) 287 k+GETARG_C(i)-MAXSTACK)
311#define KBc(i) (cl->p->k+GETARG_Bc(i)) 288#define KBc(i) (k+GETARG_Bc(i))
312 289
313#define Arith(op, optm) { \ 290#define Arith(op, optm) { \
314 const TObject *b = RB(i); const TObject *c = RKC(i); \ 291 const TObject *b = RB(i); const TObject *c = RKC(i); \
@@ -321,38 +298,26 @@ static void powOp (lua_State *L, StkId ra, StkId rb, StkId rc) {
321} 298}
322 299
323 300
324#define luaV_poscall(L,c,f,ci) \
325 if (c != NO_REG) { \
326 luaD_poscall(L, c, f); \
327 L->top = ci->top; \
328 } \
329 else { \
330 luaD_poscall(L, LUA_MULTRET, f); \
331 }
332
333
334#define dojump(pc, i) ((pc) += GETARG_sBc(i)) 301#define dojump(pc, i) ((pc) += GETARG_sBc(i))
335 302
336/* 303/*
337** Executes the given Lua function. Parameters are between [base,top). 304** Executes current Lua function. Parameters are between [base,top).
338** Returns n such that the results are between [n,top). 305** Returns n such that the results are between [n,top).
339*/ 306*/
340StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) { 307StkId luaV_execute (lua_State *L) {
308 StkId base;
309 LClosure *cl;
310 TObject *k;
341 const Instruction *pc; 311 const Instruction *pc;
342 lua_Hook linehook; 312 lua_Hook linehook;
343 reinit: 313 reinit:
344 lua_assert(L->ci->savedpc == NULL); 314 base = L->ci->base;
315 cl = &clvalue(base - 1)->l;
316 k = cl->p->k;
317 linehook = L->ci->linehook;
345 L->ci->pc = &pc; 318 L->ci->pc = &pc;
346 L->ci->top = base + cl->p->maxstacksize; 319 pc = L->ci->savedpc;
347 if (cl->p->is_vararg) /* varargs? */ 320 L->ci->savedpc = NULL;
348 adjust_varargs(L, base, cl->p->numparams);
349 if (base > L->stack_last - cl->p->maxstacksize)
350 luaD_stackerror(L);
351 while (L->top < L->ci->top)
352 setnilvalue(L->top++);
353 L->top = L->ci->top;
354 linehook = L->ci->linehook = L->linehook;
355 pc = cl->p->code;
356 /* main loop of interpreter */ 321 /* main loop of interpreter */
357 for (;;) { 322 for (;;) {
358 const Instruction i = *pc++; 323 const Instruction i = *pc++;
@@ -535,18 +500,21 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
535 case OP_CALL: { 500 case OP_CALL: {
536 StkId firstResult; 501 StkId firstResult;
537 int b = GETARG_B(i); 502 int b = GETARG_B(i);
538 if (b != NO_REG) L->top = ra+b+1; 503 int nresults;
539 /* else previous instruction set top */ 504 if (b != 0) L->top = ra+b; /* else previous instruction set top */
505 nresults = GETARG_C(i) - 1;
540 firstResult = luaD_precall(L, ra); 506 firstResult = luaD_precall(L, ra);
541 if (firstResult) { 507 if (firstResult) {
508 if (firstResult == base) { /* yield?? */
509 (L->ci-1)->savedpc = pc;
510 return NULL;
511 }
542 /* it was a C function (`precall' called it); adjust results */ 512 /* it was a C function (`precall' called it); adjust results */
543 luaV_poscall(L, GETARG_C(i), firstResult, L->ci); 513 luaD_poscall(L, nresults, firstResult);
514 if (nresults >= 0) L->top = L->ci->top;
544 } 515 }
545 else { /* it is a Lua function: `call' it */ 516 else { /* it is a Lua function: `call' it */
546 CallInfo *ci = L->ci; 517 (L->ci-1)->savedpc = pc;
547 (ci-1)->savedpc = pc;
548 base = ci->base;
549 cl = &clvalue(base - 1)->l;
550 goto reinit; 518 goto reinit;
551 } 519 }
552 break; 520 break;
@@ -556,19 +524,23 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
556 int b; 524 int b;
557 if (L->openupval) luaF_close(L, base); 525 if (L->openupval) luaF_close(L, base);
558 b = GETARG_B(i); 526 b = GETARG_B(i);
559 if (b != NO_REG) L->top = ra+b; 527 if (b != 0) L->top = ra+b-1;
560 ci = L->ci - 1; 528 ci = L->ci - 1;
561 if (ci->savedpc == NULL) 529 if (ci->savedpc == NULL)
562 return ra; 530 return ra;
563 else { /* previous function is Lua: continue its execution */ 531 else { /* previous function is Lua: continue its execution */
532 int nresults;
564 lua_assert(ttype(ci->base-1) == LUA_TFUNCTION); 533 lua_assert(ttype(ci->base-1) == LUA_TFUNCTION);
565 base = ci->base; /* restore previous values */ 534 base = ci->base; /* restore previous values */
566 linehook = ci->linehook; 535 linehook = ci->linehook;
567 cl = &clvalue(base - 1)->l; 536 cl = &clvalue(base - 1)->l;
537 k = cl->p->k;
568 pc = ci->savedpc; 538 pc = ci->savedpc;
569 ci->savedpc = NULL; 539 ci->savedpc = NULL;
570 lua_assert(GET_OPCODE(*(pc-1)) == OP_CALL); 540 lua_assert(GET_OPCODE(*(pc-1)) == OP_CALL);
571 luaV_poscall(L, GETARG_C(*(pc-1)), ra, ci); 541 nresults = GETARG_C(*(pc-1)) - 1;
542 luaD_poscall(L, nresults, ra);
543 if (nresults >= 0) L->top = L->ci->top;
572 } 544 }
573 break; 545 break;
574 } 546 }