1 | /* |
2 | ** State and stack handling. |
3 | ** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h |
4 | ** |
5 | ** Portions taken verbatim or adapted from the Lua interpreter. |
6 | ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h |
7 | */ |
8 | |
9 | #define lj_state_c |
10 | #define LUA_CORE |
11 | |
12 | #include "lj_obj.h" |
13 | #include "lj_gc.h" |
14 | #include "lj_err.h" |
15 | #include "lj_buf.h" |
16 | #include "lj_str.h" |
17 | #include "lj_tab.h" |
18 | #include "lj_func.h" |
19 | #include "lj_meta.h" |
20 | #include "lj_state.h" |
21 | #include "lj_frame.h" |
22 | #if LJ_HASFFI |
23 | #include "lj_ctype.h" |
24 | #endif |
25 | #include "lj_trace.h" |
26 | #include "lj_dispatch.h" |
27 | #include "lj_vm.h" |
28 | #include "lj_prng.h" |
29 | #include "lj_lex.h" |
30 | #include "lj_alloc.h" |
31 | #include "luajit.h" |
32 | |
33 | /* -- Stack handling ------------------------------------------------------ */ |
34 | |
35 | /* Stack sizes. */ |
36 | #define LJ_STACK_MIN LUA_MINSTACK /* Min. stack size. */ |
37 | #define LJ_STACK_MAX LUAI_MAXSTACK /* Max. stack size. */ |
38 | #define LJ_STACK_START (2*LJ_STACK_MIN) /* Starting stack size. */ |
39 | #define LJ_STACK_MAXEX (LJ_STACK_MAX + 1 + LJ_STACK_EXTRA) |
40 | |
41 | /* Explanation of LJ_STACK_EXTRA: |
42 | ** |
43 | ** Calls to metamethods store their arguments beyond the current top |
44 | ** without checking for the stack limit. This avoids stack resizes which |
45 | ** would invalidate passed TValue pointers. The stack check is performed |
46 | ** later by the function header. This can safely resize the stack or raise |
47 | ** an error. Thus we need some extra slots beyond the current stack limit. |
48 | ** |
49 | ** Most metamethods need 4 slots above top (cont, mobj, arg1, arg2) plus |
50 | ** one extra slot if mobj is not a function. Only lj_meta_tset needs 5 |
51 | ** slots above top, but then mobj is always a function. So we can get by |
52 | ** with 5 extra slots. |
53 | ** LJ_FR2: We need 2 more slots for the frame PC and the continuation PC. |
54 | */ |
55 | |
56 | /* Resize stack slots and adjust pointers in state. */ |
57 | static void resizestack(lua_State *L, MSize n) |
58 | { |
59 | TValue *st, *oldst = tvref(L->stack); |
60 | ptrdiff_t delta; |
61 | MSize oldsize = L->stacksize; |
62 | MSize realsize = n + 1 + LJ_STACK_EXTRA; |
63 | GCobj *up; |
64 | lj_assertL((MSize)(tvref(L->maxstack)-oldst) == L->stacksize-LJ_STACK_EXTRA-1, |
65 | "inconsistent stack size" ); |
66 | st = (TValue *)lj_mem_realloc(L, tvref(L->stack), |
67 | (MSize)(oldsize*sizeof(TValue)), |
68 | (MSize)(realsize*sizeof(TValue))); |
69 | setmref(L->stack, st); |
70 | delta = (char *)st - (char *)oldst; |
71 | setmref(L->maxstack, st + n); |
72 | while (oldsize < realsize) /* Clear new slots. */ |
73 | setnilV(st + oldsize++); |
74 | L->stacksize = realsize; |
75 | if ((size_t)(mref(G(L)->jit_base, char) - (char *)oldst) < oldsize) |
76 | setmref(G(L)->jit_base, mref(G(L)->jit_base, char) + delta); |
77 | L->base = (TValue *)((char *)L->base + delta); |
78 | L->top = (TValue *)((char *)L->top + delta); |
79 | for (up = gcref(L->openupval); up != NULL; up = gcnext(up)) |
80 | setmref(gco2uv(up)->v, (TValue *)((char *)uvval(gco2uv(up)) + delta)); |
81 | } |
82 | |
83 | /* Relimit stack after error, in case the limit was overdrawn. */ |
84 | void lj_state_relimitstack(lua_State *L) |
85 | { |
86 | if (L->stacksize > LJ_STACK_MAXEX && L->top-tvref(L->stack) < LJ_STACK_MAX-1) |
87 | resizestack(L, LJ_STACK_MAX); |
88 | } |
89 | |
90 | /* Try to shrink the stack (called from GC). */ |
91 | void lj_state_shrinkstack(lua_State *L, MSize used) |
92 | { |
93 | if (L->stacksize > LJ_STACK_MAXEX) |
94 | return; /* Avoid stack shrinking while handling stack overflow. */ |
95 | if (4*used < L->stacksize && |
96 | 2*(LJ_STACK_START+LJ_STACK_EXTRA) < L->stacksize && |
97 | /* Don't shrink stack of live trace. */ |
98 | (tvref(G(L)->jit_base) == NULL || obj2gco(L) != gcref(G(L)->cur_L))) |
99 | resizestack(L, L->stacksize >> 1); |
100 | } |
101 | |
102 | /* Try to grow stack. */ |
103 | void LJ_FASTCALL lj_state_growstack(lua_State *L, MSize need) |
104 | { |
105 | MSize n; |
106 | if (L->stacksize > LJ_STACK_MAXEX) /* Overflow while handling overflow? */ |
107 | lj_err_throw(L, LUA_ERRERR); |
108 | n = L->stacksize + need; |
109 | if (n > LJ_STACK_MAX) { |
110 | n += 2*LUA_MINSTACK; |
111 | } else if (n < 2*L->stacksize) { |
112 | n = 2*L->stacksize; |
113 | if (n >= LJ_STACK_MAX) |
114 | n = LJ_STACK_MAX; |
115 | } |
116 | resizestack(L, n); |
117 | if (L->stacksize > LJ_STACK_MAXEX) |
118 | lj_err_msg(L, LJ_ERR_STKOV); |
119 | } |
120 | |
121 | void LJ_FASTCALL lj_state_growstack1(lua_State *L) |
122 | { |
123 | lj_state_growstack(L, 1); |
124 | } |
125 | |
126 | /* Allocate basic stack for new state. */ |
127 | static void stack_init(lua_State *L1, lua_State *L) |
128 | { |
129 | TValue *stend, *st = lj_mem_newvec(L, LJ_STACK_START+LJ_STACK_EXTRA, TValue); |
130 | setmref(L1->stack, st); |
131 | L1->stacksize = LJ_STACK_START + LJ_STACK_EXTRA; |
132 | stend = st + L1->stacksize; |
133 | setmref(L1->maxstack, stend - LJ_STACK_EXTRA - 1); |
134 | setthreadV(L1, st++, L1); /* Needed for curr_funcisL() on empty stack. */ |
135 | if (LJ_FR2) setnilV(st++); |
136 | L1->base = L1->top = st; |
137 | while (st < stend) /* Clear new slots. */ |
138 | setnilV(st++); |
139 | } |
140 | |
141 | /* -- State handling ------------------------------------------------------ */ |
142 | |
143 | /* Open parts that may cause memory-allocation errors. */ |
144 | static TValue *cpluaopen(lua_State *L, lua_CFunction dummy, void *ud) |
145 | { |
146 | global_State *g = G(L); |
147 | UNUSED(dummy); |
148 | UNUSED(ud); |
149 | stack_init(L, L); |
150 | /* NOBARRIER: State initialization, all objects are white. */ |
151 | setgcref(L->env, obj2gco(lj_tab_new(L, 0, LJ_MIN_GLOBAL))); |
152 | settabV(L, registry(L), lj_tab_new(L, 0, LJ_MIN_REGISTRY)); |
153 | lj_str_init(L); |
154 | lj_meta_init(L); |
155 | lj_lex_init(L); |
156 | fixstring(lj_err_str(L, LJ_ERR_ERRMEM)); /* Preallocate memory error msg. */ |
157 | g->gc.threshold = 4*g->gc.total; |
158 | lj_trace_initstate(g); |
159 | lj_err_verify(); |
160 | return NULL; |
161 | } |
162 | |
163 | static void close_state(lua_State *L) |
164 | { |
165 | global_State *g = G(L); |
166 | lj_func_closeuv(L, tvref(L->stack)); |
167 | lj_gc_freeall(g); |
168 | lj_assertG(gcref(g->gc.root) == obj2gco(L), |
169 | "main thread is not first GC object" ); |
170 | lj_assertG(g->str.num == 0, "leaked %d strings" , g->str.num); |
171 | lj_trace_freestate(g); |
172 | #if LJ_HASFFI |
173 | lj_ctype_freestate(g); |
174 | #endif |
175 | lj_str_freetab(g); |
176 | lj_buf_free(g, &g->tmpbuf); |
177 | lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue); |
178 | #if LJ_64 |
179 | if (mref(g->gc.lightudseg, uint32_t)) { |
180 | MSize segnum = g->gc.lightudnum ? (2 << lj_fls(g->gc.lightudnum)) : 2; |
181 | lj_mem_freevec(g, mref(g->gc.lightudseg, uint32_t), segnum, uint32_t); |
182 | } |
183 | #endif |
184 | lj_assertG(g->gc.total == sizeof(GG_State), |
185 | "memory leak of %lld bytes" , |
186 | (long long)(g->gc.total - sizeof(GG_State))); |
187 | #ifndef LUAJIT_USE_SYSMALLOC |
188 | if (g->allocf == lj_alloc_f) |
189 | lj_alloc_destroy(g->allocd); |
190 | else |
191 | #endif |
192 | g->allocf(g->allocd, G2GG(g), sizeof(GG_State), 0); |
193 | } |
194 | |
195 | #if LJ_64 && !LJ_GC64 && !(defined(LUAJIT_USE_VALGRIND) && defined(LUAJIT_USE_SYSMALLOC)) |
196 | lua_State *lj_state_newstate(lua_Alloc allocf, void *allocd) |
197 | #else |
198 | LUA_API lua_State *lua_newstate(lua_Alloc allocf, void *allocd) |
199 | #endif |
200 | { |
201 | PRNGState prng; |
202 | GG_State *GG; |
203 | lua_State *L; |
204 | global_State *g; |
205 | /* We need the PRNG for the memory allocator, so initialize this first. */ |
206 | if (!lj_prng_seed_secure(&prng)) { |
207 | lj_assertX(0, "secure PRNG seeding failed" ); |
208 | /* Can only return NULL here, so this errors with "not enough memory". */ |
209 | return NULL; |
210 | } |
211 | #ifndef LUAJIT_USE_SYSMALLOC |
212 | if (allocf == LJ_ALLOCF_INTERNAL) { |
213 | allocd = lj_alloc_create(&prng); |
214 | if (!allocd) return NULL; |
215 | allocf = lj_alloc_f; |
216 | } |
217 | #endif |
218 | GG = (GG_State *)allocf(allocd, NULL, 0, sizeof(GG_State)); |
219 | if (GG == NULL || !checkptrGC(GG)) return NULL; |
220 | memset(GG, 0, sizeof(GG_State)); |
221 | L = &GG->L; |
222 | g = &GG->g; |
223 | L->gct = ~LJ_TTHREAD; |
224 | L->marked = LJ_GC_WHITE0 | LJ_GC_FIXED | LJ_GC_SFIXED; /* Prevent free. */ |
225 | L->dummy_ffid = FF_C; |
226 | setmref(L->glref, g); |
227 | g->gc.currentwhite = LJ_GC_WHITE0 | LJ_GC_FIXED; |
228 | g->strempty.marked = LJ_GC_WHITE0; |
229 | g->strempty.gct = ~LJ_TSTR; |
230 | g->allocf = allocf; |
231 | g->allocd = allocd; |
232 | g->prng = prng; |
233 | #ifndef LUAJIT_USE_SYSMALLOC |
234 | if (allocf == lj_alloc_f) { |
235 | lj_alloc_setprng(allocd, &g->prng); |
236 | } |
237 | #endif |
238 | setgcref(g->mainthref, obj2gco(L)); |
239 | setgcref(g->uvhead.prev, obj2gco(&g->uvhead)); |
240 | setgcref(g->uvhead.next, obj2gco(&g->uvhead)); |
241 | g->str.mask = ~(MSize)0; |
242 | setnilV(registry(L)); |
243 | setnilV(&g->nilnode.val); |
244 | setnilV(&g->nilnode.key); |
245 | #if !LJ_GC64 |
246 | setmref(g->nilnode.freetop, &g->nilnode); |
247 | #endif |
248 | lj_buf_init(NULL, &g->tmpbuf); |
249 | g->gc.state = GCSpause; |
250 | setgcref(g->gc.root, obj2gco(L)); |
251 | setmref(g->gc.sweep, &g->gc.root); |
252 | g->gc.total = sizeof(GG_State); |
253 | g->gc.pause = LUAI_GCPAUSE; |
254 | g->gc.stepmul = LUAI_GCMUL; |
255 | lj_dispatch_init((GG_State *)L); |
256 | L->status = LUA_ERRERR+1; /* Avoid touching the stack upon memory error. */ |
257 | if (lj_vm_cpcall(L, NULL, NULL, cpluaopen) != 0) { |
258 | /* Memory allocation error: free partial state. */ |
259 | close_state(L); |
260 | return NULL; |
261 | } |
262 | L->status = LUA_OK; |
263 | return L; |
264 | } |
265 | |
266 | static TValue *cpfinalize(lua_State *L, lua_CFunction dummy, void *ud) |
267 | { |
268 | UNUSED(dummy); |
269 | UNUSED(ud); |
270 | lj_gc_finalize_cdata(L); |
271 | lj_gc_finalize_udata(L); |
272 | /* Frame pop omitted. */ |
273 | return NULL; |
274 | } |
275 | |
276 | LUA_API void lua_close(lua_State *L) |
277 | { |
278 | global_State *g = G(L); |
279 | int i; |
280 | L = mainthread(g); /* Only the main thread can be closed. */ |
281 | #if LJ_HASPROFILE |
282 | luaJIT_profile_stop(L); |
283 | #endif |
284 | setgcrefnull(g->cur_L); |
285 | lj_func_closeuv(L, tvref(L->stack)); |
286 | lj_gc_separateudata(g, 1); /* Separate udata which have GC metamethods. */ |
287 | #if LJ_HASJIT |
288 | G2J(g)->flags &= ~JIT_F_ON; |
289 | G2J(g)->state = LJ_TRACE_IDLE; |
290 | lj_dispatch_update(g); |
291 | #endif |
292 | for (i = 0;;) { |
293 | hook_enter(g); |
294 | L->status = LUA_OK; |
295 | L->base = L->top = tvref(L->stack) + 1 + LJ_FR2; |
296 | L->cframe = NULL; |
297 | if (lj_vm_cpcall(L, NULL, NULL, cpfinalize) == LUA_OK) { |
298 | if (++i >= 10) break; |
299 | lj_gc_separateudata(g, 1); /* Separate udata again. */ |
300 | if (gcref(g->gc.mmudata) == NULL) /* Until nothing is left to do. */ |
301 | break; |
302 | } |
303 | } |
304 | close_state(L); |
305 | } |
306 | |
307 | lua_State *lj_state_new(lua_State *L) |
308 | { |
309 | lua_State *L1 = lj_mem_newobj(L, lua_State); |
310 | L1->gct = ~LJ_TTHREAD; |
311 | L1->dummy_ffid = FF_C; |
312 | L1->status = LUA_OK; |
313 | L1->stacksize = 0; |
314 | setmref(L1->stack, NULL); |
315 | L1->cframe = NULL; |
316 | /* NOBARRIER: The lua_State is new (marked white). */ |
317 | setgcrefnull(L1->openupval); |
318 | setmrefr(L1->glref, L->glref); |
319 | setgcrefr(L1->env, L->env); |
320 | stack_init(L1, L); /* init stack */ |
321 | lj_assertL(iswhite(obj2gco(L1)), "new thread object is not white" ); |
322 | return L1; |
323 | } |
324 | |
325 | void LJ_FASTCALL lj_state_free(global_State *g, lua_State *L) |
326 | { |
327 | lj_assertG(L != mainthread(g), "free of main thread" ); |
328 | if (obj2gco(L) == gcref(g->cur_L)) |
329 | setgcrefnull(g->cur_L); |
330 | lj_func_closeuv(L, tvref(L->stack)); |
331 | lj_assertG(gcref(L->openupval) == NULL, "stale open upvalues" ); |
332 | lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue); |
333 | lj_mem_freet(g, L); |
334 | } |
335 | |
336 | |