99 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			99 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
|  | /*
 | ||
|  | ** $Id: lmem.c,v 1.91 2015/03/06 19:45:54 roberto Exp $ | ||
|  | ** Interface to Memory Manager | ||
|  | ** See Copyright Notice in lua.h | ||
|  | */ | ||
|  | 
 | ||
|  | #define lmem_c
 | ||
|  | #define LUA_CORE
 | ||
|  | 
 | ||
|  | #include "lmem.h"
 | ||
|  | #include "lprefix.h"
 | ||
|  | 
 | ||
|  | #include <stddef.h>
 | ||
|  | 
 | ||
|  | #include "lua.h"
 | ||
|  | #include "ldebug.h"
 | ||
|  | #include "ldo.h"
 | ||
|  | #include "lgc.h"
 | ||
|  | #include "lobject.h"
 | ||
|  | #include "lstate.h"
 | ||
|  | 
 | ||
|  | namespace NS_SLUA { | ||
|  | 
 | ||
|  | /*
 | ||
|  | ** About the realloc function: | ||
|  | ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); | ||
|  | ** ('osize' is the old size, 'nsize' is the new size) | ||
|  | ** | ||
|  | ** * frealloc(ud, NULL, x, s) creates a new block of size 's' (no | ||
|  | ** matter 'x'). | ||
|  | ** | ||
|  | ** * frealloc(ud, p, x, 0) frees the block 'p' | ||
|  | ** (in this specific case, frealloc must return NULL); | ||
|  | ** particularly, frealloc(ud, NULL, 0, 0) does nothing | ||
|  | ** (which is equivalent to free(NULL) in ISO C) | ||
|  | ** | ||
|  | ** frealloc returns NULL if it cannot create or reallocate the area | ||
|  | ** (any reallocation to an equal or smaller size cannot fail!) | ||
|  | */ | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | #define MINSIZEARRAY	4
 | ||
|  | 
 | ||
|  | 
 | ||
|  | void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, | ||
|  |                      int limit, const char *what) { | ||
|  |   void *newblock; | ||
|  |   int newsize; | ||
|  |   if (*size >= limit/2) {  /* cannot double it? */ | ||
|  |     if (*size >= limit)  /* cannot grow even a little? */ | ||
|  |       luaG_runerror(L, "too many %s (limit is %d)", what, limit); | ||
|  |     newsize = limit;  /* still have at least one free place */ | ||
|  |   } | ||
|  |   else { | ||
|  |     newsize = (*size)*2; | ||
|  |     if (newsize < MINSIZEARRAY) | ||
|  |       newsize = MINSIZEARRAY;  /* minimum size */ | ||
|  |   } | ||
|  |   newblock = luaM_reallocv(L, block, *size, newsize, size_elems); | ||
|  |   *size = newsize;  /* update only when everything else is OK */ | ||
|  |   return newblock; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | l_noret luaM_toobig (lua_State *L) { | ||
|  |   luaG_runerror(L, "memory allocation error: block too big"); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | /*
 | ||
|  | ** generic allocation routine. | ||
|  | */ | ||
|  | void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { | ||
|  |   void *newblock; | ||
|  |   global_State *g = G(L); | ||
|  |   size_t realosize = (block) ? osize : 0; | ||
|  |   lua_assert((realosize == 0) == (block == NULL)); | ||
|  | #if defined(HARDMEMTESTS)
 | ||
|  |   if (nsize > realosize && g->gcrunning) | ||
|  |     luaC_fullgc(L, 1);  /* force a GC whenever possible */ | ||
|  | #endif
 | ||
|  |   newblock = (*g->frealloc)(g->ud, block, osize, nsize); | ||
|  |   if (newblock == NULL && nsize > 0) { | ||
|  |     lua_assert(nsize > realosize);  /* cannot fail when shrinking a block */ | ||
|  |     if (g->version) {  /* is state fully built? */ | ||
|  |       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); | ||
|  |   } | ||
|  |   lua_assert((nsize == 0) == (newblock == NULL)); | ||
|  |   g->GCdebt = (g->GCdebt + nsize) - realosize; | ||
|  |   return newblock; | ||
|  | } | ||
|  | 
 | ||
|  | } // end NS_SLUA
 |