rlm@1
|
1 /*
|
rlm@1
|
2 ** $Id: lmem.c,v 1.70.1.1 2007/12/27 13:02:25 roberto Exp $
|
rlm@1
|
3 ** Interface to Memory Manager
|
rlm@1
|
4 ** See Copyright Notice in lua.h
|
rlm@1
|
5 */
|
rlm@1
|
6
|
rlm@1
|
7
|
rlm@1
|
8 #include <stddef.h>
|
rlm@1
|
9
|
rlm@1
|
10 #define lmem_c
|
rlm@1
|
11 #define LUA_CORE
|
rlm@1
|
12
|
rlm@1
|
13 #include "lua.h"
|
rlm@1
|
14
|
rlm@1
|
15 #include "ldebug.h"
|
rlm@1
|
16 #include "ldo.h"
|
rlm@1
|
17 #include "lmem.h"
|
rlm@1
|
18 #include "lobject.h"
|
rlm@1
|
19 #include "lstate.h"
|
rlm@1
|
20
|
rlm@1
|
21
|
rlm@1
|
22
|
rlm@1
|
23 /*
|
rlm@1
|
24 ** About the realloc function:
|
rlm@1
|
25 ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
|
rlm@1
|
26 ** (`osize' is the old size, `nsize' is the new size)
|
rlm@1
|
27 **
|
rlm@1
|
28 ** Lua ensures that (ptr == NULL) iff (osize == 0).
|
rlm@1
|
29 **
|
rlm@1
|
30 ** * frealloc(ud, NULL, 0, x) creates a new block of size `x'
|
rlm@1
|
31 **
|
rlm@1
|
32 ** * frealloc(ud, p, x, 0) frees the block `p'
|
rlm@1
|
33 ** (in this specific case, frealloc must return NULL).
|
rlm@1
|
34 ** particularly, frealloc(ud, NULL, 0, 0) does nothing
|
rlm@1
|
35 ** (which is equivalent to free(NULL) in ANSI C)
|
rlm@1
|
36 **
|
rlm@1
|
37 ** frealloc returns NULL if it cannot create or reallocate the area
|
rlm@1
|
38 ** (any reallocation to an equal or smaller size cannot fail!)
|
rlm@1
|
39 */
|
rlm@1
|
40
|
rlm@1
|
41
|
rlm@1
|
42
|
rlm@1
|
43 #define MINSIZEARRAY 4
|
rlm@1
|
44
|
rlm@1
|
45
|
rlm@1
|
46 void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
|
rlm@1
|
47 int limit, const char *errormsg) {
|
rlm@1
|
48 void *newblock;
|
rlm@1
|
49 int newsize;
|
rlm@1
|
50 if (*size >= limit/2) { /* cannot double it? */
|
rlm@1
|
51 if (*size >= limit) /* cannot grow even a little? */
|
rlm@1
|
52 luaG_runerror(L, errormsg);
|
rlm@1
|
53 newsize = limit; /* still have at least one free place */
|
rlm@1
|
54 }
|
rlm@1
|
55 else {
|
rlm@1
|
56 newsize = (*size)*2;
|
rlm@1
|
57 if (newsize < MINSIZEARRAY)
|
rlm@1
|
58 newsize = MINSIZEARRAY; /* minimum size */
|
rlm@1
|
59 }
|
rlm@1
|
60 newblock = luaM_reallocv(L, block, *size, newsize, size_elems);
|
rlm@1
|
61 *size = newsize; /* update only when everything else is OK */
|
rlm@1
|
62 return newblock;
|
rlm@1
|
63 }
|
rlm@1
|
64
|
rlm@1
|
65
|
rlm@1
|
66 void *luaM_toobig (lua_State *L) {
|
rlm@1
|
67 luaG_runerror(L, "memory allocation error: block too big");
|
rlm@1
|
68 return NULL; /* to avoid warnings */
|
rlm@1
|
69 }
|
rlm@1
|
70
|
rlm@1
|
71
|
rlm@1
|
72
|
rlm@1
|
73 /*
|
rlm@1
|
74 ** generic allocation routine.
|
rlm@1
|
75 */
|
rlm@1
|
76 void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
|
rlm@1
|
77 global_State *g = G(L);
|
rlm@1
|
78 lua_assert((osize == 0) == (block == NULL));
|
rlm@1
|
79 block = (*g->frealloc)(g->ud, block, osize, nsize);
|
rlm@1
|
80 if (block == NULL && nsize > 0)
|
rlm@1
|
81 luaD_throw(L, LUA_ERRMEM);
|
rlm@1
|
82 lua_assert((nsize == 0) == (block == NULL));
|
rlm@1
|
83 g->totalbytes = (g->totalbytes - osize) + nsize;
|
rlm@1
|
84 return block;
|
rlm@1
|
85 }
|
rlm@1
|
86
|