]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
FFI: Record C function calls with bool return values.
authorMike Pall <mike>
Fri, 25 Nov 2011 18:36:35 +0000 (19:36 +0100)
committerMike Pall <mike>
Fri, 25 Nov 2011 18:36:35 +0000 (19:36 +0100)
src/Makefile.dep
src/lj_cconv.c
src/lj_crecord.c
src/lj_jit.h
src/lj_record.c

index b9d0df476b1de4cf762c0a1433443536540dd3fb..afcf5c123f232b5d386b406eb94cbecf1e0433da 100644 (file)
@@ -93,7 +93,7 @@ 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_crecord.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 \
index d73984f473d2c0e3dd867e066f92530131d58229..9d4783553f9958a1236c2f54d2ceba12c2e2be9b 100644 (file)
@@ -391,7 +391,7 @@ int lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid,
        lua_assert(tvisnum(o));
       }
     } else {
-      uint32_t b = ((*sp) & 1);
+      uint32_t b = (*sp != 0);
       setboolV(o, b);
       setboolV(&cts->g->tmptv2, b);  /* Remember for trace recorder. */
     }
index 9457b5192c64f07f658c5b733c2078fd32fe78e1..313bee818090a7c1364039b43d656246f5abe077 100644 (file)
@@ -27,6 +27,7 @@
 #include "lj_trace.h"
 #include "lj_record.h"
 #include "lj_ffrecord.h"
+#include "lj_snap.h"
 #include "lj_crecord.h"
 #include "lj_dispatch.h"
 
@@ -839,6 +840,26 @@ static TRef crec_call_args(jit_State *J, RecordFFData *rd,
   return tr;
 }
 
+/* Create a snapshot for the caller, simulating a 'false' return value. */
+static void crec_snap_caller(jit_State *J)
+{
+  lua_State *L = J->L;
+  TValue *base = L->base, *top = L->top;
+  const BCIns *pc = J->pc;
+  TRef ftr = J->base[-1];
+  ptrdiff_t delta;
+  if (!frame_islua(base-1))
+    lj_trace_err(J, LJ_TRERR_NYICALL);
+  J->pc = frame_pc(base-1); delta = 1+bc_a(J->pc[-1]);
+  L->top = base; L->base = base - delta;
+  J->base[-1] = TREF_FALSE;
+  J->base -= delta; J->baseslot -= delta; J->maxslot = delta; J->framedepth--;
+  lj_snap_add(J);
+  L->base = base; L->top = top;
+  J->framedepth++; J->base += delta; J->baseslot += delta; J->maxslot = 1;
+  J->base[-1] = ftr; J->pc = pc;
+}
+
 /* Record function call. */
 static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
 {
@@ -867,8 +888,7 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
       ctr = ctype_child(cts, ctr);
     }
     if (!(ctype_isnum(ctr->info) || ctype_isptr(ctr->info) ||
-         ctype_isvoid(ctr->info)) ||
-       ctype_isbool(ctr->info) || t == IRT_CDATA)
+         ctype_isvoid(ctr->info)) || t == IRT_CDATA)
       lj_trace_err(J, LJ_TRERR_NYICALL);
     if ((ct->info & CTF_VARARG)
 #if LJ_TARGET_X86
@@ -878,7 +898,12 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
       func = emitir(IRT(IR_CARG, IRT_NIL), func,
                    lj_ir_kint(J, ctype_typeid(cts, ct)));
     tr = emitir(IRT(IR_CALLXS, t), crec_call_args(J, rd, cts, ct), func);
-    if (t == IRT_FLOAT || t == IRT_U32) {
+    if (ctype_isbool(ctr->info)) {
+      crec_snap_caller(J);
+      lj_ir_set(J, IRTGI(IR_NE), tr, lj_ir_kint(J, 0));
+      J->postproc = LJ_POST_FIXGUARDSNAP;
+      tr = TREF_TRUE;
+    } else if (t == IRT_FLOAT || t == IRT_U32) {
       tr = emitconv(tr, IRT_NUM, t, 0);
     } else if (t == IRT_I8 || t == IRT_I16) {
       tr = emitconv(tr, IRT_INT, t, IRCONV_SEXT);
index 11dc973731df8f5fb9562eb993d211a2bdc6f10b..8a4c04c808ef2b5a6a42d65baee7c43d1fdc094c 100644 (file)
@@ -122,6 +122,7 @@ typedef enum {
   LJ_POST_NONE,                /* No action. */
   LJ_POST_FIXCOMP,     /* Fixup comparison and emit pending guard. */
   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_FFRETRY      /* Suppress recording of retried fast functions. */
 } PostProc;
index a76f5d94f73790afbe6e39ea16fe2b3ee961e887..2c27a718fcbb398c4fc34ef8390e5075ad5f7011 100644 (file)
@@ -1573,8 +1573,14 @@ void lj_record_ins(jit_State *J)
       rec_comp_fixup(J, pc, (!tvistruecond(&J2G(J)->tmptv2) ^ (bc_op(*pc)&1)));
       /* fallthrough */
     case LJ_POST_FIXGUARD:  /* Fixup and emit pending guard. */
-      if (!tvistruecond(&J2G(J)->tmptv2))
+    case LJ_POST_FIXGUARDSNAP:  /* Fixup and emit pending guard and snapshot. */
+      if (!tvistruecond(&J2G(J)->tmptv2)) {
        J->fold.ins.o ^= 1;  /* Flip guard to opposite. */
+       if (J->postproc == LJ_POST_FIXGUARDSNAP) {
+         SnapShot *snap = &J->cur.snap[J->cur.nsnap-1];
+         J->cur.snapmap[snap->mapofs+snap->nent-1]--;  /* False -> true. */
+       }
+      }
       lj_opt_fold(J);  /* Emit pending guard. */
       /* fallthrough */
     case LJ_POST_FIXBOOL: