- initial import of revision 374 from cnc
[apt.git] / lua / lmem.c
1 /*
2 ** $Id: lmem.c,v 1.61 2002/12/04 17:38:31 roberto Exp $
3 ** Interface to Memory Manager
4 ** See Copyright Notice in lua.h
5 */
6
7
8 #include <stdlib.h>
9
10 #define lmem_c
11
12 #include "lua.h"
13
14 #include "ldebug.h"
15 #include "ldo.h"
16 #include "lmem.h"
17 #include "lobject.h"
18 #include "lstate.h"
19
20
21
22 /*
23 ** definition for realloc function. It must assure that l_realloc(NULL,
24 ** 0, x) allocates a new block (ANSI C assures that). (`os' is the old
25 ** block size; some allocators may use that.)
26 */
27 #ifndef l_realloc
28 #define l_realloc(b,os,s)       realloc(b,s)
29 #endif
30
31 /*
32 ** definition for free function. (`os' is the old block size; some
33 ** allocators may use that.)
34 */
35 #ifndef l_free
36 #define l_free(b,os)    free(b)
37 #endif
38
39
40 #define MINSIZEARRAY    4
41
42
43 void *luaM_growaux (lua_State *L, void *block, int *size, int size_elems,
44                     int limit, const char *errormsg) {
45   void *newblock;
46   int newsize = (*size)*2;
47   if (newsize < MINSIZEARRAY)
48     newsize = MINSIZEARRAY;  /* minimum size */
49   else if (*size >= limit/2) {  /* cannot double it? */
50     if (*size < limit - MINSIZEARRAY)  /* try something smaller... */
51       newsize = limit;  /* still have at least MINSIZEARRAY free places */
52     else luaG_runerror(L, errormsg);
53   }
54   newblock = luaM_realloc(L, block,
55                           cast(lu_mem, *size)*cast(lu_mem, size_elems),
56                           cast(lu_mem, newsize)*cast(lu_mem, size_elems));
57   *size = newsize;  /* update only when everything else is OK */
58   return newblock;
59 }
60
61
62 /*
63 ** generic allocation routine.
64 */
65 void *luaM_realloc (lua_State *L, void *block, lu_mem oldsize, lu_mem size) {
66   lua_assert((oldsize == 0) == (block == NULL));
67   if (size == 0) {
68     if (block != NULL) {
69       l_free(block, oldsize);
70       block = NULL;
71     }
72     else return NULL;  /* avoid `nblocks' computations when oldsize==size==0 */
73   }
74   else if (size >= MAX_SIZET)
75     luaG_runerror(L, "memory allocation error: block too big");
76   else {
77     block = l_realloc(block, oldsize, size);
78     if (block == NULL) {
79       if (L)
80         luaD_throw(L, LUA_ERRMEM);
81       else return NULL;  /* error before creating state! */
82     }
83   }
84   if (L) {
85     lua_assert(G(L) != NULL && G(L)->nblocks > 0);
86     G(L)->nblocks -= oldsize;
87     G(L)->nblocks += size;
88   }
89   return block;
90 }
91