aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2004-06-02 16:07:55 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2004-06-02 16:07:55 -0300
commite8d4fe72366dd44e45ffd9fca09d92c3db4f8214 (patch)
treed9f28bbce22a50c9e1de2f239ee6584934afb510 /lvm.c
parentb8691f13a8e3e9bb7fbd91d1f099eb517a9d5b35 (diff)
downloadlua-e8d4fe72366dd44e45ffd9fca09d92c3db4f8214.tar.gz
lua-e8d4fe72366dd44e45ffd9fca09d92c3db4f8214.tar.bz2
lua-e8d4fe72366dd44e45ffd9fca09d92c3db4f8214.zip
new macro `lua_threadyield' + lock stuff in `luaconf.h' + details
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c80
1 files changed, 39 insertions, 41 deletions
diff --git a/lvm.c b/lvm.c
index 5363ebef..44d77783 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.6 2004/05/14 19:25:09 roberto Exp $ 2** $Id: lvm.c,v 2.7 2004/05/31 18:51:50 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*/
@@ -58,8 +58,8 @@ int luaV_tostring (lua_State *L, StkId obj) {
58static void traceexec (lua_State *L, const Instruction *pc) { 58static void traceexec (lua_State *L, const Instruction *pc) {
59 lu_byte mask = L->hookmask; 59 lu_byte mask = L->hookmask;
60 CallInfo *ci = L->ci; 60 CallInfo *ci = L->ci;
61 const Instruction *oldpc = ci->u.l.savedpc; 61 const Instruction *oldpc = ci->savedpc;
62 ci->u.l.savedpc = pc; 62 ci->savedpc = pc;
63 if (mask > LUA_MASKLINE) { /* instruction-hook set? */ 63 if (mask > LUA_MASKLINE) { /* instruction-hook set? */
64 if (L->hookcount == 0) { 64 if (L->hookcount == 0) {
65 resethookcount(L); 65 resethookcount(L);
@@ -122,18 +122,18 @@ StkId luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val,
122 /* else will try the tag method */ 122 /* else will try the tag method */
123 } 123 }
124 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) { 124 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) {
125 if (pc) L->ci->u.l.savedpc = pc; 125 L->ci->savedpc = pc;
126 luaG_typeerror(L, t, "index"); 126 luaG_typeerror(L, t, "index");
127 } 127 }
128 if (ttisfunction(tm)) { 128 if (ttisfunction(tm)) {
129 if (pc) L->ci->u.l.savedpc = pc; 129 L->ci->savedpc = pc;
130 prepTMcall(L, tm, t, key); 130 prepTMcall(L, tm, t, key);
131 callTMres(L, val); 131 callTMres(L, val);
132 return L->base; 132 return L->base;
133 } 133 }
134 t = tm; /* else repeat with `tm' */ 134 t = tm; /* else repeat with `tm' */
135 } 135 }
136 if (pc) L->ci->u.l.savedpc = pc; 136 L->ci->savedpc = pc;
137 luaG_runerror(L, "loop in gettable"); 137 luaG_runerror(L, "loop in gettable");
138 return NULL; /* to avoid warnings */ 138 return NULL; /* to avoid warnings */
139} 139}
@@ -156,11 +156,11 @@ StkId luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val,
156 /* else will try the tag method */ 156 /* else will try the tag method */
157 } 157 }
158 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) { 158 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) {
159 if (pc) L->ci->u.l.savedpc = pc; 159 L->ci->savedpc = pc;
160 luaG_typeerror(L, t, "index"); 160 luaG_typeerror(L, t, "index");
161 } 161 }
162 if (ttisfunction(tm)) { 162 if (ttisfunction(tm)) {
163 if (pc) L->ci->u.l.savedpc = pc; 163 L->ci->savedpc = pc;
164 prepTMcall(L, tm, t, key); 164 prepTMcall(L, tm, t, key);
165 setobj2s(L, L->top+3, val); /* 3th argument */ 165 setobj2s(L, L->top+3, val); /* 3th argument */
166 callTM(L); 166 callTM(L);
@@ -168,7 +168,7 @@ StkId luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val,
168 } 168 }
169 t = tm; /* else repeat with `tm' */ 169 t = tm; /* else repeat with `tm' */
170 } 170 }
171 if (pc) L->ci->u.l.savedpc = pc; 171 L->ci->savedpc = pc;
172 luaG_runerror(L, "loop in settable"); 172 luaG_runerror(L, "loop in settable");
173 return NULL; /* to avoid warnings */ 173 return NULL; /* to avoid warnings */
174} 174}
@@ -331,7 +331,7 @@ static StkId Arith (lua_State *L, StkId ra, const TValue *rb,
331 const TValue *rc, TMS op, const Instruction *pc) { 331 const TValue *rc, TMS op, const Instruction *pc) {
332 TValue tempb, tempc; 332 TValue tempb, tempc;
333 const TValue *b, *c; 333 const TValue *b, *c;
334 L->ci->u.l.savedpc = pc; 334 L->ci->savedpc = pc;
335 if ((b = luaV_tonumber(rb, &tempb)) != NULL && 335 if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
336 (c = luaV_tonumber(rc, &tempc)) != NULL) { 336 (c = luaV_tonumber(rc, &tempc)) != NULL) {
337 switch (op) { 337 switch (op) {
@@ -374,7 +374,7 @@ static StkId Arith (lua_State *L, StkId ra, const TValue *rb,
374#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) 374#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))
375 375
376 376
377#define dojump(pc, i) ((pc) += (i)) 377#define dojump(L,pc,i) {(pc) += (i); lua_threadyield(L);}
378 378
379 379
380StkId luaV_execute (lua_State *L, int nexeccalls) { 380StkId luaV_execute (lua_State *L, int nexeccalls) {
@@ -386,7 +386,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
386 if (L->hookmask & LUA_MASKCALL) 386 if (L->hookmask & LUA_MASKCALL)
387 luaD_callhook(L, LUA_HOOKCALL, -1); 387 luaD_callhook(L, LUA_HOOKCALL, -1);
388 retentry: /* entry point when returning to old functions */ 388 retentry: /* entry point when returning to old functions */
389 pc = L->ci->u.l.savedpc; 389 pc = L->ci->savedpc;
390 cl = &clvalue(L->ci->func)->l; 390 cl = &clvalue(L->ci->func)->l;
391 base = L->base; 391 base = L->base;
392 k = cl->p->k; 392 k = cl->p->k;
@@ -398,7 +398,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
398 (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { 398 (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
399 traceexec(L, pc); /***/ 399 traceexec(L, pc); /***/
400 if (L->isSuspended) { /* did hook yield? */ 400 if (L->isSuspended) { /* did hook yield? */
401 L->ci->u.l.savedpc = pc - 1; 401 L->ci->savedpc = pc - 1;
402 return NULL; 402 return NULL;
403 } 403 }
404 base = L->base; 404 base = L->base;
@@ -406,10 +406,8 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
406 /* warning!! several calls may realloc the stack and invalidate `ra' */ 406 /* warning!! several calls may realloc the stack and invalidate `ra' */
407 ra = RA(i); 407 ra = RA(i);
408 lua_assert(base == L->ci->base && base == L->base); 408 lua_assert(base == L->ci->base && base == L->base);
409 lua_assert(L->top <= L->stack + L->stacksize && L->top >= base); 409 lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
410 lua_assert(L->top == L->ci->top || 410 lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
411 GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL ||
412 GET_OPCODE(i) == OP_RETURN || GET_OPCODE(i) == OP_SETLISTO);
413 switch (GET_OPCODE(i)) { 411 switch (GET_OPCODE(i)) {
414 case OP_MOVE: { 412 case OP_MOVE: {
415 setobjs2s(L, ra, RB(i)); 413 setobjs2s(L, ra, RB(i));
@@ -465,7 +463,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
465 int b = GETARG_B(i); 463 int b = GETARG_B(i);
466 b = fb2int(b); 464 b = fb2int(b);
467 sethvalue(L, ra, luaH_new(L, b, GETARG_C(i))); 465 sethvalue(L, ra, luaH_new(L, b, GETARG_C(i)));
468 L->ci->u.l.savedpc = pc; 466 L->ci->savedpc = pc;
469 luaC_checkGC(L); /***/ 467 luaC_checkGC(L); /***/
470 base = L->base; 468 base = L->base;
471 break; 469 break;
@@ -528,7 +526,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
528 } 526 }
529 else { 527 else {
530 setnilvalue(&temp); 528 setnilvalue(&temp);
531 L->ci->u.l.savedpc = pc; 529 L->ci->savedpc = pc;
532 if (!call_binTM(L, RB(i), &temp, ra, TM_UNM)) /***/ 530 if (!call_binTM(L, RB(i), &temp, ra, TM_UNM)) /***/
533 luaG_aritherror(L, RB(i), &temp); 531 luaG_aritherror(L, RB(i), &temp);
534 base = L->base; 532 base = L->base;
@@ -543,7 +541,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
543 case OP_CONCAT: { 541 case OP_CONCAT: {
544 int b = GETARG_B(i); 542 int b = GETARG_B(i);
545 int c = GETARG_C(i); 543 int c = GETARG_C(i);
546 L->ci->u.l.savedpc = pc; 544 L->ci->savedpc = pc;
547 luaV_concat(L, c-b+1, c); /* may change `base' (and `ra') */ /***/ 545 luaV_concat(L, c-b+1, c); /* may change `base' (and `ra') */ /***/
548 luaC_checkGC(L); /***/ 546 luaC_checkGC(L); /***/
549 base = L->base; 547 base = L->base;
@@ -551,27 +549,27 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
551 break; 549 break;
552 } 550 }
553 case OP_JMP: { 551 case OP_JMP: {
554 dojump(pc, GETARG_sBx(i)); 552 dojump(L, pc, GETARG_sBx(i));
555 break; 553 break;
556 } 554 }
557 case OP_EQ: { 555 case OP_EQ: {
558 L->ci->u.l.savedpc = pc; 556 L->ci->savedpc = pc;
559 if (equalobj(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; /***/ 557 if (equalobj(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; /***/
560 else dojump(pc, GETARG_sBx(*pc) + 1); 558 else dojump(L, pc, GETARG_sBx(*pc) + 1);
561 base = L->base; 559 base = L->base;
562 break; 560 break;
563 } 561 }
564 case OP_LT: { 562 case OP_LT: {
565 L->ci->u.l.savedpc = pc; 563 L->ci->savedpc = pc;
566 if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; /***/ 564 if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; /***/
567 else dojump(pc, GETARG_sBx(*pc) + 1); 565 else dojump(L, pc, GETARG_sBx(*pc) + 1);
568 base = L->base; 566 base = L->base;
569 break; 567 break;
570 } 568 }
571 case OP_LE: { 569 case OP_LE: {
572 L->ci->u.l.savedpc = pc; 570 L->ci->savedpc = pc;
573 if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; /***/ 571 if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; /***/
574 else dojump(pc, GETARG_sBx(*pc) + 1); 572 else dojump(L, pc, GETARG_sBx(*pc) + 1);
575 base = L->base; 573 base = L->base;
576 break; 574 break;
577 } 575 }
@@ -580,7 +578,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
580 if (l_isfalse(rb) == GETARG_C(i)) pc++; 578 if (l_isfalse(rb) == GETARG_C(i)) pc++;
581 else { 579 else {
582 setobjs2s(L, ra, rb); 580 setobjs2s(L, ra, rb);
583 dojump(pc, GETARG_sBx(*pc) + 1); 581 dojump(L, pc, GETARG_sBx(*pc) + 1);
584 } 582 }
585 break; 583 break;
586 } 584 }
@@ -589,7 +587,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
589 int b = GETARG_B(i); 587 int b = GETARG_B(i);
590 int nresults = GETARG_C(i) - 1; 588 int nresults = GETARG_C(i) - 1;
591 if (b != 0) L->top = ra+b; /* else previous instruction set top */ 589 if (b != 0) L->top = ra+b; /* else previous instruction set top */
592 L->ci->u.l.savedpc = pc; 590 L->ci->savedpc = pc;
593 pcr = luaD_precall(L, ra, nresults); 591 pcr = luaD_precall(L, ra, nresults);
594 if (pcr == PCRLUA) { 592 if (pcr == PCRLUA) {
595 nexeccalls++; 593 nexeccalls++;
@@ -610,7 +608,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
610 int pcr; 608 int pcr;
611 int b = GETARG_B(i); 609 int b = GETARG_B(i);
612 if (b != 0) L->top = ra+b; /* else previous instruction set top */ 610 if (b != 0) L->top = ra+b; /* else previous instruction set top */
613 L->ci->u.l.savedpc = pc; 611 L->ci->savedpc = pc;
614 lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); 612 lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
615 pcr = luaD_precall(L, ra, LUA_MULTRET); 613 pcr = luaD_precall(L, ra, LUA_MULTRET);
616 if (pcr == PCRLUA) { 614 if (pcr == PCRLUA) {
@@ -625,8 +623,8 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
625 for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */ 623 for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */
626 setobjs2s(L, func+aux, pfunc+aux); 624 setobjs2s(L, func+aux, pfunc+aux);
627 ci->top = L->top = base+aux; /* correct top */ 625 ci->top = L->top = base+aux; /* correct top */
628 ci->u.l.savedpc = L->ci->u.l.savedpc; 626 ci->savedpc = L->ci->savedpc;
629 ci->u.l.tailcalls++; /* one more call lost */ 627 ci->tailcalls++; /* one more call lost */
630 L->ci--; /* remove new frame */ 628 L->ci--; /* remove new frame */
631 goto callentry; 629 goto callentry;
632 } 630 }
@@ -645,13 +643,13 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
645 int b = GETARG_B(i); 643 int b = GETARG_B(i);
646 if (b != 0) L->top = ra+b-1; 644 if (b != 0) L->top = ra+b-1;
647 if (L->openupval) luaF_close(L, base); 645 if (L->openupval) luaF_close(L, base);
648 L->ci->u.l.savedpc = pc; 646 L->ci->savedpc = pc;
649 if (--nexeccalls == 0) /* was previous function running `here'? */ 647 if (--nexeccalls == 0) /* was previous function running `here'? */
650 return ra; /* no: return */ 648 return ra; /* no: return */
651 else { /* yes: continue its execution */ 649 else { /* yes: continue its execution */
652 int nresults = (ci+1)->nresults; 650 int nresults = (ci+1)->nresults;
653 lua_assert(isLua(ci)); 651 lua_assert(isLua(ci));
654 lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL); 652 lua_assert(GET_OPCODE(*(ci->savedpc - 1)) == OP_CALL);
655 luaD_poscall(L, nresults, ra); 653 luaD_poscall(L, nresults, ra);
656 if (nresults >= 0) L->top = L->ci->top; 654 if (nresults >= 0) L->top = L->ci->top;
657 goto retentry; 655 goto retentry;
@@ -662,7 +660,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
662 lua_Number idx = nvalue(ra) + step; /* increment index */ 660 lua_Number idx = nvalue(ra) + step; /* increment index */
663 lua_Number limit = nvalue(ra+1); 661 lua_Number limit = nvalue(ra+1);
664 if (step > 0 ? idx <= limit : idx >= limit) { 662 if (step > 0 ? idx <= limit : idx >= limit) {
665 dojump(pc, GETARG_sBx(i)); /* jump back */ 663 dojump(L, pc, GETARG_sBx(i)); /* jump back */
666 setnvalue(ra, idx); /* update internal index... */ 664 setnvalue(ra, idx); /* update internal index... */
667 setnvalue(ra+3, idx); /* ...and external index */ 665 setnvalue(ra+3, idx); /* ...and external index */
668 } 666 }
@@ -672,7 +670,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
672 const TValue *init = ra; 670 const TValue *init = ra;
673 const TValue *plimit = ra+1; 671 const TValue *plimit = ra+1;
674 const TValue *pstep = ra+2; 672 const TValue *pstep = ra+2;
675 L->ci->u.l.savedpc = pc; 673 L->ci->savedpc = pc;
676 if (!tonumber(init, ra)) 674 if (!tonumber(init, ra))
677 luaG_runerror(L, "`for' initial value must be a number"); 675 luaG_runerror(L, "`for' initial value must be a number");
678 else if (!tonumber(plimit, ra+1)) 676 else if (!tonumber(plimit, ra+1))
@@ -680,7 +678,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
680 else if (!tonumber(pstep, ra+2)) 678 else if (!tonumber(pstep, ra+2))
681 luaG_runerror(L, "`for' step must be a number"); 679 luaG_runerror(L, "`for' step must be a number");
682 setnvalue(ra, nvalue(ra) - nvalue(pstep)); 680 setnvalue(ra, nvalue(ra) - nvalue(pstep));
683 dojump(pc, GETARG_sBx(i)); 681 dojump(L, pc, GETARG_sBx(i));
684 break; 682 break;
685 } 683 }
686 case OP_TFORLOOP: { 684 case OP_TFORLOOP: {
@@ -689,7 +687,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
689 setobjs2s(L, cb+1, ra+1); 687 setobjs2s(L, cb+1, ra+1);
690 setobjs2s(L, cb, ra); 688 setobjs2s(L, cb, ra);
691 L->top = cb+3; /* func. + 2 args (state and index) */ 689 L->top = cb+3; /* func. + 2 args (state and index) */
692 L->ci->u.l.savedpc = pc; 690 L->ci->savedpc = pc;
693 luaD_call(L, cb, GETARG_C(i)); /***/ 691 luaD_call(L, cb, GETARG_C(i)); /***/
694 L->top = L->ci->top; 692 L->top = L->ci->top;
695 base = L->base; 693 base = L->base;
@@ -698,7 +696,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
698 pc++; /* skip jump (break loop) */ 696 pc++; /* skip jump (break loop) */
699 else { 697 else {
700 setobjs2s(L, cb-1, cb); /* save control variable */ 698 setobjs2s(L, cb-1, cb); /* save control variable */
701 dojump(pc, GETARG_sBx(*pc) + 1); /* jump back */ 699 dojump(L, pc, GETARG_sBx(*pc) + 1); /* jump back */
702 } 700 }
703 break; 701 break;
704 } 702 }
@@ -707,7 +705,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
707 setobjs2s(L, ra+1, ra); 705 setobjs2s(L, ra+1, ra);
708 setobj2s(L, ra, luaH_getstr(hvalue(gt(L)), luaS_new(L, "next"))); 706 setobj2s(L, ra, luaH_getstr(hvalue(gt(L)), luaS_new(L, "next")));
709 } 707 }
710 dojump(pc, GETARG_sBx(i)); 708 dojump(L, pc, GETARG_sBx(i));
711 break; 709 break;
712 } 710 }
713 case OP_SETLIST: 711 case OP_SETLIST:
@@ -755,7 +753,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
755 } 753 }
756 } 754 }
757 setclvalue(L, ra, ncl); 755 setclvalue(L, ra, ncl);
758 L->ci->u.l.savedpc = pc; 756 L->ci->savedpc = pc;
759 luaC_checkGC(L); /***/ 757 luaC_checkGC(L); /***/
760 base = L->base; 758 base = L->base;
761 break; 759 break;