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