diff options
-rw-r--r-- | ldo.c | 119 | ||||
-rw-r--r-- | lvm.c | 87 |
2 files changed, 128 insertions, 78 deletions
@@ -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 | ||
108 | static void luaD_callHook (lua_State *L, lua_Hook callhook, | 115 | void 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 | ||
120 | static StkId callCclosure (lua_State *L, const struct CClosure *cl) { | 125 | #define newci(L) ((++L->ci == L->end_ci) ? growci(L) : L->ci) |
126 | |||
127 | static 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 | |||
137 | StkId 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 | |||
168 | void 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 | */ |
139 | void luaD_call (lua_State *L, StkId func) { | 192 | void 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 | ||
180 | static void f_call (lua_State *L, void *ud) { | 208 | static 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 | ||
338 | int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) { | 363 | int 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); |
@@ -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 | */ |
341 | StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) { | 346 | StkId 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; |