rpm
4.5
|
00001 /* 00002 ** $Id: lmem.c,v 1.61 2002/12/04 17:38:31 roberto Exp $ 00003 ** Interface to Memory Manager 00004 ** See Copyright Notice in lua.h 00005 */ 00006 00007 00008 #include <stdlib.h> 00009 00010 #define lmem_c 00011 00012 #include "lua.h" 00013 00014 #include "ldebug.h" 00015 #include "ldo.h" 00016 #include "lmem.h" 00017 #include "lobject.h" 00018 #include "lstate.h" 00019 00020 00021 00022 /* 00023 ** definition for realloc function. It must assure that l_realloc(NULL, 00024 ** 0, x) allocates a new block (ANSI C assures that). (`os' is the old 00025 ** block size; some allocators may use that.) 00026 */ 00027 #ifndef l_realloc 00028 #define l_realloc(b,os,s) realloc(b,s) 00029 #endif 00030 00031 /* 00032 ** definition for free function. (`os' is the old block size; some 00033 ** allocators may use that.) 00034 */ 00035 #ifndef l_free 00036 #define l_free(b,os) free(b) 00037 #endif 00038 00039 00040 #define MINSIZEARRAY 4 00041 00042 00043 void *luaM_growaux (lua_State *L, void *block, int *size, int size_elems, 00044 int limit, const char *errormsg) { 00045 void *newblock; 00046 int newsize = (*size)*2; 00047 if (newsize < MINSIZEARRAY) 00048 newsize = MINSIZEARRAY; /* minimum size */ 00049 else if (*size >= limit/2) { /* cannot double it? */ 00050 if (*size < limit - MINSIZEARRAY) /* try something smaller... */ 00051 newsize = limit; /* still have at least MINSIZEARRAY free places */ 00052 else luaG_runerror(L, errormsg); 00053 } 00054 newblock = luaM_realloc(L, block, 00055 cast(lu_mem, *size)*cast(lu_mem, size_elems), 00056 cast(lu_mem, newsize)*cast(lu_mem, size_elems)); 00057 *size = newsize; /* update only when everything else is OK */ 00058 return newblock; 00059 } 00060 00061 00062 /* 00063 ** generic allocation routine. 00064 */ 00065 void *luaM_realloc (lua_State *L, void *block, lu_mem oldsize, lu_mem size) { 00066 lua_assert((oldsize == 0) == (block == NULL)); 00067 if (size == 0) { 00068 if (block != NULL) { 00069 l_free(block, oldsize); 00070 block = NULL; 00071 } 00072 else return NULL; /* avoid `nblocks' computations when oldsize==size==0 */ 00073 } 00074 else if (size >= MAX_SIZET) 00075 luaG_runerror(L, "memory allocation error: block too big"); 00076 else { 00077 block = l_realloc(block, oldsize, size); 00078 if (block == NULL) { 00079 if (L) 00080 luaD_throw(L, LUA_ERRMEM); 00081 else return NULL; /* error before creating state! */ 00082 } 00083 } 00084 if (L) { 00085 lua_assert(G(L) != NULL && G(L)->nblocks > 0); 00086 G(L)->nblocks -= oldsize; 00087 G(L)->nblocks += size; 00088 } 00089 return block; 00090 } 00091