diff options
Diffstat (limited to 'src/lj_crecord.c')
-rw-r--r-- | src/lj_crecord.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index 80f00e18..e5413fb3 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
@@ -12,9 +12,11 @@ | |||
12 | 12 | ||
13 | #include "lj_err.h" | 13 | #include "lj_err.h" |
14 | #include "lj_str.h" | 14 | #include "lj_str.h" |
15 | #include "lj_tab.h" | ||
15 | #include "lj_ctype.h" | 16 | #include "lj_ctype.h" |
16 | #include "lj_cparse.h" | 17 | #include "lj_cparse.h" |
17 | #include "lj_cconv.h" | 18 | #include "lj_cconv.h" |
19 | #include "lj_clib.h" | ||
18 | #include "lj_ir.h" | 20 | #include "lj_ir.h" |
19 | #include "lj_jit.h" | 21 | #include "lj_jit.h" |
20 | #include "lj_iropt.h" | 22 | #include "lj_iropt.h" |
@@ -837,6 +839,38 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd) | |||
837 | } | 839 | } |
838 | } | 840 | } |
839 | 841 | ||
842 | /* -- C library namespace metamethods ------------------------------------- */ | ||
843 | |||
844 | void LJ_FASTCALL recff_clib_index(jit_State *J, RecordFFData *rd) | ||
845 | { | ||
846 | CTState *cts = ctype_ctsG(J2G(J)); | ||
847 | if (tref_isudata(J->base[0]) && tref_isstr(J->base[1]) && | ||
848 | udataV(&rd->argv[0])->udtype == UDTYPE_FFI_CLIB) { | ||
849 | CLibrary *cl = (CLibrary *)uddata(udataV(&rd->argv[0])); | ||
850 | GCstr *name = strV(&rd->argv[1]); | ||
851 | CType *ct; | ||
852 | CTypeID id = lj_ctype_getname(cts, &ct, name, CLNS_INDEX); | ||
853 | cTValue *tv = lj_tab_getstr(cl->cache, name); | ||
854 | if (id && tv && tviscdata(tv)) { | ||
855 | /* Specialize to the symbol name and make the result a constant. */ | ||
856 | emitir(IRTG(IR_EQ, IRT_STR), J->base[1], lj_ir_kstr(J, name)); | ||
857 | if (ctype_isconstval(ct->info)) { | ||
858 | if (ct->size >= 0x80000000u && | ||
859 | (ctype_child(cts, ct)->info & CTF_UNSIGNED)) | ||
860 | J->base[0] = lj_ir_knum(J, (lua_Number)(uint32_t)ct->size); | ||
861 | else | ||
862 | J->base[0] = lj_ir_kint(J, (int32_t)ct->size); | ||
863 | } else if (ctype_isextern(ct->info)) { | ||
864 | lj_trace_err(J, LJ_TRERR_BADTYPE); /* NYI: access extern variables. */ | ||
865 | } else { | ||
866 | J->base[0] = lj_ir_kgc(J, obj2gco(cdataV(tv)), IRT_CDATA); | ||
867 | } | ||
868 | } else { | ||
869 | lj_trace_err(J, LJ_TRERR_NOCACHE); | ||
870 | } | ||
871 | } /* else: interpreter will throw. */ | ||
872 | } | ||
873 | |||
840 | /* -- FFI library functions ----------------------------------------------- */ | 874 | /* -- FFI library functions ----------------------------------------------- */ |
841 | 875 | ||
842 | void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd) | 876 | void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd) |