diff options
Diffstat (limited to 'src/lj_state.c')
-rw-r--r-- | src/lj_state.c | 43 |
1 files changed, 28 insertions, 15 deletions
diff --git a/src/lj_state.c b/src/lj_state.c index f8913519..632dd07e 100644 --- a/src/lj_state.c +++ b/src/lj_state.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include "lj_obj.h" | 12 | #include "lj_obj.h" |
13 | #include "lj_gc.h" | 13 | #include "lj_gc.h" |
14 | #include "lj_err.h" | 14 | #include "lj_err.h" |
15 | #include "lj_buf.h" | ||
15 | #include "lj_str.h" | 16 | #include "lj_str.h" |
16 | #include "lj_tab.h" | 17 | #include "lj_tab.h" |
17 | #include "lj_func.h" | 18 | #include "lj_func.h" |
@@ -26,6 +27,7 @@ | |||
26 | #include "lj_vm.h" | 27 | #include "lj_vm.h" |
27 | #include "lj_lex.h" | 28 | #include "lj_lex.h" |
28 | #include "lj_alloc.h" | 29 | #include "lj_alloc.h" |
30 | #include "luajit.h" | ||
29 | 31 | ||
30 | /* -- Stack handling ------------------------------------------------------ */ | 32 | /* -- Stack handling ------------------------------------------------------ */ |
31 | 33 | ||
@@ -47,6 +49,7 @@ | |||
47 | ** one extra slot if mobj is not a function. Only lj_meta_tset needs 5 | 49 | ** one extra slot if mobj is not a function. Only lj_meta_tset needs 5 |
48 | ** slots above top, but then mobj is always a function. So we can get by | 50 | ** slots above top, but then mobj is always a function. So we can get by |
49 | ** with 5 extra slots. | 51 | ** with 5 extra slots. |
52 | ** LJ_FR2: We need 2 more slots for the frame PC and the continuation PC. | ||
50 | */ | 53 | */ |
51 | 54 | ||
52 | /* Resize stack slots and adjust pointers in state. */ | 55 | /* Resize stack slots and adjust pointers in state. */ |
@@ -59,7 +62,7 @@ static void resizestack(lua_State *L, MSize n) | |||
59 | GCobj *up; | 62 | GCobj *up; |
60 | lua_assert((MSize)(tvref(L->maxstack)-oldst)==L->stacksize-LJ_STACK_EXTRA-1); | 63 | lua_assert((MSize)(tvref(L->maxstack)-oldst)==L->stacksize-LJ_STACK_EXTRA-1); |
61 | st = (TValue *)lj_mem_realloc(L, tvref(L->stack), | 64 | st = (TValue *)lj_mem_realloc(L, tvref(L->stack), |
62 | (MSize)(L->stacksize*sizeof(TValue)), | 65 | (MSize)(oldsize*sizeof(TValue)), |
63 | (MSize)(realsize*sizeof(TValue))); | 66 | (MSize)(realsize*sizeof(TValue))); |
64 | setmref(L->stack, st); | 67 | setmref(L->stack, st); |
65 | delta = (char *)st - (char *)oldst; | 68 | delta = (char *)st - (char *)oldst; |
@@ -67,12 +70,12 @@ static void resizestack(lua_State *L, MSize n) | |||
67 | while (oldsize < realsize) /* Clear new slots. */ | 70 | while (oldsize < realsize) /* Clear new slots. */ |
68 | setnilV(st + oldsize++); | 71 | setnilV(st + oldsize++); |
69 | L->stacksize = realsize; | 72 | L->stacksize = realsize; |
73 | if ((size_t)(mref(G(L)->jit_base, char) - (char *)oldst) < oldsize) | ||
74 | setmref(G(L)->jit_base, mref(G(L)->jit_base, char) + delta); | ||
70 | L->base = (TValue *)((char *)L->base + delta); | 75 | L->base = (TValue *)((char *)L->base + delta); |
71 | L->top = (TValue *)((char *)L->top + delta); | 76 | L->top = (TValue *)((char *)L->top + delta); |
72 | for (up = gcref(L->openupval); up != NULL; up = gcnext(up)) | 77 | for (up = gcref(L->openupval); up != NULL; up = gcnext(up)) |
73 | setmref(gco2uv(up)->v, (TValue *)((char *)uvval(gco2uv(up)) + delta)); | 78 | setmref(gco2uv(up)->v, (TValue *)((char *)uvval(gco2uv(up)) + delta)); |
74 | if (obj2gco(L) == gcref(G(L)->jit_L)) | ||
75 | setmref(G(L)->jit_base, mref(G(L)->jit_base, char) + delta); | ||
76 | } | 79 | } |
77 | 80 | ||
78 | /* Relimit stack after error, in case the limit was overdrawn. */ | 81 | /* Relimit stack after error, in case the limit was overdrawn. */ |
@@ -89,7 +92,8 @@ void lj_state_shrinkstack(lua_State *L, MSize used) | |||
89 | return; /* Avoid stack shrinking while handling stack overflow. */ | 92 | return; /* Avoid stack shrinking while handling stack overflow. */ |
90 | if (4*used < L->stacksize && | 93 | if (4*used < L->stacksize && |
91 | 2*(LJ_STACK_START+LJ_STACK_EXTRA) < L->stacksize && | 94 | 2*(LJ_STACK_START+LJ_STACK_EXTRA) < L->stacksize && |
92 | obj2gco(L) != gcref(G(L)->jit_L)) /* Don't shrink stack of live trace. */ | 95 | /* Don't shrink stack of live trace. */ |
96 | (tvref(G(L)->jit_base) == NULL || obj2gco(L) != gcref(G(L)->cur_L))) | ||
93 | resizestack(L, L->stacksize >> 1); | 97 | resizestack(L, L->stacksize >> 1); |
94 | } | 98 | } |
95 | 99 | ||
@@ -125,8 +129,9 @@ static void stack_init(lua_State *L1, lua_State *L) | |||
125 | L1->stacksize = LJ_STACK_START + LJ_STACK_EXTRA; | 129 | L1->stacksize = LJ_STACK_START + LJ_STACK_EXTRA; |
126 | stend = st + L1->stacksize; | 130 | stend = st + L1->stacksize; |
127 | setmref(L1->maxstack, stend - LJ_STACK_EXTRA - 1); | 131 | setmref(L1->maxstack, stend - LJ_STACK_EXTRA - 1); |
128 | L1->base = L1->top = st+1; | 132 | setthreadV(L1, st++, L1); /* Needed for curr_funcisL() on empty stack. */ |
129 | setthreadV(L1, st, L1); /* Needed for curr_funcisL() on empty stack. */ | 133 | if (LJ_FR2) setnilV(st++); |
134 | L1->base = L1->top = st; | ||
130 | while (st < stend) /* Clear new slots. */ | 135 | while (st < stend) /* Clear new slots. */ |
131 | setnilV(st++); | 136 | setnilV(st++); |
132 | } | 137 | } |
@@ -164,7 +169,7 @@ static void close_state(lua_State *L) | |||
164 | lj_ctype_freestate(g); | 169 | lj_ctype_freestate(g); |
165 | #endif | 170 | #endif |
166 | lj_mem_freevec(g, g->strhash, g->strmask+1, GCRef); | 171 | lj_mem_freevec(g, g->strhash, g->strmask+1, GCRef); |
167 | lj_str_freebuf(g, &g->tmpbuf); | 172 | lj_buf_free(g, &g->tmpbuf); |
168 | lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue); | 173 | lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue); |
169 | lua_assert(g->gc.total == sizeof(GG_State)); | 174 | lua_assert(g->gc.total == sizeof(GG_State)); |
170 | #ifndef LUAJIT_USE_SYSMALLOC | 175 | #ifndef LUAJIT_USE_SYSMALLOC |
@@ -175,7 +180,7 @@ static void close_state(lua_State *L) | |||
175 | g->allocf(g->allocd, G2GG(g), sizeof(GG_State), 0); | 180 | g->allocf(g->allocd, G2GG(g), sizeof(GG_State), 0); |
176 | } | 181 | } |
177 | 182 | ||
178 | #if LJ_64 && !(defined(LUAJIT_USE_VALGRIND) && defined(LUAJIT_USE_SYSMALLOC)) | 183 | #if LJ_64 && !LJ_GC64 && !(defined(LUAJIT_USE_VALGRIND) && defined(LUAJIT_USE_SYSMALLOC)) |
179 | lua_State *lj_state_newstate(lua_Alloc f, void *ud) | 184 | lua_State *lj_state_newstate(lua_Alloc f, void *ud) |
180 | #else | 185 | #else |
181 | LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud) | 186 | LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud) |
@@ -184,7 +189,7 @@ LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud) | |||
184 | GG_State *GG = (GG_State *)f(ud, NULL, 0, sizeof(GG_State)); | 189 | GG_State *GG = (GG_State *)f(ud, NULL, 0, sizeof(GG_State)); |
185 | lua_State *L = &GG->L; | 190 | lua_State *L = &GG->L; |
186 | global_State *g = &GG->g; | 191 | global_State *g = &GG->g; |
187 | if (GG == NULL || !checkptr32(GG)) return NULL; | 192 | if (GG == NULL || !checkptrGC(GG)) return NULL; |
188 | memset(GG, 0, sizeof(GG_State)); | 193 | memset(GG, 0, sizeof(GG_State)); |
189 | L->gct = ~LJ_TTHREAD; | 194 | L->gct = ~LJ_TTHREAD; |
190 | L->marked = LJ_GC_WHITE0 | LJ_GC_FIXED | LJ_GC_SFIXED; /* Prevent free. */ | 195 | L->marked = LJ_GC_WHITE0 | LJ_GC_FIXED | LJ_GC_SFIXED; /* Prevent free. */ |
@@ -202,8 +207,10 @@ LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud) | |||
202 | setnilV(registry(L)); | 207 | setnilV(registry(L)); |
203 | setnilV(&g->nilnode.val); | 208 | setnilV(&g->nilnode.val); |
204 | setnilV(&g->nilnode.key); | 209 | setnilV(&g->nilnode.key); |
210 | #if !LJ_GC64 | ||
205 | setmref(g->nilnode.freetop, &g->nilnode); | 211 | setmref(g->nilnode.freetop, &g->nilnode); |
206 | lj_str_initbuf(&g->tmpbuf); | 212 | #endif |
213 | lj_buf_init(NULL, &g->tmpbuf); | ||
207 | g->gc.state = GCSpause; | 214 | g->gc.state = GCSpause; |
208 | setgcref(g->gc.root, obj2gco(L)); | 215 | setgcref(g->gc.root, obj2gco(L)); |
209 | setmref(g->gc.sweep, &g->gc.root); | 216 | setmref(g->gc.sweep, &g->gc.root); |
@@ -217,7 +224,7 @@ LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud) | |||
217 | close_state(L); | 224 | close_state(L); |
218 | return NULL; | 225 | return NULL; |
219 | } | 226 | } |
220 | L->status = 0; | 227 | L->status = LUA_OK; |
221 | return L; | 228 | return L; |
222 | } | 229 | } |
223 | 230 | ||
@@ -236,6 +243,10 @@ LUA_API void lua_close(lua_State *L) | |||
236 | global_State *g = G(L); | 243 | global_State *g = G(L); |
237 | int i; | 244 | int i; |
238 | L = mainthread(g); /* Only the main thread can be closed. */ | 245 | L = mainthread(g); /* Only the main thread can be closed. */ |
246 | #if LJ_HASPROFILE | ||
247 | luaJIT_profile_stop(L); | ||
248 | #endif | ||
249 | setgcrefnull(g->cur_L); | ||
239 | lj_func_closeuv(L, tvref(L->stack)); | 250 | lj_func_closeuv(L, tvref(L->stack)); |
240 | lj_gc_separateudata(g, 1); /* Separate udata which have GC metamethods. */ | 251 | lj_gc_separateudata(g, 1); /* Separate udata which have GC metamethods. */ |
241 | #if LJ_HASJIT | 252 | #if LJ_HASJIT |
@@ -245,10 +256,10 @@ LUA_API void lua_close(lua_State *L) | |||
245 | #endif | 256 | #endif |
246 | for (i = 0;;) { | 257 | for (i = 0;;) { |
247 | hook_enter(g); | 258 | hook_enter(g); |
248 | L->status = 0; | 259 | L->status = LUA_OK; |
260 | L->base = L->top = tvref(L->stack) + 1 + LJ_FR2; | ||
249 | L->cframe = NULL; | 261 | L->cframe = NULL; |
250 | L->base = L->top = tvref(L->stack) + 1; | 262 | if (lj_vm_cpcall(L, NULL, NULL, cpfinalize) == LUA_OK) { |
251 | if (lj_vm_cpcall(L, NULL, NULL, cpfinalize) == 0) { | ||
252 | if (++i >= 10) break; | 263 | if (++i >= 10) break; |
253 | lj_gc_separateudata(g, 1); /* Separate udata again. */ | 264 | lj_gc_separateudata(g, 1); /* Separate udata again. */ |
254 | if (gcref(g->gc.mmudata) == NULL) /* Until nothing is left to do. */ | 265 | if (gcref(g->gc.mmudata) == NULL) /* Until nothing is left to do. */ |
@@ -263,7 +274,7 @@ lua_State *lj_state_new(lua_State *L) | |||
263 | lua_State *L1 = lj_mem_newobj(L, lua_State); | 274 | lua_State *L1 = lj_mem_newobj(L, lua_State); |
264 | L1->gct = ~LJ_TTHREAD; | 275 | L1->gct = ~LJ_TTHREAD; |
265 | L1->dummy_ffid = FF_C; | 276 | L1->dummy_ffid = FF_C; |
266 | L1->status = 0; | 277 | L1->status = LUA_OK; |
267 | L1->stacksize = 0; | 278 | L1->stacksize = 0; |
268 | setmref(L1->stack, NULL); | 279 | setmref(L1->stack, NULL); |
269 | L1->cframe = NULL; | 280 | L1->cframe = NULL; |
@@ -279,6 +290,8 @@ lua_State *lj_state_new(lua_State *L) | |||
279 | void LJ_FASTCALL lj_state_free(global_State *g, lua_State *L) | 290 | void LJ_FASTCALL lj_state_free(global_State *g, lua_State *L) |
280 | { | 291 | { |
281 | lua_assert(L != mainthread(g)); | 292 | lua_assert(L != mainthread(g)); |
293 | if (obj2gco(L) == gcref(g->cur_L)) | ||
294 | setgcrefnull(g->cur_L); | ||
282 | lj_func_closeuv(L, tvref(L->stack)); | 295 | lj_func_closeuv(L, tvref(L->stack)); |
283 | lua_assert(gcref(L->openupval) == NULL); | 296 | lua_assert(gcref(L->openupval) == NULL); |
284 | lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue); | 297 | lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue); |