mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-06-18 02:59:21 +00:00
Fix fast jit issues (#1201)
This commit is contained in:
parent
9694ad7890
commit
66cd90d847
|
@ -2880,6 +2880,68 @@ alu_imm_imm_to_r_f32(x86::Assembler &a, ALU_OP op, int32 reg_no_dst,
|
||||||
return mov_imm_to_r_f32(a, reg_no_dst, data);
|
return mov_imm_to_r_f32(a, reg_no_dst, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
alu_r_m_float(x86::Assembler &a, ALU_OP op, int32 reg_no, x86::Mem &m,
|
||||||
|
bool is_f32)
|
||||||
|
{
|
||||||
|
switch (op) {
|
||||||
|
case ADD:
|
||||||
|
{
|
||||||
|
if (is_f32)
|
||||||
|
a.addss(regs_float[reg_no], m);
|
||||||
|
else
|
||||||
|
a.addsd(regs_float[reg_no], m);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SUB:
|
||||||
|
{
|
||||||
|
if (is_f32)
|
||||||
|
a.subss(regs_float[reg_no], m);
|
||||||
|
else
|
||||||
|
a.subsd(regs_float[reg_no], m);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MUL:
|
||||||
|
{
|
||||||
|
if (is_f32)
|
||||||
|
a.mulss(regs_float[reg_no], m);
|
||||||
|
else
|
||||||
|
a.mulsd(regs_float[reg_no], m);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_S:
|
||||||
|
{
|
||||||
|
if (is_f32)
|
||||||
|
a.divss(regs_float[reg_no], m);
|
||||||
|
else
|
||||||
|
a.divsd(regs_float[reg_no], m);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MAX:
|
||||||
|
{
|
||||||
|
if (is_f32)
|
||||||
|
a.maxss(regs_float[reg_no], m);
|
||||||
|
else
|
||||||
|
a.maxsd(regs_float[reg_no], m);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MIN:
|
||||||
|
{
|
||||||
|
if (is_f32)
|
||||||
|
a.minss(regs_float[reg_no], m);
|
||||||
|
else
|
||||||
|
a.minsd(regs_float[reg_no], m);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
bh_assert(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode float alu operation of imm and reg, and save result to reg
|
* Encode float alu operation of imm and reg, and save result to reg
|
||||||
*
|
*
|
||||||
|
@ -2902,10 +2964,9 @@ alu_imm_r_to_r_f32(x86::Assembler &a, ALU_OP op, int32 reg_no_dst,
|
||||||
a.movaps(cache, regs_float[reg_no2_src]);
|
a.movaps(cache, regs_float[reg_no2_src]);
|
||||||
|
|
||||||
/* imm -> gp -> xmm */
|
/* imm -> gp -> xmm */
|
||||||
mov_imm_to_r_f32(a, reg_no2_src, data1_src);
|
mov_imm_to_r_f32(a, reg_no_dst, data1_src);
|
||||||
|
|
||||||
a.addss(regs_float[reg_no2_src], cache);
|
return alu_r_m_float(a, op, reg_no_dst, cache, true);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2930,8 +2991,9 @@ alu_r_imm_to_r_f32(x86::Assembler &a, ALU_OP op, int32 reg_no_dst,
|
||||||
Imm imm(*(uint32 *)&data2_src);
|
Imm imm(*(uint32 *)&data2_src);
|
||||||
mov_imm_to_m(a, cache, imm, 4);
|
mov_imm_to_m(a, cache, imm, 4);
|
||||||
|
|
||||||
a.addss(regs_float[reg_no1_src], cache);
|
mov_r_to_r_f32(a, reg_no_dst, reg_no1_src);
|
||||||
return true;
|
|
||||||
|
return alu_r_m_float(a, op, reg_no_dst, cache, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3076,10 +3138,9 @@ alu_imm_r_to_r_f64(x86::Assembler &a, ALU_OP op, int32 reg_no_dst,
|
||||||
a.movapd(cache, regs_float[reg_no2_src]);
|
a.movapd(cache, regs_float[reg_no2_src]);
|
||||||
|
|
||||||
/* imm -> gp -> xmm */
|
/* imm -> gp -> xmm */
|
||||||
mov_imm_to_r_f64(a, reg_no2_src, data1_src);
|
mov_imm_to_r_f64(a, reg_no_dst, data1_src);
|
||||||
|
|
||||||
a.addsd(regs_float[reg_no2_src], cache);
|
return alu_r_m_float(a, op, reg_no_dst, cache, false);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3104,8 +3165,9 @@ alu_r_imm_to_r_f64(x86::Assembler &a, ALU_OP op, int32 reg_no_dst,
|
||||||
Imm imm(*(uint64 *)&data2_src);
|
Imm imm(*(uint64 *)&data2_src);
|
||||||
mov_imm_to_m(a, cache, imm, 8);
|
mov_imm_to_m(a, cache, imm, 8);
|
||||||
|
|
||||||
a.addsd(regs_float[reg_no1_src], cache);
|
mov_r_to_r_f64(a, reg_no_dst, reg_no1_src);
|
||||||
return true;
|
|
||||||
|
return alu_r_m_float(a, op, reg_no_dst, cache, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3359,18 +3421,42 @@ bit_r_imm_i64(x86::Assembler &a, BIT_OP op, int32 reg_no, int64 data)
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case OR:
|
case OR:
|
||||||
if (data != 0)
|
if (data != 0) {
|
||||||
|
if (data >= INT32_MIN && data <= INT32_MAX) {
|
||||||
|
imm.setValue((int32)data);
|
||||||
a.or_(regs_i64[reg_no], imm);
|
a.or_(regs_i64[reg_no], imm);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
a.mov(regs_i64[REG_I64_FREE_IDX], imm);
|
||||||
|
a.or_(regs_i64[reg_no], regs_i64[REG_I64_FREE_IDX]);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case XOR:
|
case XOR:
|
||||||
if (data == -1LL)
|
if (data == -1LL)
|
||||||
a.not_(regs_i64[reg_no]);
|
a.not_(regs_i64[reg_no]);
|
||||||
else if (data != 0)
|
else if (data != 0) {
|
||||||
|
if (data >= INT32_MIN && data <= INT32_MAX) {
|
||||||
|
imm.setValue((int32)data);
|
||||||
a.xor_(regs_i64[reg_no], imm);
|
a.xor_(regs_i64[reg_no], imm);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
a.mov(regs_i64[REG_I64_FREE_IDX], imm);
|
||||||
|
a.xor_(regs_i64[reg_no], regs_i64[REG_I64_FREE_IDX]);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case AND:
|
case AND:
|
||||||
if (data != -1LL)
|
if (data != -1LL) {
|
||||||
|
if (data >= INT32_MIN && data <= INT32_MAX) {
|
||||||
|
imm.setValue((int32)data);
|
||||||
a.and_(regs_i64[reg_no], imm);
|
a.and_(regs_i64[reg_no], imm);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
a.mov(regs_i64[REG_I64_FREE_IDX], imm);
|
||||||
|
a.and_(regs_i64[reg_no], regs_i64[REG_I64_FREE_IDX]);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
bh_assert(0);
|
bh_assert(0);
|
||||||
|
@ -4958,6 +5044,7 @@ fail:
|
||||||
* Encode detecting the cmp flags in reg, and jmp to the relative address
|
* Encode detecting the cmp flags in reg, and jmp to the relative address
|
||||||
* according to the condition opcode
|
* according to the condition opcode
|
||||||
*
|
*
|
||||||
|
* @param cc the compiler context
|
||||||
* @param a the assembler to emit the code
|
* @param a the assembler to emit the code
|
||||||
* @param reg_no the no of register which contains cmp flags of cmp result
|
* @param reg_no the no of register which contains cmp flags of cmp result
|
||||||
* @param op the condition opcode to jmp
|
* @param op the condition opcode to jmp
|
||||||
|
@ -4966,12 +5053,13 @@ fail:
|
||||||
* @return return the next address of native code after encoded
|
* @return return the next address of native code after encoded
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
cmp_r_and_jmp_relative(x86::Assembler &a, int32 reg_no, COND_OP op,
|
cmp_r_and_jmp_relative(JitCompContext *cc, x86::Assembler &a, int32 reg_no,
|
||||||
int32 offset)
|
COND_OP op, int32 offset)
|
||||||
{
|
{
|
||||||
Imm target(INT32_MAX);
|
Imm target(INT32_MAX);
|
||||||
char *stream = (char *)a.code()->sectionById(0)->buffer().data()
|
char *stream = (char *)a.code()->sectionById(0)->buffer().data()
|
||||||
+ a.code()->sectionById(0)->buffer().size();
|
+ a.code()->sectionById(0)->buffer().size();
|
||||||
|
bool fp_cmp = cc->last_cmp_on_fp;
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case EQ:
|
case EQ:
|
||||||
|
@ -4981,17 +5069,46 @@ cmp_r_and_jmp_relative(x86::Assembler &a, int32 reg_no, COND_OP op,
|
||||||
a.jne(target);
|
a.jne(target);
|
||||||
break;
|
break;
|
||||||
case GTS:
|
case GTS:
|
||||||
|
{
|
||||||
|
if (fp_cmp) {
|
||||||
|
a.jnbe(target);
|
||||||
|
}
|
||||||
|
else {
|
||||||
a.jg(target);
|
a.jg(target);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case LES:
|
case LES:
|
||||||
|
{
|
||||||
|
if (fp_cmp) {
|
||||||
|
a.jbe(target);
|
||||||
|
}
|
||||||
|
else {
|
||||||
a.jng(target);
|
a.jng(target);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case GES:
|
case GES:
|
||||||
a.jge(target);
|
{
|
||||||
|
if (fp_cmp) {
|
||||||
|
a.jnb(target);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
a.jnl(target);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case LTS:
|
case LTS:
|
||||||
|
{
|
||||||
|
if (fp_cmp) {
|
||||||
|
a.jb(target);
|
||||||
|
}
|
||||||
|
else {
|
||||||
a.jl(target);
|
a.jl(target);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case GTU:
|
case GTU:
|
||||||
a.ja(target);
|
a.ja(target);
|
||||||
break;
|
break;
|
||||||
|
@ -5074,7 +5191,8 @@ lower_select(JitCompContext *cc, x86::Assembler &a, COND_OP op, JitReg r0,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r3 && r0 != r3) {
|
if (r3 && r0 != r3) {
|
||||||
if (!cmp_r_and_jmp_relative(a, jit_reg_no(r1), op, (int32)size_mov2))
|
if (!cmp_r_and_jmp_relative(cc, a, jit_reg_no(r1), op,
|
||||||
|
(int32)size_mov2))
|
||||||
return false;
|
return false;
|
||||||
a.embedDataArray(TypeId::kInt8, stream_mov2, size_mov2);
|
a.embedDataArray(TypeId::kInt8, stream_mov2, size_mov2);
|
||||||
}
|
}
|
||||||
|
@ -6398,7 +6516,7 @@ static uint8 hreg_info_F32[3][16] = {
|
||||||
{ 0, 0, 0, 0, 0, 0, 0, 0,
|
{ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
1, 1, 1, 1, 1, 1, 1, 1 },
|
1, 1, 1, 1, 1, 1, 1, 1 },
|
||||||
{ 1, 1, 1, 1, 1, 1, 1, 1,
|
{ 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0 }, /* caller_saved_native */
|
1, 1, 1, 1, 1, 1, 1, 1 }, /* caller_saved_native */
|
||||||
{ 1, 1, 1, 1, 1, 1, 1, 1,
|
{ 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
1, 1, 1, 1, 1, 1, 1, 1 }, /* caller_saved_jitted */
|
1, 1, 1, 1, 1, 1, 1, 1 }, /* caller_saved_jitted */
|
||||||
};
|
};
|
||||||
|
@ -6409,7 +6527,7 @@ static uint8 hreg_info_F64[3][16] = {
|
||||||
{ 1, 1, 1, 1, 1, 1, 1, 1,
|
{ 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0 },
|
0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
{ 1, 1, 1, 1, 1, 1, 1, 1,
|
{ 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0 }, /* caller_saved_native */
|
1, 1, 1, 1, 1, 1, 1, 1 }, /* caller_saved_native */
|
||||||
{ 1, 1, 1, 1, 1, 1, 1, 1,
|
{ 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
1, 1, 1, 1, 1, 1, 1, 1 }, /* caller_saved_jitted */
|
1, 1, 1, 1, 1, 1, 1, 1 }, /* caller_saved_jitted */
|
||||||
};
|
};
|
||||||
|
@ -6466,12 +6584,16 @@ jit_codegen_get_hreg_by_name(const char *name)
|
||||||
return jit_reg_new(JIT_REG_KIND_I32, REG_ECX_IDX);
|
return jit_reg_new(JIT_REG_KIND_I32, REG_ECX_IDX);
|
||||||
else if (strcmp(name, "edx") == 0)
|
else if (strcmp(name, "edx") == 0)
|
||||||
return jit_reg_new(JIT_REG_KIND_I32, REG_EDX_IDX);
|
return jit_reg_new(JIT_REG_KIND_I32, REG_EDX_IDX);
|
||||||
|
else if (strcmp(name, "esi") == 0)
|
||||||
|
return jit_reg_new(JIT_REG_KIND_I32, REG_ESI_IDX);
|
||||||
else if (strcmp(name, "rax") == 0)
|
else if (strcmp(name, "rax") == 0)
|
||||||
return jit_reg_new(JIT_REG_KIND_I64, REG_RAX_IDX);
|
return jit_reg_new(JIT_REG_KIND_I64, REG_RAX_IDX);
|
||||||
else if (strcmp(name, "rcx") == 0)
|
else if (strcmp(name, "rcx") == 0)
|
||||||
return jit_reg_new(JIT_REG_KIND_I64, REG_RCX_IDX);
|
return jit_reg_new(JIT_REG_KIND_I64, REG_RCX_IDX);
|
||||||
else if (strcmp(name, "rdx") == 0)
|
else if (strcmp(name, "rdx") == 0)
|
||||||
return jit_reg_new(JIT_REG_KIND_I64, REG_RDX_IDX);
|
return jit_reg_new(JIT_REG_KIND_I64, REG_RDX_IDX);
|
||||||
|
else if (strcmp(name, "r9") == 0)
|
||||||
|
return jit_reg_new(JIT_REG_KIND_I64, REG_R9_IDX);
|
||||||
else if (strcmp(name, "xmm0") == 0)
|
else if (strcmp(name, "xmm0") == 0)
|
||||||
return jit_reg_new(JIT_REG_KIND_F32, 0);
|
return jit_reg_new(JIT_REG_KIND_F32, 0);
|
||||||
else if (strcmp(name, "xmm0_f64") == 0)
|
else if (strcmp(name, "xmm0_f64") == 0)
|
||||||
|
|
|
@ -255,13 +255,10 @@ pack_argv(JitCompContext *cc)
|
||||||
static bool
|
static bool
|
||||||
unpack_argv(JitCompContext *cc, const WASMType *func_type, JitReg argv)
|
unpack_argv(JitCompContext *cc, const WASMType *func_type, JitReg argv)
|
||||||
{
|
{
|
||||||
/* argv to stack*/
|
uint32 i, offset_by_cell = 0;
|
||||||
uint32 i, top_by_cell, offset_by_cell;
|
|
||||||
JitReg value;
|
JitReg value;
|
||||||
|
|
||||||
/* stack top */
|
/* push results in argv to stack*/
|
||||||
top_by_cell = cc->jit_frame->sp - cc->jit_frame->lp;
|
|
||||||
offset_by_cell = 0;
|
|
||||||
for (i = 0; i < func_type->result_count; i++) {
|
for (i = 0; i < func_type->result_count; i++) {
|
||||||
switch (func_type->types[func_type->param_count + i]) {
|
switch (func_type->types[func_type->param_count + i]) {
|
||||||
case VALUE_TYPE_I32:
|
case VALUE_TYPE_I32:
|
||||||
|
@ -272,40 +269,32 @@ unpack_argv(JitCompContext *cc, const WASMType *func_type, JitReg argv)
|
||||||
{
|
{
|
||||||
value = jit_cc_new_reg_I32(cc);
|
value = jit_cc_new_reg_I32(cc);
|
||||||
GEN_INSN(LDI32, value, argv, NEW_CONST(I32, offset_by_cell));
|
GEN_INSN(LDI32, value, argv, NEW_CONST(I32, offset_by_cell));
|
||||||
GEN_INSN(STI32, value, cc->fp_reg,
|
PUSH_I32(value);
|
||||||
NEW_CONST(I32, offset_of_local(top_by_cell
|
offset_by_cell += 4;
|
||||||
+ offset_by_cell)));
|
|
||||||
offset_by_cell += 1;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VALUE_TYPE_I64:
|
case VALUE_TYPE_I64:
|
||||||
{
|
{
|
||||||
value = jit_cc_new_reg_I64(cc);
|
value = jit_cc_new_reg_I64(cc);
|
||||||
GEN_INSN(LDI64, value, argv, NEW_CONST(I32, offset_by_cell));
|
GEN_INSN(LDI64, value, argv, NEW_CONST(I32, offset_by_cell));
|
||||||
GEN_INSN(STI64, value, cc->fp_reg,
|
PUSH_I64(value);
|
||||||
NEW_CONST(I32, offset_of_local(top_by_cell
|
offset_by_cell += 8;
|
||||||
+ offset_by_cell)));
|
|
||||||
offset_by_cell += 2;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VALUE_TYPE_F32:
|
case VALUE_TYPE_F32:
|
||||||
{
|
{
|
||||||
value = jit_cc_new_reg_F32(cc);
|
value = jit_cc_new_reg_F32(cc);
|
||||||
GEN_INSN(LDF32, value, argv, NEW_CONST(I32, offset_by_cell));
|
GEN_INSN(LDF32, value, argv, NEW_CONST(I32, offset_by_cell));
|
||||||
GEN_INSN(STF32, value, cc->fp_reg,
|
PUSH_F32(value);
|
||||||
NEW_CONST(I32, offset_of_local(top_by_cell
|
offset_by_cell += 4;
|
||||||
+ offset_by_cell)));
|
|
||||||
offset_by_cell += 1;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VALUE_TYPE_F64:
|
case VALUE_TYPE_F64:
|
||||||
{
|
{
|
||||||
value = jit_cc_new_reg_F64(cc);
|
value = jit_cc_new_reg_F64(cc);
|
||||||
GEN_INSN(LDF64, value, argv, NEW_CONST(I32, offset_by_cell));
|
GEN_INSN(LDF64, value, argv, NEW_CONST(I32, offset_by_cell));
|
||||||
GEN_INSN(STF64, value, cc->fp_reg,
|
PUSH_F64(value);
|
||||||
NEW_CONST(I32, offset_of_local(top_by_cell
|
offset_by_cell += 8;
|
||||||
+ offset_by_cell)));
|
|
||||||
offset_by_cell += 2;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -316,6 +305,9 @@ unpack_argv(JitCompContext *cc, const WASMType *func_type, JitReg argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Update the committed_sp as the callee has updated the frame sp */
|
||||||
|
cc->jit_frame->committed_sp = cc->jit_frame->sp;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
fail:
|
fail:
|
||||||
return false;
|
return false;
|
||||||
|
@ -325,11 +317,14 @@ bool
|
||||||
jit_compile_op_call_indirect(JitCompContext *cc, uint32 type_idx,
|
jit_compile_op_call_indirect(JitCompContext *cc, uint32 type_idx,
|
||||||
uint32 tbl_idx)
|
uint32 tbl_idx)
|
||||||
{
|
{
|
||||||
JitReg element_indices, native_ret, argv;
|
JitReg elem_idx, native_ret, argv;
|
||||||
|
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
|
||||||
|
JitReg edx_hreg, r9_hreg;
|
||||||
|
#endif
|
||||||
WASMType *func_type;
|
WASMType *func_type;
|
||||||
JitInsn *insn;
|
JitInsn *insn;
|
||||||
|
|
||||||
POP_I32(element_indices);
|
POP_I32(elem_idx);
|
||||||
|
|
||||||
func_type = cc->cur_wasm_module->types[type_idx];
|
func_type = cc->cur_wasm_module->types[type_idx];
|
||||||
if (!pre_call(cc, func_type)) {
|
if (!pre_call(cc, func_type)) {
|
||||||
|
@ -341,23 +336,34 @@ jit_compile_op_call_indirect(JitCompContext *cc, uint32 type_idx,
|
||||||
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
|
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
|
||||||
/* Set native_ret to x86::eax */
|
/* Set native_ret to x86::eax */
|
||||||
native_ret = jit_codegen_get_hreg_by_name("eax");
|
native_ret = jit_codegen_get_hreg_by_name("eax");
|
||||||
|
|
||||||
|
edx_hreg = jit_codegen_get_hreg_by_name("edx");
|
||||||
|
GEN_INSN(MOV, edx_hreg, elem_idx);
|
||||||
|
elem_idx = edx_hreg;
|
||||||
|
|
||||||
|
r9_hreg = jit_codegen_get_hreg_by_name("r9");
|
||||||
|
GEN_INSN(MOV, r9_hreg, argv);
|
||||||
|
argv = r9_hreg;
|
||||||
#else
|
#else
|
||||||
native_ret = jit_cc_new_reg_I32(cc);
|
native_ret = jit_cc_new_reg_I32(cc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
insn = GEN_INSN(CALLNATIVE, native_ret,
|
insn = GEN_INSN(CALLNATIVE, native_ret,
|
||||||
NEW_CONST(PTR, (uintptr_t)wasm_call_indirect), 5);
|
NEW_CONST(PTR, (uintptr_t)jit_call_indirect), 6);
|
||||||
if (!insn) {
|
if (!insn) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(jit_insn_opndv(insn, 2)) = cc->exec_env_reg;
|
*(jit_insn_opndv(insn, 2)) = cc->exec_env_reg;
|
||||||
*(jit_insn_opndv(insn, 3)) = NEW_CONST(I32, tbl_idx);
|
*(jit_insn_opndv(insn, 3)) = NEW_CONST(I32, tbl_idx);
|
||||||
*(jit_insn_opndv(insn, 4)) = element_indices;
|
*(jit_insn_opndv(insn, 4)) = elem_idx;
|
||||||
*(jit_insn_opndv(insn, 5)) = NEW_CONST(I32, func_type->param_count);
|
*(jit_insn_opndv(insn, 5)) = NEW_CONST(I32, type_idx);
|
||||||
*(jit_insn_opndv(insn, 6)) = argv;
|
*(jit_insn_opndv(insn, 6)) = NEW_CONST(I32, func_type->param_cell_num);
|
||||||
|
*(jit_insn_opndv(insn, 7)) = argv;
|
||||||
|
|
||||||
|
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
|
||||||
jit_lock_reg_in_insn(cc, insn, native_ret);
|
jit_lock_reg_in_insn(cc, insn, native_ret);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Check whether there is exception thrown */
|
/* Check whether there is exception thrown */
|
||||||
GEN_INSN(CMP, cc->cmp_reg, native_ret, NEW_CONST(I32, 0));
|
GEN_INSN(CMP, cc->cmp_reg, native_ret, NEW_CONST(I32, 0));
|
||||||
|
@ -370,10 +376,6 @@ jit_compile_op_call_indirect(JitCompContext *cc, uint32 type_idx,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!post_return(cc, func_type)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear part of memory regs and table regs as their values
|
/* Clear part of memory regs and table regs as their values
|
||||||
may be changed in the function call */
|
may be changed in the function call */
|
||||||
if (cc->cur_wasm_module->possible_memory_grow)
|
if (cc->cur_wasm_module->possible_memory_grow)
|
||||||
|
|
|
@ -476,6 +476,9 @@ bool
|
||||||
jit_compile_op_memory_grow(JitCompContext *cc, uint32 mem_idx)
|
jit_compile_op_memory_grow(JitCompContext *cc, uint32 mem_idx)
|
||||||
{
|
{
|
||||||
JitReg delta, module_inst, grow_result, res, memory_inst, prev_page_count;
|
JitReg delta, module_inst, grow_result, res, memory_inst, prev_page_count;
|
||||||
|
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
|
||||||
|
JitReg esi_hreg;
|
||||||
|
#endif
|
||||||
JitInsn *insn;
|
JitInsn *insn;
|
||||||
|
|
||||||
/* WASMMemoryInstance->cur_page_count before enlarging */
|
/* WASMMemoryInstance->cur_page_count before enlarging */
|
||||||
|
@ -491,14 +494,24 @@ jit_compile_op_memory_grow(JitCompContext *cc, uint32 mem_idx)
|
||||||
#else
|
#else
|
||||||
grow_result = jit_cc_new_reg_I32(cc);
|
grow_result = jit_cc_new_reg_I32(cc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
POP_I32(delta);
|
POP_I32(delta);
|
||||||
|
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
|
||||||
|
esi_hreg = jit_codegen_get_hreg_by_name("esi");
|
||||||
|
GEN_INSN(MOV, esi_hreg, delta);
|
||||||
|
delta = esi_hreg;
|
||||||
|
#endif
|
||||||
|
|
||||||
module_inst = get_module_inst_reg(cc->jit_frame);
|
module_inst = get_module_inst_reg(cc->jit_frame);
|
||||||
|
|
||||||
insn = GEN_INSN(CALLNATIVE, grow_result,
|
insn = GEN_INSN(CALLNATIVE, grow_result,
|
||||||
NEW_CONST(PTR, (uintptr_t)wasm_enlarge_memory), 2);
|
NEW_CONST(PTR, (uintptr_t)wasm_enlarge_memory), 2);
|
||||||
if (insn) {
|
if (!insn) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
*(jit_insn_opndv(insn, 2)) = module_inst;
|
*(jit_insn_opndv(insn, 2)) = module_inst;
|
||||||
*(jit_insn_opndv(insn, 3)) = delta;
|
*(jit_insn_opndv(insn, 3)) = delta;
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
|
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
|
||||||
jit_lock_reg_in_insn(cc, insn, grow_result);
|
jit_lock_reg_in_insn(cc, insn, grow_result);
|
||||||
|
|
|
@ -1322,36 +1322,117 @@ jit_compile_op_i64_shift(JitCompContext *cc, IntShift shift_op)
|
||||||
return compile_op_int_shift(cc, shift_op, false);
|
return compile_op_int_shift(cc, shift_op, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float32
|
||||||
|
negf(float32 f32)
|
||||||
|
{
|
||||||
|
return -f32;
|
||||||
|
}
|
||||||
|
|
||||||
|
static float64
|
||||||
|
neg(float64 f64)
|
||||||
|
{
|
||||||
|
return -f64;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
compile_op_float_math(JitCompContext *cc, FloatMath math_op, bool is_f32)
|
||||||
|
{
|
||||||
|
JitReg value, res, xmm0;
|
||||||
|
JitInsn *insn = NULL;
|
||||||
|
void *func = NULL;
|
||||||
|
|
||||||
|
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
|
||||||
|
if (is_f32) {
|
||||||
|
res = xmm0 = jit_codegen_get_hreg_by_name("xmm0");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
res = jit_codegen_get_hreg_by_name("xmm0_f64");
|
||||||
|
xmm0 = jit_codegen_get_hreg_by_name("xmm0");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (is_f32)
|
||||||
|
res = jit_cc_new_reg_F32(cc);
|
||||||
|
else
|
||||||
|
res = jit_cc_new_reg_F64(cc);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (is_f32)
|
||||||
|
POP_F32(value);
|
||||||
|
else
|
||||||
|
POP_F64(value);
|
||||||
|
|
||||||
|
switch (math_op) {
|
||||||
|
case FLOAT_ABS:
|
||||||
|
func = is_f32 ? (void *)fabsf : (void *)fabs;
|
||||||
|
break;
|
||||||
|
case FLOAT_NEG:
|
||||||
|
func = is_f32 ? (void *)negf : (void *)neg;
|
||||||
|
break;
|
||||||
|
case FLOAT_CEIL:
|
||||||
|
func = is_f32 ? (void *)ceilf : (void *)ceil;
|
||||||
|
break;
|
||||||
|
case FLOAT_FLOOR:
|
||||||
|
func = is_f32 ? (void *)floorf : (void *)floor;
|
||||||
|
break;
|
||||||
|
case FLOAT_TRUNC:
|
||||||
|
func = is_f32 ? (void *)truncf : (void *)trunc;
|
||||||
|
break;
|
||||||
|
case FLOAT_NEAREST:
|
||||||
|
func = is_f32 ? (void *)rintf : (void *)rint;
|
||||||
|
break;
|
||||||
|
case FLOAT_SQRT:
|
||||||
|
func = is_f32 ? (void *)sqrtf : (void *)sqrt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
insn = GEN_INSN(CALLNATIVE, res, NEW_CONST(PTR, (uintptr_t)func), 1);
|
||||||
|
if (!insn) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
*(jit_insn_opndv(insn, 2)) = value;
|
||||||
|
|
||||||
|
if (is_f32)
|
||||||
|
PUSH_F32(res);
|
||||||
|
else
|
||||||
|
PUSH_F64(res);
|
||||||
|
|
||||||
|
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
|
||||||
|
jit_lock_reg_in_insn(cc, insn, xmm0);
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
fail:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_f32_math(JitCompContext *cc, FloatMath math_op)
|
jit_compile_op_f32_math(JitCompContext *cc, FloatMath math_op)
|
||||||
{
|
{
|
||||||
bh_assert(0);
|
return compile_op_float_math(cc, math_op, true);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_f64_math(JitCompContext *cc, FloatMath math_op)
|
jit_compile_op_f64_math(JitCompContext *cc, FloatMath math_op)
|
||||||
{
|
{
|
||||||
bh_assert(0);
|
return compile_op_float_math(cc, math_op, false);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
static bool
|
||||||
jit_compile_op_f32_arithmetic(JitCompContext *cc, FloatArithmetic arith_op)
|
compile_op_float_arithmetic(JitCompContext *cc, FloatArithmetic arith_op,
|
||||||
{
|
bool is_f32)
|
||||||
bh_assert(0);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
jit_compile_op_f64_arithmetic(JitCompContext *cc, FloatArithmetic arith_op)
|
|
||||||
{
|
{
|
||||||
JitReg lhs, rhs, res;
|
JitReg lhs, rhs, res;
|
||||||
|
|
||||||
|
if (is_f32) {
|
||||||
|
POP_F32(rhs);
|
||||||
|
POP_F32(lhs);
|
||||||
|
res = jit_cc_new_reg_F32(cc);
|
||||||
|
}
|
||||||
|
else {
|
||||||
POP_F64(rhs);
|
POP_F64(rhs);
|
||||||
POP_F64(lhs);
|
POP_F64(lhs);
|
||||||
|
|
||||||
res = jit_cc_new_reg_F64(cc);
|
res = jit_cc_new_reg_F64(cc);
|
||||||
|
}
|
||||||
|
|
||||||
switch (arith_op) {
|
switch (arith_op) {
|
||||||
case FLOAT_ADD:
|
case FLOAT_ADD:
|
||||||
{
|
{
|
||||||
|
@ -1391,6 +1472,9 @@ jit_compile_op_f64_arithmetic(JitCompContext *cc, FloatArithmetic arith_op)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_f32)
|
||||||
|
PUSH_F32(res);
|
||||||
|
else
|
||||||
PUSH_F64(res);
|
PUSH_F64(res);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1398,6 +1482,18 @@ fail:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
jit_compile_op_f32_arithmetic(JitCompContext *cc, FloatArithmetic arith_op)
|
||||||
|
{
|
||||||
|
return compile_op_float_arithmetic(cc, arith_op, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
jit_compile_op_f64_arithmetic(JitCompContext *cc, FloatArithmetic arith_op)
|
||||||
|
{
|
||||||
|
return compile_op_float_arithmetic(cc, arith_op, false);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_f32_copysign(JitCompContext *cc)
|
jit_compile_op_f32_copysign(JitCompContext *cc)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,6 +11,7 @@ pop_value_from_wasm_stack(JitCompContext *cc, bool is_32bit, JitReg *p_value,
|
||||||
uint8 *p_type)
|
uint8 *p_type)
|
||||||
{
|
{
|
||||||
JitValue *jit_value;
|
JitValue *jit_value;
|
||||||
|
JitReg value;
|
||||||
uint8 type;
|
uint8 type;
|
||||||
|
|
||||||
if (!jit_block_stack_top(&cc->block_stack)) {
|
if (!jit_block_stack_top(&cc->block_stack)) {
|
||||||
|
@ -29,9 +30,6 @@ pop_value_from_wasm_stack(JitCompContext *cc, bool is_32bit, JitReg *p_value,
|
||||||
if (p_type != NULL) {
|
if (p_type != NULL) {
|
||||||
*p_type = jit_value->type;
|
*p_type = jit_value->type;
|
||||||
}
|
}
|
||||||
if (p_value != NULL) {
|
|
||||||
*p_value = jit_value->value->reg;
|
|
||||||
}
|
|
||||||
|
|
||||||
wasm_runtime_free(jit_value);
|
wasm_runtime_free(jit_value);
|
||||||
|
|
||||||
|
@ -57,19 +55,25 @@ pop_value_from_wasm_stack(JitCompContext *cc, bool is_32bit, JitReg *p_value,
|
||||||
case VALUE_TYPE_FUNCREF:
|
case VALUE_TYPE_FUNCREF:
|
||||||
case VALUE_TYPE_EXTERNREF:
|
case VALUE_TYPE_EXTERNREF:
|
||||||
#endif
|
#endif
|
||||||
pop_i32(cc->jit_frame);
|
value = pop_i32(cc->jit_frame);
|
||||||
break;
|
break;
|
||||||
case VALUE_TYPE_I64:
|
case VALUE_TYPE_I64:
|
||||||
pop_i64(cc->jit_frame);
|
value = pop_i64(cc->jit_frame);
|
||||||
break;
|
break;
|
||||||
case VALUE_TYPE_F32:
|
case VALUE_TYPE_F32:
|
||||||
pop_f32(cc->jit_frame);
|
value = pop_f32(cc->jit_frame);
|
||||||
break;
|
break;
|
||||||
case VALUE_TYPE_F64:
|
case VALUE_TYPE_F64:
|
||||||
pop_f64(cc->jit_frame);
|
value = pop_f64(cc->jit_frame);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
bh_assert(0);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p_value != NULL) {
|
||||||
|
*p_value = value;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,10 +103,23 @@ jit_compile_op_select(JitCompContext *cc, bool is_select_32)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_select_32)
|
switch (val1_type) {
|
||||||
|
case VALUE_TYPE_I32:
|
||||||
selected = jit_cc_new_reg_I32(cc);
|
selected = jit_cc_new_reg_I32(cc);
|
||||||
else
|
break;
|
||||||
|
case VALUE_TYPE_I64:
|
||||||
selected = jit_cc_new_reg_I64(cc);
|
selected = jit_cc_new_reg_I64(cc);
|
||||||
|
break;
|
||||||
|
case VALUE_TYPE_F32:
|
||||||
|
selected = jit_cc_new_reg_F32(cc);
|
||||||
|
break;
|
||||||
|
case VALUE_TYPE_F64:
|
||||||
|
selected = jit_cc_new_reg_F64(cc);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bh_assert(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
GEN_INSN(CMP, cc->cmp_reg, cond, NEW_CONST(I32, 0));
|
GEN_INSN(CMP, cc->cmp_reg, cond, NEW_CONST(I32, 0));
|
||||||
GEN_INSN(SELECTNE, selected, cc->cmp_reg, val1, val2);
|
GEN_INSN(SELECTNE, selected, cc->cmp_reg, val1, val2);
|
||||||
|
|
|
@ -396,6 +396,8 @@ clear_values(JitFrame *frame)
|
||||||
size_t total_size =
|
size_t total_size =
|
||||||
sizeof(JitValueSlot) * (frame->max_locals + frame->max_stacks);
|
sizeof(JitValueSlot) * (frame->max_locals + frame->max_stacks);
|
||||||
memset(frame->lp, 0, total_size);
|
memset(frame->lp, 0, total_size);
|
||||||
|
frame->committed_sp = NULL;
|
||||||
|
frame->committed_ip = NULL;
|
||||||
clear_fixed_virtual_regs(frame);
|
clear_fixed_virtual_regs(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ wasm_load(uint8 *buf, uint32 size, char *error_buf, uint32 error_buf_size)
|
||||||
|
|
||||||
WASMModule *
|
WASMModule *
|
||||||
wasm_load_from_sections(WASMSection *section_list, char *error_buf,
|
wasm_load_from_sections(WASMSection *section_list, char *error_buf,
|
||||||
uint32_t error_buf_size)
|
uint32 error_buf_size)
|
||||||
{
|
{
|
||||||
return wasm_loader_load_from_sections(section_list, error_buf,
|
return wasm_loader_load_from_sections(section_list, error_buf,
|
||||||
error_buf_size);
|
error_buf_size);
|
||||||
|
@ -1509,8 +1509,8 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst, uint32 stack_size,
|
||||||
if (stack_size == 0)
|
if (stack_size == 0)
|
||||||
stack_size = DEFAULT_WASM_STACK_SIZE;
|
stack_size = DEFAULT_WASM_STACK_SIZE;
|
||||||
#if WASM_ENABLE_SPEC_TEST != 0
|
#if WASM_ENABLE_SPEC_TEST != 0
|
||||||
if (stack_size < 48 * 1024)
|
if (stack_size < 100 * 1024)
|
||||||
stack_size = 48 * 1024;
|
stack_size = 100 * 1024;
|
||||||
#endif
|
#endif
|
||||||
module_inst->default_wasm_stack_size = stack_size;
|
module_inst->default_wasm_stack_size = stack_size;
|
||||||
|
|
||||||
|
@ -2270,14 +2270,14 @@ wasm_enlarge_table(WASMModuleInstance *module_inst, uint32 table_idx,
|
||||||
}
|
}
|
||||||
#endif /* WASM_ENABLE_REF_TYPES != 0 */
|
#endif /* WASM_ENABLE_REF_TYPES != 0 */
|
||||||
|
|
||||||
bool
|
static bool
|
||||||
wasm_call_indirect(WASMExecEnv *exec_env, uint32_t tbl_idx,
|
call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 elem_idx,
|
||||||
uint32_t element_indices, uint32_t argc, uint32_t argv[])
|
uint32 argc, uint32 argv[], bool check_type_idx, uint32 type_idx)
|
||||||
{
|
{
|
||||||
WASMModuleInstance *module_inst = NULL;
|
WASMModuleInstance *module_inst = NULL;
|
||||||
WASMTableInstance *table_inst = NULL;
|
WASMTableInstance *table_inst = NULL;
|
||||||
uint32_t function_indices = 0;
|
uint32 func_idx = 0;
|
||||||
WASMFunctionInstance *function_inst = NULL;
|
WASMFunctionInstance *func_inst = NULL;
|
||||||
|
|
||||||
module_inst = (WASMModuleInstance *)exec_env->module_inst;
|
module_inst = (WASMModuleInstance *)exec_env->module_inst;
|
||||||
bh_assert(module_inst);
|
bh_assert(module_inst);
|
||||||
|
@ -2288,7 +2288,7 @@ wasm_call_indirect(WASMExecEnv *exec_env, uint32_t tbl_idx,
|
||||||
goto got_exception;
|
goto got_exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (element_indices >= table_inst->cur_size) {
|
if (elem_idx >= table_inst->cur_size) {
|
||||||
wasm_set_exception(module_inst, "undefined element");
|
wasm_set_exception(module_inst, "undefined element");
|
||||||
goto got_exception;
|
goto got_exception;
|
||||||
}
|
}
|
||||||
|
@ -2297,8 +2297,8 @@ wasm_call_indirect(WASMExecEnv *exec_env, uint32_t tbl_idx,
|
||||||
* please be aware that table_inst->base_addr may point
|
* please be aware that table_inst->base_addr may point
|
||||||
* to another module's table
|
* to another module's table
|
||||||
**/
|
**/
|
||||||
function_indices = ((uint32_t *)table_inst->base_addr)[element_indices];
|
func_idx = ((uint32 *)table_inst->base_addr)[elem_idx];
|
||||||
if (function_indices == NULL_REF) {
|
if (func_idx == NULL_REF) {
|
||||||
wasm_set_exception(module_inst, "uninitialized element");
|
wasm_set_exception(module_inst, "uninitialized element");
|
||||||
goto got_exception;
|
goto got_exception;
|
||||||
}
|
}
|
||||||
|
@ -2306,14 +2306,29 @@ wasm_call_indirect(WASMExecEnv *exec_env, uint32_t tbl_idx,
|
||||||
/**
|
/**
|
||||||
* we insist to call functions owned by the module itself
|
* we insist to call functions owned by the module itself
|
||||||
**/
|
**/
|
||||||
if (function_indices >= module_inst->function_count) {
|
if (func_idx >= module_inst->function_count) {
|
||||||
wasm_set_exception(module_inst, "unknown function");
|
wasm_set_exception(module_inst, "unknown function");
|
||||||
goto got_exception;
|
goto got_exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
function_inst = module_inst->functions + function_indices;
|
func_inst = module_inst->functions + func_idx;
|
||||||
|
|
||||||
wasm_interp_call_wasm(module_inst, exec_env, function_inst, argc, argv);
|
if (check_type_idx) {
|
||||||
|
WASMType *cur_type = module_inst->module->types[type_idx];
|
||||||
|
WASMType *cur_func_type;
|
||||||
|
|
||||||
|
if (func_inst->is_import_func)
|
||||||
|
cur_func_type = func_inst->u.func_import->func_type;
|
||||||
|
else
|
||||||
|
cur_func_type = func_inst->u.func->func_type;
|
||||||
|
|
||||||
|
if (!wasm_type_equal(cur_type, cur_func_type)) {
|
||||||
|
wasm_set_exception(module_inst, "indirect call type mismatch");
|
||||||
|
goto got_exception;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_interp_call_wasm(module_inst, exec_env, func_inst, argc, argv);
|
||||||
|
|
||||||
(void)clear_wasi_proc_exit_exception(module_inst);
|
(void)clear_wasi_proc_exit_exception(module_inst);
|
||||||
return !wasm_get_exception(module_inst) ? true : false;
|
return !wasm_get_exception(module_inst) ? true : false;
|
||||||
|
@ -2322,6 +2337,23 @@ got_exception:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
wasm_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 elem_idx,
|
||||||
|
uint32 argc, uint32 argv[])
|
||||||
|
{
|
||||||
|
return call_indirect(exec_env, tbl_idx, elem_idx, argc, argv, false, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if WASM_ENABLE_FAST_JIT != 0
|
||||||
|
bool
|
||||||
|
jit_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 elem_idx,
|
||||||
|
uint32 type_idx, uint32 argc, uint32 argv[])
|
||||||
|
{
|
||||||
|
return call_indirect(exec_env, tbl_idx, elem_idx, argc, argv, true,
|
||||||
|
type_idx);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if WASM_ENABLE_THREAD_MGR != 0
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
bool
|
bool
|
||||||
wasm_set_aux_stack(WASMExecEnv *exec_env, uint32 start_offset, uint32 size)
|
wasm_set_aux_stack(WASMExecEnv *exec_env, uint32 start_offset, uint32 size)
|
||||||
|
|
|
@ -296,7 +296,7 @@ wasm_load(uint8 *buf, uint32 size, char *error_buf, uint32 error_buf_size);
|
||||||
|
|
||||||
WASMModule *
|
WASMModule *
|
||||||
wasm_load_from_sections(WASMSection *section_list, char *error_buf,
|
wasm_load_from_sections(WASMSection *section_list, char *error_buf,
|
||||||
uint32_t error_buf_size);
|
uint32 error_buf_size);
|
||||||
|
|
||||||
void
|
void
|
||||||
wasm_unload(WASMModule *module);
|
wasm_unload(WASMModule *module);
|
||||||
|
@ -382,16 +382,22 @@ wasm_get_app_addr_range(WASMModuleInstance *module_inst, uint32 app_offset,
|
||||||
uint32 *p_app_start_offset, uint32 *p_app_end_offset);
|
uint32 *p_app_start_offset, uint32 *p_app_end_offset);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
wasm_get_native_addr_range(WASMModuleInstance *module_inst, uint8_t *native_ptr,
|
wasm_get_native_addr_range(WASMModuleInstance *module_inst, uint8 *native_ptr,
|
||||||
uint8_t **p_native_start_addr,
|
uint8 **p_native_start_addr,
|
||||||
uint8_t **p_native_end_addr);
|
uint8 **p_native_end_addr);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count);
|
wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
wasm_call_indirect(WASMExecEnv *exec_env, uint32_t tbl_idx,
|
wasm_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 elem_idx,
|
||||||
uint32_t element_indices, uint32_t argc, uint32_t argv[]);
|
uint32 argc, uint32 argv[]);
|
||||||
|
|
||||||
|
#if WASM_ENABLE_FAST_JIT != 0
|
||||||
|
bool
|
||||||
|
jit_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 elem_idx,
|
||||||
|
uint32 type_idx, uint32 argc, uint32 argv[]);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if WASM_ENABLE_THREAD_MGR != 0
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
bool
|
bool
|
||||||
|
|
Loading…
Reference in New Issue
Block a user