mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-08 07:34:07 +00:00
FFI: Allow indexing a struct constructor to get constants.
Specialize to the CTypeID held by a constructor in all cases.
This commit is contained in:
parent
0fa32e5d31
commit
6f746577d0
@ -127,6 +127,17 @@ collect_attrib:
|
|||||||
return ct;
|
return ct;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (cd->typeid == CTID_CTYPEID) {
|
||||||
|
/* Allow indexing a (pointer to) struct constructor to get constants. */
|
||||||
|
CType *sct = ct = ctype_raw(cts, *(CTypeID *)p);
|
||||||
|
if (ctype_isptr(sct->info))
|
||||||
|
sct = ctype_rawchild(cts, sct);
|
||||||
|
if (ctype_isstruct(sct->info)) {
|
||||||
|
CTSize ofs;
|
||||||
|
CType *fct = lj_ctype_getfield(cts, sct, name, &ofs);
|
||||||
|
if (fct && ctype_isconstval(fct->info))
|
||||||
|
return fct;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
GCstr *s = lj_ctype_repr(cts->L, ctype_typeid(cts, ct), NULL);
|
GCstr *s = lj_ctype_repr(cts->L, ctype_typeid(cts, ct), NULL);
|
||||||
|
@ -374,6 +374,18 @@ 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)
|
||||||
@ -435,6 +447,8 @@ void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd)
|
|||||||
GCstr *name = strV(&rd->argv[1]);
|
GCstr *name = strV(&rd->argv[1]);
|
||||||
/* Always specialize to the field name. */
|
/* Always specialize to the field name. */
|
||||||
emitir(IRTG(IR_EQ, IRT_STR), idx, lj_ir_kstr(J, name));
|
emitir(IRTG(IR_EQ, IRT_STR), idx, lj_ir_kstr(J, name));
|
||||||
|
if (cd->typeid == CTID_CTYPEID)
|
||||||
|
ct = ctype_raw(cts, crec_constructor(J, cd, ptr));
|
||||||
if (ctype_isptr(ct->info)) { /* Automatically perform '->'. */
|
if (ctype_isptr(ct->info)) { /* Automatically perform '->'. */
|
||||||
CType *cct = ctype_rawchild(cts, ct);
|
CType *cct = ctype_rawchild(cts, ct);
|
||||||
if (ctype_isstruct(cct->info)) {
|
if (ctype_isstruct(cct->info)) {
|
||||||
@ -575,7 +589,7 @@ void LJ_FASTCALL recff_cdata_call(jit_State *J, RecordFFData *rd)
|
|||||||
{
|
{
|
||||||
GCcdata *cd = argv2cdata(J, J->base[0], &rd->argv[0]);
|
GCcdata *cd = argv2cdata(J, J->base[0], &rd->argv[0]);
|
||||||
if (cd->typeid == CTID_CTYPEID) {
|
if (cd->typeid == CTID_CTYPEID) {
|
||||||
crec_alloc(J, rd, *(CTypeID *)cdataptr(cd));
|
crec_alloc(J, rd, crec_constructor(J, cd, J->base[0]));
|
||||||
} else {
|
} else {
|
||||||
lj_trace_err(J, LJ_TRERR_BADTYPE);
|
lj_trace_err(J, LJ_TRERR_BADTYPE);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user