mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 15:14:08 +00:00
FFI: Add ffi.istype() function.
This commit is contained in:
parent
9ea679410c
commit
5d096dcfde
@ -316,6 +316,24 @@ of <tt>ct</tt>, which must be a <tt>struct</tt>. Additionally returns
|
|||||||
the position and the field size (in bits) for bit fields.
|
the position and the field size (in bits) for bit fields.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<h3 id="ffi_istype"><tt>status = ffi.istype(ct, obj)</tt></h3>
|
||||||
|
<p>
|
||||||
|
Returns <tt>true</tt> if <tt>obj</tt> has the C type given by
|
||||||
|
<tt>ct</tt>. Returns <tt>false</tt> otherwise.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
C type qualifiers (<tt>const</tt> etc.) are ignored. Pointers are
|
||||||
|
checked with the standard pointer compatibility rules, but without any
|
||||||
|
special treatment for <tt>void *</tt>. If <tt>ct</tt> specifies a
|
||||||
|
<tt>struct</tt>/<tt>union</tt>, then a pointer to this type is accepted,
|
||||||
|
too. Otherwise the types must match exactly.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Note: this function accepts all kinds of Lua objects for the
|
||||||
|
<tt>obj</tt> argument, but always returns <tt>false</tt> for non-cdata
|
||||||
|
objects.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h2 id="util">Utility Functions</h2>
|
<h2 id="util">Utility Functions</h2>
|
||||||
|
|
||||||
<h3 id="ffi_string"><tt>str = ffi.string(ptr [,len])</tt></h3>
|
<h3 id="ffi_string"><tt>str = ffi.string(ptr [,len])</tt></h3>
|
||||||
|
@ -456,6 +456,36 @@ LJLIB_CF(ffi_typeof)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LJLIB_CF(ffi_istype) LJLIB_REC(ffi_istype)
|
||||||
|
{
|
||||||
|
CTState *cts = ctype_cts(L);
|
||||||
|
CTypeID id1 = ffi_checkctype(L, cts);
|
||||||
|
TValue *o = lj_lib_checkany(L, 2);
|
||||||
|
int b = 0;
|
||||||
|
if (tviscdata(o)) {
|
||||||
|
GCcdata *cd = cdataV(o);
|
||||||
|
CTypeID id2 = cd->typeid == CTID_CTYPEID ? *(CTypeID *)cdataptr(cd) :
|
||||||
|
cd->typeid;
|
||||||
|
CType *ct1 = lj_ctype_rawref(cts, id1);
|
||||||
|
CType *ct2 = lj_ctype_rawref(cts, id2);
|
||||||
|
if (ct1 == ct2) {
|
||||||
|
b = 1;
|
||||||
|
} else if (ctype_type(ct1->info) == ctype_type(ct2->info) &&
|
||||||
|
ct1->size == ct2->size) {
|
||||||
|
if (ctype_ispointer(ct1->info))
|
||||||
|
b = lj_cconv_compatptr(cts, ct1, ct2, CCF_IGNQUAL);
|
||||||
|
else if (ctype_isnum(ct1->info) || ctype_isvoid(ct1->info))
|
||||||
|
b = (((ct1->info ^ ct2->info) & ~CTF_QUAL) == 0);
|
||||||
|
} else if (ctype_isstruct(ct1->info) && ctype_isptr(ct2->info) &&
|
||||||
|
ct1 == ctype_rawchild(cts, ct2)) {
|
||||||
|
b = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setboolV(L->top-1, b);
|
||||||
|
setboolV(&G(L)->tmptv2, b); /* Remember for trace recorder. */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
LJLIB_CF(ffi_sizeof)
|
LJLIB_CF(ffi_sizeof)
|
||||||
{
|
{
|
||||||
CTState *cts = ctype_cts(L);
|
CTState *cts = ctype_cts(L);
|
||||||
|
@ -51,6 +51,18 @@ static GCcdata *argv2cdata(jit_State *J, TRef tr, cTValue *o)
|
|||||||
return cd;
|
return cd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Specialize to the CTypeID held by a cdata constructor. */
|
||||||
|
static CTypeID crec_constructor(jit_State *J, GCcdata *cd, TRef tr)
|
||||||
|
{
|
||||||
|
CTypeID id;
|
||||||
|
lua_assert(tref_iscdata(tr) && cd->typeid == CTID_CTYPEID);
|
||||||
|
id = *(CTypeID *)cdataptr(cd);
|
||||||
|
tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCcdata)));
|
||||||
|
tr = emitir(IRT(IR_XLOAD, IRT_INT), tr, 0);
|
||||||
|
emitir(IRTG(IR_EQ, IRT_INT), tr, lj_ir_kint(J, (int32_t)id));
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
static CTypeID argv2ctype(jit_State *J, TRef tr, cTValue *o)
|
static CTypeID argv2ctype(jit_State *J, TRef tr, cTValue *o)
|
||||||
{
|
{
|
||||||
if (tref_isstr(tr)) {
|
if (tref_isstr(tr)) {
|
||||||
@ -70,7 +82,8 @@ static CTypeID argv2ctype(jit_State *J, TRef tr, cTValue *o)
|
|||||||
return cp.val.id;
|
return cp.val.id;
|
||||||
} else {
|
} else {
|
||||||
GCcdata *cd = argv2cdata(J, tr, o);
|
GCcdata *cd = argv2cdata(J, tr, o);
|
||||||
return cd->typeid == CTID_CTYPEID ? *(CTypeID *)cdataptr(cd) : cd->typeid;
|
return cd->typeid == CTID_CTYPEID ? crec_constructor(J, cd, tr) :
|
||||||
|
cd->typeid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -427,18 +440,6 @@ doconv:
|
|||||||
|
|
||||||
/* -- C data metamethods -------------------------------------------------- */
|
/* -- C data metamethods -------------------------------------------------- */
|
||||||
|
|
||||||
/* Specialize to the CTypeID held by a cdata constructor. */
|
|
||||||
static CTypeID crec_constructor(jit_State *J, GCcdata *cd, TRef tr)
|
|
||||||
{
|
|
||||||
CTypeID id;
|
|
||||||
lua_assert(tref_iscdata(tr) && cd->typeid == CTID_CTYPEID);
|
|
||||||
id = *(CTypeID *)cdataptr(cd);
|
|
||||||
tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCcdata)));
|
|
||||||
tr = emitir(IRT(IR_XLOAD, IRT_INT), tr, 0);
|
|
||||||
emitir(IRTG(IR_EQ, IRT_INT), tr, lj_ir_kint(J, (int32_t)id));
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This would be rather difficult in FOLD, so do it here:
|
/* This would be rather difficult in FOLD, so do it here:
|
||||||
** (base+k)+(idx*sz)+ofs ==> (base+idx*sz)+(ofs+k)
|
** (base+k)+(idx*sz)+ofs ==> (base+idx*sz)+(ofs+k)
|
||||||
** (base+(idx+k)*sz)+ofs ==> (base+idx*sz)+(ofs+k*sz)
|
** (base+(idx+k)*sz)+ofs ==> (base+idx*sz)+(ofs+k*sz)
|
||||||
@ -1100,6 +1101,18 @@ void LJ_FASTCALL recff_ffi_fill(jit_State *J, RecordFFData *rd)
|
|||||||
} /* else: interpreter will throw. */
|
} /* else: interpreter will throw. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LJ_FASTCALL recff_ffi_istype(jit_State *J, RecordFFData *rd)
|
||||||
|
{
|
||||||
|
argv2ctype(J, J->base[0], &rd->argv[0]);
|
||||||
|
if (tref_iscdata(J->base[1])) {
|
||||||
|
argv2ctype(J, J->base[1], &rd->argv[1]);
|
||||||
|
J->postproc = LJ_POST_FIXBOOL;
|
||||||
|
J->base[0] = TREF_TRUE;
|
||||||
|
} else {
|
||||||
|
J->base[0] = TREF_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LJ_FASTCALL recff_ffi_abi(jit_State *J, RecordFFData *rd)
|
void LJ_FASTCALL recff_ffi_abi(jit_State *J, RecordFFData *rd)
|
||||||
{
|
{
|
||||||
if (tref_isstr(J->base[0])) {
|
if (tref_isstr(J->base[0])) {
|
||||||
|
@ -19,6 +19,7 @@ LJ_FUNC void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd);
|
|||||||
LJ_FUNC void LJ_FASTCALL recff_ffi_string(jit_State *J, RecordFFData *rd);
|
LJ_FUNC void LJ_FASTCALL recff_ffi_string(jit_State *J, RecordFFData *rd);
|
||||||
LJ_FUNC void LJ_FASTCALL recff_ffi_copy(jit_State *J, RecordFFData *rd);
|
LJ_FUNC void LJ_FASTCALL recff_ffi_copy(jit_State *J, RecordFFData *rd);
|
||||||
LJ_FUNC void LJ_FASTCALL recff_ffi_fill(jit_State *J, RecordFFData *rd);
|
LJ_FUNC void LJ_FASTCALL recff_ffi_fill(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_abi(jit_State *J, RecordFFData *rd);
|
||||||
LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd);
|
LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd);
|
||||||
#else
|
#else
|
||||||
@ -30,6 +31,7 @@ LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd);
|
|||||||
#define recff_ffi_string recff_nyi
|
#define recff_ffi_string recff_nyi
|
||||||
#define recff_ffi_copy recff_nyi
|
#define recff_ffi_copy recff_nyi
|
||||||
#define recff_ffi_fill recff_nyi
|
#define recff_ffi_fill recff_nyi
|
||||||
|
#define recff_ffi_istype recff_nyi
|
||||||
#define recff_ffi_abi recff_nyi
|
#define recff_ffi_abi recff_nyi
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user