1 /* $NetBSD: ldo.c,v 1.1.1.2 2012/03/15 00:08:09 alnsn Exp $ */
4 ** $Id: ldo.c,v 1.1.1.2 2012/03/15 00:08:09 alnsn Exp $
5 ** Stack and Call structure of Lua
6 ** See Copyright Notice in lua.h
39 ** {======================================================
40 ** Error-recovery functions
41 ** =======================================================
45 /* chain list of long jump buffers */
47 struct lua_longjmp
*previous
;
49 volatile int status
; /* error code */
53 void luaD_seterrorobj (lua_State
*L
, int errcode
, StkId oldtop
) {
56 setsvalue2s(L
, oldtop
, luaS_newliteral(L
, MEMERRMSG
));
60 setsvalue2s(L
, oldtop
, luaS_newliteral(L
, "error in error handling"));
65 setobjs2s(L
, oldtop
, L
->top
- 1); /* error message on current top */
73 static void restore_stack_limit (lua_State
*L
) {
74 lua_assert(L
->stack_last
- L
->stack
== L
->stacksize
- EXTRA_STACK
- 1);
75 if (L
->size_ci
> LUAI_MAXCALLS
) { /* there was an overflow? */
76 int inuse
= cast_int(L
->ci
- L
->base_ci
);
77 if (inuse
+ 1 < LUAI_MAXCALLS
) /* can `undo' overflow? */
78 luaD_reallocCI(L
, LUAI_MAXCALLS
);
83 static void resetstack (lua_State
*L
, int status
) {
85 L
->base
= L
->ci
->base
;
86 luaF_close(L
, L
->base
); /* close eventual pending closures */
87 luaD_seterrorobj(L
, status
, L
->base
);
88 L
->nCcalls
= L
->baseCcalls
;
90 restore_stack_limit(L
);
96 void luaD_throw (lua_State
*L
, int errcode
) {
98 L
->errorJmp
->status
= errcode
;
99 LUAI_THROW(L
, L
->errorJmp
);
102 L
->status
= cast_byte(errcode
);
104 resetstack(L
, errcode
);
113 int luaD_rawrunprotected (lua_State
*L
, Pfunc f
, void *ud
) {
114 struct lua_longjmp lj
;
116 lj
.previous
= L
->errorJmp
; /* chain new error handler */
121 L
->errorJmp
= lj
.previous
; /* restore old error handler */
125 /* }====================================================== */
128 static void correctstack (lua_State
*L
, TValue
*oldstack
) {
131 L
->top
= (L
->top
- oldstack
) + L
->stack
;
132 for (up
= L
->openupval
; up
!= NULL
; up
= up
->gch
.next
)
133 gco2uv(up
)->v
= (gco2uv(up
)->v
- oldstack
) + L
->stack
;
134 for (ci
= L
->base_ci
; ci
<= L
->ci
; ci
++) {
135 ci
->top
= (ci
->top
- oldstack
) + L
->stack
;
136 ci
->base
= (ci
->base
- oldstack
) + L
->stack
;
137 ci
->func
= (ci
->func
- oldstack
) + L
->stack
;
139 L
->base
= (L
->base
- oldstack
) + L
->stack
;
143 void luaD_reallocstack (lua_State
*L
, int newsize
) {
144 TValue
*oldstack
= L
->stack
;
145 int realsize
= newsize
+ 1 + EXTRA_STACK
;
146 lua_assert(L
->stack_last
- L
->stack
== L
->stacksize
- EXTRA_STACK
- 1);
147 luaM_reallocvector(L
, L
->stack
, L
->stacksize
, realsize
, TValue
);
148 L
->stacksize
= realsize
;
149 L
->stack_last
= L
->stack
+newsize
;
150 correctstack(L
, oldstack
);
154 void luaD_reallocCI (lua_State
*L
, int newsize
) {
155 CallInfo
*oldci
= L
->base_ci
;
156 luaM_reallocvector(L
, L
->base_ci
, L
->size_ci
, newsize
, CallInfo
);
157 L
->size_ci
= newsize
;
158 L
->ci
= (L
->ci
- oldci
) + L
->base_ci
;
159 L
->end_ci
= L
->base_ci
+ L
->size_ci
- 1;
163 void luaD_growstack (lua_State
*L
, int n
) {
164 if (n
<= L
->stacksize
) /* double size is enough? */
165 luaD_reallocstack(L
, 2*L
->stacksize
);
167 luaD_reallocstack(L
, L
->stacksize
+ n
);
171 static CallInfo
*growCI (lua_State
*L
) {
172 if (L
->size_ci
> LUAI_MAXCALLS
) /* overflow while handling overflow? */
173 luaD_throw(L
, LUA_ERRERR
);
175 luaD_reallocCI(L
, 2*L
->size_ci
);
176 if (L
->size_ci
> LUAI_MAXCALLS
)
177 luaG_runerror(L
, "stack overflow");
183 void luaD_callhook (lua_State
*L
, int event
, int line
) {
184 lua_Hook hook
= L
->hook
;
185 if (hook
&& L
->allowhook
) {
186 ptrdiff_t top
= savestack(L
, L
->top
);
187 ptrdiff_t ci_top
= savestack(L
, L
->ci
->top
);
190 ar
.currentline
= line
;
191 if (event
== LUA_HOOKTAILRET
)
192 ar
.i_ci
= 0; /* tail call; no debug information about it */
194 ar
.i_ci
= cast_int(L
->ci
- L
->base_ci
);
195 luaD_checkstack(L
, LUA_MINSTACK
); /* ensure minimum stack size */
196 L
->ci
->top
= L
->top
+ LUA_MINSTACK
;
197 lua_assert(L
->ci
->top
<= L
->stack_last
);
198 L
->allowhook
= 0; /* cannot call hooks inside a hook */
202 lua_assert(!L
->allowhook
);
204 L
->ci
->top
= restorestack(L
, ci_top
);
205 L
->top
= restorestack(L
, top
);
210 static StkId
adjust_varargs (lua_State
*L
, Proto
*p
, int actual
) {
212 int nfixargs
= p
->numparams
;
215 for (; actual
< nfixargs
; ++actual
)
216 setnilvalue(L
->top
++);
217 #if defined(LUA_COMPAT_VARARG)
218 if (p
->is_vararg
& VARARG_NEEDSARG
) { /* compat. with old-style vararg? */
219 int nvar
= actual
- nfixargs
; /* number of extra arguments */
220 lua_assert(p
->is_vararg
& VARARG_HASARG
);
222 luaD_checkstack(L
, p
->maxstacksize
);
223 htab
= luaH_new(L
, nvar
, 1); /* create `arg' table */
224 for (i
=0; i
<nvar
; i
++) /* put extra arguments into `arg' table */
225 setobj2n(L
, luaH_setnum(L
, htab
, i
+1), L
->top
- nvar
+ i
);
226 /* store counter in field `n' */
227 setnvalue(luaH_setstr(L
, htab
, luaS_newliteral(L
, "n")), cast_num(nvar
));
230 /* move fixed parameters to final position */
231 fixed
= L
->top
- actual
; /* first fixed argument */
232 base
= L
->top
; /* final position of first argument */
233 for (i
=0; i
<nfixargs
; i
++) {
234 setobjs2s(L
, L
->top
++, fixed
+i
);
235 setnilvalue(fixed
+i
);
237 /* add `arg' parameter */
239 sethvalue(L
, L
->top
++, htab
);
240 lua_assert(iswhite(obj2gco(htab
)));
246 static StkId
tryfuncTM (lua_State
*L
, StkId func
) {
247 const TValue
*tm
= luaT_gettmbyobj(L
, func
, TM_CALL
);
249 ptrdiff_t funcr
= savestack(L
, func
);
250 if (!ttisfunction(tm
))
251 luaG_typeerror(L
, func
, "call");
252 /* Open a hole inside the stack at `func' */
253 for (p
= L
->top
; p
> func
; p
--) setobjs2s(L
, p
, p
-1);
255 func
= restorestack(L
, funcr
); /* previous call may change stack */
256 setobj2s(L
, func
, tm
); /* tag method is the new function to be called */
263 ((L->ci == L->end_ci) ? growCI(L) : \
264 (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci))
267 int luaD_precall (lua_State
*L
, StkId func
, int nresults
) {
270 if (!ttisfunction(func
)) /* `func' is not a function? */
271 func
= tryfuncTM(L
, func
); /* check the `function' tag method */
272 funcr
= savestack(L
, func
);
273 cl
= &clvalue(func
)->l
;
274 L
->ci
->savedpc
= L
->savedpc
;
275 if (!cl
->isC
) { /* Lua function? prepare its call */
279 luaD_checkstack(L
, p
->maxstacksize
);
280 func
= restorestack(L
, funcr
);
281 if (!p
->is_vararg
) { /* no varargs? */
283 if (L
->top
> base
+ p
->numparams
)
284 L
->top
= base
+ p
->numparams
;
286 else { /* vararg function */
287 int nargs
= cast_int(L
->top
- func
) - 1;
288 base
= adjust_varargs(L
, p
, nargs
);
289 func
= restorestack(L
, funcr
); /* previous call may change the stack */
291 ci
= inc_ci(L
); /* now `enter' new function */
293 L
->base
= ci
->base
= base
;
294 ci
->top
= L
->base
+ p
->maxstacksize
;
295 lua_assert(ci
->top
<= L
->stack_last
);
296 L
->savedpc
= p
->code
; /* starting point */
298 ci
->nresults
= nresults
;
299 for (st
= L
->top
; st
< ci
->top
; st
++)
302 if (L
->hookmask
& LUA_MASKCALL
) {
303 L
->savedpc
++; /* hooks assume 'pc' is already incremented */
304 luaD_callhook(L
, LUA_HOOKCALL
, -1);
305 L
->savedpc
--; /* correct 'pc' */
309 else { /* if is a C function, call it */
312 luaD_checkstack(L
, LUA_MINSTACK
); /* ensure minimum stack size */
313 ci
= inc_ci(L
); /* now `enter' new function */
314 ci
->func
= restorestack(L
, funcr
);
315 L
->base
= ci
->base
= ci
->func
+ 1;
316 ci
->top
= L
->top
+ LUA_MINSTACK
;
317 lua_assert(ci
->top
<= L
->stack_last
);
318 ci
->nresults
= nresults
;
319 if (L
->hookmask
& LUA_MASKCALL
)
320 luaD_callhook(L
, LUA_HOOKCALL
, -1);
322 n
= (*curr_func(L
)->c
.f
)(L
); /* do the actual call */
324 if (n
< 0) /* yielding? */
327 luaD_poscall(L
, L
->top
- n
);
334 static StkId
callrethooks (lua_State
*L
, StkId firstResult
) {
335 ptrdiff_t fr
= savestack(L
, firstResult
); /* next call may change stack */
336 luaD_callhook(L
, LUA_HOOKRET
, -1);
337 if (f_isLua(L
->ci
)) { /* Lua function? */
338 while ((L
->hookmask
& LUA_MASKRET
) && L
->ci
->tailcalls
--) /* tail calls */
339 luaD_callhook(L
, LUA_HOOKTAILRET
, -1);
341 return restorestack(L
, fr
);
345 int luaD_poscall (lua_State
*L
, StkId firstResult
) {
349 if (L
->hookmask
& LUA_MASKRET
)
350 firstResult
= callrethooks(L
, firstResult
);
352 res
= ci
->func
; /* res == final position of 1st result */
353 wanted
= ci
->nresults
;
354 L
->base
= (ci
- 1)->base
; /* restore base */
355 L
->savedpc
= (ci
- 1)->savedpc
; /* restore savedpc */
356 /* move results to correct place */
357 for (i
= wanted
; i
!= 0 && firstResult
< L
->top
; i
--)
358 setobjs2s(L
, res
++, firstResult
++);
362 return (wanted
- LUA_MULTRET
); /* 0 iff wanted == LUA_MULTRET */
367 ** Call a function (C or Lua). The function to be called is at *func.
368 ** The arguments are on the stack, right after the function.
369 ** When returns, all the results are on the stack, starting at the original
370 ** function position.
372 void luaD_call (lua_State
*L
, StkId func
, int nResults
) {
373 if (++L
->nCcalls
>= LUAI_MAXCCALLS
) {
374 if (L
->nCcalls
== LUAI_MAXCCALLS
)
375 luaG_runerror(L
, "C stack overflow");
376 else if (L
->nCcalls
>= (LUAI_MAXCCALLS
+ (LUAI_MAXCCALLS
>>3)))
377 luaD_throw(L
, LUA_ERRERR
); /* error while handing stack error */
379 if (luaD_precall(L
, func
, nResults
) == PCRLUA
) /* is a Lua function? */
380 luaV_execute(L
, 1); /* call it */
386 static void resume (lua_State
*L
, void *ud
) {
387 StkId firstArg
= cast(StkId
, ud
);
388 CallInfo
*ci
= L
->ci
;
389 if (L
->status
== 0) { /* start coroutine? */
390 lua_assert(ci
== L
->base_ci
&& firstArg
> L
->base
);
391 if (luaD_precall(L
, firstArg
- 1, LUA_MULTRET
) != PCRLUA
)
394 else { /* resuming from previous yield */
395 lua_assert(L
->status
== LUA_YIELD
);
397 if (!f_isLua(ci
)) { /* `common' yield? */
398 /* finish interrupted execution of `OP_CALL' */
399 lua_assert(GET_OPCODE(*((ci
-1)->savedpc
- 1)) == OP_CALL
||
400 GET_OPCODE(*((ci
-1)->savedpc
- 1)) == OP_TAILCALL
);
401 if (luaD_poscall(L
, firstArg
)) /* complete it... */
402 L
->top
= L
->ci
->top
; /* and correct top if not multiple results */
404 else /* yielded inside a hook: just continue its execution */
405 L
->base
= L
->ci
->base
;
407 luaV_execute(L
, cast_int(L
->ci
- L
->base_ci
));
411 static int resume_error (lua_State
*L
, const char *msg
) {
412 L
->top
= L
->ci
->base
;
413 setsvalue2s(L
, L
->top
, luaS_new(L
, msg
));
420 LUA_API
int lua_resume (lua_State
*L
, int nargs
) {
423 if (L
->status
!= LUA_YIELD
&& (L
->status
!= 0 || L
->ci
!= L
->base_ci
))
424 return resume_error(L
, "cannot resume non-suspended coroutine");
425 if (L
->nCcalls
>= LUAI_MAXCCALLS
)
426 return resume_error(L
, "C stack overflow");
427 luai_userstateresume(L
, nargs
);
428 lua_assert(L
->errfunc
== 0);
429 L
->baseCcalls
= ++L
->nCcalls
;
430 status
= luaD_rawrunprotected(L
, resume
, L
->top
- nargs
);
431 if (status
!= 0) { /* error? */
432 L
->status
= cast_byte(status
); /* mark thread as `dead' */
433 luaD_seterrorobj(L
, status
, L
->top
);
437 lua_assert(L
->nCcalls
== L
->baseCcalls
);
446 LUA_API
int lua_yield (lua_State
*L
, int nresults
) {
447 luai_userstateyield(L
, nresults
);
449 if (L
->nCcalls
> L
->baseCcalls
)
450 luaG_runerror(L
, "attempt to yield across metamethod/C-call boundary");
451 L
->base
= L
->top
- nresults
; /* protect stack slots below */
452 L
->status
= LUA_YIELD
;
458 int luaD_pcall (lua_State
*L
, Pfunc func
, void *u
,
459 ptrdiff_t old_top
, ptrdiff_t ef
) {
461 unsigned short oldnCcalls
= L
->nCcalls
;
462 ptrdiff_t old_ci
= saveci(L
, L
->ci
);
463 lu_byte old_allowhooks
= L
->allowhook
;
464 ptrdiff_t old_errfunc
= L
->errfunc
;
466 status
= luaD_rawrunprotected(L
, func
, u
);
467 if (status
!= 0) { /* an error occurred? */
468 StkId oldtop
= restorestack(L
, old_top
);
469 luaF_close(L
, oldtop
); /* close eventual pending closures */
470 luaD_seterrorobj(L
, status
, oldtop
);
471 L
->nCcalls
= oldnCcalls
;
472 L
->ci
= restoreci(L
, old_ci
);
473 L
->base
= L
->ci
->base
;
474 L
->savedpc
= L
->ci
->savedpc
;
475 L
->allowhook
= old_allowhooks
;
476 restore_stack_limit(L
);
478 L
->errfunc
= old_errfunc
;
485 ** Execute a protected parser.
487 struct SParser
{ /* data to `f_parser' */
489 Mbuffer buff
; /* buffer to be used by the scanner */
493 static void f_parser (lua_State
*L
, void *ud
) {
497 struct SParser
*p
= cast(struct SParser
*, ud
);
498 int c
= luaZ_lookahead(p
->z
);
500 tf
= ((c
== LUA_SIGNATURE
[0]) ? luaU_undump
: luaY_parser
)(L
, p
->z
,
502 cl
= luaF_newLclosure(L
, tf
->nups
, hvalue(gt(L
)));
504 for (i
= 0; i
< tf
->nups
; i
++) /* initialize eventual upvalues */
505 cl
->l
.upvals
[i
] = luaF_newupval(L
);
506 setclvalue(L
, L
->top
, cl
);
511 int luaD_protectedparser (lua_State
*L
, ZIO
*z
, const char *name
) {
514 p
.z
= z
; p
.name
= name
;
515 luaZ_initbuffer(L
, &p
.buff
);
516 status
= luaD_pcall(L
, f_parser
, &p
, savestack(L
, L
->top
), L
->errfunc
);
517 luaZ_freebuffer(L
, &p
.buff
);