diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/luajit-2.0/src/lj_cdata.c | 284 |
1 files changed, 0 insertions, 284 deletions
diff --git a/libraries/luajit-2.0/src/lj_cdata.c b/libraries/luajit-2.0/src/lj_cdata.c deleted file mode 100644 index 497b84e..0000000 --- a/libraries/luajit-2.0/src/lj_cdata.c +++ /dev/null | |||
@@ -1,284 +0,0 @@ | |||
1 | /* | ||
2 | ** C data management. | ||
3 | ** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h | ||
4 | */ | ||
5 | |||
6 | #include "lj_obj.h" | ||
7 | |||
8 | #if LJ_HASFFI | ||
9 | |||
10 | #include "lj_gc.h" | ||
11 | #include "lj_err.h" | ||
12 | #include "lj_str.h" | ||
13 | #include "lj_tab.h" | ||
14 | #include "lj_ctype.h" | ||
15 | #include "lj_cconv.h" | ||
16 | #include "lj_cdata.h" | ||
17 | |||
18 | /* -- C data allocation --------------------------------------------------- */ | ||
19 | |||
20 | /* Allocate a new C data object holding a reference to another object. */ | ||
21 | GCcdata *lj_cdata_newref(CTState *cts, const void *p, CTypeID id) | ||
22 | { | ||
23 | CTypeID refid = lj_ctype_intern(cts, CTINFO_REF(id), CTSIZE_PTR); | ||
24 | GCcdata *cd = lj_cdata_new(cts, refid, CTSIZE_PTR); | ||
25 | *(const void **)cdataptr(cd) = p; | ||
26 | return cd; | ||
27 | } | ||
28 | |||
29 | /* Allocate variable-sized or specially aligned C data object. */ | ||
30 | GCcdata *lj_cdata_newv(CTState *cts, CTypeID id, CTSize sz, CTSize align) | ||
31 | { | ||
32 | global_State *g; | ||
33 | MSize extra = sizeof(GCcdataVar) + sizeof(GCcdata) + | ||
34 | (align > CT_MEMALIGN ? (1u<<align) - (1u<<CT_MEMALIGN) : 0); | ||
35 | char *p = lj_mem_newt(cts->L, extra + sz, char); | ||
36 | uintptr_t adata = (uintptr_t)p + sizeof(GCcdataVar) + sizeof(GCcdata); | ||
37 | uintptr_t almask = (1u << align) - 1u; | ||
38 | GCcdata *cd = (GCcdata *)(((adata + almask) & ~almask) - sizeof(GCcdata)); | ||
39 | lua_assert((char *)cd - p < 65536); | ||
40 | cdatav(cd)->offset = (uint16_t)((char *)cd - p); | ||
41 | cdatav(cd)->extra = extra; | ||
42 | cdatav(cd)->len = sz; | ||
43 | g = cts->g; | ||
44 | setgcrefr(cd->nextgc, g->gc.root); | ||
45 | setgcref(g->gc.root, obj2gco(cd)); | ||
46 | newwhite(g, obj2gco(cd)); | ||
47 | cd->marked |= 0x80; | ||
48 | cd->gct = ~LJ_TCDATA; | ||
49 | cd->typeid = id; | ||
50 | return cd; | ||
51 | } | ||
52 | |||
53 | /* Free a C data object. */ | ||
54 | void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd) | ||
55 | { | ||
56 | if (LJ_UNLIKELY(cd->marked & LJ_GC_CDATA_FIN)) { | ||
57 | GCobj *root; | ||
58 | makewhite(g, obj2gco(cd)); | ||
59 | obj2gco(cd)->gch.marked |= LJ_GC_FINALIZED; | ||
60 | if ((root = gcref(g->gc.mmudata)) != NULL) { | ||
61 | setgcrefr(cd->nextgc, root->gch.nextgc); | ||
62 | setgcref(root->gch.nextgc, obj2gco(cd)); | ||
63 | setgcref(g->gc.mmudata, obj2gco(cd)); | ||
64 | } else { | ||
65 | setgcref(cd->nextgc, obj2gco(cd)); | ||
66 | setgcref(g->gc.mmudata, obj2gco(cd)); | ||
67 | } | ||
68 | } else if (LJ_LIKELY(!cdataisv(cd))) { | ||
69 | CType *ct = ctype_raw(ctype_ctsG(g), cd->typeid); | ||
70 | CTSize sz = ctype_hassize(ct->info) ? ct->size : CTSIZE_PTR; | ||
71 | lua_assert(ctype_hassize(ct->info) || ctype_isfunc(ct->info) || | ||
72 | ctype_isextern(ct->info)); | ||
73 | lj_mem_free(g, cd, sizeof(GCcdata) + sz); | ||
74 | } else { | ||
75 | lj_mem_free(g, memcdatav(cd), sizecdatav(cd)); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | TValue * LJ_FASTCALL lj_cdata_setfin(lua_State *L, GCcdata *cd) | ||
80 | { | ||
81 | global_State *g = G(L); | ||
82 | GCtab *t = ctype_ctsG(g)->finalizer; | ||
83 | if (gcref(t->metatable)) { | ||
84 | /* Add cdata to finalizer table, if still enabled. */ | ||
85 | TValue *tv, tmp; | ||
86 | setcdataV(L, &tmp, cd); | ||
87 | lj_gc_anybarriert(L, t); | ||
88 | tv = lj_tab_set(L, t, &tmp); | ||
89 | cd->marked |= LJ_GC_CDATA_FIN; | ||
90 | return tv; | ||
91 | } else { | ||
92 | /* Otherwise return dummy TValue. */ | ||
93 | return &g->tmptv; | ||
94 | } | ||
95 | } | ||
96 | |||
97 | /* -- C data indexing ----------------------------------------------------- */ | ||
98 | |||
99 | /* Index C data by a TValue. Return CType and pointer. */ | ||
100 | CType *lj_cdata_index(CTState *cts, GCcdata *cd, cTValue *key, uint8_t **pp, | ||
101 | CTInfo *qual) | ||
102 | { | ||
103 | uint8_t *p = (uint8_t *)cdataptr(cd); | ||
104 | CType *ct = ctype_get(cts, cd->typeid); | ||
105 | ptrdiff_t idx; | ||
106 | |||
107 | /* Resolve reference for cdata object. */ | ||
108 | if (ctype_isref(ct->info)) { | ||
109 | lua_assert(ct->size == CTSIZE_PTR); | ||
110 | p = *(uint8_t **)p; | ||
111 | ct = ctype_child(cts, ct); | ||
112 | } | ||
113 | |||
114 | collect_attrib: | ||
115 | /* Skip attributes and collect qualifiers. */ | ||
116 | while (ctype_isattrib(ct->info)) { | ||
117 | if (ctype_attrib(ct->info) == CTA_QUAL) *qual |= ct->size; | ||
118 | ct = ctype_child(cts, ct); | ||
119 | } | ||
120 | lua_assert(!ctype_isref(ct->info)); /* Interning rejects refs to refs. */ | ||
121 | |||
122 | if (tvisint(key)) { | ||
123 | idx = (ptrdiff_t)intV(key); | ||
124 | goto integer_key; | ||
125 | } else if (tvisnum(key)) { /* Numeric key. */ | ||
126 | idx = LJ_64 ? (ptrdiff_t)numV(key) : (ptrdiff_t)lj_num2int(numV(key)); | ||
127 | integer_key: | ||
128 | if (ctype_ispointer(ct->info)) { | ||
129 | CTSize sz = lj_ctype_size(cts, ctype_cid(ct->info)); /* Element size. */ | ||
130 | if (sz != CTSIZE_INVALID) { | ||
131 | if (ctype_isptr(ct->info)) { | ||
132 | p = (uint8_t *)cdata_getptr(p, ct->size); | ||
133 | } else if ((ct->info & (CTF_VECTOR|CTF_COMPLEX))) { | ||
134 | if ((ct->info & CTF_COMPLEX)) idx &= 1; | ||
135 | *qual |= CTF_CONST; /* Valarray elements are constant. */ | ||
136 | } | ||
137 | *pp = p + idx*(int32_t)sz; | ||
138 | return ct; | ||
139 | } | ||
140 | } | ||
141 | } else if (tviscdata(key)) { /* Integer cdata key. */ | ||
142 | GCcdata *cdk = cdataV(key); | ||
143 | CType *ctk = ctype_raw(cts, cdk->typeid); | ||
144 | if (ctype_isenum(ctk->info)) ctk = ctype_child(cts, ctk); | ||
145 | if (ctype_isinteger(ctk->info)) { | ||
146 | lj_cconv_ct_ct(cts, ctype_get(cts, CTID_INT_PSZ), ctk, | ||
147 | (uint8_t *)&idx, cdataptr(cdk), 0); | ||
148 | goto integer_key; | ||
149 | } | ||
150 | } else if (tvisstr(key)) { /* String key. */ | ||
151 | GCstr *name = strV(key); | ||
152 | if (ctype_isstruct(ct->info)) { | ||
153 | CTSize ofs; | ||
154 | CType *fct = lj_ctype_getfield(cts, ct, name, &ofs); | ||
155 | if (fct) { | ||
156 | *pp = p + ofs; | ||
157 | return fct; | ||
158 | } | ||
159 | } else if (ctype_iscomplex(ct->info)) { | ||
160 | if (name->len == 2) { | ||
161 | *qual |= CTF_CONST; /* Complex fields are constant. */ | ||
162 | if (strdata(name)[0] == 'r' && strdata(name)[1] == 'e') { | ||
163 | *pp = p; | ||
164 | return ct; | ||
165 | } else if (strdata(name)[0] == 'i' && strdata(name)[1] == 'm') { | ||
166 | *pp = p + (ct->size >> 1); | ||
167 | return ct; | ||
168 | } | ||
169 | } | ||
170 | } else if (cd->typeid == CTID_CTYPEID) { | ||
171 | /* Allow indexing a (pointer to) struct constructor to get constants. */ | ||
172 | CType *sct = ctype_raw(cts, *(CTypeID *)p); | ||
173 | if (ctype_isptr(sct->info)) | ||
174 | sct = ctype_rawchild(cts, sct); | ||
175 | if (ctype_isstruct(sct->info)) { | ||
176 | CTSize ofs; | ||
177 | CType *fct = lj_ctype_getfield(cts, sct, name, &ofs); | ||
178 | if (fct && ctype_isconstval(fct->info)) | ||
179 | return fct; | ||
180 | } | ||
181 | } | ||
182 | } | ||
183 | if (ctype_isptr(ct->info)) { /* Automatically perform '->'. */ | ||
184 | if (ctype_isstruct(ctype_rawchild(cts, ct)->info)) { | ||
185 | p = (uint8_t *)cdata_getptr(p, ct->size); | ||
186 | ct = ctype_child(cts, ct); | ||
187 | goto collect_attrib; | ||
188 | } | ||
189 | } | ||
190 | *qual |= 1; /* Lookup failed. */ | ||
191 | return ct; /* But return the resolved raw type. */ | ||
192 | } | ||
193 | |||
194 | /* -- C data getters ------------------------------------------------------ */ | ||
195 | |||
196 | /* Get constant value and convert to TValue. */ | ||
197 | static void cdata_getconst(CTState *cts, TValue *o, CType *ct) | ||
198 | { | ||
199 | CType *ctt = ctype_child(cts, ct); | ||
200 | lua_assert(ctype_isinteger(ctt->info) && ctt->size <= 4); | ||
201 | /* Constants are already zero-extended/sign-extended to 32 bits. */ | ||
202 | if ((ctt->info & CTF_UNSIGNED) && (int32_t)ct->size < 0) | ||
203 | setnumV(o, (lua_Number)(uint32_t)ct->size); | ||
204 | else | ||
205 | setintV(o, (int32_t)ct->size); | ||
206 | } | ||
207 | |||
208 | /* Get C data value and convert to TValue. */ | ||
209 | int lj_cdata_get(CTState *cts, CType *s, TValue *o, uint8_t *sp) | ||
210 | { | ||
211 | CTypeID sid; | ||
212 | |||
213 | if (ctype_isconstval(s->info)) { | ||
214 | cdata_getconst(cts, o, s); | ||
215 | return 0; /* No GC step needed. */ | ||
216 | } else if (ctype_isbitfield(s->info)) { | ||
217 | return lj_cconv_tv_bf(cts, s, o, sp); | ||
218 | } | ||
219 | |||
220 | /* Get child type of pointer/array/field. */ | ||
221 | lua_assert(ctype_ispointer(s->info) || ctype_isfield(s->info)); | ||
222 | sid = ctype_cid(s->info); | ||
223 | s = ctype_get(cts, sid); | ||
224 | |||
225 | /* Resolve reference for field. */ | ||
226 | if (ctype_isref(s->info)) { | ||
227 | lua_assert(s->size == CTSIZE_PTR); | ||
228 | sp = *(uint8_t **)sp; | ||
229 | sid = ctype_cid(s->info); | ||
230 | s = ctype_get(cts, sid); | ||
231 | } | ||
232 | |||
233 | /* Skip attributes and enums. */ | ||
234 | while (ctype_isattrib(s->info) || ctype_isenum(s->info)) | ||
235 | s = ctype_child(cts, s); | ||
236 | |||
237 | return lj_cconv_tv_ct(cts, s, sid, o, sp); | ||
238 | } | ||
239 | |||
240 | /* -- C data setters ------------------------------------------------------ */ | ||
241 | |||
242 | /* Convert TValue and set C data value. */ | ||
243 | void lj_cdata_set(CTState *cts, CType *d, uint8_t *dp, TValue *o, CTInfo qual) | ||
244 | { | ||
245 | if (ctype_isconstval(d->info)) { | ||
246 | goto err_const; | ||
247 | } else if (ctype_isbitfield(d->info)) { | ||
248 | if (((d->info|qual) & CTF_CONST)) goto err_const; | ||
249 | lj_cconv_bf_tv(cts, d, dp, o); | ||
250 | return; | ||
251 | } | ||
252 | |||
253 | /* Get child type of pointer/array/field. */ | ||
254 | lua_assert(ctype_ispointer(d->info) || ctype_isfield(d->info)); | ||
255 | d = ctype_child(cts, d); | ||
256 | |||
257 | /* Resolve reference for field. */ | ||
258 | if (ctype_isref(d->info)) { | ||
259 | lua_assert(d->size == CTSIZE_PTR); | ||
260 | dp = *(uint8_t **)dp; | ||
261 | d = ctype_child(cts, d); | ||
262 | } | ||
263 | |||
264 | /* Skip attributes and collect qualifiers. */ | ||
265 | for (;;) { | ||
266 | if (ctype_isattrib(d->info)) { | ||
267 | if (ctype_attrib(d->info) == CTA_QUAL) qual |= d->size; | ||
268 | } else { | ||
269 | break; | ||
270 | } | ||
271 | d = ctype_child(cts, d); | ||
272 | } | ||
273 | |||
274 | lua_assert(ctype_hassize(d->info) && !ctype_isvoid(d->info)); | ||
275 | |||
276 | if (((d->info|qual) & CTF_CONST)) { | ||
277 | err_const: | ||
278 | lj_err_caller(cts->L, LJ_ERR_FFI_WRCONST); | ||
279 | } | ||
280 | |||
281 | lj_cconv_ct_tv(cts, d, dp, o, 0); | ||
282 | } | ||
283 | |||
284 | #endif | ||