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