FFI: Record C function calls with bool return values.
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user