aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-01-25 20:14:54 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-01-25 20:14:54 -0200
commit50e29525936be4891f9db090f293432913b5f7c0 (patch)
tree8e487b87f82761e15cd096ac345354f57f38fedc /lvm.c
parentb217ae644e3a83def93be2fe742e2cd0970e1a5f (diff)
downloadlua-50e29525936be4891f9db090f293432913b5f7c0.tar.gz
lua-50e29525936be4891f9db090f293432913b5f7c0.tar.bz2
lua-50e29525936be4891f9db090f293432913b5f7c0.zip
first version of dynamic stack
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c83
1 files changed, 42 insertions, 41 deletions
diff --git a/lvm.c b/lvm.c
index 0a980f7d..8ecf0fb8 100644
--- a/lvm.c
+++ b/lvm.c
@@ -29,10 +29,9 @@
29 29
30static void luaV_checkGC (lua_State *L, StkId top) { 30static void luaV_checkGC (lua_State *L, StkId top) {
31 if (G(L)->nblocks >= G(L)->GCthreshold) { 31 if (G(L)->nblocks >= G(L)->GCthreshold) {
32 StkId temp = L->top; 32 L->top = top; /* limit for active registers */
33 L->top = top;
34 luaC_collectgarbage(L); 33 luaC_collectgarbage(L);
35 L->top = temp; /* restore old top position */ 34 L->top = L->ci->top; /* restore old top position */
36 } 35 }
37} 36}
38 37
@@ -83,32 +82,37 @@ static void traceexec (lua_State *L, lua_Hook linehook) {
83 if (newline != ci->line || pc <= ci->lastpc) { 82 if (newline != ci->line || pc <= ci->lastpc) {
84 ci->line = newline; 83 ci->line = newline;
85 luaD_lineHook(L, newline, linehook); 84 luaD_lineHook(L, newline, linehook);
85 ci = L->ci; /* previous call may realocate `ci' */
86 } 86 }
87 ci->lastpc = pc; 87 ci->lastpc = pc;
88} 88}
89 89
90 90
91static void callTMres (lua_State *L, const TObject *f,
92 const TObject *p1, const TObject *p2, TObject *result ) {
93 StkId stack = L->stack;
94 setobj(L->top, f); /* push function */
95 setobj(L->top+1, p1); /* 1st argument */
96 setobj(L->top+2, p2); /* 2nd argument */
97 luaD_checkstack(L, 3); /* cannot check before (could invalidate p1, p2) */
98 L->top += 3;
99 luaD_call(L, L->top - 3, 1);
100 if (stack != L->stack) /* stack changed? */
101 result = (result - stack) + L->stack; /* correct pointer */
102 setobj(result, --L->top); /* get result */
103}
104
91 105
92/* maximum stack used by a call to a tag method (func + args) */
93#define MAXSTACK_TM 4
94 106
95static void callTM (lua_State *L, const TObject *f, 107static void callTM (lua_State *L, const TObject *f,
96 const TObject *p1, const TObject *p2, const TObject *p3, TObject *result ) { 108 const TObject *p1, const TObject *p2, const TObject *p3) {
97 StkId base = L->top; 109 setobj(L->top, f); /* push function */
98 luaD_checkstack(L, MAXSTACK_TM); 110 setobj(L->top+1, p1); /* 1st argument */
99 setobj(base, f); /* push function */ 111 setobj(L->top+2, p2); /* 2nd argument */
100 setobj(base+1, p1); /* 1st argument */ 112 setobj(L->top+3, p3); /* 3th argument */
101 setobj(base+2, p2); /* 2nd argument */ 113 luaD_checkstack(L, 4); /* cannot check before (could invalidate p1...p3) */
102 L->top += 3; 114 L->top += 4;
103 if (p3) { 115 luaD_call(L, L->top - 4, 0);
104 setobj(base+3, p3); /* 3th argument */
105 L->top++;
106 }
107 luaD_call(L, base, 1);
108 if (result) { /* need a result? */
109 setobj(result, base); /* get it */
110 }
111 L->top = base; /* restore top */
112} 116}
113 117
114 118
@@ -139,7 +143,7 @@ void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) {
139 } 143 }
140 } 144 }
141 if (ttype(tm) == LUA_TFUNCTION) 145 if (ttype(tm) == LUA_TFUNCTION)
142 callTM(L, tm, t, key, NULL, res); 146 callTMres(L, tm, t, key, res);
143 else { 147 else {
144 t = (StkId)tm; /* ?? */ 148 t = (StkId)tm; /* ?? */
145 goto init; /* return luaV_gettable(L, tm, key, res); */ 149 goto init; /* return luaV_gettable(L, tm, key, res); */
@@ -167,7 +171,7 @@ void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) {
167 } 171 }
168 } 172 }
169 if (ttype(tm) == LUA_TFUNCTION) 173 if (ttype(tm) == LUA_TFUNCTION)
170 callTM(L, tm, t, key, val, NULL); 174 callTM(L, tm, t, key, val);
171 else { 175 else {
172 t = (StkId)tm; /* ?? */ 176 t = (StkId)tm; /* ?? */
173 goto init; /* luaV_settable(L, tm, key, val); */ 177 goto init; /* luaV_settable(L, tm, key, val); */
@@ -181,7 +185,7 @@ static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2,
181 if (ttype(tm) == LUA_TNIL) 185 if (ttype(tm) == LUA_TNIL)
182 tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ 186 tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
183 if (ttype(tm) != LUA_TFUNCTION) return 0; 187 if (ttype(tm) != LUA_TFUNCTION) return 0;
184 callTM(L, tm, p1, p2, NULL, res); 188 callTMres(L, tm, p1, p2, res);
185 return 1; 189 return 1;
186} 190}
187 191
@@ -229,7 +233,6 @@ int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r) {
229 233
230 234
231void luaV_strconc (lua_State *L, int total, int last) { 235void luaV_strconc (lua_State *L, int total, int last) {
232 luaV_checkGC(L, L->ci->base + last + 1);
233 do { 236 do {
234 StkId top = L->ci->base + last + 1; 237 StkId top = L->ci->base + last + 1;
235 int n = 2; /* number of elements handled in this pass (at least 2) */ 238 int n = 2; /* number of elements handled in this pass (at least 2) */
@@ -273,7 +276,7 @@ static void powOp (lua_State *L, StkId ra, StkId rb, StkId rc) {
273 luaV_gettable(L, gt(L), &o, &f); 276 luaV_gettable(L, gt(L), &o, &f);
274 if (ttype(&f) != LUA_TFUNCTION) 277 if (ttype(&f) != LUA_TFUNCTION)
275 luaD_error(L, "`pow' (for `^' operator) is not a function"); 278 luaD_error(L, "`pow' (for `^' operator) is not a function");
276 callTM(L, &f, b, c, NULL, ra); 279 callTMres(L, &f, b, c, ra);
277 } 280 }
278 else 281 else
279 call_arith(L, rb, rc, ra, TM_POW); 282 call_arith(L, rb, rc, ra, TM_POW);
@@ -324,17 +327,18 @@ StkId luaV_execute (lua_State *L) {
324 k = cl->p->k; 327 k = cl->p->k;
325 linehook = L->linehook; 328 linehook = L->linehook;
326 L->ci->pc = &pc; 329 L->ci->pc = &pc;
330 L->ci->pb = &base;
327 pc = L->ci->savedpc; 331 pc = L->ci->savedpc;
328 L->ci->savedpc = NULL;
329 /* main loop of interpreter */ 332 /* main loop of interpreter */
330 for (;;) { 333 for (;;) {
331 const Instruction i = *pc++; 334 const Instruction i = *pc++;
332 const StkId ra = RA(i); 335 StkId ra;
333 if (linehook) 336 if (linehook)
334 traceexec(L, linehook); 337 traceexec(L, linehook);
338 ra = RA(i);
339 lua_assert(L->top <= L->stack + L->stacksize && L->top >= L->ci->base);
335 lua_assert(L->top == L->ci->top || GET_OPCODE(i) == OP_CALL || 340 lua_assert(L->top == L->ci->top || GET_OPCODE(i) == OP_CALL ||
336 GET_OPCODE(i) == OP_RETURN || GET_OPCODE(i) == OP_SETLISTO); 341 GET_OPCODE(i) == OP_RETURN || GET_OPCODE(i) == OP_SETLISTO);
337 lua_assert(L->ci->savedpc == NULL);
338 switch (GET_OPCODE(i)) { 342 switch (GET_OPCODE(i)) {
339 case OP_MOVE: { 343 case OP_MOVE: {
340 setobj(ra, RB(i)); 344 setobj(ra, RB(i));
@@ -344,10 +348,6 @@ StkId luaV_execute (lua_State *L) {
344 setobj(ra, KBc(i)); 348 setobj(ra, KBc(i));
345 break; 349 break;
346 } 350 }
347 case OP_LOADINT: {
348 setnvalue(ra, (lua_Number)GETARG_sBc(i));
349 break;
350 }
351 case OP_LOADBOOL: { 351 case OP_LOADBOOL: {
352 setbvalue(ra, GETARG_B(i)); 352 setbvalue(ra, GETARG_B(i));
353 if (GETARG_C(i)) pc++; /* skip next instruction (if C) */ 353 if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
@@ -441,8 +441,9 @@ StkId luaV_execute (lua_State *L) {
441 case OP_CONCAT: { 441 case OP_CONCAT: {
442 int b = GETARG_B(i); 442 int b = GETARG_B(i);
443 int c = GETARG_C(i); 443 int c = GETARG_C(i);
444 luaV_strconc(L, c-b+1, c); 444 luaV_strconc(L, c-b+1, c); /* this call may change `base' (and `ra') */
445 setobj(ra, base+b); 445 setobj(base+GETARG_A(i), base+b);
446 luaV_checkGC(L, base+c+1);
446 break; 447 break;
447 } 448 }
448 case OP_JMP: { 449 case OP_JMP: {
@@ -493,7 +494,7 @@ StkId luaV_execute (lua_State *L) {
493 nresults = GETARG_C(i) - 1; 494 nresults = GETARG_C(i) - 1;
494 firstResult = luaD_precall(L, ra); 495 firstResult = luaD_precall(L, ra);
495 if (firstResult) { 496 if (firstResult) {
496 if (firstResult == base) { /* yield?? */ 497 if (firstResult > L->top) { /* yield? */
497 (L->ci-1)->savedpc = pc; 498 (L->ci-1)->savedpc = pc;
498 return NULL; 499 return NULL;
499 } 500 }
@@ -514,16 +515,16 @@ StkId luaV_execute (lua_State *L) {
514 b = GETARG_B(i); 515 b = GETARG_B(i);
515 if (b != 0) L->top = ra+b-1; 516 if (b != 0) L->top = ra+b-1;
516 ci = L->ci - 1; 517 ci = L->ci - 1;
517 if (ci->savedpc == NULL) 518 lua_assert((ci+1)->pc == &pc);
518 return ra; 519 if (ci->pc != &pc) /* previous function was running `here'? */
519 else { /* previous function is Lua: continue its execution */ 520 return ra; /* no: return */
521 else { /* yes: continue its execution */
520 int nresults; 522 int nresults;
521 lua_assert(ttype(ci->base-1) == LUA_TFUNCTION); 523 lua_assert(ttype(ci->base-1) == LUA_TFUNCTION);
522 base = ci->base; /* restore previous values */ 524 base = ci->base; /* restore previous values */
523 cl = &clvalue(base - 1)->l; 525 cl = &clvalue(base - 1)->l;
524 k = cl->p->k; 526 k = cl->p->k;
525 pc = ci->savedpc; 527 pc = ci->savedpc;
526 ci->savedpc = NULL;
527 lua_assert(GET_OPCODE(*(pc-1)) == OP_CALL); 528 lua_assert(GET_OPCODE(*(pc-1)) == OP_CALL);
528 nresults = GETARG_C(*(pc-1)) - 1; 529 nresults = GETARG_C(*(pc-1)) - 1;
529 luaD_poscall(L, nresults, ra); 530 luaD_poscall(L, nresults, ra);
@@ -607,7 +608,6 @@ StkId luaV_execute (lua_State *L) {
607 Proto *p; 608 Proto *p;
608 Closure *ncl; 609 Closure *ncl;
609 int nup, j; 610 int nup, j;
610 luaV_checkGC(L, L->top);
611 p = cl->p->p[GETARG_Bc(i)]; 611 p = cl->p->p[GETARG_Bc(i)];
612 nup = p->nupvalues; 612 nup = p->nupvalues;
613 ncl = luaF_newLclosure(L, nup); 613 ncl = luaF_newLclosure(L, nup);
@@ -621,6 +621,7 @@ StkId luaV_execute (lua_State *L) {
621 } 621 }
622 } 622 }
623 setclvalue(ra, ncl); 623 setclvalue(ra, ncl);
624 luaV_checkGC(L, L->top);
624 break; 625 break;
625 } 626 }
626 } 627 }