FFI: Compile VLA/VLS and large cdata allocs with default initialization.
This commit is contained in:
@@ -975,19 +975,15 @@ dotypecheck:
|
||||
static void asm_cnew(ASMState *as, IRIns *ir)
|
||||
{
|
||||
CTState *cts = ctype_ctsG(J2G(as->J));
|
||||
CTypeID ctypeid = (CTypeID)IR(ir->op1)->i;
|
||||
CTSize sz = (ir->o == IR_CNEWI || ir->op2 == REF_NIL) ?
|
||||
lj_ctype_size(cts, ctypeid) : (CTSize)IR(ir->op2)->i;
|
||||
CTypeID id = (CTypeID)IR(ir->op1)->i;
|
||||
CTSize sz;
|
||||
CTInfo info = lj_ctype_info(cts, id, &sz);
|
||||
const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco];
|
||||
IRRef args[2];
|
||||
RegSet allow = (RSET_GPR & ~RSET_SCRATCH);
|
||||
IRRef args[4];
|
||||
RegSet drop = RSET_SCRATCH;
|
||||
lua_assert(sz != CTSIZE_INVALID);
|
||||
lua_assert(sz != CTSIZE_INVALID || (ir->o == IR_CNEW && ir->op2 != REF_NIL));
|
||||
|
||||
args[0] = ASMREF_L; /* lua_State *L */
|
||||
args[1] = ASMREF_TMP1; /* MSize size */
|
||||
as->gcsteps++;
|
||||
|
||||
if (ra_hasreg(ir->r))
|
||||
rset_clear(drop, ir->r); /* Dest reg handled below. */
|
||||
ra_evictset(as, drop);
|
||||
@@ -996,6 +992,7 @@ static void asm_cnew(ASMState *as, IRIns *ir)
|
||||
|
||||
/* Initialize immutable cdata object. */
|
||||
if (ir->o == IR_CNEWI) {
|
||||
RegSet allow = (RSET_GPR & ~RSET_SCRATCH);
|
||||
int32_t ofs = sizeof(GCcdata);
|
||||
lua_assert(sz == 4 || sz == 8);
|
||||
if (sz == 8) {
|
||||
@@ -1010,12 +1007,24 @@ static void asm_cnew(ASMState *as, IRIns *ir)
|
||||
if (ofs == sizeof(GCcdata)) break;
|
||||
ofs -= 4; if (LJ_BE) ir++; else ir--;
|
||||
}
|
||||
} else if (ir->op2 != REF_NIL) { /* Create VLA/VLS/aligned cdata. */
|
||||
ci = &lj_ir_callinfo[IRCALL_lj_cdata_newv];
|
||||
args[0] = ASMREF_L; /* lua_State *L */
|
||||
args[1] = ir->op1; /* CTypeID id */
|
||||
args[2] = ir->op2; /* CTSize sz */
|
||||
args[3] = ASMREF_TMP1; /* CTSize align */
|
||||
asm_gencall(as, ci, args);
|
||||
emit_loadi(as, ra_releasetmp(as, ASMREF_TMP1), (int32_t)ctype_align(info));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize gct and ctypeid. lj_mem_newgco() already sets marked. */
|
||||
emit_tsi(as, MIPSI_SB, RID_RET+1, RID_RET, offsetof(GCcdata, gct));
|
||||
emit_tsi(as, MIPSI_SH, RID_TMP, RID_RET, offsetof(GCcdata, ctypeid));
|
||||
emit_ti(as, MIPSI_LI, RID_RET+1, ~LJ_TCDATA);
|
||||
emit_ti(as, MIPSI_LI, RID_TMP, ctypeid); /* Lower 16 bit used. Sign-ext ok. */
|
||||
emit_ti(as, MIPSI_LI, RID_TMP, id); /* Lower 16 bit used. Sign-ext ok. */
|
||||
args[0] = ASMREF_L; /* lua_State *L */
|
||||
args[1] = ASMREF_TMP1; /* MSize size */
|
||||
asm_gencall(as, ci, args);
|
||||
ra_allockreg(as, (int32_t)(sz+sizeof(GCcdata)),
|
||||
ra_releasetmp(as, ASMREF_TMP1));
|
||||
@@ -1197,11 +1206,16 @@ static void asm_arithov(ASMState *as, IRIns *ir)
|
||||
|
||||
static void asm_mulov(ASMState *as, IRIns *ir)
|
||||
{
|
||||
#if LJ_DUALNUM
|
||||
#error "NYI: MULOV"
|
||||
#else
|
||||
UNUSED(as); UNUSED(ir); lua_assert(0); /* Unused in single-number mode. */
|
||||
#endif
|
||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||
Reg tmp, right, left = ra_alloc2(as, ir, RSET_GPR);
|
||||
right = (left >> 8); left &= 255;
|
||||
tmp = ra_scratch(as, rset_exclude(rset_exclude(rset_exclude(RSET_GPR, left),
|
||||
right), dest));
|
||||
asm_guard(as, MIPSI_BNE, RID_TMP, tmp);
|
||||
emit_dta(as, MIPSI_SRA, RID_TMP, dest, 31);
|
||||
emit_dst(as, MIPSI_MFHI, tmp, 0, 0);
|
||||
emit_dst(as, MIPSI_MFLO, dest, 0, 0);
|
||||
emit_dst(as, MIPSI_MULT, 0, left, right);
|
||||
}
|
||||
|
||||
#if LJ_HASFFI
|
||||
|
||||
Reference in New Issue
Block a user