1*088332b5SXin Li /* 2*088332b5SXin Li ** $Id: lmem.h $ 3*088332b5SXin Li ** Interface to Memory Manager 4*088332b5SXin Li ** See Copyright Notice in lua.h 5*088332b5SXin Li */ 6*088332b5SXin Li 7*088332b5SXin Li #ifndef lmem_h 8*088332b5SXin Li #define lmem_h 9*088332b5SXin Li 10*088332b5SXin Li 11*088332b5SXin Li #include <stddef.h> 12*088332b5SXin Li 13*088332b5SXin Li #include "llimits.h" 14*088332b5SXin Li #include "lua.h" 15*088332b5SXin Li 16*088332b5SXin Li 17*088332b5SXin Li #define luaM_error(L) luaD_throw(L, LUA_ERRMEM) 18*088332b5SXin Li 19*088332b5SXin Li 20*088332b5SXin Li /* 21*088332b5SXin Li ** This macro tests whether it is safe to multiply 'n' by the size of 22*088332b5SXin Li ** type 't' without overflows. Because 'e' is always constant, it avoids 23*088332b5SXin Li ** the runtime division MAX_SIZET/(e). 24*088332b5SXin Li ** (The macro is somewhat complex to avoid warnings: The 'sizeof' 25*088332b5SXin Li ** comparison avoids a runtime comparison when overflow cannot occur. 26*088332b5SXin Li ** The compiler should be able to optimize the real test by itself, but 27*088332b5SXin Li ** when it does it, it may give a warning about "comparison is always 28*088332b5SXin Li ** false due to limited range of data type"; the +1 tricks the compiler, 29*088332b5SXin Li ** avoiding this warning but also this optimization.) 30*088332b5SXin Li */ 31*088332b5SXin Li #define luaM_testsize(n,e) \ 32*088332b5SXin Li (sizeof(n) >= sizeof(size_t) && cast_sizet((n)) + 1 > MAX_SIZET/(e)) 33*088332b5SXin Li 34*088332b5SXin Li #define luaM_checksize(L,n,e) \ 35*088332b5SXin Li (luaM_testsize(n,e) ? luaM_toobig(L) : cast_void(0)) 36*088332b5SXin Li 37*088332b5SXin Li 38*088332b5SXin Li /* 39*088332b5SXin Li ** Computes the minimum between 'n' and 'MAX_SIZET/sizeof(t)', so that 40*088332b5SXin Li ** the result is not larger than 'n' and cannot overflow a 'size_t' 41*088332b5SXin Li ** when multiplied by the size of type 't'. (Assumes that 'n' is an 42*088332b5SXin Li ** 'int' or 'unsigned int' and that 'int' is not larger than 'size_t'.) 43*088332b5SXin Li */ 44*088332b5SXin Li #define luaM_limitN(n,t) \ 45*088332b5SXin Li ((cast_sizet(n) <= MAX_SIZET/sizeof(t)) ? (n) : \ 46*088332b5SXin Li cast_uint((MAX_SIZET/sizeof(t)))) 47*088332b5SXin Li 48*088332b5SXin Li 49*088332b5SXin Li /* 50*088332b5SXin Li ** Arrays of chars do not need any test 51*088332b5SXin Li */ 52*088332b5SXin Li #define luaM_reallocvchar(L,b,on,n) \ 53*088332b5SXin Li cast_charp(luaM_saferealloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char))) 54*088332b5SXin Li 55*088332b5SXin Li #define luaM_freemem(L, b, s) luaM_free_(L, (b), (s)) 56*088332b5SXin Li #define luaM_free(L, b) luaM_free_(L, (b), sizeof(*(b))) 57*088332b5SXin Li #define luaM_freearray(L, b, n) luaM_free_(L, (b), (n)*sizeof(*(b))) 58*088332b5SXin Li 59*088332b5SXin Li #define luaM_new(L,t) cast(t*, luaM_malloc_(L, sizeof(t), 0)) 60*088332b5SXin Li #define luaM_newvector(L,n,t) cast(t*, luaM_malloc_(L, (n)*sizeof(t), 0)) 61*088332b5SXin Li #define luaM_newvectorchecked(L,n,t) \ 62*088332b5SXin Li (luaM_checksize(L,n,sizeof(t)), luaM_newvector(L,n,t)) 63*088332b5SXin Li 64*088332b5SXin Li #define luaM_newobject(L,tag,s) luaM_malloc_(L, (s), tag) 65*088332b5SXin Li 66*088332b5SXin Li #define luaM_growvector(L,v,nelems,size,t,limit,e) \ 67*088332b5SXin Li ((v)=cast(t *, luaM_growaux_(L,v,nelems,&(size),sizeof(t), \ 68*088332b5SXin Li luaM_limitN(limit,t),e))) 69*088332b5SXin Li 70*088332b5SXin Li #define luaM_reallocvector(L, v,oldn,n,t) \ 71*088332b5SXin Li (cast(t *, luaM_realloc_(L, v, cast_sizet(oldn) * sizeof(t), \ 72*088332b5SXin Li cast_sizet(n) * sizeof(t)))) 73*088332b5SXin Li 74*088332b5SXin Li #define luaM_shrinkvector(L,v,size,fs,t) \ 75*088332b5SXin Li ((v)=cast(t *, luaM_shrinkvector_(L, v, &(size), fs, sizeof(t)))) 76*088332b5SXin Li 77*088332b5SXin Li LUAI_FUNC l_noret luaM_toobig (lua_State *L); 78*088332b5SXin Li 79*088332b5SXin Li /* not to be called directly */ 80*088332b5SXin Li LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, 81*088332b5SXin Li size_t size); 82*088332b5SXin Li LUAI_FUNC void *luaM_saferealloc_ (lua_State *L, void *block, size_t oldsize, 83*088332b5SXin Li size_t size); 84*088332b5SXin Li LUAI_FUNC void luaM_free_ (lua_State *L, void *block, size_t osize); 85*088332b5SXin Li LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int nelems, 86*088332b5SXin Li int *size, int size_elem, int limit, 87*088332b5SXin Li const char *what); 88*088332b5SXin Li LUAI_FUNC void *luaM_shrinkvector_ (lua_State *L, void *block, int *nelem, 89*088332b5SXin Li int final_n, int size_elem); 90*088332b5SXin Li LUAI_FUNC void *luaM_malloc_ (lua_State *L, size_t size, int tag); 91*088332b5SXin Li 92*088332b5SXin Li #endif 93*088332b5SXin Li 94