diff options
author | Li Jin <dragon-fly@qq.com> | 2021-03-03 21:31:01 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2021-03-03 21:33:37 +0800 |
commit | 1df786307c1983b8ce693e3916081a8bcd4e95ae (patch) | |
tree | 6c7aeb2198d825877fd3d179c394b7a5c1f06a17 /src/lua/lmem.c | |
parent | 66168b112b707172b9035edf8c1daed469781e06 (diff) | |
download | yuescript-1df786307c1983b8ce693e3916081a8bcd4e95ae.tar.gz yuescript-1df786307c1983b8ce693e3916081a8bcd4e95ae.tar.bz2 yuescript-1df786307c1983b8ce693e3916081a8bcd4e95ae.zip |
add new metatable syntax for issue #41, fix reusing local variable issue, update built-in Lua.
Diffstat (limited to 'src/lua/lmem.c')
-rw-r--r-- | src/lua/lmem.c | 33 |
1 files changed, 16 insertions, 17 deletions
diff --git a/src/lua/lmem.c b/src/lua/lmem.c index 43739bf..9029d58 100644 --- a/src/lua/lmem.c +++ b/src/lua/lmem.c | |||
@@ -24,12 +24,12 @@ | |||
24 | 24 | ||
25 | #if defined(EMERGENCYGCTESTS) | 25 | #if defined(EMERGENCYGCTESTS) |
26 | /* | 26 | /* |
27 | ** First allocation will fail whenever not building initial state | 27 | ** First allocation will fail whenever not building initial state. |
28 | ** and not shrinking a block. (This fail will trigger 'tryagain' and | 28 | ** (This fail will trigger 'tryagain' and a full GC cycle at every |
29 | ** a full GC cycle at every allocation.) | 29 | ** allocation.) |
30 | */ | 30 | */ |
31 | static void *firsttry (global_State *g, void *block, size_t os, size_t ns) { | 31 | static void *firsttry (global_State *g, void *block, size_t os, size_t ns) { |
32 | if (ttisnil(&g->nilvalue) && ns > os) | 32 | if (completestate(g) && ns > 0) /* frees never fail */ |
33 | return NULL; /* fail */ | 33 | return NULL; /* fail */ |
34 | else /* normal allocation */ | 34 | else /* normal allocation */ |
35 | return (*g->frealloc)(g->ud, block, os, ns); | 35 | return (*g->frealloc)(g->ud, block, os, ns); |
@@ -83,7 +83,7 @@ void *luaM_growaux_ (lua_State *L, void *block, int nelems, int *psize, | |||
83 | if (nelems + 1 <= size) /* does one extra element still fit? */ | 83 | if (nelems + 1 <= size) /* does one extra element still fit? */ |
84 | return block; /* nothing to be done */ | 84 | return block; /* nothing to be done */ |
85 | if (size >= limit / 2) { /* cannot double it? */ | 85 | if (size >= limit / 2) { /* cannot double it? */ |
86 | if (unlikely(size >= limit)) /* cannot grow even a little? */ | 86 | if (l_unlikely(size >= limit)) /* cannot grow even a little? */ |
87 | luaG_runerror(L, "too many %s (limit is %d)", what, limit); | 87 | luaG_runerror(L, "too many %s (limit is %d)", what, limit); |
88 | size = limit; /* still have at least one free place */ | 88 | size = limit; /* still have at least one free place */ |
89 | } | 89 | } |
@@ -138,15 +138,17 @@ void luaM_free_ (lua_State *L, void *block, size_t osize) { | |||
138 | 138 | ||
139 | 139 | ||
140 | /* | 140 | /* |
141 | ** In case of allocation fail, this function will call the GC to try | 141 | ** In case of allocation fail, this function will do an emergency |
142 | ** to free some memory and then try the allocation again. | 142 | ** collection to free some memory and then try the allocation again. |
143 | ** (It should not be called when shrinking a block, because then the | 143 | ** The GC should not be called while state is not fully built, as the |
144 | ** interpreter may be in the middle of a collection step.) | 144 | ** collector is not yet fully initialized. Also, it should not be called |
145 | ** when 'gcstopem' is true, because then the interpreter is in the | ||
146 | ** middle of a collection step. | ||
145 | */ | 147 | */ |
146 | static void *tryagain (lua_State *L, void *block, | 148 | static void *tryagain (lua_State *L, void *block, |
147 | size_t osize, size_t nsize) { | 149 | size_t osize, size_t nsize) { |
148 | global_State *g = G(L); | 150 | global_State *g = G(L); |
149 | if (ttisnil(&g->nilvalue)) { /* is state fully build? */ | 151 | if (completestate(g) && !g->gcstopem) { |
150 | luaC_fullgc(L, 1); /* try to free some memory... */ | 152 | luaC_fullgc(L, 1); /* try to free some memory... */ |
151 | return (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ | 153 | return (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ |
152 | } | 154 | } |
@@ -156,17 +158,14 @@ static void *tryagain (lua_State *L, void *block, | |||
156 | 158 | ||
157 | /* | 159 | /* |
158 | ** Generic allocation routine. | 160 | ** Generic allocation routine. |
159 | ** If allocation fails while shrinking a block, do not try again; the | ||
160 | ** GC shrinks some blocks and it is not reentrant. | ||
161 | */ | 161 | */ |
162 | void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { | 162 | void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { |
163 | void *newblock; | 163 | void *newblock; |
164 | global_State *g = G(L); | 164 | global_State *g = G(L); |
165 | lua_assert((osize == 0) == (block == NULL)); | 165 | lua_assert((osize == 0) == (block == NULL)); |
166 | newblock = firsttry(g, block, osize, nsize); | 166 | newblock = firsttry(g, block, osize, nsize); |
167 | if (unlikely(newblock == NULL && nsize > 0)) { | 167 | if (l_unlikely(newblock == NULL && nsize > 0)) { |
168 | if (nsize > osize) /* not shrinking a block? */ | 168 | newblock = tryagain(L, block, osize, nsize); |
169 | newblock = tryagain(L, block, osize, nsize); | ||
170 | if (newblock == NULL) /* still no memory? */ | 169 | if (newblock == NULL) /* still no memory? */ |
171 | return NULL; /* do not update 'GCdebt' */ | 170 | return NULL; /* do not update 'GCdebt' */ |
172 | } | 171 | } |
@@ -179,7 +178,7 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { | |||
179 | void *luaM_saferealloc_ (lua_State *L, void *block, size_t osize, | 178 | void *luaM_saferealloc_ (lua_State *L, void *block, size_t osize, |
180 | size_t nsize) { | 179 | size_t nsize) { |
181 | void *newblock = luaM_realloc_(L, block, osize, nsize); | 180 | void *newblock = luaM_realloc_(L, block, osize, nsize); |
182 | if (unlikely(newblock == NULL && nsize > 0)) /* allocation failed? */ | 181 | if (l_unlikely(newblock == NULL && nsize > 0)) /* allocation failed? */ |
183 | luaM_error(L); | 182 | luaM_error(L); |
184 | return newblock; | 183 | return newblock; |
185 | } | 184 | } |
@@ -191,7 +190,7 @@ void *luaM_malloc_ (lua_State *L, size_t size, int tag) { | |||
191 | else { | 190 | else { |
192 | global_State *g = G(L); | 191 | global_State *g = G(L); |
193 | void *newblock = firsttry(g, NULL, tag, size); | 192 | void *newblock = firsttry(g, NULL, tag, size); |
194 | if (unlikely(newblock == NULL)) { | 193 | if (l_unlikely(newblock == NULL)) { |
195 | newblock = tryagain(L, NULL, tag, size); | 194 | newblock = tryagain(L, NULL, tag, size); |
196 | if (newblock == NULL) | 195 | if (newblock == NULL) |
197 | luaM_error(L); | 196 | luaM_error(L); |