diff options
author | Mike Pall <mike> | 2010-12-05 00:43:47 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2010-12-05 00:52:17 +0100 |
commit | 7cb250c4b4a22e834746ede4f00a72d7ccc09009 (patch) | |
tree | 2ce638e2d7312d2220574ac95aabcab02bff37a0 /src | |
parent | 513b0ba18f003a3e6c666f0b2d422d3553fdbfcb (diff) | |
download | luajit-7cb250c4b4a22e834746ede4f00a72d7ccc09009.tar.gz luajit-7cb250c4b4a22e834746ede4f00a72d7ccc09009.tar.bz2 luajit-7cb250c4b4a22e834746ede4f00a72d7ccc09009.zip |
FFI: Add ffi.* library.
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 2 | ||||
-rw-r--r-- | src/Makefile.dep | 8 | ||||
-rw-r--r-- | src/lib_ffi.c | 374 | ||||
-rw-r--r-- | src/lib_init.c | 5 | ||||
-rw-r--r-- | src/ljamalg.c | 1 | ||||
-rw-r--r-- | src/lualib.h | 2 | ||||
-rw-r--r-- | src/msvcbuild.bat | 2 |
7 files changed, 390 insertions, 4 deletions
diff --git a/src/Makefile b/src/Makefile index 6e72d16b..ed9d3303 100644 --- a/src/Makefile +++ b/src/Makefile | |||
@@ -317,7 +317,7 @@ LJVM_BOUT= $(LJVM_S) | |||
317 | LJVM_MODE= elfasm | 317 | LJVM_MODE= elfasm |
318 | 318 | ||
319 | LJLIB_O= lib_base.o lib_math.o lib_bit.o lib_string.o lib_table.o \ | 319 | LJLIB_O= lib_base.o lib_math.o lib_bit.o lib_string.o lib_table.o \ |
320 | lib_io.o lib_os.o lib_package.o lib_debug.o lib_jit.o | 320 | lib_io.o lib_os.o lib_package.o lib_debug.o lib_jit.o lib_ffi.o |
321 | LJLIB_C= $(LJLIB_O:.o=.c) | 321 | LJLIB_C= $(LJLIB_O:.o=.c) |
322 | 322 | ||
323 | LJCORE_O= lj_gc.o lj_err.o lj_char.o lj_bc.o lj_obj.o \ | 323 | LJCORE_O= lj_gc.o lj_err.o lj_char.o lj_bc.o lj_obj.o \ |
diff --git a/src/Makefile.dep b/src/Makefile.dep index 75d71afb..145438db 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep | |||
@@ -20,7 +20,10 @@ lib_bit.o: lib_bit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \ | |||
20 | lj_arch.h lj_err.h lj_errmsg.h lj_str.h lj_lib.h lj_libdef.h | 20 | lj_arch.h lj_err.h lj_errmsg.h lj_str.h lj_lib.h lj_libdef.h |
21 | lib_debug.o: lib_debug.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ | 21 | lib_debug.o: lib_debug.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ |
22 | lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_lib.h lj_libdef.h | 22 | lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_lib.h lj_libdef.h |
23 | lib_init.o: lib_init.c lua.h luaconf.h lauxlib.h lualib.h | 23 | lib_ffi.o: lib_ffi.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \ |
24 | lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_ctype.h lj_cparse.h \ | ||
25 | lj_cdata.h lj_cconv.h lj_lib.h lj_libdef.h | ||
26 | lib_init.o: lib_init.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h | ||
24 | lib_io.o: lib_io.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \ | 27 | lib_io.o: lib_io.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \ |
25 | lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_ff.h lj_ffdef.h \ | 28 | lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_ff.h lj_ffdef.h \ |
26 | lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_lib.h \ | 29 | lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_lib.h \ |
@@ -148,5 +151,6 @@ ljamalg.o: ljamalg.c lua.h luaconf.h lauxlib.h lj_gc.c lj_obj.h lj_def.h \ | |||
148 | lj_target_*.h lj_record.c lj_record.h lj_asm.h lj_recdef.h lj_asm.c \ | 151 | lj_target_*.h lj_record.c lj_record.h lj_asm.h lj_recdef.h lj_asm.c \ |
149 | lj_trace.c lj_gdbjit.h lj_gdbjit.c lj_alloc.c lib_aux.c lib_base.c \ | 152 | lj_trace.c lj_gdbjit.h lj_gdbjit.c lj_alloc.c lib_aux.c lib_base.c \ |
150 | lualib.h lj_libdef.h lib_math.c lib_string.c lib_table.c lib_io.c \ | 153 | lualib.h lj_libdef.h lib_math.c lib_string.c lib_table.c lib_io.c \ |
151 | lib_os.c lib_package.c lib_debug.c lib_bit.c lib_jit.c lib_init.c | 154 | lib_os.c lib_package.c lib_debug.c lib_bit.c lib_jit.c lib_ffi.c \ |
155 | lib_init.c | ||
152 | luajit.o: luajit.c lua.h luaconf.h lauxlib.h lualib.h luajit.h lj_arch.h | 156 | luajit.o: luajit.c lua.h luaconf.h lauxlib.h lualib.h luajit.h lj_arch.h |
diff --git a/src/lib_ffi.c b/src/lib_ffi.c new file mode 100644 index 00000000..70d4c4a3 --- /dev/null +++ b/src/lib_ffi.c | |||
@@ -0,0 +1,374 @@ | |||
1 | /* | ||
2 | ** FFI library. | ||
3 | ** Copyright (C) 2005-2010 Mike Pall. See Copyright Notice in luajit.h | ||
4 | */ | ||
5 | |||
6 | #define lib_ffi_c | ||
7 | #define LUA_LIB | ||
8 | |||
9 | #include "lua.h" | ||
10 | #include "lauxlib.h" | ||
11 | #include "lualib.h" | ||
12 | |||
13 | #include "lj_obj.h" | ||
14 | |||
15 | #if LJ_HASFFI | ||
16 | |||
17 | #include "lj_gc.h" | ||
18 | #include "lj_err.h" | ||
19 | #include "lj_str.h" | ||
20 | #include "lj_ctype.h" | ||
21 | #include "lj_cparse.h" | ||
22 | #include "lj_cdata.h" | ||
23 | #include "lj_cconv.h" | ||
24 | #include "lj_lib.h" | ||
25 | |||
26 | /* -- C type checks ------------------------------------------------------- */ | ||
27 | |||
28 | /* Check first argument for a C type and returns its ID. */ | ||
29 | static CTypeID ffi_checkctype(lua_State *L, CTState *cts) | ||
30 | { | ||
31 | TValue *o = L->base; | ||
32 | if (!(o < L->top)) { | ||
33 | err_argtype: | ||
34 | lj_err_argtype(L, 1, "C type"); | ||
35 | } | ||
36 | if (tvisstr(o)) { /* Parse an abstract C type declaration. */ | ||
37 | GCstr *s = strV(o); | ||
38 | CPState cp; | ||
39 | int errcode; | ||
40 | cp.L = L; | ||
41 | cp.cts = cts; | ||
42 | cp.srcname = strdata(s); | ||
43 | cp.p = strdata(s); | ||
44 | cp.mode = CPARSE_MODE_ABSTRACT|CPARSE_MODE_NOIMPLICIT; | ||
45 | errcode = lj_cparse(&cp); | ||
46 | if (errcode) lj_err_throw(L, errcode); /* Propagate errors. */ | ||
47 | return cp.val.id; | ||
48 | } else { | ||
49 | GCcdata *cd; | ||
50 | if (!tviscdata(o)) goto err_argtype; | ||
51 | cd = cdataV(o); | ||
52 | return cd->typeid == CTID_CTYPEID ? *(CTypeID *)cdataptr(cd) : cd->typeid; | ||
53 | } | ||
54 | } | ||
55 | |||
56 | /* Check argument for C data and return it. */ | ||
57 | static GCcdata *ffi_checkcdata(lua_State *L, int narg) | ||
58 | { | ||
59 | TValue *o = L->base + narg-1; | ||
60 | if (!(o < L->top && tviscdata(o))) | ||
61 | lj_err_argt(L, narg, LUA_TCDATA); | ||
62 | return cdataV(o); | ||
63 | } | ||
64 | |||
65 | /* Convert argument to C pointer. */ | ||
66 | static void *ffi_checkptr(lua_State *L, int narg, CTypeID id) | ||
67 | { | ||
68 | CTState *cts = ctype_cts(L); | ||
69 | TValue *o = L->base + narg-1; | ||
70 | void *p; | ||
71 | if (o >= L->top) | ||
72 | lj_err_arg(L, narg, LJ_ERR_NOVAL); | ||
73 | lj_cconv_ct_tv(cts, ctype_get(cts, id), (uint8_t *)&p, o, 0); | ||
74 | return p; | ||
75 | } | ||
76 | |||
77 | /* -- C type metamethods -------------------------------------------------- */ | ||
78 | |||
79 | #define LJLIB_MODULE_ffi_meta | ||
80 | |||
81 | LJLIB_CF(ffi_meta___index) | ||
82 | { | ||
83 | CTState *cts = ctype_cts(L); | ||
84 | CTInfo qual = 0; | ||
85 | CType *ct; | ||
86 | uint8_t *p; | ||
87 | TValue *o = L->base; | ||
88 | if (!(o+1 < L->top && tviscdata(o))) /* Also checks for presence of key. */ | ||
89 | lj_err_argt(L, 1, LUA_TCDATA); | ||
90 | ct = lj_cdata_index(cts, cdataV(o), o+1, &p, &qual); | ||
91 | lj_cdata_get(cts, ct, L->top-1, p); | ||
92 | return 1; | ||
93 | } | ||
94 | |||
95 | LJLIB_CF(ffi_meta___newindex) | ||
96 | { | ||
97 | CTState *cts = ctype_cts(L); | ||
98 | CTInfo qual = 0; | ||
99 | CType *ct; | ||
100 | uint8_t *p; | ||
101 | TValue *o = L->base; | ||
102 | if (!(o+2 < L->top && tviscdata(o))) /* Also checks for key and value. */ | ||
103 | lj_err_argt(L, 1, LUA_TCDATA); | ||
104 | ct = lj_cdata_index(cts, cdataV(o), o+1, &p, &qual); | ||
105 | lj_cdata_set(cts, ct, p, o+2, qual); | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | /* Forward declaration. */ | ||
110 | static int lj_cf_ffi_new(lua_State *L); | ||
111 | |||
112 | LJLIB_CF(ffi_meta___call) | ||
113 | { | ||
114 | GCcdata *cd = ffi_checkcdata(L, 1); | ||
115 | if (cd->typeid == CTID_CTYPEID) | ||
116 | return lj_cf_ffi_new(L); | ||
117 | lj_err_caller(L, LJ_ERR_FFI_NYICALL); | ||
118 | return 0; /* unreachable */ | ||
119 | } | ||
120 | |||
121 | LJLIB_CF(ffi_meta___tostring) | ||
122 | { | ||
123 | GCcdata *cd = ffi_checkcdata(L, 1); | ||
124 | const char *msg = "cdata<%s>: %p"; | ||
125 | CTypeID id = cd->typeid; | ||
126 | if (id == CTID_CTYPEID) { | ||
127 | msg = "ctype<%s>"; | ||
128 | id = *(CTypeID *)cdataptr(cd); | ||
129 | } else { | ||
130 | CType *ct = ctype_raw(ctype_cts(L), id); | ||
131 | if (ctype_iscomplex(ct->info)) { | ||
132 | setstrV(L, L->top-1, lj_ctype_repr_complex(L, cdataptr(cd), ct->size)); | ||
133 | return 1; | ||
134 | } else if (ct->size == 8 && ctype_isinteger(ct->info)) { | ||
135 | setstrV(L, L->top-1, lj_ctype_repr_int64(L, *(uint64_t *)cdataptr(cd), | ||
136 | (ct->info & CTF_UNSIGNED))); | ||
137 | return 1; | ||
138 | } | ||
139 | } | ||
140 | lj_str_pushf(L, msg, strdata(lj_ctype_repr(L, id, NULL)), cdataptr(cd)); | ||
141 | return 1; | ||
142 | } | ||
143 | |||
144 | #include "lj_libdef.h" | ||
145 | |||
146 | /* -- FFI library functions ----------------------------------------------- */ | ||
147 | |||
148 | #define LJLIB_MODULE_ffi | ||
149 | |||
150 | LJLIB_CF(ffi_cdef) | ||
151 | { | ||
152 | GCstr *s = lj_lib_checkstr(L, 1); | ||
153 | CPState cp; | ||
154 | int errcode; | ||
155 | cp.L = L; | ||
156 | cp.cts = ctype_cts(L); | ||
157 | cp.srcname = strdata(s); | ||
158 | cp.p = strdata(s); | ||
159 | cp.mode = CPARSE_MODE_MULTI|CPARSE_MODE_DIRECT; | ||
160 | errcode = lj_cparse(&cp); | ||
161 | if (errcode) lj_err_throw(L, errcode); /* Propagate errors. */ | ||
162 | lj_gc_check(L); | ||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | LJLIB_CF(ffi_new) | ||
167 | { | ||
168 | CTState *cts = ctype_cts(L); | ||
169 | CTypeID id = ffi_checkctype(L, cts); | ||
170 | CTSize sz; | ||
171 | CTInfo info = lj_ctype_info(cts, id, &sz); | ||
172 | TValue *o = L->base+1; | ||
173 | GCcdata *cd; | ||
174 | if ((info & CTF_VLA)) { | ||
175 | o++; | ||
176 | sz = lj_ctype_vlsize(cts, ctype_raw(cts, id), | ||
177 | (CTSize)lj_lib_checkint(L, 2)); | ||
178 | } | ||
179 | if (sz == CTSIZE_INVALID) | ||
180 | lj_err_arg(L, 1, LJ_ERR_FFI_INVSIZE); | ||
181 | if (!(info & CTF_VLA) && ctype_align(info) <= CT_MEMALIGN) | ||
182 | cd = lj_cdata_new(cts, id, sz); | ||
183 | else | ||
184 | cd = lj_cdata_newv(cts, id, sz, ctype_align(info)); | ||
185 | setcdataV(L, o-1, cd); /* Anchor the uninitialized cdata. */ | ||
186 | lj_cconv_ct_init(cts, ctype_raw(cts, id), sz, cdataptr(cd), | ||
187 | o, (MSize)(L->top - o)); /* Initialize cdata. */ | ||
188 | L->top = o; /* Only return the cdata itself. */ | ||
189 | lj_gc_check(L); | ||
190 | return 1; | ||
191 | } | ||
192 | |||
193 | LJLIB_CF(ffi_typeof) | ||
194 | { | ||
195 | CTState *cts = ctype_cts(L); | ||
196 | CTypeID id = ffi_checkctype(L, cts); | ||
197 | GCcdata *cd = lj_cdata_new(cts, CTID_CTYPEID, 4); | ||
198 | *(CTypeID *)cdataptr(cd) = id; | ||
199 | setcdataV(L, L->top-1, cd); | ||
200 | return 1; | ||
201 | } | ||
202 | |||
203 | LJLIB_CF(ffi_sizeof) | ||
204 | { | ||
205 | CTState *cts = ctype_cts(L); | ||
206 | CTypeID id = ffi_checkctype(L, cts); | ||
207 | CTSize sz; | ||
208 | if (LJ_UNLIKELY(tviscdata(L->base) && cdataisv(cdataV(L->base)))) { | ||
209 | sz = cdatavlen(cdataV(L->base)); | ||
210 | } else { | ||
211 | CType *ct = lj_ctype_rawref(cts, id); | ||
212 | if (ctype_isvltype(ct->info)) | ||
213 | sz = lj_ctype_vlsize(cts, ct, (CTSize)lj_lib_checkint(L, 2)); | ||
214 | else | ||
215 | sz = ctype_hassize(ct->info) ? ct->size : CTSIZE_INVALID; | ||
216 | if (LJ_UNLIKELY(sz == CTSIZE_INVALID)) { | ||
217 | setnilV(L->top-1); | ||
218 | return 1; | ||
219 | } | ||
220 | } | ||
221 | setintV(L->top-1, (int32_t)sz); | ||
222 | return 1; | ||
223 | } | ||
224 | |||
225 | LJLIB_CF(ffi_alignof) | ||
226 | { | ||
227 | CTState *cts = ctype_cts(L); | ||
228 | CTypeID id = ffi_checkctype(L, cts); | ||
229 | CTSize sz = 0; | ||
230 | CTInfo info = lj_ctype_info(cts, id, &sz); | ||
231 | setintV(L->top-1, 1 << ctype_align(info)); | ||
232 | return 1; | ||
233 | } | ||
234 | |||
235 | LJLIB_CF(ffi_offsetof) | ||
236 | { | ||
237 | CTState *cts = ctype_cts(L); | ||
238 | CTypeID id = ffi_checkctype(L, cts); | ||
239 | GCstr *name = lj_lib_checkstr(L, 2); | ||
240 | CType *ct = lj_ctype_rawref(cts, id); | ||
241 | CTSize ofs; | ||
242 | if (ctype_isstruct(ct->info) && ct->size != CTSIZE_INVALID) { | ||
243 | CType *fct = lj_ctype_getfield(cts, ct, name, &ofs); | ||
244 | if (fct) { | ||
245 | setintV(L->top-1, ofs); | ||
246 | if (ctype_isfield(fct->info)) { | ||
247 | return 1; | ||
248 | } else if (ctype_isbitfield(fct->info)) { | ||
249 | setintV(L->top++, ctype_bitpos(fct->info)); | ||
250 | setintV(L->top++, ctype_bitbsz(fct->info)); | ||
251 | return 3; | ||
252 | } | ||
253 | } | ||
254 | } | ||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | LJLIB_CF(ffi_cast) | ||
259 | { | ||
260 | CTState *cts = ctype_cts(L); | ||
261 | CTypeID id = ffi_checkctype(L, cts); | ||
262 | TValue *o = lj_lib_checkany(L, 2); | ||
263 | L->top = o+1; /* Make sure this is the last item on the stack. */ | ||
264 | if (!(tviscdata(o) && cdataV(o)->typeid == id)) { | ||
265 | CTSize sz = lj_ctype_size(cts, id); | ||
266 | GCcdata *cd; | ||
267 | if (sz == CTSIZE_INVALID) | ||
268 | lj_err_caller(L, LJ_ERR_FFI_INVSIZE); | ||
269 | cd = lj_cdata_new(cts, id, sz); /* Create destination cdata. */ | ||
270 | lj_cconv_ct_tv(cts, ctype_raw(cts, id), cdataptr(cd), o, CCF_CAST); | ||
271 | setcdataV(L, o, cd); | ||
272 | lj_gc_check(L); | ||
273 | } | ||
274 | return 1; | ||
275 | } | ||
276 | |||
277 | LJLIB_CF(ffi_string) | ||
278 | { | ||
279 | CTState *cts = ctype_cts(L); | ||
280 | TValue *o = lj_lib_checkany(L, 1); | ||
281 | size_t sz = (size_t)(CTSize)lj_lib_optint(L, 2, (int32_t)CTSIZE_INVALID); | ||
282 | CType *ct = ctype_get(cts, sz==CTSIZE_INVALID ? CTID_P_CVOID : CTID_P_CCHAR); | ||
283 | const char *p; | ||
284 | L->top = o+1; /* Make sure this is the last item on the stack. */ | ||
285 | lj_cconv_ct_tv(cts, ct, (uint8_t *)&p, o, 0); | ||
286 | if (sz == CTSIZE_INVALID) sz = strlen(p); | ||
287 | setstrV(L, o, lj_str_new(L, p, sz)); | ||
288 | lj_gc_check(L); | ||
289 | return 1; | ||
290 | } | ||
291 | |||
292 | LJLIB_CF(ffi_copy) | ||
293 | { | ||
294 | void *dp = ffi_checkptr(L, 1, CTID_P_VOID); | ||
295 | void *sp = ffi_checkptr(L, 2, CTID_P_CVOID); | ||
296 | TValue *o = L->base+1; | ||
297 | CTSize sz; | ||
298 | if (tvisstr(o) && o+1 >= L->top) { | ||
299 | sz = strV(o)->len+1; /* Copy Lua string including trailing '\0'. */ | ||
300 | } else { | ||
301 | sz = (CTSize)lj_lib_checkint(L, 3); | ||
302 | if (tvisstr(o) && sz > strV(o)->len+1) | ||
303 | sz = strV(o)->len+1; /* Max. copy length is string length. */ | ||
304 | } | ||
305 | memcpy(dp, sp, sz); | ||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | LJLIB_CF(ffi_fill) | ||
310 | { | ||
311 | void *dp = ffi_checkptr(L, 1, CTID_P_VOID); | ||
312 | CTSize sz = (CTSize)lj_lib_checkint(L, 2); | ||
313 | int32_t fill = lj_lib_optint(L, 3, 0); | ||
314 | memset(dp, fill, sz); | ||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | #define H_(le, be) LJ_ENDIAN_SELECT(0x##le, 0x##be) | ||
319 | |||
320 | /* Test ABI string. */ | ||
321 | LJLIB_CF(ffi_abi) | ||
322 | { | ||
323 | GCstr *s = lj_lib_checkstr(L, 1); | ||
324 | int b = 0; | ||
325 | switch (s->hash) { | ||
326 | #if LJ_64 | ||
327 | case H_(849858eb,ad35fd06): b = 1; break; /* 64bit */ | ||
328 | #else | ||
329 | case H_(662d3c79,d0e22477): b = 1; break; /* 32bit */ | ||
330 | #endif | ||
331 | #if LJ_ARCH_HASFPU | ||
332 | case H_(e33ee463,e33ee463): b = 1; break; /* fpu */ | ||
333 | #endif | ||
334 | #if LJ_ABI_SOFTFP | ||
335 | case H_(61211a23,c2e8c81c): b = 1; break; /* softfp */ | ||
336 | #else | ||
337 | case H_(539417a8,8ce0812f): b = 1; break; /* hardfp */ | ||
338 | #endif | ||
339 | #if LJ_ABI_EABI | ||
340 | case H_(2182df8f,f2ed1152): b = 1; break; /* eabi */ | ||
341 | #endif | ||
342 | #if LJ_ABI_WIN | ||
343 | case H_(4ab624a8,4ab624a8): b = 1; break; /* win */ | ||
344 | #endif | ||
345 | case H_(3af93066,1f001464): b = 1; break; /* le/be */ | ||
346 | default: | ||
347 | break; | ||
348 | } | ||
349 | setboolV(L->top-1, b); | ||
350 | return 1; | ||
351 | } | ||
352 | |||
353 | #undef H_ | ||
354 | |||
355 | LJLIB_PUSH(top-3) LJLIB_SET(os) | ||
356 | LJLIB_PUSH(top-2) LJLIB_SET(arch) | ||
357 | |||
358 | #include "lj_libdef.h" | ||
359 | |||
360 | /* ------------------------------------------------------------------------ */ | ||
361 | |||
362 | LUALIB_API int luaopen_ffi(lua_State *L) | ||
363 | { | ||
364 | lj_ctype_init(L); | ||
365 | LJ_LIB_REG_(L, NULL, ffi_meta); | ||
366 | /* NOBARRIER: basemt is a GC root. */ | ||
367 | setgcref(basemt_it(G(L), LJ_TCDATA), obj2gco(tabV(L->top-1))); | ||
368 | lua_pushliteral(L, LJ_OS_NAME); | ||
369 | lua_pushliteral(L, LJ_ARCH_NAME); | ||
370 | LJ_LIB_REG_(L, NULL, ffi); /* Note: no global "ffi" created! */ | ||
371 | return 1; | ||
372 | } | ||
373 | |||
374 | #endif | ||
diff --git a/src/lib_init.c b/src/lib_init.c index dd3a29af..8501e21d 100644 --- a/src/lib_init.c +++ b/src/lib_init.c | |||
@@ -11,6 +11,8 @@ | |||
11 | #include "lauxlib.h" | 11 | #include "lauxlib.h" |
12 | #include "lualib.h" | 12 | #include "lualib.h" |
13 | 13 | ||
14 | #include "lj_arch.h" | ||
15 | |||
14 | static const luaL_Reg lj_lib_load[] = { | 16 | static const luaL_Reg lj_lib_load[] = { |
15 | { "", luaopen_base }, | 17 | { "", luaopen_base }, |
16 | { LUA_LOADLIBNAME, luaopen_package }, | 18 | { LUA_LOADLIBNAME, luaopen_package }, |
@@ -26,6 +28,9 @@ static const luaL_Reg lj_lib_load[] = { | |||
26 | }; | 28 | }; |
27 | 29 | ||
28 | static const luaL_Reg lj_lib_preload[] = { | 30 | static const luaL_Reg lj_lib_preload[] = { |
31 | #if LJ_HASFFI | ||
32 | { LUA_FFILIBNAME, luaopen_ffi }, | ||
33 | #endif | ||
29 | { NULL, NULL } | 34 | { NULL, NULL } |
30 | }; | 35 | }; |
31 | 36 | ||
diff --git a/src/ljamalg.c b/src/ljamalg.c index 9681d759..30547d3f 100644 --- a/src/ljamalg.c +++ b/src/ljamalg.c | |||
@@ -70,5 +70,6 @@ | |||
70 | #include "lib_debug.c" | 70 | #include "lib_debug.c" |
71 | #include "lib_bit.c" | 71 | #include "lib_bit.c" |
72 | #include "lib_jit.c" | 72 | #include "lib_jit.c" |
73 | #include "lib_ffi.c" | ||
73 | #include "lib_init.c" | 74 | #include "lib_init.c" |
74 | 75 | ||
diff --git a/src/lualib.h b/src/lualib.h index 9c473c88..fab30b11 100644 --- a/src/lualib.h +++ b/src/lualib.h | |||
@@ -20,6 +20,7 @@ | |||
20 | #define LUA_DBLIBNAME "debug" | 20 | #define LUA_DBLIBNAME "debug" |
21 | #define LUA_BITLIBNAME "bit" | 21 | #define LUA_BITLIBNAME "bit" |
22 | #define LUA_JITLIBNAME "jit" | 22 | #define LUA_JITLIBNAME "jit" |
23 | #define LUA_FFILIBNAME "ffi" | ||
23 | 24 | ||
24 | LUALIB_API int luaopen_base(lua_State *L); | 25 | LUALIB_API int luaopen_base(lua_State *L); |
25 | LUALIB_API int luaopen_math(lua_State *L); | 26 | LUALIB_API int luaopen_math(lua_State *L); |
@@ -31,6 +32,7 @@ LUALIB_API int luaopen_package(lua_State *L); | |||
31 | LUALIB_API int luaopen_debug(lua_State *L); | 32 | LUALIB_API int luaopen_debug(lua_State *L); |
32 | LUALIB_API int luaopen_bit(lua_State *L); | 33 | LUALIB_API int luaopen_bit(lua_State *L); |
33 | LUALIB_API int luaopen_jit(lua_State *L); | 34 | LUALIB_API int luaopen_jit(lua_State *L); |
35 | LUALIB_API int luaopen_ffi(lua_State *L); | ||
34 | 36 | ||
35 | LUALIB_API void luaL_openlibs(lua_State *L); | 37 | LUALIB_API void luaL_openlibs(lua_State *L); |
36 | 38 | ||
diff --git a/src/msvcbuild.bat b/src/msvcbuild.bat index 5a5e4ec8..899b876c 100644 --- a/src/msvcbuild.bat +++ b/src/msvcbuild.bat | |||
@@ -20,7 +20,7 @@ | |||
20 | @set LJLIB=lib /nologo | 20 | @set LJLIB=lib /nologo |
21 | @set DASMDIR=..\dynasm | 21 | @set DASMDIR=..\dynasm |
22 | @set DASM=lua %DASMDIR%\dynasm.lua | 22 | @set DASM=lua %DASMDIR%\dynasm.lua |
23 | @set ALL_LIB=lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c | 23 | @set ALL_LIB=lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c |
24 | 24 | ||
25 | if not exist buildvm_x86.h^ | 25 | if not exist buildvm_x86.h^ |
26 | %DASM% -LN -o buildvm_x86.h buildvm_x86.dasc | 26 | %DASM% -LN -o buildvm_x86.h buildvm_x86.dasc |