mudgangster

Tiny, scriptable MUD client
Log | Files | Refs | README

lmem.cc (2675B)


      1 /*
      2 ** $Id: lmem.c,v 1.91.1.1 2017/04/19 17:20:42 roberto Exp $
      3 ** Interface to Memory Manager
      4 ** See Copyright Notice in lua.h
      5 */
      6 
      7 #define lmem_c
      8 #define LUA_CORE
      9 
     10 #include "lprefix.h"
     11 
     12 
     13 #include <stddef.h>
     14 
     15 #include "lua.h"
     16 
     17 #include "ldebug.h"
     18 #include "ldo.h"
     19 #include "lgc.h"
     20 #include "lmem.h"
     21 #include "lobject.h"
     22 #include "lstate.h"
     23 
     24 
     25 
     26 /*
     27 ** About the realloc function:
     28 ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
     29 ** ('osize' is the old size, 'nsize' is the new size)
     30 **
     31 ** * frealloc(ud, NULL, x, s) creates a new block of size 's' (no
     32 ** matter 'x').
     33 **
     34 ** * frealloc(ud, p, x, 0) frees the block 'p'
     35 ** (in this specific case, frealloc must return NULL);
     36 ** particularly, frealloc(ud, NULL, 0, 0) does nothing
     37 ** (which is equivalent to free(NULL) in ISO C)
     38 **
     39 ** frealloc returns NULL if it cannot create or reallocate the area
     40 ** (any reallocation to an equal or smaller size cannot fail!)
     41 */
     42 
     43 
     44 
     45 #define MINSIZEARRAY	4
     46 
     47 
     48 void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
     49                      int limit, const char *what) {
     50   void *newblock;
     51   int newsize;
     52   if (*size >= limit/2) {  /* cannot double it? */
     53     if (*size >= limit)  /* cannot grow even a little? */
     54       luaG_runerror(L, "too many %s (limit is %d)", what, limit);
     55     newsize = limit;  /* still have at least one free place */
     56   }
     57   else {
     58     newsize = (*size)*2;
     59     if (newsize < MINSIZEARRAY)
     60       newsize = MINSIZEARRAY;  /* minimum size */
     61   }
     62   newblock = luaM_reallocv(L, block, *size, newsize, size_elems);
     63   *size = newsize;  /* update only when everything else is OK */
     64   return newblock;
     65 }
     66 
     67 
     68 l_noret luaM_toobig (lua_State *L) {
     69   luaG_runerror(L, "memory allocation error: block too big");
     70 }
     71 
     72 
     73 
     74 /*
     75 ** generic allocation routine.
     76 */
     77 void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
     78   void *newblock;
     79   global_State *g = G(L);
     80   size_t realosize = (block) ? osize : 0;
     81   lua_assert((realosize == 0) == (block == NULL));
     82 #if defined(HARDMEMTESTS)
     83   if (nsize > realosize && g->gcrunning)
     84     luaC_fullgc(L, 1);  /* force a GC whenever possible */
     85 #endif
     86   newblock = (*g->frealloc)(g->ud, block, osize, nsize);
     87   if (newblock == NULL && nsize > 0) {
     88     lua_assert(nsize > realosize);  /* cannot fail when shrinking a block */
     89     if (g->version) {  /* is state fully built? */
     90       luaC_fullgc(L, 1);  /* try to free some memory... */
     91       newblock = (*g->frealloc)(g->ud, block, osize, nsize);  /* try again */
     92     }
     93     if (newblock == NULL)
     94       luaD_throw(L, LUA_ERRMEM);
     95   }
     96   lua_assert((nsize == 0) == (newblock == NULL));
     97   g->GCdebt = (g->GCdebt + nsize) - realosize;
     98   return newblock;
     99 }
    100