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