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); |
