summaryrefslogtreecommitdiff
path: root/lmem.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-12-08 15:28:25 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-12-08 15:28:25 -0200
commite663a24ab03a54fa221c20a793812e5c5ffdf94f (patch)
tree8fbd40f779f0eed29d46f26c07e1234fd5df8bae /lmem.c
parent40f823ec907fd725617e37199199b3ed424bd88c (diff)
downloadlua-github-e663a24ab03a54fa221c20a793812e5c5ffdf94f.tar.gz
more freedom in handling memory-allocation errors (not all allocations
automatically raise an error), which allows fixing a bug when resizing a table.
Diffstat (limited to 'lmem.c')
-rw-r--r--lmem.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/lmem.c b/lmem.c
index 23dc14d6..afacbb9f 100644
--- a/lmem.c
+++ b/lmem.c
@@ -1,5 +1,5 @@
/*
-** $Id: lmem.c,v 1.92 2017/12/06 18:36:31 roberto Exp roberto $
+** $Id: lmem.c,v 1.93 2017/12/07 18:59:52 roberto Exp roberto $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
@@ -69,9 +69,12 @@ void *luaM_growaux_ (lua_State *L, void *block, int nelems, int *psize,
if (size < MINSIZEARRAY)
size = MINSIZEARRAY; /* minimum size */
}
+ lua_assert(nelems + 1 <= size && size <= limit);
/* 'limit' ensures that multiplication will not overflow */
- newblock = luaM_realloc(L, block, cast(size_t, *psize) * size_elems,
- cast(size_t, size) * size_elems);
+ newblock = luaM_realloc_(L, block, cast(size_t, *psize) * size_elems,
+ cast(size_t, size) * size_elems);
+ if (newblock == NULL)
+ luaM_error(L);
*psize = size; /* update only when everything else is OK */
return newblock;
}
@@ -115,20 +118,20 @@ void luaM_free_ (lua_State *L, void *block, size_t osize) {
/*
** generic allocation routine.
*/
-void *luaM_realloc (lua_State *L, void *block, size_t osize, size_t nsize) {
+void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
void *newblock;
global_State *g = G(L);
lua_assert((osize == 0) == (block == NULL));
hardtest(L, osize, nsize);
newblock = (*g->frealloc)(g->ud, block, osize, nsize);
if (newblock == NULL && nsize > 0) {
- lua_assert(nsize > osize); /* cannot fail when shrinking a block */
- if (g->version) { /* is state fully built? */
+ /* Is state fully built? Not shrinking a block? */
+ if (g->version && nsize > osize) {
luaC_fullgc(L, 1); /* try to free some memory... */
newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */
}
if (newblock == NULL)
- luaD_throw(L, LUA_ERRMEM);
+ return NULL;
}
lua_assert((nsize == 0) == (newblock == NULL));
g->GCdebt = (g->GCdebt + nsize) - osize;
@@ -136,7 +139,16 @@ void *luaM_realloc (lua_State *L, void *block, size_t osize, size_t nsize) {
}
-void *luaM_malloc (lua_State *L, size_t size, int tag) {
+void *luaM_saferealloc_ (lua_State *L, void *block, size_t osize,
+ size_t nsize) {
+ void *newblock = luaM_realloc_(L, block, osize, nsize);
+ if (newblock == NULL && nsize > 0) /* allocation failed? */
+ luaM_error(L);
+ return newblock;
+}
+
+
+void *luaM_malloc_ (lua_State *L, size_t size, int tag) {
hardtest(L, 0, size);
if (size == 0)
return NULL; /* that's all */
@@ -149,7 +161,7 @@ void *luaM_malloc (lua_State *L, size_t size, int tag) {
newblock = (*g->frealloc)(g->ud, NULL, tag, size); /* try again */
}
if (newblock == NULL)
- luaD_throw(L, LUA_ERRMEM);
+ luaM_error(L);
}
g->GCdebt += size;
return newblock;