diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/luajit-2.0/src/lj_func.c | 184 |
1 files changed, 0 insertions, 184 deletions
diff --git a/libraries/luajit-2.0/src/lj_func.c b/libraries/luajit-2.0/src/lj_func.c deleted file mode 100644 index 97be0a2..0000000 --- a/libraries/luajit-2.0/src/lj_func.c +++ /dev/null | |||
@@ -1,184 +0,0 @@ | |||
1 | /* | ||
2 | ** Function handling (prototypes, functions and upvalues). | ||
3 | ** Copyright (C) 2005-2011 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_func_c | ||
10 | #define LUA_CORE | ||
11 | |||
12 | #include "lj_obj.h" | ||
13 | #include "lj_gc.h" | ||
14 | #include "lj_func.h" | ||
15 | #include "lj_trace.h" | ||
16 | #include "lj_vm.h" | ||
17 | |||
18 | /* -- Prototypes ---------------------------------------------------------- */ | ||
19 | |||
20 | void LJ_FASTCALL lj_func_freeproto(global_State *g, GCproto *pt) | ||
21 | { | ||
22 | lj_mem_free(g, pt, pt->sizept); | ||
23 | } | ||
24 | |||
25 | /* -- Upvalues ------------------------------------------------------------ */ | ||
26 | |||
27 | static void unlinkuv(GCupval *uv) | ||
28 | { | ||
29 | lua_assert(uvprev(uvnext(uv)) == uv && uvnext(uvprev(uv)) == uv); | ||
30 | setgcrefr(uvnext(uv)->prev, uv->prev); | ||
31 | setgcrefr(uvprev(uv)->next, uv->next); | ||
32 | } | ||
33 | |||
34 | /* Find existing open upvalue for a stack slot or create a new one. */ | ||
35 | static GCupval *func_finduv(lua_State *L, TValue *slot) | ||
36 | { | ||
37 | global_State *g = G(L); | ||
38 | GCRef *pp = &L->openupval; | ||
39 | GCupval *p; | ||
40 | GCupval *uv; | ||
41 | /* Search the sorted list of open upvalues. */ | ||
42 | while (gcref(*pp) != NULL && uvval((p = gco2uv(gcref(*pp)))) >= slot) { | ||
43 | lua_assert(!p->closed && uvval(p) != &p->tv); | ||
44 | if (uvval(p) == slot) { /* Found open upvalue pointing to same slot? */ | ||
45 | if (isdead(g, obj2gco(p))) /* Resurrect it, if it's dead. */ | ||
46 | flipwhite(obj2gco(p)); | ||
47 | return p; | ||
48 | } | ||
49 | pp = &p->nextgc; | ||
50 | } | ||
51 | /* No matching upvalue found. Create a new one. */ | ||
52 | uv = lj_mem_newt(L, sizeof(GCupval), GCupval); | ||
53 | newwhite(g, uv); | ||
54 | uv->gct = ~LJ_TUPVAL; | ||
55 | uv->closed = 0; /* Still open. */ | ||
56 | setmref(uv->v, slot); /* Pointing to the stack slot. */ | ||
57 | /* NOBARRIER: The GCupval is new (marked white) and open. */ | ||
58 | setgcrefr(uv->nextgc, *pp); /* Insert into sorted list of open upvalues. */ | ||
59 | setgcref(*pp, obj2gco(uv)); | ||
60 | setgcref(uv->prev, obj2gco(&g->uvhead)); /* Insert into GC list, too. */ | ||
61 | setgcrefr(uv->next, g->uvhead.next); | ||
62 | setgcref(uvnext(uv)->prev, obj2gco(uv)); | ||
63 | setgcref(g->uvhead.next, obj2gco(uv)); | ||
64 | lua_assert(uvprev(uvnext(uv)) == uv && uvnext(uvprev(uv)) == uv); | ||
65 | return uv; | ||
66 | } | ||
67 | |||
68 | /* Create an empty and closed upvalue. */ | ||
69 | static GCupval *func_emptyuv(lua_State *L) | ||
70 | { | ||
71 | GCupval *uv = (GCupval *)lj_mem_newgco(L, sizeof(GCupval)); | ||
72 | uv->gct = ~LJ_TUPVAL; | ||
73 | uv->closed = 1; | ||
74 | setnilV(&uv->tv); | ||
75 | setmref(uv->v, &uv->tv); | ||
76 | return uv; | ||
77 | } | ||
78 | |||
79 | /* Close all open upvalues pointing to some stack level or above. */ | ||
80 | void LJ_FASTCALL lj_func_closeuv(lua_State *L, TValue *level) | ||
81 | { | ||
82 | GCupval *uv; | ||
83 | global_State *g = G(L); | ||
84 | while (gcref(L->openupval) != NULL && | ||
85 | uvval((uv = gco2uv(gcref(L->openupval)))) >= level) { | ||
86 | GCobj *o = obj2gco(uv); | ||
87 | lua_assert(!isblack(o) && !uv->closed && uvval(uv) != &uv->tv); | ||
88 | setgcrefr(L->openupval, uv->nextgc); /* No longer in open list. */ | ||
89 | if (isdead(g, o)) { | ||
90 | lj_func_freeuv(g, uv); | ||
91 | } else { | ||
92 | unlinkuv(uv); | ||
93 | lj_gc_closeuv(g, uv); | ||
94 | } | ||
95 | } | ||
96 | } | ||
97 | |||
98 | void LJ_FASTCALL lj_func_freeuv(global_State *g, GCupval *uv) | ||
99 | { | ||
100 | if (!uv->closed) | ||
101 | unlinkuv(uv); | ||
102 | lj_mem_freet(g, uv); | ||
103 | } | ||
104 | |||
105 | /* -- Functions (closures) ------------------------------------------------ */ | ||
106 | |||
107 | GCfunc *lj_func_newC(lua_State *L, MSize nelems, GCtab *env) | ||
108 | { | ||
109 | GCfunc *fn = (GCfunc *)lj_mem_newgco(L, sizeCfunc(nelems)); | ||
110 | fn->c.gct = ~LJ_TFUNC; | ||
111 | fn->c.ffid = FF_C; | ||
112 | fn->c.nupvalues = (uint8_t)nelems; | ||
113 | /* NOBARRIER: The GCfunc is new (marked white). */ | ||
114 | setmref(fn->c.pc, &G(L)->bc_cfunc_ext); | ||
115 | setgcref(fn->c.env, obj2gco(env)); | ||
116 | return fn; | ||
117 | } | ||
118 | |||
119 | static GCfunc *func_newL(lua_State *L, GCproto *pt, GCtab *env) | ||
120 | { | ||
121 | uint32_t count; | ||
122 | GCfunc *fn = (GCfunc *)lj_mem_newgco(L, sizeLfunc((MSize)pt->sizeuv)); | ||
123 | fn->l.gct = ~LJ_TFUNC; | ||
124 | fn->l.ffid = FF_LUA; | ||
125 | fn->l.nupvalues = 0; /* Set to zero until upvalues are initialized. */ | ||
126 | /* NOBARRIER: Really a setgcref. But the GCfunc is new (marked white). */ | ||
127 | setmref(fn->l.pc, proto_bc(pt)); | ||
128 | setgcref(fn->l.env, obj2gco(env)); | ||
129 | /* Saturating 3 bit counter (0..7) for created closures. */ | ||
130 | count = (uint32_t)pt->flags + PROTO_CLCOUNT; | ||
131 | pt->flags = (uint8_t)(count - ((count >> PROTO_CLC_BITS) & PROTO_CLCOUNT)); | ||
132 | return fn; | ||
133 | } | ||
134 | |||
135 | /* Create a new Lua function with empty upvalues. */ | ||
136 | GCfunc *lj_func_newL_empty(lua_State *L, GCproto *pt, GCtab *env) | ||
137 | { | ||
138 | GCfunc *fn = func_newL(L, pt, env); | ||
139 | MSize i, nuv = pt->sizeuv; | ||
140 | /* NOBARRIER: The GCfunc is new (marked white). */ | ||
141 | for (i = 0; i < nuv; i++) { | ||
142 | GCupval *uv = func_emptyuv(L); | ||
143 | uv->dhash = (uint32_t)(uintptr_t)pt ^ ((uint32_t)proto_uv(pt)[i] << 24); | ||
144 | setgcref(fn->l.uvptr[i], obj2gco(uv)); | ||
145 | } | ||
146 | fn->l.nupvalues = (uint8_t)nuv; | ||
147 | return fn; | ||
148 | } | ||
149 | |||
150 | /* Do a GC check and create a new Lua function with inherited upvalues. */ | ||
151 | GCfunc *lj_func_newL_gc(lua_State *L, GCproto *pt, GCfuncL *parent) | ||
152 | { | ||
153 | GCfunc *fn; | ||
154 | GCRef *puv; | ||
155 | MSize i, nuv; | ||
156 | TValue *base; | ||
157 | lj_gc_check_fixtop(L); | ||
158 | fn = func_newL(L, pt, tabref(parent->env)); | ||
159 | /* NOBARRIER: The GCfunc is new (marked white). */ | ||
160 | puv = parent->uvptr; | ||
161 | nuv = pt->sizeuv; | ||
162 | base = L->base; | ||
163 | for (i = 0; i < nuv; i++) { | ||
164 | uint32_t v = proto_uv(pt)[i]; | ||
165 | GCupval *uv; | ||
166 | if ((v & 0x8000)) { | ||
167 | uv = func_finduv(L, base + (v & 0xff)); | ||
168 | uv->dhash = (uint32_t)(uintptr_t)mref(parent->pc, char) ^ (v << 24); | ||
169 | } else { | ||
170 | uv = &gcref(puv[v])->uv; | ||
171 | } | ||
172 | setgcref(fn->l.uvptr[i], obj2gco(uv)); | ||
173 | } | ||
174 | fn->l.nupvalues = (uint8_t)nuv; | ||
175 | return fn; | ||
176 | } | ||
177 | |||
178 | void LJ_FASTCALL lj_func_free(global_State *g, GCfunc *fn) | ||
179 | { | ||
180 | MSize size = isluafunc(fn) ? sizeLfunc((MSize)fn->l.nupvalues) : | ||
181 | sizeCfunc((MSize)fn->c.nupvalues); | ||
182 | lj_mem_free(g, fn, size); | ||
183 | } | ||
184 | |||