rpm  4.5
lmem.c
Go to the documentation of this file.
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