diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-01-09 20:02:47 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-01-09 20:02:47 -0200 |
commit | f083812c020186d0d919833100c1a0b6eda8c2c0 (patch) | |
tree | 29c2e1d25f05af62277aab03e8e070aaa1a0d664 /lvm.c | |
parent | 3533382a1ed7ba21f0233057c886be2dd8a71d92 (diff) | |
download | lua-f083812c020186d0d919833100c1a0b6eda8c2c0.tar.gz lua-f083812c020186d0d919833100c1a0b6eda8c2c0.tar.bz2 lua-f083812c020186d0d919833100c1a0b6eda8c2c0.zip |
first implementation of coroutines
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 86 |
1 files changed, 29 insertions, 57 deletions
@@ -254,29 +254,6 @@ void luaV_strconc (lua_State *L, int total, StkId top) { | |||
254 | } | 254 | } |
255 | 255 | ||
256 | 256 | ||
257 | static 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 | |||
280 | static void powOp (lua_State *L, StkId ra, StkId rb, StkId rc) { | 257 | static 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 | */ |
340 | StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) { | 307 | StkId 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 | } |