aboutsummaryrefslogtreecommitdiff
path: root/lmem.h
diff options
context:
space:
mode:
Diffstat (limited to 'lmem.h')
-rw-r--r--lmem.h53
1 files changed, 33 insertions, 20 deletions
diff --git a/lmem.h b/lmem.h
index 7af316f0..4ccb88ab 100644
--- a/lmem.h
+++ b/lmem.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lmem.h,v 1.42 2014/12/19 13:45:40 roberto Exp roberto $ 2** $Id: lmem.h,v 1.43 2014/12/19 17:26:14 roberto Exp roberto $
3** Interface to Memory Manager 3** Interface to Memory Manager
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -15,11 +15,9 @@
15 15
16 16
17/* 17/*
18** This macro reallocs a vector 'b' from 'on' to 'n' elements, where 18** This macro tests whether it is safe to multiply 'n' by the size of
19** each element has size 'e'. In case of arithmetic overflow of the 19** type 't' without overflows. Because 'e' is always constant, it avoids
20** product 'n'*'e', it raises an error (calling 'luaM_toobig'). Because 20** the runtime division MAX_SIZET/(e).
21** 'e' is always constant, it avoids the runtime division MAX_SIZET/(e).
22**
23** (The macro is somewhat complex to avoid warnings: The 'sizeof' 21** (The macro is somewhat complex to avoid warnings: The 'sizeof'
24** comparison avoids a runtime comparison when overflow cannot occur. 22** comparison avoids a runtime comparison when overflow cannot occur.
25** The compiler should be able to optimize the real test by itself, but 23** The compiler should be able to optimize the real test by itself, but
@@ -27,10 +25,20 @@
27** false due to limited range of data type"; the +1 tricks the compiler, 25** false due to limited range of data type"; the +1 tricks the compiler,
28** avoiding this warning but also this optimization.) 26** avoiding this warning but also this optimization.)
29*/ 27*/
28#define luaM_testsize(n,e) \
29 (sizeof(n) >= sizeof(size_t) && cast(size_t, (n)) + 1 > MAX_SIZET/(e))
30
31#define luaM_checksize(L,n,e) \
32 (luaM_testsize(n,e) ? luaM_toobig(L) : cast_void(0))
33
34/*
35** This macro reallocs a vector 'b' from 'on' to 'n' elements, where
36** each element has size 'e'. In case of arithmetic overflow of the
37** product 'n'*'e', it raises an error (calling 'luaM_toobig').
38*/
30#define luaM_reallocv(L,b,on,n,e) \ 39#define luaM_reallocv(L,b,on,n,e) \
31 (((sizeof(n) >= sizeof(size_t) && cast(size_t, (n)) + 1 > MAX_SIZET/(e)) \ 40 (luaM_checksize(L,n,e), \
32 ? luaM_toobig(L) : cast_void(0)) , \ 41 luaM_realloc_(L, (b), cast(size_t, on)*(e), cast(size_t, n)*(e)))
33 luaM_realloc_(L, (b), (on)*(e), (n)*(e)))
34 42
35/* 43/*
36** Arrays of chars do not need any test 44** Arrays of chars do not need any test
@@ -38,32 +46,37 @@
38#define luaM_reallocvchar(L,b,on,n) \ 46#define luaM_reallocvchar(L,b,on,n) \
39 cast(char *, luaM_realloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char))) 47 cast(char *, luaM_realloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char)))
40 48
41#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) 49#define luaM_freemem(L, b, s) luaM_free_(L, (b), (s))
42#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) 50#define luaM_free(L, b) luaM_free_(L, (b), sizeof(*(b)))
43#define luaM_freearray(L, b, n) luaM_realloc_(L, (b), (n)*sizeof(*(b)), 0) 51#define luaM_freearray(L, b, n) luaM_free_(L, (b), (n)*sizeof(*(b)))
44 52
45#define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s)) 53#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t), 0))
46#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t)))
47#define luaM_newvector(L,n,t) \ 54#define luaM_newvector(L,n,t) \
48 cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) 55 (luaM_checksize(L,n,sizeof(t)), cast(t *, luaM_malloc(L, (n)*sizeof(t), 0)))
49 56
50#define luaM_newobject(L,tag,s) luaM_realloc_(L, NULL, tag, (s)) 57#define luaM_newobject(L,tag,s) luaM_malloc(L, (s), tag)
51 58
52#define luaM_growvector(L,v,nelems,size,t,limit,e) \ 59#define luaM_growvector(L,v,nelems,size,t,limit,e) \
53 if ((nelems)+1 > (size)) \ 60 ((v)=cast(t *, luaM_growaux_(L,v,nelems,&(size),sizeof(t),limit,e)))
54 ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e)))
55 61
56#define luaM_reallocvector(L, v,oldn,n,t) \ 62#define luaM_reallocvector(L, v,oldn,n,t) \
57 ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) 63 ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
58 64
65#define luaM_shrinkvector(L,v,size,fs,t) \
66 ((v)=cast(t *, luaM_shrinkvector_(L, v, &(size), fs, sizeof(t))))
67
59LUAI_FUNC l_noret luaM_toobig (lua_State *L); 68LUAI_FUNC l_noret luaM_toobig (lua_State *L);
60 69
61/* not to be called directly */ 70/* not to be called directly */
62LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, 71LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
63 size_t size); 72 size_t size);
64LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, 73LUAI_FUNC void luaM_free_ (lua_State *L, void *block, size_t osize);
65 size_t size_elem, int limit, 74LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int nelems,
75 int *size, int size_elem, int limit,
66 const char *what); 76 const char *what);
77LUAI_FUNC void *luaM_shrinkvector_ (lua_State *L, void *block, int *nelem,
78 int final_n, int size_elem);
79LUAI_FUNC void *luaM_malloc (lua_State *L, size_t size, int tag);
67 80
68#endif 81#endif
69 82