mirror of
https://github.com/lua/lua
synced 2025-04-12 16:02:52 +03:00
(much) better handling of memory alloction errors
This commit is contained in:
parent
ae55f3eead
commit
435f587ed0
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lbuiltin.c,v 1.116 2000/06/12 13:52:05 roberto Exp roberto $
|
** $Id: lbuiltin.c,v 1.117 2000/06/30 14:35:17 roberto Exp roberto $
|
||||||
** Built-in functions
|
** Built-in functions
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -365,8 +365,8 @@ void luaB_tostring (lua_State *L) {
|
|||||||
sprintf(buff, "function: %p", clvalue(o));
|
sprintf(buff, "function: %p", clvalue(o));
|
||||||
break;
|
break;
|
||||||
case TAG_USERDATA:
|
case TAG_USERDATA:
|
||||||
sprintf(buff, "userdata: %p(%d)", tsvalue(o)->u.d.value,
|
sprintf(buff, "userdata(%d): %p", tsvalue(o)->u.d.tag,
|
||||||
tsvalue(o)->u.d.tag);
|
tsvalue(o)->u.d.value);
|
||||||
break;
|
break;
|
||||||
case TAG_NIL:
|
case TAG_NIL:
|
||||||
lua_pushstring(L, "nil");
|
lua_pushstring(L, "nil");
|
||||||
@ -680,8 +680,6 @@ static const struct luaL_reg builtin_funcs[] = {
|
|||||||
|
|
||||||
|
|
||||||
void luaB_predefine (lua_State *L) {
|
void luaB_predefine (lua_State *L) {
|
||||||
/* pre-register mem error messages, to avoid loop when error arises */
|
|
||||||
luaS_newfixed(L, memEM);
|
|
||||||
luaL_openl(L, builtin_funcs);
|
luaL_openl(L, builtin_funcs);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
luaB_opentests(L); /* internal test functions */
|
luaB_opentests(L); /* internal test functions */
|
||||||
|
6
lcode.c
6
lcode.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lcode.c,v 1.40 2000/06/28 20:20:36 roberto Exp roberto $
|
** $Id: lcode.c,v 1.41 2000/06/30 14:35:17 roberto Exp roberto $
|
||||||
** Code generator for Lua
|
** Code generator for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -620,8 +620,8 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
|
|||||||
}
|
}
|
||||||
if (fs->debug) {
|
if (fs->debug) {
|
||||||
LexState *ls = fs->ls;
|
LexState *ls = fs->ls;
|
||||||
luaX_checklimit(ls, ls->lastline, MAXARG_U, "lines in a chunk");
|
luaM_growvector(fs->L, fs->f->lines, fs->pc, 1, int,
|
||||||
luaM_growvector(fs->L, fs->f->lines, fs->pc, 1, int, "??", MAXARG_U);
|
"code size overflow", MAX_INT);
|
||||||
fs->f->lines[fs->pc] = ls->lastline;
|
fs->f->lines[fs->pc] = ls->lastline;
|
||||||
}
|
}
|
||||||
/* put new instruction in code array */
|
/* put new instruction in code array */
|
||||||
|
92
ldo.c
92
ldo.c
@ -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
|
** Stack and Call structure of Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -237,17 +237,41 @@ static void message (lua_State *L, const char *s) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
** Reports an error, and jumps up to the available recovery label
|
||||||
*/
|
*/
|
||||||
void lua_error (lua_State *L, const char *s) {
|
void lua_error (lua_State *L, const char *s) {
|
||||||
if (s) message(L, s);
|
if (s) message(L, s);
|
||||||
if (L->errorJmp)
|
luaD_breakrun(L, LUA_ERRRUN);
|
||||||
longjmp(L->errorJmp->b, 1);
|
|
||||||
else {
|
|
||||||
message(L, "unable to recover; exiting\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -257,59 +281,45 @@ void lua_error (lua_State *L, const char *s) {
|
|||||||
*/
|
*/
|
||||||
int luaD_protectedrun (lua_State *L) {
|
int luaD_protectedrun (lua_State *L) {
|
||||||
struct lua_longjmp myErrorJmp;
|
struct lua_longjmp myErrorJmp;
|
||||||
StkId base = L->Cstack.base;
|
chain_longjmp(L, &myErrorJmp);
|
||||||
int numCblocks = L->numCblocks;
|
|
||||||
int status;
|
|
||||||
struct lua_longjmp *volatile oldErr = L->errorJmp;
|
|
||||||
L->errorJmp = &myErrorJmp;
|
|
||||||
if (setjmp(myErrorJmp.b) == 0) {
|
if (setjmp(myErrorJmp.b) == 0) {
|
||||||
|
StkId base = L->Cstack.base;
|
||||||
luaD_call(L, base, MULT_RET);
|
luaD_call(L, base, MULT_RET);
|
||||||
L->Cstack.lua2C = base; /* position of the new results */
|
L->Cstack.lua2C = base; /* position of the new results */
|
||||||
L->Cstack.num = L->top - base;
|
L->Cstack.num = L->top - base;
|
||||||
L->Cstack.base = base + L->Cstack.num; /* incorporate results on stack */
|
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 */
|
else { /* an error occurred: restore the stack */
|
||||||
L->Cstack.num = 0; /* no results */
|
restore_longjmp(L, &myErrorJmp);
|
||||||
L->top = L->Cstack.base = L->Cstack.lua2C = base;
|
|
||||||
L->numCblocks = numCblocks;
|
|
||||||
restore_stack_limit(L);
|
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) {
|
static int protectedparser (lua_State *L, ZIO *z, int bin) {
|
||||||
struct lua_longjmp myErrorJmp;
|
struct lua_longjmp myErrorJmp;
|
||||||
StkId base = L->Cstack.base;
|
chain_longjmp(L, &myErrorJmp);
|
||||||
int numCblocks = L->numCblocks;
|
L->top = L->Cstack.base; /* clear C2Lua */
|
||||||
int status;
|
|
||||||
Proto *volatile tf;
|
|
||||||
struct lua_longjmp *volatile oldErr = L->errorJmp;
|
|
||||||
L->errorJmp = &myErrorJmp;
|
|
||||||
L->top = base; /* clear C2Lua */
|
|
||||||
if (setjmp(myErrorJmp.b) == 0) {
|
if (setjmp(myErrorJmp.b) == 0) {
|
||||||
tf = bin ? luaU_undump1(L, z) : luaY_parser(L, z);
|
Proto *tf = bin ? luaU_undump1(L, z) : luaY_parser(L, z);
|
||||||
status = 0;
|
L->errorJmp = myErrorJmp.previous;
|
||||||
}
|
if (tf == NULL) return -1; /* `natural' end */
|
||||||
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 */
|
|
||||||
luaV_Lclosure(L, tf, 0);
|
luaV_Lclosure(L, tf, 0);
|
||||||
return 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 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int do_main (lua_State *L, ZIO *z, int bin) {
|
static int do_main (lua_State *L, ZIO *z, int bin) {
|
||||||
@ -320,8 +330,8 @@ static int do_main (lua_State *L, ZIO *z, int bin) {
|
|||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
old_blocks = L->nblocks;
|
old_blocks = L->nblocks;
|
||||||
status = protectedparser(L, z, bin);
|
status = protectedparser(L, z, bin);
|
||||||
if (status == 1) return 1; /* error */
|
if (status > 0) return status; /* error */
|
||||||
else if (status == 2) return 0; /* `natural' end */
|
else if (status < 0) return 0; /* `natural' end */
|
||||||
else {
|
else {
|
||||||
unsigned long newelems2 = 2*(L->nblocks-old_blocks);
|
unsigned long newelems2 = 2*(L->nblocks-old_blocks);
|
||||||
L->GCthreshold += newelems2;
|
L->GCthreshold += newelems2;
|
||||||
|
14
lmem.c
14
lmem.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lmem.c,v 1.33 2000/06/12 13:52:05 roberto Exp roberto $
|
** $Id: lmem.c,v 1.34 2000/06/26 19:28:31 roberto Exp roberto $
|
||||||
** Interface to Memory Manager
|
** Interface to Memory Manager
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
|
|
||||||
|
#include "ldo.h"
|
||||||
#include "lmem.h"
|
#include "lmem.h"
|
||||||
#include "lobject.h"
|
#include "lobject.h"
|
||||||
#include "lstate.h"
|
#include "lstate.h"
|
||||||
@ -36,6 +37,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#undef realloc
|
#undef realloc
|
||||||
@ -59,6 +61,7 @@ union L_U { double d; char *s; long l; };
|
|||||||
unsigned long memdebug_numblocks = 0;
|
unsigned long memdebug_numblocks = 0;
|
||||||
unsigned long memdebug_total = 0;
|
unsigned long memdebug_total = 0;
|
||||||
unsigned long memdebug_maxmem = 0;
|
unsigned long memdebug_maxmem = 0;
|
||||||
|
unsigned long memdebug_memlimit = LONG_MAX;
|
||||||
|
|
||||||
|
|
||||||
static void *checkblock (void *block) {
|
static void *checkblock (void *block) {
|
||||||
@ -88,6 +91,8 @@ static void *debug_realloc (void *block, size_t size) {
|
|||||||
freeblock(block);
|
freeblock(block);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
else if (memdebug_total+size > memdebug_memlimit)
|
||||||
|
return NULL; /* to test memory allocation errors */
|
||||||
else {
|
else {
|
||||||
size_t realsize = HEADER+size+MARKSIZE;
|
size_t realsize = HEADER+size+MARKSIZE;
|
||||||
char *newblock = (char *)(malloc)(realsize); /* alloc a new block */
|
char *newblock = (char *)(malloc)(realsize); /* alloc a new block */
|
||||||
@ -139,8 +144,11 @@ void *luaM_realloc (lua_State *L, void *block, lint32 size) {
|
|||||||
else if (size >= MAX_SIZET)
|
else if (size >= MAX_SIZET)
|
||||||
lua_error(L, "memory allocation error: block too big");
|
lua_error(L, "memory allocation error: block too big");
|
||||||
block = realloc(block, size);
|
block = realloc(block, size);
|
||||||
if (block == NULL)
|
if (block == NULL) {
|
||||||
lua_error(L, memEM);
|
if (L)
|
||||||
|
luaD_breakrun(L, LUA_ERRMEM); /* break run without error message */
|
||||||
|
else return NULL; /* error before creating state! */
|
||||||
|
}
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
23
lstate.c
23
lstate.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstate.c,v 1.28 2000/06/30 14:35:17 roberto Exp roberto $
|
** $Id: lstate.c,v 1.29 2000/06/30 19:17:08 roberto Exp roberto $
|
||||||
** Global State
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -28,8 +28,14 @@ lua_State *lua_state = NULL;
|
|||||||
|
|
||||||
|
|
||||||
lua_State *lua_newstate (int stacksize, int put_builtin) {
|
lua_State *lua_newstate (int stacksize, int put_builtin) {
|
||||||
|
struct lua_longjmp myErrorJmp;
|
||||||
lua_State *L = luaM_new(NULL, lua_State);
|
lua_State *L = luaM_new(NULL, lua_State);
|
||||||
L->errorJmp = NULL;
|
if (L == NULL) return NULL; /* memory allocation error */
|
||||||
|
L->stack = NULL;
|
||||||
|
L->strt.size = L->udt.size = 0;
|
||||||
|
L->strt.nuse = L->udt.nuse = 0;
|
||||||
|
L->strt.hash = NULL;
|
||||||
|
L->udt.hash = NULL;
|
||||||
L->Mbuffer = NULL;
|
L->Mbuffer = NULL;
|
||||||
L->Mbuffbase = 0;
|
L->Mbuffbase = 0;
|
||||||
L->Mbuffsize = 0;
|
L->Mbuffsize = 0;
|
||||||
@ -40,6 +46,7 @@ lua_State *lua_newstate (int stacksize, int put_builtin) {
|
|||||||
L->rootcl = NULL;
|
L->rootcl = NULL;
|
||||||
L->roottable = NULL;
|
L->roottable = NULL;
|
||||||
L->IMtable = NULL;
|
L->IMtable = NULL;
|
||||||
|
L->last_tag = -1;
|
||||||
L->refArray = NULL;
|
L->refArray = NULL;
|
||||||
L->refSize = 0;
|
L->refSize = 0;
|
||||||
L->refFree = NONEXT;
|
L->refFree = NONEXT;
|
||||||
@ -49,17 +56,24 @@ lua_State *lua_newstate (int stacksize, int put_builtin) {
|
|||||||
L->callhook = NULL;
|
L->callhook = NULL;
|
||||||
L->linehook = NULL;
|
L->linehook = NULL;
|
||||||
L->allowhooks = 1;
|
L->allowhooks = 1;
|
||||||
|
L->errorJmp = &myErrorJmp;
|
||||||
|
if (setjmp(myErrorJmp.b) == 0) { /* to catch memory allocation errors */
|
||||||
L->gt = luaH_new(L, 10);
|
L->gt = luaH_new(L, 10);
|
||||||
if (stacksize == 0) stacksize = DEFAULT_STACK_SIZE;
|
luaD_init(L, (stacksize == 0) ? DEFAULT_STACK_SIZE : stacksize);
|
||||||
luaD_init(L, stacksize);
|
|
||||||
luaS_init(L);
|
luaS_init(L);
|
||||||
luaX_init(L);
|
luaX_init(L);
|
||||||
luaT_init(L);
|
luaT_init(L);
|
||||||
if (put_builtin)
|
if (put_builtin)
|
||||||
luaB_predefine(L);
|
luaB_predefine(L);
|
||||||
L->GCthreshold = L->nblocks*4;
|
L->GCthreshold = L->nblocks*4;
|
||||||
|
L->errorJmp = NULL;
|
||||||
return L;
|
return L;
|
||||||
}
|
}
|
||||||
|
else { /* memory allocation error: free partial state */
|
||||||
|
lua_close(L);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void lua_close (lua_State *L) {
|
void lua_close (lua_State *L) {
|
||||||
@ -75,7 +89,6 @@ void lua_close (lua_State *L) {
|
|||||||
luaM_free(L, L->Cblocks);
|
luaM_free(L, L->Cblocks);
|
||||||
LUA_ASSERT(L->numCblocks == 0, "Cblocks still open");
|
LUA_ASSERT(L->numCblocks == 0, "Cblocks still open");
|
||||||
LUA_ASSERT(L->nblocks == 0, "wrong count for nblocks");
|
LUA_ASSERT(L->nblocks == 0, "wrong count for nblocks");
|
||||||
LUA_ASSERT(L->Cstack.base == L->top, "C2Lua not empty");
|
|
||||||
luaM_free(L, L);
|
luaM_free(L, L);
|
||||||
if (L == lua_state) {
|
if (L == lua_state) {
|
||||||
LUA_ASSERT(memdebug_numblocks == 0, "memory leak!");
|
LUA_ASSERT(memdebug_numblocks == 0, "memory leak!");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstring.c,v 1.39 2000/06/15 17:01:12 roberto Exp roberto $
|
** $Id: lstring.c,v 1.40 2000/06/30 14:35:17 roberto Exp $
|
||||||
** String table (keeps all strings handled by Lua)
|
** String table (keeps all strings handled by Lua)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -19,10 +19,10 @@
|
|||||||
|
|
||||||
|
|
||||||
void luaS_init (lua_State *L) {
|
void luaS_init (lua_State *L) {
|
||||||
L->strt.size = L->udt.size = 1;
|
|
||||||
L->strt.nuse = L->udt.nuse = 0;
|
|
||||||
L->strt.hash = luaM_newvector(L, 1, TString *);
|
L->strt.hash = luaM_newvector(L, 1, TString *);
|
||||||
L->udt.hash = luaM_newvector(L, 1, TString *);
|
L->udt.hash = luaM_newvector(L, 1, TString *);
|
||||||
|
L->strt.size = L->udt.size = 1;
|
||||||
|
L->strt.nuse = L->udt.nuse = 0;
|
||||||
L->strt.hash[0] = L->udt.hash[0] = NULL;
|
L->strt.hash[0] = L->udt.hash[0] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
ltable.c
10
ltable.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltable.c,v 1.49 2000/06/28 17:03:56 roberto Exp roberto $
|
** $Id: ltable.c,v 1.50 2000/06/30 14:35:17 roberto Exp roberto $
|
||||||
** Lua tables (hash)
|
** Lua tables (hash)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -154,19 +154,22 @@ static void setnodevector (lua_State *L, Hash *t, lint32 size) {
|
|||||||
ttype(&t->node[i].key) = ttype(&t->node[i].val) = TAG_NIL;
|
ttype(&t->node[i].key) = ttype(&t->node[i].val) = TAG_NIL;
|
||||||
t->node[i].next = NULL;
|
t->node[i].next = NULL;
|
||||||
}
|
}
|
||||||
|
L->nblocks += gcsize(L, size) - gcsize(L, t->size);
|
||||||
t->size = size;
|
t->size = size;
|
||||||
t->firstfree = &t->node[size-1]; /* first free position to be used */
|
t->firstfree = &t->node[size-1]; /* first free position to be used */
|
||||||
L->nblocks += gcsize(L, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Hash *luaH_new (lua_State *L, int size) {
|
Hash *luaH_new (lua_State *L, int size) {
|
||||||
Hash *t = luaM_new(L, Hash);
|
Hash *t = luaM_new(L, Hash);
|
||||||
setnodevector(L, t, luaO_power2(size));
|
|
||||||
t->htag = TagDefault;
|
t->htag = TagDefault;
|
||||||
t->next = L->roottable;
|
t->next = L->roottable;
|
||||||
L->roottable = t;
|
L->roottable = t;
|
||||||
t->marked = 0;
|
t->marked = 0;
|
||||||
|
t->size = 0;
|
||||||
|
L->nblocks += gcsize(L, 0);
|
||||||
|
t->node = NULL;
|
||||||
|
setnodevector(L, t, luaO_power2(size));
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +207,6 @@ static void rehash (lua_State *L, Hash *t) {
|
|||||||
setnodevector(L, t, oldsize/2);
|
setnodevector(L, t, oldsize/2);
|
||||||
else
|
else
|
||||||
setnodevector(L, t, oldsize);
|
setnodevector(L, t, oldsize);
|
||||||
L->nblocks -= gcsize(L, oldsize);
|
|
||||||
for (i=0; i<oldsize; i++) {
|
for (i=0; i<oldsize; i++) {
|
||||||
Node *old = nold+i;
|
Node *old = nold+i;
|
||||||
if (ttype(&old->val) != TAG_NIL)
|
if (ttype(&old->val) != TAG_NIL)
|
||||||
|
22
ltests.c
22
ltests.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltests.c,v 1.28 2000/06/28 17:06:07 roberto Exp roberto $
|
** $Id: ltests.c,v 1.29 2000/06/30 19:17:08 roberto Exp roberto $
|
||||||
** Internal Module for Debugging of the Lua Implementation
|
** Internal Module for Debugging of the Lua Implementation
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -169,10 +169,15 @@ static void get_limits (void) {
|
|||||||
|
|
||||||
|
|
||||||
static void mem_query (void) {
|
static void mem_query (void) {
|
||||||
|
lua_Object arg = lua_getparam(1);
|
||||||
|
if (arg == LUA_NOOBJECT) {
|
||||||
lua_pushnumber(memdebug_total);
|
lua_pushnumber(memdebug_total);
|
||||||
lua_pushnumber(memdebug_numblocks);
|
lua_pushnumber(memdebug_numblocks);
|
||||||
lua_pushnumber(memdebug_maxmem);
|
lua_pushnumber(memdebug_maxmem);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
memdebug_memlimit = luaL_check_int(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void hash_query (void) {
|
static void hash_query (void) {
|
||||||
@ -375,7 +380,10 @@ static void testC (void) {
|
|||||||
else if EQ("newstate") {
|
else if EQ("newstate") {
|
||||||
int stacksize = getnum(&pc);
|
int stacksize = getnum(&pc);
|
||||||
lua_State *L1 = lua_newstate(stacksize, getnum(&pc));
|
lua_State *L1 = lua_newstate(stacksize, getnum(&pc));
|
||||||
|
if (L1)
|
||||||
lua_pushuserdata(L1);
|
lua_pushuserdata(L1);
|
||||||
|
else
|
||||||
|
lua_pushnil();
|
||||||
}
|
}
|
||||||
else if EQ("closestate") {
|
else if EQ("closestate") {
|
||||||
(lua_close)((lua_State *)lua_getuserdata(reg[getreg(&pc)]));
|
(lua_close)((lua_State *)lua_getuserdata(reg[getreg(&pc)]));
|
||||||
@ -385,15 +393,21 @@ static void testC (void) {
|
|||||||
lua_Object str = reg[getreg(&pc)];
|
lua_Object str = reg[getreg(&pc)];
|
||||||
lua_State *L1;
|
lua_State *L1;
|
||||||
lua_Object temp;
|
lua_Object temp;
|
||||||
int i;
|
int status;
|
||||||
if (!lua_isuserdata(ol1) || !lua_isstring(str))
|
if (!lua_isuserdata(ol1) || !lua_isstring(str))
|
||||||
lua_error("bad arguments for `doremote'");
|
lua_error("bad arguments for `doremote'");
|
||||||
L1 = (lua_State *)lua_getuserdata(ol1);
|
L1 = (lua_State *)lua_getuserdata(ol1);
|
||||||
(lua_dostring)(L1, lua_getstring(str));
|
status = (lua_dostring)(L1, lua_getstring(str));
|
||||||
i = 1;
|
if (status != 0) {
|
||||||
|
lua_pushnil();
|
||||||
|
lua_pushnumber(status);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int i = 1;
|
||||||
while ((temp = (lua_getresult)(L1, i++)) != LUA_NOOBJECT)
|
while ((temp = (lua_getresult)(L1, i++)) != LUA_NOOBJECT)
|
||||||
lua_pushstring((lua_getstring)(L1, temp));
|
lua_pushstring((lua_getstring)(L1, temp));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#if LUA_DEPRECATETFUNCS
|
#if LUA_DEPRECATETFUNCS
|
||||||
else if EQ("rawsetglobal") {
|
else if EQ("rawsetglobal") {
|
||||||
lua_rawsetglobal(getname(&pc));
|
lua_rawsetglobal(getname(&pc));
|
||||||
|
6
ltm.c
6
ltm.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltm.c,v 1.42 2000/06/08 17:48:31 roberto Exp roberto $
|
** $Id: ltm.c,v 1.43 2000/06/12 13:52:05 roberto Exp roberto $
|
||||||
** Tag methods
|
** Tag methods
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -69,17 +69,17 @@ static void init_entry (lua_State *L, int tag) {
|
|||||||
|
|
||||||
void luaT_init (lua_State *L) {
|
void luaT_init (lua_State *L) {
|
||||||
int t;
|
int t;
|
||||||
L->last_tag = NUM_TAGS-1;
|
|
||||||
luaM_growvector(L, L->IMtable, 0, NUM_TAGS, struct IM, "", MAX_INT);
|
luaM_growvector(L, L->IMtable, 0, NUM_TAGS, struct IM, "", MAX_INT);
|
||||||
|
L->last_tag = NUM_TAGS-1;
|
||||||
for (t=0; t<=L->last_tag; t++)
|
for (t=0; t<=L->last_tag; t++)
|
||||||
init_entry(L, t);
|
init_entry(L, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int lua_newtag (lua_State *L) {
|
int lua_newtag (lua_State *L) {
|
||||||
++L->last_tag;
|
|
||||||
luaM_growvector(L, L->IMtable, L->last_tag, 1, struct IM,
|
luaM_growvector(L, L->IMtable, L->last_tag, 1, struct IM,
|
||||||
"tag table overflow", MAX_INT);
|
"tag table overflow", MAX_INT);
|
||||||
|
L->last_tag++;
|
||||||
init_entry(L, L->last_tag);
|
init_entry(L, L->last_tag);
|
||||||
return L->last_tag;
|
return L->last_tag;
|
||||||
}
|
}
|
||||||
|
8
lua.c
8
lua.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lua.c,v 1.41 2000/06/19 13:15:15 roberto Exp roberto $
|
** $Id: lua.c,v 1.42 2000/06/30 19:17:08 roberto Exp roberto $
|
||||||
** Lua stand-alone interpreter
|
** Lua stand-alone interpreter
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -62,6 +62,10 @@ static int ldo (int (*f)(lua_State *L, const char *), const char *name) {
|
|||||||
handler h = lreset();
|
handler h = lreset();
|
||||||
res = f(lua_state, name); /* dostring | dofile */
|
res = f(lua_state, name); /* dostring | dofile */
|
||||||
signal(SIGINT, h); /* restore old action */
|
signal(SIGINT, h); /* restore old action */
|
||||||
|
if (res == LUA_ERRMEM) {
|
||||||
|
/* Lua gives no message in such case, so lua.c provides one */
|
||||||
|
fprintf(stderr, "lua: memory allocation error\n");
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,7 +125,7 @@ static void l_getargs (void) {
|
|||||||
static void file_input (const char *argv) {
|
static void file_input (const char *argv) {
|
||||||
int result = ldo(lua_dofile, argv);
|
int result = ldo(lua_dofile, argv);
|
||||||
if (result) {
|
if (result) {
|
||||||
if (result == 2) {
|
if (result == LUA_ERRFILE) {
|
||||||
fprintf(stderr, "lua: cannot execute file ");
|
fprintf(stderr, "lua: cannot execute file ");
|
||||||
perror(argv);
|
perror(argv);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user