Browse Source

configurable stack size + some corrections in error recovery in

`protectedrun'
v5-2
Roberto Ierusalimschy 25 years ago
parent
commit
f356eb010b
  1. 59
      ldo.c

59
ldo.c

@ -1,5 +1,5 @@
/*
** $Id: ldo.c,v 1.55 1999/12/02 16:24:45 roberto Exp roberto $
** $Id: ldo.c,v 1.56 1999/12/02 16:41:29 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@ -28,23 +28,19 @@
#include "lzio.h"
#ifndef DEFAULT_STACK_SIZE
#define DEFAULT_STACK_SIZE 1024
#endif
#define EXTRA_STACK 32 /* space to handle stack overflow errors */
/*
** typical numer of recursive calls that fit in the stack
** (only for error messages)
** typical numer of stack slots used by a (big) function
** (this constant is used only for choosing error messages)
*/
#define REC_DEEP (DEFAULT_STACK_SIZE/20)
#define SLOTS_PER_F 20
void luaD_init (lua_State *L) {
L->stack = luaM_newvector(L, DEFAULT_STACK_SIZE+EXTRA_STACK, TObject);
L->stack_last = L->stack+(DEFAULT_STACK_SIZE-1);
void luaD_init (lua_State *L, int stacksize) {
L->stack = luaM_newvector(L, stacksize+EXTRA_STACK, TObject);
L->stack_last = L->stack+(stacksize-1);
L->stacksize = stacksize;
L->Cstack.base = L->Cstack.lua2C = L->top = L->stack;
L->Cstack.num = 0;
}
@ -52,15 +48,15 @@ void luaD_init (lua_State *L) {
void luaD_checkstack (lua_State *L, int n) {
if (L->stack_last-L->top <= n) { /* stack overflow? */
if (L->stack_last-L->stack > (DEFAULT_STACK_SIZE-1)) {
if (L->stack_last-L->stack > (L->stacksize-1)) {
/* overflow while handling overflow: do what?? */
L->top -= EXTRA_STACK;
lua_error(L, "BAD STACK OVERFLOW! DATA CORRUPTED!!");
}
else {
L->stack_last += EXTRA_STACK; /* to be used by error message */
if (lua_stackedfunction(L, REC_DEEP) == LUA_NOOBJECT) {
/* less than REC_DEEP funcs on stack: doesn't look like a rec. loop */
if (lua_stackedfunction(L, L->stacksize/SLOTS_PER_F) == LUA_NOOBJECT) {
/* too few funcs on stack: doesn't look like a rec. loop */
lua_error(L, "Lua2C - C2Lua overflow");
}
else
@ -71,8 +67,8 @@ void luaD_checkstack (lua_State *L, int n) {
static void restore_stack_limit (lua_State *L) {
if (L->top-L->stack < DEFAULT_STACK_SIZE-1)
L->stack_last = L->stack+(DEFAULT_STACK_SIZE-1);
if (L->top-L->stack < L->stacksize-1)
L->stack_last = L->stack+(L->stacksize-1);
}
@ -145,7 +141,7 @@ static StkId callC (lua_State *L, lua_CFunction f, StkId base) {
if (L->callhook)
luaD_callHook(L, base, NULL, 0);
(*f)(L); /* do the actual call */
if (L->callhook) /* test again: `func' may have changed callhook */
if (L->callhook) /* test again: `func' may change callhook */
luaD_callHook(L, base, NULL, 1);
firstResult = L->Cstack.base;
L->Cstack = oldCLS;
@ -201,7 +197,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
luaV_execute(L, c, tfvalue(proto), func+1);
break;
}
default: { /* func is not a function */
default: { /* `func' is not a function */
/* Check the tag method for invalid functions */
const TObject *im = luaT_getimbyObj(L, func, IM_FUNCTION);
if (ttype(im) == LUA_T_NIL)
@ -251,13 +247,12 @@ void lua_error (lua_State *L, const char *s) {
** parameters are on top of it. Leave nResults on the stack.
*/
int luaD_protectedrun (lua_State *L) {
volatile struct C_Lua_Stack oldCLS = L->Cstack;
struct lua_longjmp myErrorJmp;
volatile StkId base = L->Cstack.base;
volatile int status;
struct lua_longjmp *volatile oldErr = L->errorJmp;
L->errorJmp = &myErrorJmp;
if (setjmp(myErrorJmp.b) == 0) {
StkId base = L->Cstack.base;
luaD_call(L, base, MULT_RET);
L->Cstack.lua2C = base; /* position of the new results */
L->Cstack.num = L->top - base;
@ -265,8 +260,8 @@ int luaD_protectedrun (lua_State *L) {
status = 0;
}
else { /* an error occurred: restore the stack */
L->Cstack = oldCLS;
L->top = L->Cstack.base;
L->Cstack.num = 0; /* no results */
L->top = L->Cstack.base = L->Cstack.lua2C = base;
restore_stack_limit(L);
status = 1;
}
@ -279,29 +274,29 @@ int luaD_protectedrun (lua_State *L) {
** returns 0 = chunk loaded; 1 = error; 2 = no more chunks to load
*/
static int protectedparser (lua_State *L, ZIO *z, int bin) {
volatile struct C_Lua_Stack oldCLS = L->Cstack;
struct lua_longjmp myErrorJmp;
volatile StkId base = L->Cstack.base;
volatile int status;
TProtoFunc *volatile tf;
struct lua_longjmp *volatile oldErr = L->errorJmp;
L->errorJmp = &myErrorJmp;
L->top = base; /* erase C2Lua */
if (setjmp(myErrorJmp.b) == 0) {
tf = bin ? luaU_undump1(L, z) : luaY_parser(L, z);
status = 0;
}
else { /* an error occurred: restore L->Cstack and L->top */
L->Cstack = oldCLS;
L->top = L->Cstack.base;
else { /* an error occurred: restore Cstack and top */
L->Cstack.num = 0; /* no results */
L->top = L->Cstack.base = L->Cstack.lua2C = base;
tf = NULL;
status = 1;
}
L->errorJmp = oldErr;
if (status) return 1; /* error code */
if (tf == NULL) return 2; /* `natural' end */
luaD_adjusttop(L, L->Cstack.base, 1); /* one slot for the pseudo-function */
L->Cstack.base->ttype = LUA_T_PROTO;
L->Cstack.base->value.tf = tf;
luaV_closure(L, 0);
L->top->ttype = LUA_T_PROTO; /* push new function on the stack */
L->top->value.tf = tf;
incr_top;
return 0;
}
@ -313,7 +308,7 @@ static int do_main (lua_State *L, ZIO *z, int bin) {
long old_blocks = (luaC_checkGC(L), L->nblocks);
status = protectedparser(L, z, bin);
if (status == 1) return 1; /* error */
else if (status == 2) return 0; /* 'natural' end */
else if (status == 2) return 0; /* `natural' end */
else {
unsigned long newelems2 = 2*(L->nblocks-old_blocks);
L->GCthreshold += newelems2;

Loading…
Cancel
Save