1 | /* |
2 | ** State and stack handling. |
3 | ** Copyright (C) 2005-2014 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_str.h" |
16 | #include "lj_tab.h" |
17 | #include "lj_func.h" |
18 | #include "lj_meta.h" |
19 | #include "lj_state.h" |
20 | #include "lj_frame.h" |
21 | #if LJ_HASFFI |
22 | #include "lj_ctype.h" |
23 | #endif |
24 | #include "lj_trace.h" |
25 | #include "lj_dispatch.h" |
26 | #include "lj_vm.h" |
27 | #include "lj_lex.h" |
28 | #include "lj_alloc.h" |
29 | |
30 | /* -- Stack handling ------------------------------------------------------ */ |
31 | |
32 | /* Stack sizes. */ |
33 | #define LJ_STACK_MIN LUA_MINSTACK /* Min. stack size. */ |
34 | #define LJ_STACK_MAX LUAI_MAXSTACK /* Max. stack size. */ |
35 | #define LJ_STACK_START (2*LJ_STACK_MIN) /* Starting stack size. */ |
36 | #define LJ_STACK_MAXEX (LJ_STACK_MAX + 1 + LJ_STACK_EXTRA) |
37 | |
38 | /* Explanation of LJ_STACK_EXTRA: |
39 | ** |
40 | ** Calls to metamethods store their arguments beyond the current top |
41 | ** without checking for the stack limit. This avoids stack resizes which |
42 | ** would invalidate passed TValue pointers. The stack check is performed |
43 | ** later by the function header. This can safely resize the stack or raise |
44 | ** an error. Thus we need some extra slots beyond the current stack limit. |
45 | ** |
46 | ** Most metamethods need 4 slots above top (cont, mobj, arg1, arg2) plus |
47 | ** 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 |
49 | ** with 5 extra slots. |
50 | */ |
51 | |
52 | /* Resize stack slots and adjust pointers in state. */ |
53 | static void resizestack(lua_State *L, MSize n) |
54 | { |
55 | TValue *st, *oldst = tvref(L->stack); |
56 | ptrdiff_t delta; |
57 | MSize oldsize = L->stacksize; |
58 | MSize realsize = n + 1 + LJ_STACK_EXTRA; |
59 | GCobj *up; |
60 | lua_assert((MSize)(tvref(L->maxstack)-oldst)==L->stacksize-LJ_STACK_EXTRA-1); |
61 | st = (TValue *)lj_mem_realloc(L, tvref(L->stack), |
62 | (MSize)(L->stacksize*sizeof(TValue)), |
63 | (MSize)(realsize*sizeof(TValue))); |
64 | setmref(L->stack, st); |
65 | delta = (char *)st - (char *)oldst; |
66 | setmref(L->maxstack, st + n); |
67 | while (oldsize < realsize) /* Clear new slots. */ |
68 | setnilV(st + oldsize++); |
69 | L->stacksize = realsize; |
70 | L->base = (TValue *)((char *)L->base + delta); |
71 | L->top = (TValue *)((char *)L->top + delta); |
72 | for (up = gcref(L->openupval); up != NULL; up = gcnext(up)) |
73 | 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 | } |
77 | |
78 | /* Relimit stack after error, in case the limit was overdrawn. */ |
79 | void lj_state_relimitstack(lua_State *L) |
80 | { |
81 | if (L->stacksize > LJ_STACK_MAXEX && L->top-tvref(L->stack) < LJ_STACK_MAX-1) |
82 | resizestack(L, LJ_STACK_MAX); |
83 | } |
84 | |
85 | /* Try to shrink the stack (called from GC). */ |
86 | void lj_state_shrinkstack(lua_State *L, MSize used) |
87 | { |
88 | if (L->stacksize > LJ_STACK_MAXEX) |
89 | return; /* Avoid stack shrinking while handling stack overflow. */ |
90 | if (4*used < L->stacksize && |
91 | 2*(LJ_STACK_START+LJ_STACK_EXTRA) < L->stacksize && |
92 | obj2gco(L) != gcref(G(L)->jit_L)) /* Don't shrink stack of live trace. */ |
93 | resizestack(L, L->stacksize >> 1); |
94 | } |
95 | |
96 | /* Try to grow stack. */ |
97 | void LJ_FASTCALL lj_state_growstack(lua_State *L, MSize need) |
98 | { |
99 | MSize n; |
100 | if (L->stacksize > LJ_STACK_MAXEX) /* Overflow while handling overflow? */ |
101 | lj_err_throw(L, LUA_ERRERR); |
102 | n = L->stacksize + need; |
103 | if (n > LJ_STACK_MAX) { |
104 | n += 2*LUA_MINSTACK; |
105 | } else if (n < 2*L->stacksize) { |
106 | n = 2*L->stacksize; |
107 | if (n >= LJ_STACK_MAX) |
108 | n = LJ_STACK_MAX; |
109 | } |
110 | resizestack(L, n); |
111 | if (L->stacksize > LJ_STACK_MAXEX) |
112 | lj_err_msg(L, LJ_ERR_STKOV); |
113 | } |
114 | |
115 | void LJ_FASTCALL lj_state_growstack1(lua_State *L) |
116 | { |
117 | lj_state_growstack(L, 1); |
118 | } |
119 | |
120 | /* Allocate basic stack for new state. */ |
121 | static void stack_init(lua_State *L1, lua_State *L) |
122 | { |
123 | TValue *stend, *st = lj_mem_newvec(L, LJ_STACK_START+LJ_STACK_EXTRA, TValue); |
124 | setmref(L1->stack, st); |
125 | L1->stacksize = LJ_STACK_START + LJ_STACK_EXTRA; |
126 | stend = st + L1->stacksize; |
127 | setmref(L1->maxstack, stend - LJ_STACK_EXTRA - 1); |
128 | L1->base = L1->top = st+1; |
129 | setthreadV(L1, st, L1); /* Needed for curr_funcisL() on empty stack. */ |
130 | while (st < stend) /* Clear new slots. */ |
131 | setnilV(st++); |
132 | } |
133 | |
134 | /* -- State handling ------------------------------------------------------ */ |
135 | |
136 | /* Open parts that may cause memory-allocation errors. */ |
137 | static TValue *cpluaopen(lua_State *L, lua_CFunction dummy, void *ud) |
138 | { |
139 | global_State *g = G(L); |
140 | UNUSED(dummy); |
141 | UNUSED(ud); |
142 | stack_init(L, L); |
143 | /* NOBARRIER: State initialization, all objects are white. */ |
144 | setgcref(L->env, obj2gco(lj_tab_new(L, 0, LJ_MIN_GLOBAL))); |
145 | settabV(L, registry(L), lj_tab_new(L, 0, LJ_MIN_REGISTRY)); |
146 | lj_str_resize(L, LJ_MIN_STRTAB-1); |
147 | lj_meta_init(L); |
148 | lj_lex_init(L); |
149 | fixstring(lj_err_str(L, LJ_ERR_ERRMEM)); /* Preallocate memory error msg. */ |
150 | g->gc.threshold = 4*g->gc.total; |
151 | lj_trace_initstate(g); |
152 | return NULL; |
153 | } |
154 | |
155 | static void close_state(lua_State *L) |
156 | { |
157 | global_State *g = G(L); |
158 | lj_func_closeuv(L, tvref(L->stack)); |
159 | lj_gc_freeall(g); |
160 | lua_assert(gcref(g->gc.root) == obj2gco(L)); |
161 | lua_assert(g->strnum == 0); |
162 | lj_trace_freestate(g); |
163 | #if LJ_HASFFI |
164 | lj_ctype_freestate(g); |
165 | #endif |
166 | lj_mem_freevec(g, g->strhash, g->strmask+1, GCRef); |
167 | lj_str_freebuf(g, &g->tmpbuf); |
168 | lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue); |
169 | lua_assert(g->gc.total == sizeof(GG_State)); |
170 | #ifndef LUAJIT_USE_SYSMALLOC |
171 | if (g->allocf == lj_alloc_f) |
172 | lj_alloc_destroy(g->allocd); |
173 | else |
174 | #endif |
175 | g->allocf(g->allocd, G2GG(g), sizeof(GG_State), 0); |
176 | } |
177 | |
178 | #if LJ_64 |
179 | lua_State *lj_state_newstate(lua_Alloc f, void *ud) |
180 | #else |
181 | LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud) |
182 | #endif |
183 | { |
184 | GG_State *GG = (GG_State *)f(ud, NULL, 0, sizeof(GG_State)); |
185 | lua_State *L = &GG->L; |
186 | global_State *g = &GG->g; |
187 | if (GG == NULL || !checkptr32(GG)) return NULL; |
188 | memset(GG, 0, sizeof(GG_State)); |
189 | L->gct = ~LJ_TTHREAD; |
190 | L->marked = LJ_GC_WHITE0 | LJ_GC_FIXED | LJ_GC_SFIXED; /* Prevent free. */ |
191 | L->dummy_ffid = FF_C; |
192 | setmref(L->glref, g); |
193 | g->gc.currentwhite = LJ_GC_WHITE0 | LJ_GC_FIXED; |
194 | g->strempty.marked = LJ_GC_WHITE0; |
195 | g->strempty.gct = ~LJ_TSTR; |
196 | g->allocf = f; |
197 | g->allocd = ud; |
198 | setgcref(g->mainthref, obj2gco(L)); |
199 | setgcref(g->uvhead.prev, obj2gco(&g->uvhead)); |
200 | setgcref(g->uvhead.next, obj2gco(&g->uvhead)); |
201 | g->strmask = ~(MSize)0; |
202 | setnilV(registry(L)); |
203 | setnilV(&g->nilnode.val); |
204 | setnilV(&g->nilnode.key); |
205 | setmref(g->nilnode.freetop, &g->nilnode); |
206 | lj_str_initbuf(&g->tmpbuf); |
207 | g->gc.state = GCSpause; |
208 | setgcref(g->gc.root, obj2gco(L)); |
209 | setmref(g->gc.sweep, &g->gc.root); |
210 | g->gc.total = sizeof(GG_State); |
211 | g->gc.pause = LUAI_GCPAUSE; |
212 | g->gc.stepmul = LUAI_GCMUL; |
213 | lj_dispatch_init((GG_State *)L); |
214 | L->status = LUA_ERRERR+1; /* Avoid touching the stack upon memory error. */ |
215 | if (lj_vm_cpcall(L, NULL, NULL, cpluaopen) != 0) { |
216 | /* Memory allocation error: free partial state. */ |
217 | close_state(L); |
218 | return NULL; |
219 | } |
220 | L->status = 0; |
221 | return L; |
222 | } |
223 | |
224 | static TValue *cpfinalize(lua_State *L, lua_CFunction dummy, void *ud) |
225 | { |
226 | UNUSED(dummy); |
227 | UNUSED(ud); |
228 | lj_gc_finalize_cdata(L); |
229 | lj_gc_finalize_udata(L); |
230 | /* Frame pop omitted. */ |
231 | return NULL; |
232 | } |
233 | |
234 | LUA_API void lua_close(lua_State *L) |
235 | { |
236 | global_State *g = G(L); |
237 | int i; |
238 | L = mainthread(g); /* Only the main thread can be closed. */ |
239 | lj_func_closeuv(L, tvref(L->stack)); |
240 | lj_gc_separateudata(g, 1); /* Separate udata which have GC metamethods. */ |
241 | #if LJ_HASJIT |
242 | G2J(g)->flags &= ~JIT_F_ON; |
243 | G2J(g)->state = LJ_TRACE_IDLE; |
244 | lj_dispatch_update(g); |
245 | #endif |
246 | for (i = 0;;) { |
247 | hook_enter(g); |
248 | L->status = 0; |
249 | L->cframe = NULL; |
250 | L->base = L->top = tvref(L->stack) + 1; |
251 | if (lj_vm_cpcall(L, NULL, NULL, cpfinalize) == 0) { |
252 | if (++i >= 10) break; |
253 | lj_gc_separateudata(g, 1); /* Separate udata again. */ |
254 | if (gcref(g->gc.mmudata) == NULL) /* Until nothing is left to do. */ |
255 | break; |
256 | } |
257 | } |
258 | close_state(L); |
259 | } |
260 | |
261 | lua_State *lj_state_new(lua_State *L) |
262 | { |
263 | lua_State *L1 = lj_mem_newobj(L, lua_State); |
264 | L1->gct = ~LJ_TTHREAD; |
265 | L1->dummy_ffid = FF_C; |
266 | L1->status = 0; |
267 | L1->stacksize = 0; |
268 | setmref(L1->stack, NULL); |
269 | L1->cframe = NULL; |
270 | /* NOBARRIER: The lua_State is new (marked white). */ |
271 | setgcrefnull(L1->openupval); |
272 | setmrefr(L1->glref, L->glref); |
273 | setgcrefr(L1->env, L->env); |
274 | stack_init(L1, L); /* init stack */ |
275 | lua_assert(iswhite(obj2gco(L1))); |
276 | return L1; |
277 | } |
278 | |
279 | void LJ_FASTCALL lj_state_free(global_State *g, lua_State *L) |
280 | { |
281 | lua_assert(L != mainthread(g)); |
282 | lj_func_closeuv(L, tvref(L->stack)); |
283 | lua_assert(gcref(L->openupval) == NULL); |
284 | lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue); |
285 | lj_mem_freet(g, L); |
286 | } |
287 | |
288 | |