2 ** State and stack handling.
3 ** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
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
25 #include "lj_dispatch.h"
30 /* -- Stack handling ------------------------------------------------------ */
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)
38 /* Explanation of LJ_STACK_EXTRA:
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.
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.
52 /* Resize stack slots and adjust pointers in state. */
53 static void resizestack(lua_State
*L
, MSize n
)
55 TValue
*st
, *oldst
= tvref(L
->stack
);
57 MSize oldsize
= L
->stacksize
;
58 MSize realsize
= n
+ 1 + LJ_STACK_EXTRA
;
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
);
78 /* Relimit stack after error, in case the limit was overdrawn. */
79 void lj_state_relimitstack(lua_State
*L
)
81 if (L
->stacksize
> LJ_STACK_MAXEX
&& L
->top
-tvref(L
->stack
) < LJ_STACK_MAX
-1)
82 resizestack(L
, LJ_STACK_MAX
);
85 /* Try to shrink the stack (called from GC). */
86 void lj_state_shrinkstack(lua_State
*L
, MSize used
)
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);
96 /* Try to grow stack. */
97 void LJ_FASTCALL
lj_state_growstack(lua_State
*L
, MSize need
)
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
) {
105 } else if (n
< 2*L
->stacksize
) {
107 if (n
>= LJ_STACK_MAX
)
111 if (L
->stacksize
> LJ_STACK_MAXEX
)
112 lj_err_msg(L
, LJ_ERR_STKOV
);
115 void LJ_FASTCALL
lj_state_growstack1(lua_State
*L
)
117 lj_state_growstack(L
, 1);
120 /* Allocate basic stack for new state. */
121 static void stack_init(lua_State
*L1
, lua_State
*L
)
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. */
134 /* -- State handling ------------------------------------------------------ */
136 /* Open parts that may cause memory-allocation errors. */
137 static TValue
*cpluaopen(lua_State
*L
, lua_CFunction dummy
, void *ud
)
139 global_State
*g
= G(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);
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
);
155 static void close_state(lua_State
*L
)
157 global_State
*g
= G(L
);
158 lj_func_closeuv(L
, tvref(L
->stack
));
160 lua_assert(gcref(g
->gc
.root
) == obj2gco(L
));
161 lua_assert(g
->strnum
== 0);
162 lj_trace_freestate(g
);
164 lj_ctype_freestate(g
);
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
);
175 g
->allocf(g
->allocd
, G2GG(g
), sizeof(GG_State
), 0);
178 #if LJ_64 && !(defined(LUAJIT_USE_VALGRIND) && defined(LUAJIT_USE_SYSMALLOC))
179 lua_State
*lj_state_newstate(lua_Alloc f
, void *ud
)
181 LUA_API lua_State
*lua_newstate(lua_Alloc f
, void *ud
)
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
;
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. */
224 static TValue
*cpfinalize(lua_State
*L
, lua_CFunction dummy
, void *ud
)
228 lj_gc_finalize_cdata(L
);
229 lj_gc_finalize_udata(L
);
230 /* Frame pop omitted. */
234 LUA_API
void lua_close(lua_State
*L
)
236 global_State
*g
= G(L
);
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. */
242 G2J(g
)->flags
&= ~JIT_F_ON
;
243 G2J(g
)->state
= LJ_TRACE_IDLE
;
244 lj_dispatch_update(g
);
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. */
261 lua_State
*lj_state_new(lua_State
*L
)
263 lua_State
*L1
= lj_mem_newobj(L
, lua_State
);
264 L1
->gct
= ~LJ_TTHREAD
;
265 L1
->dummy_ffid
= FF_C
;
268 setmref(L1
->stack
, 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
)));
279 void LJ_FASTCALL
lj_state_free(global_State
*g
, lua_State
*L
)
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
);