summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldo.c119
-rw-r--r--lvm.c87
2 files changed, 128 insertions, 78 deletions
diff --git a/ldo.c b/ldo.c
index e46f84a3..ae70d268 100644
--- a/ldo.c
+++ b/ldo.c
@@ -43,8 +43,15 @@ void luaD_init (lua_State *L, int stacksize) {
43 stacksize += EXTRA_STACK; 43 stacksize += EXTRA_STACK;
44 L->stack = luaM_newvector(L, stacksize, TObject); 44 L->stack = luaM_newvector(L, stacksize, TObject);
45 L->stacksize = stacksize; 45 L->stacksize = stacksize;
46 L->top = L->basefunc.base = L->stack + RESERVED_STACK_PREFIX; 46 L->top = L->stack + RESERVED_STACK_PREFIX;
47 restore_stack_limit(L); 47 restore_stack_limit(L);
48 luaM_reallocvector(L, L->base_ci, 0, 20, CallInfo);
49 L->ci = L->base_ci;
50 L->ci->base = L->top;
51 L->ci->savedpc = NULL;
52 L->ci->pc = NULL;
53 L->size_ci = 20;
54 L->end_ci = L->base_ci + L->size_ci;
48} 55}
49 56
50 57
@@ -98,35 +105,81 @@ void luaD_lineHook (lua_State *L, int line, lua_Hook linehook) {
98 if (L->allowhooks) { 105 if (L->allowhooks) {
99 lua_Debug ar; 106 lua_Debug ar;
100 ar.event = "line"; 107 ar.event = "line";
101 ar._ci = L->ci; 108 ar._ci = L->ci - L->base_ci;
102 ar.currentline = line; 109 ar.currentline = line;
103 dohook(L, &ar, linehook); 110 dohook(L, &ar, linehook);
104 } 111 }
105} 112}
106 113
107 114
108static void luaD_callHook (lua_State *L, lua_Hook callhook, 115void luaD_callHook (lua_State *L, lua_Hook callhook, const char *event) {
109 const char *event) {
110 if (L->allowhooks) { 116 if (L->allowhooks) {
111 lua_Debug ar; 117 lua_Debug ar;
112 ar.event = event; 118 ar.event = event;
113 ar._ci = L->ci; 119 ar._ci = L->ci - L->base_ci;
114 L->ci->pc = NULL; /* function is not active */
115 dohook(L, &ar, callhook); 120 dohook(L, &ar, callhook);
116 } 121 }
117} 122}
118 123
119 124
120static StkId callCclosure (lua_State *L, const struct CClosure *cl) { 125#define newci(L) ((++L->ci == L->end_ci) ? growci(L) : L->ci)
126
127static CallInfo *growci (lua_State *L) {
128 lua_assert(L->ci == L->end_ci);
129 luaM_reallocvector(L, L->base_ci, L->size_ci, 2*L->size_ci, CallInfo);
130 L->ci = L->base_ci + L->size_ci;
131 L->size_ci *= 2;
132 L->end_ci = L->base_ci + L->size_ci;
133 return L->ci;
134}
135
136
137StkId luaD_precall (lua_State *L, StkId func) {
138 CallInfo *ci;
121 int n; 139 int n;
140 if (ttype(func) != LUA_TFUNCTION) {
141 /* `func' is not a function; check the `function' tag method */
142 const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL);
143 if (ttype(tm) != LUA_TFUNCTION)
144 luaG_typeerror(L, func, "call");
145 luaD_openstack(L, func);
146 setobj(func, tm); /* tag method is the new function to be called */
147 }
148 lua_assert(ttype(func) == LUA_TFUNCTION);
149 ci = newci(L);
150 ci->base = func+1;
151 ci->savedpc = NULL;
152 ci->pc = NULL;
153 if (L->callhook)
154 luaD_callHook(L, L->callhook, "call");
155 if (!clvalue(func)->c.isC) return NULL;
156 /* if is a C function, call it */
122 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 157 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
123 lua_unlock(L); 158 lua_unlock(L);
124#if LUA_COMPATUPVALUES 159#if LUA_COMPATUPVALUES
125 lua_pushupvalues(L); 160 lua_pushupvalues(L);
126#endif 161#endif
127 n = (*cl->f)(L); /* do the actual call */ 162 n = (*clvalue(func)->c.f)(L); /* do the actual call */
128 lua_lock(L); 163 lua_lock(L);
129 return L->top - n; /* return index of first result */ 164 return L->top - n;
165}
166
167
168void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
169 StkId res;
170 if (L->callhook)
171 luaD_callHook(L, L->callhook, "return");
172 res = L->ci->base - 1; /* `func' = final position of 1st result */
173 L->ci--;
174 /* move results to correct place */
175 while (wanted != 0 && firstResult < L->top) {
176 setobj(res++, firstResult++);
177 wanted--;
178 }
179 while (wanted-- > 0)
180 setnilvalue(res++);
181 L->top = res;
182 luaC_checkGC(L);
130} 183}
131 184
132 185
@@ -136,36 +189,11 @@ static StkId callCclosure (lua_State *L, const struct CClosure *cl) {
136** When returns, all the results are on the stack, starting at the original 189** When returns, all the results are on the stack, starting at the original
137** function position. 190** function position.
138*/ 191*/
139void luaD_call (lua_State *L, StkId func) { 192void luaD_call (lua_State *L, StkId func, int nResults) {
140 lua_Hook callhook; 193 StkId firstResult = luaD_precall(L, func);
141 StkId firstResult; 194 if (firstResult == NULL) /* is a Lua function? */
142 CallInfo ci; 195 firstResult = luaV_execute(L, &clvalue(func)->l, func+1); /* call it */
143 if (ttype(func) != LUA_TFUNCTION) { 196 luaD_poscall(L, nResults, firstResult);
144 /* `func' is not a function; check the `function' tag method */
145 const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL);
146 if (ttype(tm) != LUA_TFUNCTION)
147 luaG_typeerror(L, func, "call");
148 luaD_openstack(L, func);
149 setobj(func, tm); /* tag method is the new function to be called */
150 }
151 lua_assert(ttype(func) == LUA_TFUNCTION);
152 ci.prev = L->ci; /* chain new callinfo */
153 L->ci = &ci;
154 ci.base = func+1;
155 callhook = L->callhook;
156 if (callhook)
157 luaD_callHook(L, callhook, "call");
158 firstResult = (clvalue(func)->c.isC ?
159 callCclosure(L, &clvalue(func)->c) :
160 luaV_execute(L, &clvalue(func)->l, func+1));
161 if (callhook) /* same hook that was active at entry */
162 luaD_callHook(L, callhook, "return");
163 L->ci = ci.prev; /* unchain callinfo */
164 /* move results to `func' (to erase parameters and function) */
165 while (firstResult < L->top)
166 setobj(func++, firstResult++);
167 L->top = func;
168 luaC_checkGC(L);
169} 197}
170 198
171 199
@@ -179,9 +207,7 @@ struct CallS { /* data to `f_call' */
179 207
180static void f_call (lua_State *L, void *ud) { 208static void f_call (lua_State *L, void *ud) {
181 struct CallS *c = cast(struct CallS *, ud); 209 struct CallS *c = cast(struct CallS *, ud);
182 luaD_call(L, c->func); 210 luaD_call(L, c->func, c->nresults);
183 if (c->nresults != LUA_MULTRET)
184 luaD_adjusttop(L, c->func + c->nresults);
185} 211}
186 212
187 213
@@ -291,7 +317,7 @@ struct lua_longjmp {
291 jmp_buf b; 317 jmp_buf b;
292 struct lua_longjmp *previous; 318 struct lua_longjmp *previous;
293 volatile int status; /* error code */ 319 volatile int status; /* error code */
294 CallInfo *ci; /* call info of active function that set protection */ 320 int ci; /* index of call info of active function that set protection */
295 StkId top; /* top stack when protection was set */ 321 StkId top; /* top stack when protection was set */
296 int allowhooks; /* `allowhook' state when protection was set */ 322 int allowhooks; /* `allowhook' state when protection was set */
297}; 323};
@@ -307,8 +333,7 @@ static void message (lua_State *L, const char *s) {
307 incr_top; 333 incr_top;
308 setsvalue(top+1, luaS_new(L, s)); 334 setsvalue(top+1, luaS_new(L, s));
309 incr_top; 335 incr_top;
310 luaD_call(L, top); 336 luaD_call(L, top, 0);
311 L->top = top;
312 } 337 }
313} 338}
314 339
@@ -337,7 +362,7 @@ void luaD_breakrun (lua_State *L, int errcode) {
337 362
338int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) { 363int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) {
339 struct lua_longjmp lj; 364 struct lua_longjmp lj;
340 lj.ci = L->ci; 365 lj.ci = L->ci - L->base_ci;
341 lj.top = L->top; 366 lj.top = L->top;
342 lj.allowhooks = L->allowhooks; 367 lj.allowhooks = L->allowhooks;
343 lj.status = 0; 368 lj.status = 0;
@@ -346,7 +371,7 @@ int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) {
346 if (setjmp(lj.b) == 0) 371 if (setjmp(lj.b) == 0)
347 (*f)(L, ud); 372 (*f)(L, ud);
348 else { /* an error occurred: restore the state */ 373 else { /* an error occurred: restore the state */
349 L->ci = lj.ci; 374 L->ci = L->base_ci + lj.ci;
350 L->top = lj.top; 375 L->top = lj.top;
351 L->allowhooks = lj.allowhooks; 376 L->allowhooks = lj.allowhooks;
352 restore_stack_limit(L); 377 restore_stack_limit(L);
diff --git a/lvm.c b/lvm.c
index 85746e03..435229a0 100644
--- a/lvm.c
+++ b/lvm.c
@@ -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*/
341StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) { 346StkId 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;