|
|
@ -1,5 +1,5 @@ |
|
|
|
/*
|
|
|
|
** $Id: ldo.c,v 1.80 2000/06/26 19:28:31 roberto Exp roberto $ |
|
|
|
** $Id: ldo.c,v 1.81 2000/06/28 20:20:36 roberto Exp roberto $ |
|
|
|
** Stack and Call structure of Lua |
|
|
|
** See Copyright Notice in lua.h |
|
|
|
*/ |
|
|
@ -237,19 +237,43 @@ static void message (lua_State *L, const char *s) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
|
** Reports an error, and jumps up to the available recovery label |
|
|
|
*/ |
|
|
|
void lua_error (lua_State *L, const char *s) { |
|
|
|
if (s) message(L, s); |
|
|
|
if (L->errorJmp) |
|
|
|
|
|
|
|
void luaD_breakrun (lua_State *L, int errcode) { |
|
|
|
if (L->errorJmp) { |
|
|
|
L->errorJmp->status = errcode; |
|
|
|
longjmp(L->errorJmp->b, 1); |
|
|
|
} |
|
|
|
else { |
|
|
|
if (errcode != LUA_ERRMEM) |
|
|
|
message(L, "unable to recover; exiting\n"); |
|
|
|
exit(1); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
|
** Reports an error, and jumps up to the available recovery label |
|
|
|
*/ |
|
|
|
void lua_error (lua_State *L, const char *s) { |
|
|
|
if (s) message(L, s); |
|
|
|
luaD_breakrun(L, LUA_ERRRUN); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void chain_longjmp (lua_State *L, struct lua_longjmp *lj) { |
|
|
|
lj->base = L->Cstack.base; |
|
|
|
lj->numCblocks = L->numCblocks; |
|
|
|
lj->previous = L->errorJmp; |
|
|
|
L->errorJmp = lj; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void restore_longjmp (lua_State *L, struct lua_longjmp *lj) { |
|
|
|
L->Cstack.num = 0; /* no results */ |
|
|
|
L->top = L->Cstack.base = L->Cstack.lua2C = lj->base; |
|
|
|
L->numCblocks = lj->numCblocks; |
|
|
|
L->errorJmp = lj->previous; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Execute a protected call. Assumes that function is at Cstack.base and |
|
|
@ -257,58 +281,44 @@ void lua_error (lua_State *L, const char *s) { |
|
|
|
*/ |
|
|
|
int luaD_protectedrun (lua_State *L) { |
|
|
|
struct lua_longjmp myErrorJmp; |
|
|
|
StkId base = L->Cstack.base; |
|
|
|
int numCblocks = L->numCblocks; |
|
|
|
int status; |
|
|
|
struct lua_longjmp *volatile oldErr = L->errorJmp; |
|
|
|
L->errorJmp = &myErrorJmp; |
|
|
|
chain_longjmp(L, &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; |
|
|
|
L->Cstack.base = base + L->Cstack.num; /* incorporate results on stack */ |
|
|
|
status = 0; |
|
|
|
L->errorJmp = myErrorJmp.previous; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
else { /* an error occurred: restore the stack */ |
|
|
|
L->Cstack.num = 0; /* no results */ |
|
|
|
L->top = L->Cstack.base = L->Cstack.lua2C = base; |
|
|
|
L->numCblocks = numCblocks; |
|
|
|
restore_longjmp(L, &myErrorJmp); |
|
|
|
restore_stack_limit(L); |
|
|
|
status = 1; |
|
|
|
return myErrorJmp.status; |
|
|
|
} |
|
|
|
L->errorJmp = oldErr; |
|
|
|
return status; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
** returns 0 = chunk loaded; 1 = error; 2 = no more chunks to load |
|
|
|
** returns 0 = chunk loaded; >0 : error; -1 = no more chunks to load |
|
|
|
*/ |
|
|
|
static int protectedparser (lua_State *L, ZIO *z, int bin) { |
|
|
|
struct lua_longjmp myErrorJmp; |
|
|
|
StkId base = L->Cstack.base; |
|
|
|
int numCblocks = L->numCblocks; |
|
|
|
int status; |
|
|
|
Proto *volatile tf; |
|
|
|
struct lua_longjmp *volatile oldErr = L->errorJmp; |
|
|
|
L->errorJmp = &myErrorJmp; |
|
|
|
L->top = base; /* clear C2Lua */ |
|
|
|
chain_longjmp(L, &myErrorJmp); |
|
|
|
L->top = L->Cstack.base; /* clear C2Lua */ |
|
|
|
if (setjmp(myErrorJmp.b) == 0) { |
|
|
|
tf = bin ? luaU_undump1(L, z) : luaY_parser(L, z); |
|
|
|
status = 0; |
|
|
|
} |
|
|
|
else { /* an error occurred: restore Cstack and top */ |
|
|
|
L->Cstack.num = 0; /* no results */ |
|
|
|
L->top = L->Cstack.base = L->Cstack.lua2C = base; |
|
|
|
L->numCblocks = numCblocks; |
|
|
|
tf = NULL; |
|
|
|
status = 1; |
|
|
|
} |
|
|
|
L->errorJmp = oldErr; |
|
|
|
if (status) return 1; /* error code */ |
|
|
|
if (tf == NULL) return 2; /* `natural' end */ |
|
|
|
Proto *tf = bin ? luaU_undump1(L, z) : luaY_parser(L, z); |
|
|
|
L->errorJmp = myErrorJmp.previous; |
|
|
|
if (tf == NULL) return -1; /* `natural' end */ |
|
|
|
luaV_Lclosure(L, tf, 0); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
else { /* an error occurred */ |
|
|
|
restore_longjmp(L, &myErrorJmp); |
|
|
|
if (myErrorJmp.status == LUA_ERRRUN) |
|
|
|
myErrorJmp.status = LUA_ERRSYNTAX; |
|
|
|
return myErrorJmp.status; /* error code */ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -320,8 +330,8 @@ static int do_main (lua_State *L, ZIO *z, int bin) { |
|
|
|
luaC_checkGC(L); |
|
|
|
old_blocks = L->nblocks; |
|
|
|
status = protectedparser(L, z, bin); |
|
|
|
if (status == 1) return 1; /* error */ |
|
|
|
else if (status == 2) return 0; /* `natural' end */ |
|
|
|
if (status > 0) return status; /* error */ |
|
|
|
else if (status < 0) return 0; /* `natural' end */ |
|
|
|
else { |
|
|
|
unsigned long newelems2 = 2*(L->nblocks-old_blocks); |
|
|
|
L->GCthreshold += newelems2; |
|
|
|