aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/luajit-2.0/src/lj_cdata.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/luajit-2.0/src/lj_cdata.c')
-rw-r--r--libraries/luajit-2.0/src/lj_cdata.c284
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. */
21GCcdata *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. */
30GCcdata *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. */
54void 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
79TValue * 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. */
100CType *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
114collect_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. */
197static 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. */
209int 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. */
243void 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