diff --git a/src/Makefile.dep b/src/Makefile.dep index cab23b79..9571e16d 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep @@ -82,9 +82,10 @@ lj_cparse.o: lj_cparse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ lj_bc.h lj_vm.h lj_char.h lj_strscan.h lj_crecord.o: lj_crecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ctype.h \ - lj_gc.h lj_cdata.h lj_cparse.h lj_cconv.h lj_clib.h lj_ccall.h lj_ir.h \ - lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h lj_dispatch.h lj_traceerr.h \ - lj_record.h lj_ffrecord.h lj_snap.h lj_crecord.h + lj_gc.h lj_cdata.h lj_cparse.h lj_cconv.h lj_clib.h lj_ccall.h lj_ff.h \ + lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \ + lj_dispatch.h lj_traceerr.h lj_record.h lj_ffrecord.h lj_snap.h \ + lj_crecord.h lj_ctype.o: lj_ctype.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_ccallback.h lj_debug.o: lj_debug.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ diff --git a/src/lib_ffi.c b/src/lib_ffi.c index 69bebefc..689f7a9d 100644 --- a/src/lib_ffi.c +++ b/src/lib_ffi.c @@ -587,7 +587,7 @@ LJLIB_CF(ffi_istype) LJLIB_REC(.) return 1; } -LJLIB_CF(ffi_sizeof) +LJLIB_CF(ffi_sizeof) LJLIB_REC(ffi_xof FF_ffi_sizeof) { CTState *cts = ctype_cts(L); CTypeID id = ffi_checkctype(L, cts, NULL); @@ -609,7 +609,7 @@ LJLIB_CF(ffi_sizeof) return 1; } -LJLIB_CF(ffi_alignof) +LJLIB_CF(ffi_alignof) LJLIB_REC(ffi_xof FF_ffi_alignof) { CTState *cts = ctype_cts(L); CTypeID id = ffi_checkctype(L, cts, NULL); @@ -619,7 +619,7 @@ LJLIB_CF(ffi_alignof) return 1; } -LJLIB_CF(ffi_offsetof) +LJLIB_CF(ffi_offsetof) LJLIB_REC(ffi_xof FF_ffi_offsetof) { CTState *cts = ctype_cts(L); CTypeID id = ffi_checkctype(L, cts, NULL); diff --git a/src/lj_crecord.c b/src/lj_crecord.c index 6a22544a..f9220322 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c @@ -20,6 +20,7 @@ #include "lj_cconv.h" #include "lj_clib.h" #include "lj_ccall.h" +#include "lj_ff.h" #include "lj_ir.h" #include "lj_jit.h" #include "lj_ircall.h" @@ -1587,7 +1588,27 @@ void LJ_FASTCALL recff_ffi_abi(jit_State *J, RecordFFData *rd) emitir(IRTG(IR_EQ, IRT_STR), J->base[0], lj_ir_kstr(J, strV(&rd->argv[0]))); J->postproc = LJ_POST_FIXBOOL; J->base[0] = TREF_TRUE; - } /* else: interpreter will throw. */ + } else { + lj_trace_err(J, LJ_TRERR_BADTYPE); + } +} + +/* Record ffi.sizeof(), ffi.alignof(), ffi.offsetof(). */ +void LJ_FASTCALL recff_ffi_xof(jit_State *J, RecordFFData *rd) +{ + CTypeID id = argv2ctype(J, J->base[0], &rd->argv[0]); + if (rd->data == FF_ffi_sizeof) { + CType *ct = lj_ctype_rawref(ctype_ctsG(J2G(J)), id); + if (ctype_isvltype(ct->info)) + lj_trace_err(J, LJ_TRERR_BADTYPE); + } else if (rd->data == FF_ffi_offsetof) { /* Specialize to the field name. */ + if (!tref_isstr(J->base[1])) + lj_trace_err(J, LJ_TRERR_BADTYPE); + emitir(IRTG(IR_EQ, IRT_STR), J->base[1], lj_ir_kstr(J, strV(&rd->argv[1]))); + rd->nres = 3; /* Just in case. */ + } + J->postproc = LJ_POST_FIXCONST; + J->base[0] = J->base[1] = J->base[2] = TREF_NIL; } /* -- Miscellaneous library functions ------------------------------------- */ diff --git a/src/lj_crecord.h b/src/lj_crecord.h index ab0e27e7..bd217651 100644 --- a/src/lj_crecord.h +++ b/src/lj_crecord.h @@ -23,6 +23,7 @@ LJ_FUNC void LJ_FASTCALL recff_ffi_fill(jit_State *J, RecordFFData *rd); LJ_FUNC void LJ_FASTCALL recff_ffi_typeof(jit_State *J, RecordFFData *rd); LJ_FUNC void LJ_FASTCALL recff_ffi_istype(jit_State *J, RecordFFData *rd); LJ_FUNC void LJ_FASTCALL recff_ffi_abi(jit_State *J, RecordFFData *rd); +LJ_FUNC void LJ_FASTCALL recff_ffi_xof(jit_State *J, RecordFFData *rd); LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd); #endif diff --git a/src/lj_jit.h b/src/lj_jit.h index 43a99392..4549ac6c 100644 --- a/src/lj_jit.h +++ b/src/lj_jit.h @@ -144,6 +144,7 @@ typedef enum { LJ_POST_FIXGUARD, /* Fixup and emit pending guard. */ LJ_POST_FIXGUARDSNAP, /* Fixup and emit pending guard and snapshot. */ LJ_POST_FIXBOOL, /* Fixup boolean result. */ + LJ_POST_FIXCONST, /* Fixup constant results. */ LJ_POST_FFRETRY /* Suppress recording of retried fast functions. */ } PostProc; diff --git a/src/lj_record.c b/src/lj_record.c index 956f3bed..ea391bf1 100644 --- a/src/lj_record.c +++ b/src/lj_record.c @@ -1654,13 +1654,23 @@ void lj_record_ins(jit_State *J) case LJ_POST_FIXBOOL: if (!tvistruecond(&J2G(J)->tmptv2)) { BCReg s; + TValue *tv = J->L->base; for (s = 0; s < J->maxslot; s++) /* Fixup stack slot (if any). */ - if (J->base[s] == TREF_TRUE && tvisfalse(&J->L->base[s])) { + if (J->base[s] == TREF_TRUE && tvisfalse(&tv[s])) { J->base[s] = TREF_FALSE; break; } } break; + case LJ_POST_FIXCONST: + { + BCReg s; + TValue *tv = J->L->base; + for (s = 0; s < J->maxslot; s++) /* Constify stack slots (if any). */ + if (J->base[s] == TREF_NIL && !tvisnil(&tv[s])) + J->base[s] = lj_record_constify(J, &tv[s]); + } + break; case LJ_POST_FFRETRY: /* Suppress recording of retried fast function. */ if (bc_op(*J->pc) >= BC__MAX) return;