Implement multi-value feature and import binarydump tool (#308)

This commit is contained in:
Weining
2020-07-10 16:29:15 +08:00
committed by GitHub
parent 16a284a67c
commit 1a85051415
25 changed files with 2660 additions and 812 deletions

View File

@ -66,10 +66,10 @@ extern "C" {
#define EXPORT_KIND_MEMORY 2
#define EXPORT_KIND_GLOBAL 3
#define BLOCK_TYPE_BLOCK 0
#define BLOCK_TYPE_LOOP 1
#define BLOCK_TYPE_IF 2
#define BLOCK_TYPE_FUNCTION 3
#define LABEL_TYPE_BLOCK 0
#define LABEL_TYPE_LOOP 1
#define LABEL_TYPE_IF 2
#define LABEL_TYPE_FUNCTION 3
typedef struct WASMModule WASMModule;
typedef struct WASMFunction WASMFunction;
@ -98,9 +98,10 @@ typedef struct InitializerExpression {
} InitializerExpression;
typedef struct WASMType {
uint32 param_count;
/* only one result is supported currently */
uint32 result_count;
uint16 param_count;
uint16 result_count;
uint16 param_cell_num;
uint16 ret_cell_num;
/* types of params and results */
uint8 types[1];
} WASMType;
@ -206,7 +207,7 @@ typedef struct WASMFunction {
uint16 ret_cell_num;
/* cell num of local variables */
uint16 local_cell_num;
/* offset of each local, including function paramameters
/* offset of each local, including function parameters
and local variables */
uint16 *local_offsets;
@ -351,9 +352,21 @@ typedef struct WASMModule {
#endif
} WASMModule;
typedef struct BlockType {
/* Block type may be expressed in one of two forms:
* either by the type of the single return value or
* by a type index of module.
*/
union {
uint8 value_type;
WASMType *type;
} u;
bool is_value_type;
} BlockType;
typedef struct WASMBranchBlock {
uint8 block_type;
uint8 return_type;
uint8 label_type;
uint32 cell_num;
uint8 *target_addr;
uint32 *frame_sp;
} WASMBranchBlock;
@ -421,40 +434,28 @@ wasm_value_type_size(uint8 value_type)
inline static uint16
wasm_value_type_cell_num(uint8 value_type)
{
switch (value_type) {
case VALUE_TYPE_I32:
case VALUE_TYPE_F32:
return 1;
case VALUE_TYPE_I64:
case VALUE_TYPE_F64:
return 2;
default:
bh_assert(0);
if (value_type == VALUE_TYPE_VOID)
return 0;
else if (value_type == VALUE_TYPE_I32
|| value_type == VALUE_TYPE_F32)
return 1;
else if (value_type == VALUE_TYPE_I64
|| value_type == VALUE_TYPE_F64)
return 2;
else {
bh_assert(0);
}
return 0;
}
inline static uint16
inline static uint32
wasm_get_cell_num(const uint8 *types, uint32 type_count)
{
uint32 cell_num = 0;
uint32 i;
for (i = 0; i < type_count; i++)
cell_num += wasm_value_type_cell_num(types[i]);
return (uint16)cell_num;
}
inline static uint16
wasm_type_param_cell_num(const WASMType *type)
{
return wasm_get_cell_num(type->types, type->param_count);
}
inline static uint16
wasm_type_return_cell_num(const WASMType *type)
{
return wasm_get_cell_num(type->types + type->param_count,
type->result_count);
return cell_num;
}
inline static bool
@ -467,8 +468,45 @@ wasm_type_equal(const WASMType *type1, const WASMType *type2)
? true : false;
}
static inline uint32
block_type_get_param_types(BlockType *block_type,
uint8 **p_param_types)
{
uint32 param_count = 0;
if (!block_type->is_value_type) {
WASMType *wasm_type = block_type->u.type;
*p_param_types = wasm_type->types;
param_count = wasm_type->param_count;
}
else {
*p_param_types = NULL;
param_count = 0;
}
return param_count;
}
static inline uint32
block_type_get_result_types(BlockType *block_type,
uint8 **p_result_types)
{
uint32 result_count = 0;
if (block_type->is_value_type) {
if (block_type->u.value_type != VALUE_TYPE_VOID) {
*p_result_types = &block_type->u.value_type;
result_count = 1;
}
}
else {
WASMType *wasm_type = block_type->u.type;
*p_result_types = wasm_type->types + wasm_type->param_count;
result_count = wasm_type->result_count;
}
return result_count;
}
#ifdef __cplusplus
} /* end of extern "C" */
#endif
#endif /* end of _WASM_H_ */
#endif /* end of _WASM_H_ */

View File

@ -27,8 +27,8 @@ typedef struct WASMInterpFrame {
uint8 *ip;
#if WASM_ENABLE_FAST_INTERP != 0
/* return offset of current frame.
the callee will put return value here */
/* return offset of the first return value of current frame.
the callee will put return values here continuously */
uint32 ret_offset;
uint32 *lp;
uint32 operand[1];

View File

@ -414,13 +414,13 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
frame_sp += 2; \
} while (0)
#define PUSH_CSP(type, ret_type, _target_addr) do { \
bh_assert(frame_csp < frame->csp_boundary); \
frame_csp->block_type = type; \
frame_csp->return_type = ret_type; \
frame_csp->target_addr = _target_addr; \
frame_csp->frame_sp = frame_sp; \
frame_csp++; \
#define PUSH_CSP(_label_type, cell_num, _target_addr) do { \
bh_assert(frame_csp < frame->csp_boundary); \
frame_csp->label_type = _label_type; \
frame_csp->cell_num = cell_num; \
frame_csp->target_addr = _target_addr; \
frame_csp->frame_sp = frame_sp; \
frame_csp++; \
} while (0)
#define POP_I32() (--frame_sp, *(int32*)frame_sp)
@ -442,21 +442,15 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
#define POP_CSP_N(n) do { \
uint32 *frame_sp_old = frame_sp; \
uint32 cell_num = 0; \
POP_CSP_CHECK_OVERFLOW(n + 1); \
frame_csp -= n; \
frame_ip = (frame_csp - 1)->target_addr; \
/* copy return value of block */ \
/* copy arity values of block */ \
frame_sp = (frame_csp - 1)->frame_sp; \
switch ((frame_csp - 1)->return_type) { \
case VALUE_TYPE_I32: \
case VALUE_TYPE_F32: \
PUSH_I32(*(frame_sp_old - 1)); \
break; \
case VALUE_TYPE_I64: \
case VALUE_TYPE_F64: \
PUSH_I64(GET_I64_FROM_ADDR(frame_sp_old - 2)); \
break; \
} \
cell_num = (frame_csp - 1)->cell_num; \
word_copy(frame_sp, frame_sp_old - cell_num, cell_num); \
frame_sp += cell_num; \
} while (0)
/* Pop the given number of elements from the given frame's stack. */
@ -974,6 +968,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint8 *global_data = module->global_data;
uint32 linear_mem_size = memory ? num_bytes_per_page * memory->cur_page_count : 0;
WASMTableInstance *table = module->default_table;
WASMType **wasm_types = module->module->types;
WASMGlobalInstance *globals = module->globals, *global;
uint8 opcode_IMPDEP = WASM_OP_IMPDEP;
WASMInterpFrame *frame = NULL;
@ -984,7 +979,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMBranchBlock *frame_csp = NULL;
BlockAddr *cache_items;
uint8 *frame_ip_end = frame_ip + 1;
uint8 opcode, block_ret_type;
uint8 opcode;
uint32 *depths = NULL;
uint32 depth_buf[BR_TABLE_TMP_BUF_LEN];
uint32 i, depth, cond, count, fidx, tidx, frame_size = 0;
@ -993,7 +988,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint8 *else_addr, *end_addr, *maddr = NULL;
uint32 local_idx, local_offset, global_idx;
uint8 local_type, *global_addr;
uint32 cache_index;
uint32 cache_index, type_index, cell_num;
uint8 value_type;
#if WASM_ENABLE_LABELS_AS_VALUES != 0
#define HANDLE_OPCODE(op) &&HANDLE_##op
@ -1016,9 +1012,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP (WASM_OP_NOP):
HANDLE_OP_END ();
HANDLE_OP (WASM_OP_BLOCK):
block_ret_type = *frame_ip++;
HANDLE_OP (EXT_OP_BLOCK):
read_leb_uint32(frame_ip, frame_ip_end, type_index);
cell_num = wasm_types[type_index]->ret_cell_num;
goto handle_op_block;
HANDLE_OP (WASM_OP_BLOCK):
value_type = *frame_ip++;
cell_num = wasm_value_type_cell_num(value_type);
handle_op_block:
cache_index = ((uintptr_t)frame_ip) & (uintptr_t)(BLOCK_ADDR_CACHE_SIZE - 1);
cache_items = exec_env->block_addr_cache[cache_index];
if (cache_items[0].start_addr == frame_ip) {
@ -1029,24 +1031,37 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
}
else if (!wasm_loader_find_block_addr((BlockAddr*)exec_env->block_addr_cache,
frame_ip, (uint8*)-1,
BLOCK_TYPE_BLOCK,
LABEL_TYPE_BLOCK,
&else_addr, &end_addr,
NULL, 0)) {
wasm_set_exception(module, "find block address failed");
goto got_exception;
}
PUSH_CSP(BLOCK_TYPE_BLOCK, block_ret_type, end_addr);
PUSH_CSP(LABEL_TYPE_BLOCK, cell_num, end_addr);
HANDLE_OP_END ();
HANDLE_OP (EXT_OP_LOOP):
read_leb_uint32(frame_ip, frame_ip_end, type_index);
cell_num = wasm_types[type_index]->param_cell_num;
goto handle_op_loop;
HANDLE_OP (WASM_OP_LOOP):
block_ret_type = *frame_ip++;
PUSH_CSP(BLOCK_TYPE_LOOP, block_ret_type, frame_ip);
value_type = *frame_ip++;
cell_num = wasm_value_type_cell_num(value_type);
handle_op_loop:
PUSH_CSP(LABEL_TYPE_LOOP, cell_num, frame_ip);
HANDLE_OP_END ();
HANDLE_OP (WASM_OP_IF):
block_ret_type = *frame_ip++;
HANDLE_OP (EXT_OP_IF):
read_leb_uint32(frame_ip, frame_ip_end, type_index);
cell_num = wasm_types[type_index]->ret_cell_num;
goto handle_op_if;
HANDLE_OP (WASM_OP_IF):
value_type = *frame_ip++;
cell_num = wasm_value_type_cell_num(value_type);
handle_op_if:
cache_index = ((uintptr_t)frame_ip) & (uintptr_t)(BLOCK_ADDR_CACHE_SIZE - 1);
cache_items = exec_env->block_addr_cache[cache_index];
if (cache_items[0].start_addr == frame_ip) {
@ -1059,7 +1074,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
}
else if (!wasm_loader_find_block_addr((BlockAddr*)exec_env->block_addr_cache,
frame_ip, (uint8*)-1,
BLOCK_TYPE_IF,
LABEL_TYPE_IF,
&else_addr, &end_addr,
NULL, 0)) {
wasm_set_exception(module, "find block address failed");
@ -1068,7 +1083,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
cond = (uint32)POP_I32();
PUSH_CSP(BLOCK_TYPE_IF, block_ret_type, end_addr);
PUSH_CSP(LABEL_TYPE_IF, cell_num, end_addr);
/* condition of the if branch is false, else condition is met */
if (cond == 0) {
@ -1106,6 +1121,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
CHECK_SUSPEND_FLAGS();
#endif
read_leb_uint32(frame_ip, frame_ip_end, depth);
label_pop_csp_n:
POP_CSP_N(depth);
HANDLE_OP_END ();
@ -1116,7 +1132,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
read_leb_uint32(frame_ip, frame_ip_end, depth);
cond = (uint32)POP_I32();
if (cond)
POP_CSP_N(depth);
goto label_pop_csp_n;
HANDLE_OP_END ();
HANDLE_OP (WASM_OP_BR_TABLE):
@ -1147,7 +1163,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
wasm_runtime_free(depths);
depths = NULL;
}
POP_CSP_N(depth);
goto label_pop_csp_n;
HANDLE_OP_END ();
HANDLE_OP (WASM_OP_RETURN):
@ -1192,7 +1208,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
wasm_set_exception(module, "type index is overflow");
goto got_exception;
}
cur_type = module->module->types[tidx];
cur_type = wasm_types[tidx];
/* to skip 0x00 here */
frame_ip++;
@ -2705,6 +2721,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP (EXT_OP_TEE_LOCAL_FAST_I64):
HANDLE_OP (EXT_OP_COPY_STACK_TOP):
HANDLE_OP (EXT_OP_COPY_STACK_TOP_I64):
HANDLE_OP (EXT_OP_COPY_STACK_VALUES):
{
wasm_set_exception(module, "WASM interp failed: unsupported opcode.");
goto got_exception;
@ -2753,7 +2770,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
else {
WASMFunction *cur_wasm_func = cur_func->u.func;
WASMType *func_type;
uint8 ret_type;
func_type = cur_wasm_func->func_type;
@ -2790,10 +2806,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
(uint32)(cur_func->local_cell_num * 4));
/* Push function block as first block */
ret_type = func_type->result_count
? cur_func->param_types[func_type->param_count]
: VALUE_TYPE_VOID;
PUSH_CSP(BLOCK_TYPE_FUNCTION, ret_type, frame_ip_end - 1);
cell_num = func_type->ret_cell_num;
PUSH_CSP(LABEL_TYPE_FUNCTION, cell_num, frame_ip_end - 1);
wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame*)frame);
}
@ -2837,7 +2851,8 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst,
WASMInterpFrame *frame, *outs_area;
/* Allocate sufficient cells for all kinds of return values. */
unsigned all_cell_num = 2, i;
unsigned all_cell_num = function->ret_cell_num > 2 ?
function->ret_cell_num : 2, i;
/* This frame won't be used by JITed code, so only allocate interp
frame here. */
unsigned frame_size = wasm_interp_interp_frame_size(all_cell_num);

View File

@ -679,21 +679,121 @@ trunc_f64_to_int(WASMModuleInstance *module,
PUSH_##dst_op_type(value); \
} while (0)
#define RECOVER_BR_INFO() do { \
uint16 stack_index, ret_cell_num; \
stack_index = *(uint16*)frame_ip; \
frame_ip += sizeof(uint16); \
ret_cell_num = *(uint8*)frame_ip; \
frame_ip += sizeof(uint8); \
if (ret_cell_num == 1) \
frame_lp[stack_index] = \
frame_lp[*(int16*)frame_ip]; \
else if (ret_cell_num == 2) { \
*(int64*)(frame_lp + stack_index) = \
*(int64*)(frame_lp + *(int16*)frame_ip);\
} \
frame_ip += sizeof(int16); \
frame_ip = *(uint8**)frame_ip; \
static bool
copy_stack_values(WASMModuleInstance *module,
uint32 *frame_lp,
uint32 arity,
uint32 total_cell_num,
const uint8 *cells,
const int16 *src_offsets,
const uint16 *dst_offsets)
{
/* To avoid the overlap issue between src offsets and dst offset,
* we use 2 steps to do the copy. First step, copy the src values
* to a tmp buf. Second step, copy the values from tmp buf to dst.
*/
uint32 buf[16] = {0}, i;
uint32 *tmp_buf = buf;
uint8 cell;
int16 src, buf_index = 0;
uint16 dst;
/* Allocate memory if the buf is not large enough */
if (total_cell_num > sizeof(buf)/sizeof(uint32)) {
uint64 total_size = sizeof(uint32) * (uint64)total_cell_num;
if (total_size >= UINT32_MAX
|| !(tmp_buf = wasm_runtime_malloc((uint32)total_size))) {
wasm_set_exception(module,
"WASM interp failed: allocate memory failed.");
return false;
}
}
/* 1) Copy values from src to tmp buf */
for (i = 0; i < arity; i++) {
cell = cells[i];
src = src_offsets[i];
if (cell == 1)
tmp_buf[buf_index] = frame_lp[src];
else
*(uint64*)(tmp_buf + buf_index) = *(uint64*)(frame_lp + src);
buf_index += cell;
}
/* 2) Copy values from tmp buf to dest */
buf_index = 0;
for (i = 0; i < arity; i++) {
cell = cells[i];
dst = dst_offsets[i];
if (cell == 1)
frame_lp[dst] = tmp_buf[buf_index];
else
*(uint64*)(frame_lp + dst) = *(uint64*)(tmp_buf + buf_index);
buf_index += cell;
}
if (tmp_buf != buf) {
wasm_runtime_free(tmp_buf);
}
return true;
}
#define RECOVER_BR_INFO() do { \
uint32 arity; \
/* read arity */ \
arity = *(uint32*)frame_ip; \
frame_ip += sizeof(arity); \
if (arity) { \
uint32 total_cell; \
uint16 *dst_offsets = NULL; \
uint8 *cells; \
int16 *src_offsets = NULL; \
/* read total cell num */ \
total_cell = *(uint32*)frame_ip; \
frame_ip += sizeof(total_cell); \
/* cells */ \
cells = (uint8 *)frame_ip; \
frame_ip += arity * sizeof(uint8); \
/* src offsets */ \
src_offsets = (int16 *)frame_ip; \
frame_ip += arity * sizeof(int16); \
/* dst offsets */ \
dst_offsets = (uint16*)frame_ip; \
frame_ip += arity * sizeof(uint16); \
if (arity == 1) { \
if (cells[0] == 1) \
frame_lp[dst_offsets[0]] = \
frame_lp[src_offsets[0]]; \
else if (cells[0] == 2) { \
*(int64*)(frame_lp + dst_offsets[0]) = \
*(int64*)(frame_lp + src_offsets[0]); \
} \
} \
else { \
if (!copy_stack_values(module, frame_lp, \
arity, total_cell, \
cells, src_offsets, \
dst_offsets)) \
goto got_exception; \
} \
} \
frame_ip = *(uint8**)frame_ip; \
} while (0)
#define SKIP_BR_INFO() do { \
uint32 arity; \
/* read and skip arity */ \
arity = *(uint32*)frame_ip; \
frame_ip += sizeof(arity); \
if (arity) { \
/* skip total cell num */ \
frame_ip += sizeof(uint32); \
/* skip cells, src offsets and dst offsets */ \
frame_ip += (sizeof(uint8) + sizeof(int16) + sizeof(uint16)) * arity; \
} \
/* skip target address */ \
frame_ip += sizeof(uint8*); \
} while (0)
static inline int32
@ -1034,6 +1134,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#if WASM_ENABLE_THREAD_MGR != 0
CHECK_SUSPEND_FLAGS();
#endif
recover_br_info:
RECOVER_BR_INFO();
HANDLE_OP_END ();
@ -1044,10 +1145,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
cond = frame_lp[GET_OFFSET()];
if (cond)
RECOVER_BR_INFO();
else {
frame_ip += (2 + 1 + 2 + sizeof(uint8*));
}
goto recover_br_info;
else
SKIP_BR_INFO();
HANDLE_OP_END ();
@ -1062,16 +1162,44 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
if (!(didx >= 0 && (uint32)didx < count))
didx = count;
frame_ip += (didx * ((2 + 1 + 2 + sizeof(uint8*))));
RECOVER_BR_INFO();
HANDLE_OP_END ();
while (didx--)
SKIP_BR_INFO();
goto recover_br_info;
HANDLE_OP (WASM_OP_RETURN):
if (cur_func->ret_cell_num == 2) {
*((uint64 *)(prev_frame->lp + prev_frame->ret_offset)) =
GET_OPERAND(uint64, 0);
} else if (cur_func->ret_cell_num == 1) {
prev_frame->lp[prev_frame->ret_offset] = GET_OPERAND(int32, 0);;
{
uint32 ret_idx;
WASMType *func_type;
uint32 off, ret_offset;
uint8 *ret_types;
if (cur_func->is_import_func
#if WASM_ENABLE_MULTI_MODULE != 0
&& !cur_func->import_func_inst
#endif
)
func_type = cur_func->u.func_import->func_type;
else
func_type = cur_func->u.func->func_type;
/* types of each return value */
ret_types = func_type->types + func_type->param_count;
ret_offset = prev_frame->ret_offset;
for (ret_idx = 0, off = sizeof(int16) * (func_type->result_count - 1);
ret_idx < func_type->result_count;
ret_idx++, off -= sizeof(int16)) {
if (ret_types[ret_idx] == VALUE_TYPE_I64
|| ret_types[ret_idx] == VALUE_TYPE_F64) {
*((uint64 *)(prev_frame->lp + ret_offset)) =
GET_OPERAND(uint64, off);
ret_offset += 2;
}
else {
prev_frame->lp[ret_offset] = GET_OPERAND(int32, off);
ret_offset++;
}
}
}
goto return_func;
@ -1128,7 +1256,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
&& !cur_func->import_func_inst
#endif
)
cur_func_type = cur_func->u.func_import->func_type;
cur_func_type = cur_func->u.func_import->func_type;
else
cur_func_type = cur_func->u.func->func_type;
if (!wasm_type_equal(cur_type, cur_func_type)) {
@ -2350,6 +2478,37 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
*(uint64*)(frame_lp + addr2) = *(uint64*)(frame_lp + addr1);
HANDLE_OP_END ();
HANDLE_OP (EXT_OP_COPY_STACK_VALUES):
{
uint32 values_count, total_cell;
uint8 *cells;
int16 *src_offsets = NULL;
uint16 *dst_offsets = NULL;
/* read values_count */
values_count = *(uint32*)frame_ip;
frame_ip += sizeof(values_count);
/* read total cell num */
total_cell = *(uint32*)frame_ip;
frame_ip += sizeof(total_cell);
/* cells */
cells = (uint8 *)frame_ip;
frame_ip += values_count * sizeof(uint8);
/* src offsets */
src_offsets = (int16 *)frame_ip;
frame_ip += values_count * sizeof(int16);
/* dst offsets */
dst_offsets = (uint16*)frame_ip;
frame_ip += values_count * sizeof(uint16);
if (!copy_stack_values(module, frame_lp,
values_count, total_cell,
cells, src_offsets,
dst_offsets))
goto got_exception;
HANDLE_OP_END ();
}
HANDLE_OP (WASM_OP_SET_LOCAL):
HANDLE_OP (WASM_OP_TEE_LOCAL):
{
@ -2567,6 +2726,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP (WASM_OP_LOOP):
HANDLE_OP (WASM_OP_END):
HANDLE_OP (WASM_OP_NOP):
HANDLE_OP (EXT_OP_BLOCK):
HANDLE_OP (EXT_OP_LOOP):
HANDLE_OP (EXT_OP_IF):
{
wasm_set_exception(module, "WASM interp failed: unsupported opcode.");
goto got_exception;
@ -2596,8 +2758,22 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
}
}
frame_ip += cur_func->param_count * sizeof(int16);
if (cur_func->ret_cell_num != 0)
if (cur_func->ret_cell_num != 0) {
/* Get the first return value's offset. Since loader emit all return
* values' offset so we must skip remain return values' offsets.
*/
WASMType *func_type;
if (cur_func->is_import_func
#if WASM_ENABLE_MULTI_MODULE != 0
&& !cur_func->import_func_inst
#endif
)
func_type = cur_func->u.func_import->func_type;
else
func_type = cur_func->u.func->func_type;
frame->ret_offset = GET_OFFSET();
frame_ip += 2 * (func_type->result_count - 1);
}
SYNC_ALL_TO_FRAME();
prev_frame = frame;
}
@ -2712,7 +2888,8 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst,
WASMInterpFrame *frame, *outs_area;
/* Allocate sufficient cells for all kinds of return values. */
unsigned all_cell_num = 2, i;
unsigned all_cell_num = function->ret_cell_num > 2 ?
function->ret_cell_num : 2, i;
/* This frame won't be used by JITed code, so only allocate interp
frame here. */
unsigned frame_size = wasm_interp_interp_frame_size(all_cell_num);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -255,8 +255,11 @@ typedef enum WASMOpcode {
EXT_OP_TEE_LOCAL_FAST_I64 = 0xcb,
EXT_OP_COPY_STACK_TOP = 0xcc,
EXT_OP_COPY_STACK_TOP_I64 = 0xcd,
WASM_OP_IMPDEP = 0xce,
EXT_OP_COPY_STACK_VALUES = 0xce,
EXT_OP_BLOCK = 0xcf, /* block with blocktype */
EXT_OP_LOOP = 0xd0, /* loop with blocktype */
EXT_OP_IF = 0xd1, /* if with blocktype */
WASM_OP_IMPDEP = 0xd2,
/* Post-MVP extend op prefix */
WASM_OP_MISC_PREFIX = 0xfc,
@ -499,7 +502,11 @@ static type _name[WASM_INSTRUCTION_NUM] = { \
HANDLE_OPCODE (EXT_OP_TEE_LOCAL_FAST_I64), /* 0xcb */ \
HANDLE_OPCODE (EXT_OP_COPY_STACK_TOP), /* 0xcc */ \
HANDLE_OPCODE (EXT_OP_COPY_STACK_TOP_I64), /* 0xcd */ \
HANDLE_OPCODE (WASM_OP_IMPDEP), /* 0xce */ \
HANDLE_OPCODE (EXT_OP_COPY_STACK_VALUES), /* 0xce */ \
HANDLE_OPCODE (EXT_OP_BLOCK), /* 0xcf */ \
HANDLE_OPCODE (EXT_OP_LOOP), /* 0xd0 */ \
HANDLE_OPCODE (EXT_OP_IF), /* 0xd1 */ \
HANDLE_OPCODE (WASM_OP_IMPDEP), /* 0xd2 */ \
}; \
do { \
_name[WASM_OP_MISC_PREFIX] = \

View File

@ -509,9 +509,9 @@ functions_instantiate(const WASMModule *module,
import->u.function.field_name);
function->u.func_import = &import->u.function;
function->param_cell_num =
wasm_type_param_cell_num(import->u.function.func_type);
import->u.function.func_type->param_cell_num;
function->ret_cell_num =
wasm_type_return_cell_num(import->u.function.func_type);
import->u.function.func_type->ret_cell_num;
function->param_count =
(uint16)function->u.func_import->func_type->param_count;
function->param_types = function->u.func_import->func_type->types;
@ -1804,4 +1804,4 @@ wasm_get_aux_stack(WASMExecEnv *exec_env,
}
return false;
}
#endif
#endif