Refine wasm loader and interpreter, enhance wamrc to support SGX (#167)

Former-commit-id: 76f4a121d3c2a67114414fc60e80eba4bf49aa8e [formerly b1ab47945a40e6b249c9aa205d61281301585ea6]
Former-commit-id: 8e5c6e895eae22051a79a8d337a87cd2f431b6bc
This commit is contained in:
wenyongh 2020-02-18 15:15:24 +08:00 committed by GitHub
parent 20cf199ce4
commit e62bbeb9e8
16 changed files with 306 additions and 344 deletions

View File

@ -1283,7 +1283,8 @@ apply_relocation(AOTModule *module,
if ((int32)target_addr != target_addr) { if ((int32)target_addr != target_addr) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"AOT module load failed: " "AOT module load failed: "
"relocation truncated to fit R_X86_64_PC32 failed"); "relocation truncated to fit R_X86_64_PC32 failed. "
"Try using wamrc with --size-level=1 option.");
return false; return false;
} }
@ -1305,7 +1306,8 @@ apply_relocation(AOTModule *module,
&& (int32)target_addr != (int64)target_addr)) { && (int32)target_addr != (int64)target_addr)) {
snprintf(buf, sizeof(buf), snprintf(buf, sizeof(buf),
"AOT module load failed: " "AOT module load failed: "
"relocation truncated to fit %s failed", "relocation truncated to fit %s failed. "
"Try using wamrc with --size-level=1 option.",
reloc_type == R_X86_64_32 reloc_type == R_X86_64_32
? "R_X86_64_32" : "R_X86_64_32S"); ? "R_X86_64_32" : "R_X86_64_32S");
set_error_buf(error_buf, error_buf_size, buf); set_error_buf(error_buf, error_buf_size, buf);
@ -1335,7 +1337,8 @@ apply_relocation(AOTModule *module,
if ((int32)target_addr != target_addr) { if ((int32)target_addr != target_addr) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"AOT module load failed: " "AOT module load failed: "
"relocation truncated to fit R_X86_64_PC32 failed"); "relocation truncated to fit R_X86_64_PC32 failed. "
"Try using wamrc with --size-level=1 option.");
return false; return false;
} }

View File

@ -186,7 +186,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
return false; return false;
break; break;
case WASM_OP_DROP_32: case WASM_OP_DROP:
if (!aot_compile_op_drop(comp_ctx, func_ctx, true)) if (!aot_compile_op_drop(comp_ctx, func_ctx, true))
return false; return false;
break; break;
@ -196,7 +196,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
return false; return false;
break; break;
case WASM_OP_SELECT_32: case WASM_OP_SELECT:
if (!aot_compile_op_select(comp_ctx, func_ctx, true)) if (!aot_compile_op_select(comp_ctx, func_ctx, true))
return false; return false;
break; break;

View File

@ -837,7 +837,8 @@ aot_create_comp_context(AOTCompData *comp_data,
char *triple_norm_new = NULL, *cpu_new = NULL; char *triple_norm_new = NULL, *cpu_new = NULL;
char *err = NULL, *fp_round= "round.tonearest", *fp_exce = "fpexcept.strict"; char *err = NULL, *fp_round= "round.tonearest", *fp_exce = "fpexcept.strict";
char triple_buf[32] = {0}; char triple_buf[32] = {0};
uint32 opt_level; uint32 opt_level, size_level;
LLVMCodeModel code_model;
/* Initialize LLVM environment */ /* Initialize LLVM environment */
LLVMInitializeAllTargetInfos(); LLVMInitializeAllTargetInfos();
@ -896,6 +897,7 @@ aot_create_comp_context(AOTCompData *comp_data,
cpu = option->target_cpu; cpu = option->target_cpu;
features = option->cpu_features; features = option->cpu_features;
opt_level = option->opt_level; opt_level = option->opt_level;
size_level = option->size_level;
if (arch) { if (arch) {
/* Add default sub-arch if not specified */ /* Add default sub-arch if not specified */
@ -1001,6 +1003,7 @@ aot_create_comp_context(AOTCompData *comp_data,
bh_printf(" target cpu: %s\n", cpu); bh_printf(" target cpu: %s\n", cpu);
bh_printf(" cpu features: %s\n", features); bh_printf(" cpu features: %s\n", features);
bh_printf(" opt level: %d\n", opt_level); bh_printf(" opt level: %d\n", opt_level);
bh_printf(" size level: %d\n", size_level);
switch (option->output_format) { switch (option->output_format) {
case AOT_LLVMIR_UNOPT_FILE: case AOT_LLVMIR_UNOPT_FILE:
bh_printf(" output format: unoptimized LLVM IR\n"); bh_printf(" output format: unoptimized LLVM IR\n");
@ -1030,11 +1033,21 @@ aot_create_comp_context(AOTCompData *comp_data,
goto fail; goto fail;
} }
/* Set code model */
if (size_level == 0)
code_model = LLVMCodeModelLarge;
else if (size_level == 1)
code_model = LLVMCodeModelMedium;
else if (size_level == 2)
code_model = LLVMCodeModelKernel;
else
code_model = LLVMCodeModelSmall;
/* Create the target machine */ /* Create the target machine */
if (!(comp_ctx->target_machine = if (!(comp_ctx->target_machine =
LLVMCreateTargetMachine(target, triple_norm, cpu, features, LLVMCreateTargetMachine(target, triple_norm, cpu, features,
opt_level, LLVMRelocStatic, opt_level, LLVMRelocStatic,
LLVMCodeModelSmall))) { code_model))) {
aot_set_last_error("create LLVM target machine failed."); aot_set_last_error("create LLVM target machine failed.");
goto fail; goto fail;
} }

View File

@ -219,6 +219,7 @@ typedef struct AOTCompOption{
char *target_cpu; char *target_cpu;
char *cpu_features; char *cpu_features;
uint32 opt_level; uint32 opt_level;
uint32 size_level;
uint32 output_format; uint32 output_format;
} AOTCompOption, *aot_comp_option_t; } AOTCompOption, *aot_comp_option_t;

View File

@ -40,6 +40,7 @@ typedef struct AOTCompOption{
char *target_cpu; char *target_cpu;
char *cpu_features; char *cpu_features;
uint32_t opt_level; uint32_t opt_level;
uint32_t size_level;
uint32_t output_format; uint32_t output_format;
} AOTCompOption, *aot_comp_option_t; } AOTCompOption, *aot_comp_option_t;

View File

@ -167,6 +167,17 @@ typedef struct WASMFunction {
WASMType *func_type; WASMType *func_type;
uint32 local_count; uint32 local_count;
uint8 *local_types; uint8 *local_types;
/* cell num of parameters */
uint16 param_cell_num;
/* cell num of return type */
uint16 ret_cell_num;
/* cell num of local variables */
uint16 local_cell_num;
/* offset of each local, including function paramameters
and local variables */
uint16 *local_offsets;
uint32 max_stack_cell_num; uint32 max_stack_cell_num;
uint32 max_block_num; uint32 max_block_num;
/* Whether function has opcode memory.grow */ /* Whether function has opcode memory.grow */
@ -226,6 +237,11 @@ typedef struct WASIArguments {
} WASIArguments; } WASIArguments;
#endif #endif
typedef struct StringNode {
struct StringNode *next;
char *str;
} StringNode, *StringList;
typedef struct WASMModule { typedef struct WASMModule {
/* Module type, for module loaded from WASM bytecode binary, /* Module type, for module loaded from WASM bytecode binary,
this field is Wasm_Module_Bytecode; this field is Wasm_Module_Bytecode;
@ -279,7 +295,8 @@ typedef struct WASMModule {
memory.grow opcode or call enlargeMemory */ memory.grow opcode or call enlargeMemory */
bool possible_memory_grow; bool possible_memory_grow;
HashMap *const_str_set; StringList const_str_list;
BlockAddr block_addr_cache[BLOCK_ADDR_CACHE_SIZE][BLOCK_ADDR_CONFLICT_SIZE]; BlockAddr block_addr_cache[BLOCK_ADDR_CACHE_SIZE][BLOCK_ADDR_CONFLICT_SIZE];
#if WASM_ENABLE_LIBC_WASI != 0 #if WASM_ENABLE_LIBC_WASI != 0
@ -291,8 +308,7 @@ typedef struct WASMModule {
typedef struct WASMBranchBlock { typedef struct WASMBranchBlock {
uint8 block_type; uint8 block_type;
uint8 return_type; uint8 return_type;
uint8 *start_addr; uint8 *target_addr;
uint8 *end_addr;
uint32 *frame_sp; uint32 *frame_sp;
} WASMBranchBlock; } WASMBranchBlock;

View File

@ -422,12 +422,11 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
frame_sp += 2; \ frame_sp += 2; \
} while (0) } while (0)
#define PUSH_CSP(type, ret_type, start, else_, end) do {\ #define PUSH_CSP(type, ret_type, _target_addr) do { \
bh_assert(frame_csp < frame->csp_boundary); \ bh_assert(frame_csp < frame->csp_boundary); \
frame_csp->block_type = type; \ frame_csp->block_type = type; \
frame_csp->return_type = ret_type; \ frame_csp->return_type = ret_type; \
frame_csp->start_addr = start; \ frame_csp->target_addr = _target_addr; \
frame_csp->end_addr = end; \
frame_csp->frame_sp = frame_sp; \ frame_csp->frame_sp = frame_sp; \
frame_csp++; \ frame_csp++; \
} while (0) } while (0)
@ -453,25 +452,17 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
uint32 *frame_sp_old = frame_sp; \ uint32 *frame_sp_old = frame_sp; \
POP_CSP_CHECK_OVERFLOW(n + 1); \ POP_CSP_CHECK_OVERFLOW(n + 1); \
frame_csp -= n; \ frame_csp -= n; \
if ((frame_csp - 1)->block_type != BLOCK_TYPE_LOOP) \ frame_ip = (frame_csp - 1)->target_addr; \
/* block block/if/function, jump to end of block */ \
frame_ip = (frame_csp - 1)->end_addr; \
else /* loop block, jump to start of block */ \
frame_ip = (frame_csp - 1)->start_addr; \
/* copy return value of block */ \ /* copy return value of block */ \
frame_sp = (frame_csp - 1)->frame_sp; \ frame_sp = (frame_csp - 1)->frame_sp; \
switch ((frame_csp - 1)->return_type) { \ switch ((frame_csp - 1)->return_type) { \
case VALUE_TYPE_I32: \ case VALUE_TYPE_I32: \
case VALUE_TYPE_F32: \
PUSH_I32(*(frame_sp_old - 1)); \ PUSH_I32(*(frame_sp_old - 1)); \
break; \ break; \
case VALUE_TYPE_I64: \ case VALUE_TYPE_I64: \
PUSH_I64(GET_I64_FROM_ADDR(frame_sp_old - 2)); \
break; \
case VALUE_TYPE_F32: \
PUSH_F32(*(float32*)(frame_sp_old - 1)); \
break; \
case VALUE_TYPE_F64: \ case VALUE_TYPE_F64: \
PUSH_F64(GET_F64_FROM_ADDR(frame_sp_old - 2)); \ PUSH_I64(GET_I64_FROM_ADDR(frame_sp_old - 2)); \
break; \ break; \
} \ } \
} while (0) } while (0)
@ -536,12 +527,19 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
p += _off; \ p += _off; \
} while (0) } while (0)
#if WASM_ENABLE_LABELS_AS_VALUES == 0
#define RECOVER_FRAME_IP_END() \
frame_ip_end = wasm_get_func_code_end(cur_func)
#else
#define RECOVER_FRAME_IP_END() (void)0
#endif
#define RECOVER_CONTEXT(new_frame) do { \ #define RECOVER_CONTEXT(new_frame) do { \
frame = (new_frame); \ frame = (new_frame); \
cur_func = frame->function; \ cur_func = frame->function; \
prev_frame = frame->prev_frame; \ prev_frame = frame->prev_frame; \
frame_ip = frame->ip; \ frame_ip = frame->ip; \
frame_ip_end = wasm_get_func_code_end(cur_func); \ RECOVER_FRAME_IP_END(); \
frame_lp = frame->lp; \ frame_lp = frame->lp; \
frame_sp = frame->sp; \ frame_sp = frame->sp; \
frame_csp = frame->csp; \ frame_csp = frame->csp; \
@ -802,25 +800,22 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMInterpFrame *prev_frame) WASMInterpFrame *prev_frame)
{ {
WASMMemoryInstance *memory = module->default_memory; WASMMemoryInstance *memory = module->default_memory;
uint32 memory_data_size = memory ? (module->module->possible_memory_grow uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0;
? DEFAULT_NUM_BYTES_PER_PAGE * memory->cur_page_count uint32 memory_data_size = memory ? num_bytes_per_page * memory->cur_page_count : 0;
: memory->num_bytes_per_page * memory->cur_page_count)
: 0;
uint32 heap_base_offset = memory ? (uint32)memory->heap_base_offset : 0; uint32 heap_base_offset = memory ? (uint32)memory->heap_base_offset : 0;
uint32 heap_data_size = memory ? (uint32)(memory->heap_data_end - memory->heap_data) : 0; uint32 heap_data_size = memory ? (uint32)(memory->heap_data_end - memory->heap_data) : 0;
uint8 *global_data = memory ? memory->global_data : NULL;
WASMTableInstance *table = module->default_table; WASMTableInstance *table = module->default_table;
WASMGlobalInstance *globals = module->globals; WASMGlobalInstance *globals = module->globals;
uint8 *global_data = memory ? memory->global_data : NULL; uint8 opcode_IMPDEP = WASM_OP_IMPDEP;
uint8 opcode_IMPDEP2 = WASM_OP_IMPDEP2;
WASMInterpFrame *frame = NULL; WASMInterpFrame *frame = NULL;
/* Points to this special opcode so as to jump to the /* Points to this special opcode so as to jump to the call_method_from_entry. */
call_method_from_entry. */ register uint8 *frame_ip = &opcode_IMPDEP; /* cache of frame->ip */
register uint8 *frame_ip = &opcode_IMPDEP2; /* cache of frame->ip */
register uint32 *frame_lp = NULL; /* cache of frame->lp */ register uint32 *frame_lp = NULL; /* cache of frame->lp */
register uint32 *frame_sp = NULL; /* cache of frame->sp */ register uint32 *frame_sp = NULL; /* cache of frame->sp */
WASMBranchBlock *frame_csp = NULL; WASMBranchBlock *frame_csp = NULL;
WASMGlobalInstance *global; WASMGlobalInstance *global;
uint8 *frame_ip_end = frame_ip + 1, *frame_ip_org; uint8 *frame_ip_end = frame_ip + 1;
uint8 opcode, block_ret_type; uint8 opcode, block_ret_type;
uint32 *depths = NULL; uint32 *depths = NULL;
uint32 depth_buf[BR_TABLE_TMP_BUF_LEN]; uint32 depth_buf[BR_TABLE_TMP_BUF_LEN];
@ -828,7 +823,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint64 all_cell_num = 0; uint64 all_cell_num = 0;
int32 didx, val; int32 didx, val;
uint8 *else_addr, *end_addr, *maddr = NULL; uint8 *else_addr, *end_addr, *maddr = NULL;
uint32 local_idx, local_offset, global_idx, global_data_offset; uint32 local_idx, local_offset, global_idx;
uint8 local_type, *global_addr; uint8 local_type, *global_addr;
BlockAddrCache block_addr_cache[32] = { 0 }; BlockAddrCache block_addr_cache[32] = { 0 };
uint32 cache_index, block_addr_cache_size = 32; uint32 cache_index, block_addr_cache_size = 32;
@ -869,7 +864,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
} }
else { else {
if (!wasm_loader_find_block_addr(module->module, if (!wasm_loader_find_block_addr(module->module,
frame_ip, frame_ip_end, frame_ip, (uint8*)-1,
BLOCK_TYPE_BLOCK, BLOCK_TYPE_BLOCK,
&else_addr, &end_addr, &else_addr, &end_addr,
NULL, 0)) { NULL, 0)) {
@ -880,30 +875,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
block_addr_cache[cache_index].end_addr = end_addr; block_addr_cache[cache_index].end_addr = end_addr;
} }
PUSH_CSP(BLOCK_TYPE_BLOCK, block_ret_type, frame_ip, NULL, end_addr); PUSH_CSP(BLOCK_TYPE_BLOCK, block_ret_type, end_addr);
HANDLE_OP_END (); HANDLE_OP_END ();
HANDLE_OP (WASM_OP_LOOP): HANDLE_OP (WASM_OP_LOOP):
block_ret_type = *frame_ip++; block_ret_type = *frame_ip++;
PUSH_CSP(BLOCK_TYPE_LOOP, block_ret_type, frame_ip);
cache_index = ((uintptr_t)frame_ip) & (uintptr_t)(block_addr_cache_size - 1);
if (block_addr_cache[cache_index].frame_ip == frame_ip) {
end_addr = block_addr_cache[cache_index].end_addr;
}
else {
if (!wasm_loader_find_block_addr(module->module,
frame_ip, frame_ip_end,
BLOCK_TYPE_LOOP,
&else_addr, &end_addr,
NULL, 0)) {
wasm_set_exception(module, "find block address failed");
goto got_exception;
}
block_addr_cache[cache_index].frame_ip = frame_ip;
block_addr_cache[cache_index].end_addr = end_addr;
}
PUSH_CSP(BLOCK_TYPE_LOOP, block_ret_type, frame_ip, NULL, end_addr);
HANDLE_OP_END (); HANDLE_OP_END ();
HANDLE_OP (WASM_OP_IF): HANDLE_OP (WASM_OP_IF):
@ -916,7 +893,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
} }
else { else {
if (!wasm_loader_find_block_addr(module->module, if (!wasm_loader_find_block_addr(module->module,
frame_ip, frame_ip_end, frame_ip, (uint8*)-1,
BLOCK_TYPE_IF, BLOCK_TYPE_IF,
&else_addr, &end_addr, &else_addr, &end_addr,
NULL, 0)) { NULL, 0)) {
@ -931,7 +908,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
cond = (uint32)POP_I32(); cond = (uint32)POP_I32();
PUSH_CSP(BLOCK_TYPE_IF, block_ret_type, frame_ip, else_addr, end_addr); PUSH_CSP(BLOCK_TYPE_IF, block_ret_type, end_addr);
/* condition of the if branch is false, else condition is met */ /* condition of the if branch is false, else condition is met */
if (cond == 0) { if (cond == 0) {
@ -948,7 +925,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP (WASM_OP_ELSE): HANDLE_OP (WASM_OP_ELSE):
/* comes from the if branch in WASM_OP_IF */ /* comes from the if branch in WASM_OP_IF */
frame_ip = (frame_csp - 1)->end_addr; frame_ip = (frame_csp - 1)->target_addr;
HANDLE_OP_END (); HANDLE_OP_END ();
HANDLE_OP (WASM_OP_END): HANDLE_OP (WASM_OP_END):
@ -1058,12 +1035,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
/* parametric instructions */ /* parametric instructions */
HANDLE_OP (WASM_OP_DROP): HANDLE_OP (WASM_OP_DROP):
{
wasm_set_exception(module, "WASM interp failed: unsupported opcode.");
goto got_exception;
}
HANDLE_OP (WASM_OP_DROP_32):
{ {
frame_sp--; frame_sp--;
HANDLE_OP_END (); HANDLE_OP_END ();
@ -1076,12 +1047,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
} }
HANDLE_OP (WASM_OP_SELECT): HANDLE_OP (WASM_OP_SELECT):
{
wasm_set_exception(module, "WASM interp failed: unsupported opcode.");
goto got_exception;
}
HANDLE_OP (WASM_OP_SELECT_32):
{ {
cond = (uint32)POP_I32(); cond = (uint32)POP_I32();
frame_sp--; frame_sp--;
@ -1104,7 +1069,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
/* variable instructions */ /* variable instructions */
HANDLE_OP (WASM_OP_GET_LOCAL): HANDLE_OP (WASM_OP_GET_LOCAL):
{ {
frame_ip_org = frame_ip - 1;
GET_LOCAL_INDEX_TYPE_AND_OFFSET(); GET_LOCAL_INDEX_TYPE_AND_OFFSET();
switch (local_type) { switch (local_type) {
@ -1121,17 +1085,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
goto got_exception; goto got_exception;
} }
if (local_offset < 0x80) {
*frame_ip_org++ = WASM_OP_GET_LOCAL_FAST;
if (local_type == VALUE_TYPE_I32
|| local_type == VALUE_TYPE_F32)
*frame_ip_org++ = (uint8)local_offset;
else
*frame_ip_org++ = (uint8)(local_offset | 0x80);
while (frame_ip_org < frame_ip)
*frame_ip_org++ = WASM_OP_NOP;
}
HANDLE_OP_END (); HANDLE_OP_END ();
} }
@ -1147,7 +1100,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP (WASM_OP_SET_LOCAL): HANDLE_OP (WASM_OP_SET_LOCAL):
{ {
frame_ip_org = frame_ip - 1;
GET_LOCAL_INDEX_TYPE_AND_OFFSET(); GET_LOCAL_INDEX_TYPE_AND_OFFSET();
switch (local_type) { switch (local_type) {
@ -1164,17 +1116,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
goto got_exception; goto got_exception;
} }
if (local_offset < 0x80) {
*frame_ip_org++ = WASM_OP_SET_LOCAL_FAST;
if (local_type == VALUE_TYPE_I32
|| local_type == VALUE_TYPE_F32)
*frame_ip_org++ = (uint8)local_offset;
else
*frame_ip_org++ = (uint8)(local_offset | 0x80);
while (frame_ip_org < frame_ip)
*frame_ip_org++ = WASM_OP_NOP;
}
HANDLE_OP_END (); HANDLE_OP_END ();
} }
@ -1190,7 +1131,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP (WASM_OP_TEE_LOCAL): HANDLE_OP (WASM_OP_TEE_LOCAL):
{ {
frame_ip_org = frame_ip - 1;
GET_LOCAL_INDEX_TYPE_AND_OFFSET(); GET_LOCAL_INDEX_TYPE_AND_OFFSET();
switch (local_type) { switch (local_type) {
@ -1208,17 +1148,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
goto got_exception; goto got_exception;
} }
if (local_offset < 0x80) {
*frame_ip_org++ = WASM_OP_TEE_LOCAL_FAST;
if (local_type == VALUE_TYPE_I32
|| local_type == VALUE_TYPE_F32)
*frame_ip_org++ = (uint8)local_offset;
else
*frame_ip_org++ = (uint8)(local_offset | 0x80);
while (frame_ip_org < frame_ip)
*frame_ip_org++ = WASM_OP_NOP;
}
HANDLE_OP_END (); HANDLE_OP_END ();
} }
@ -1235,7 +1164,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP (WASM_OP_GET_GLOBAL): HANDLE_OP (WASM_OP_GET_GLOBAL):
{ {
frame_ip_org = frame_ip - 1;
read_leb_uint32(frame_ip, frame_ip_end, global_idx); read_leb_uint32(frame_ip, frame_ip_end, global_idx);
bh_assert(global_idx < module->global_count); bh_assert(global_idx < module->global_count);
@ -1256,35 +1184,11 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
goto got_exception; goto got_exception;
} }
if (global->data_offset < 0x80) {
*frame_ip_org++ = WASM_OP_GET_GLOBAL_FAST;
if (global->type == VALUE_TYPE_I32
|| global->type == VALUE_TYPE_F32)
*frame_ip_org++ = (uint8)global->data_offset;
else
*frame_ip_org++ = (uint8)(global->data_offset | 0x80);
while (frame_ip_org < frame_ip)
*frame_ip_org++ = WASM_OP_NOP;
}
HANDLE_OP_END ();
}
HANDLE_OP (WASM_OP_GET_GLOBAL_FAST):
{
global_data_offset = *frame_ip++;
if (global_data_offset & 0x80)
PUSH_I64(GET_I64_FROM_ADDR((uint32*)(global_data + (global_data_offset & 0x7F))));
else
PUSH_I32(*(uint32*)(global_data + global_data_offset));
HANDLE_OP_END (); HANDLE_OP_END ();
} }
HANDLE_OP (WASM_OP_SET_GLOBAL): HANDLE_OP (WASM_OP_SET_GLOBAL):
{ {
frame_ip_org = frame_ip - 1;
read_leb_uint32(frame_ip, frame_ip_end, global_idx); read_leb_uint32(frame_ip, frame_ip_end, global_idx);
bh_assert(global_idx < module->global_count); bh_assert(global_idx < module->global_count);
@ -1305,30 +1209,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
goto got_exception; goto got_exception;
} }
if (global->data_offset < 0x80) {
*frame_ip_org++ = WASM_OP_SET_GLOBAL_FAST;
if (global->type == VALUE_TYPE_I32
|| global->type == VALUE_TYPE_F32)
*frame_ip_org++ = (uint8)global->data_offset;
else
*frame_ip_org++ = (uint8)(global->data_offset | 0x80);
while (frame_ip_org < frame_ip)
*frame_ip_org++ = WASM_OP_NOP;
}
HANDLE_OP_END ();
}
HANDLE_OP (WASM_OP_SET_GLOBAL_FAST):
{
global_data_offset = *frame_ip++;
if (global_data_offset & 0x80)
PUT_I64_TO_ADDR((uint32*)(global_data + (global_data_offset & 0x7F)),
POP_I64());
else
*(uint32*)(global_data + global_data_offset) = POP_I32();
HANDLE_OP_END (); HANDLE_OP_END ();
} }
@ -1543,9 +1423,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
PUSH_I32(prev_page_count); PUSH_I32(prev_page_count);
/* update the memory instance ptr */ /* update the memory instance ptr */
memory = module->default_memory; memory = module->default_memory;
memory_data_size = module->module->possible_memory_grow memory_data_size = num_bytes_per_page * memory->cur_page_count;
? DEFAULT_NUM_BYTES_PER_PAGE * memory->cur_page_count
: memory->num_bytes_per_page * memory->cur_page_count;
global_data = memory->global_data; global_data = memory->global_data;
} }
@ -2218,8 +2096,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
} }
HANDLE_OP (WASM_OP_I32_TRUNC_S_F32): HANDLE_OP (WASM_OP_I32_TRUNC_S_F32):
/* Copy the float32/float64 values from WAVM, need to test more. /* We don't use INT32_MIN/INT32_MAX/UINT32_MIN/UINT32_MAX,
We don't use INT32_MIN/INT32_MAX/UINT32_MIN/UINT32_MAX,
since float/double values of ieee754 cannot precisely represent since float/double values of ieee754 cannot precisely represent
all int32/uint32/int64/uint64 values, e.g.: all int32/uint32/int64/uint64 values, e.g.:
UINT32_MAX is 4294967295, but (float32)4294967295 is 4294967296.0f, UINT32_MAX is 4294967295, but (float32)4294967295 is 4294967296.0f,
@ -2321,7 +2198,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP (WASM_OP_F64_REINTERPRET_I64): HANDLE_OP (WASM_OP_F64_REINTERPRET_I64):
HANDLE_OP_END (); HANDLE_OP_END ();
HANDLE_OP (WASM_OP_IMPDEP2): HANDLE_OP (WASM_OP_IMPDEP):
frame = prev_frame; frame = prev_frame;
frame_ip = frame->ip; frame_ip = frame->ip;
frame_sp = frame->sp; frame_sp = frame->sp;
@ -2336,31 +2213,30 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#endif #endif
#if WASM_ENABLE_LABELS_AS_VALUES != 0 #if WASM_ENABLE_LABELS_AS_VALUES != 0
HANDLE_OP (WASM_OP_IMPDEP1): HANDLE_OP (WASM_OP_UNUSED_0x06):
HANDLE_OP (WASM_OP_UNUSED_0x06): HANDLE_OP (WASM_OP_UNUSED_0x07):
HANDLE_OP (WASM_OP_UNUSED_0x07): HANDLE_OP (WASM_OP_UNUSED_0x08):
HANDLE_OP (WASM_OP_UNUSED_0x08): HANDLE_OP (WASM_OP_UNUSED_0x09):
HANDLE_OP (WASM_OP_UNUSED_0x09): HANDLE_OP (WASM_OP_UNUSED_0x0a):
HANDLE_OP (WASM_OP_UNUSED_0x0a): HANDLE_OP (WASM_OP_UNUSED_0x12):
HANDLE_OP (WASM_OP_UNUSED_0x12): HANDLE_OP (WASM_OP_UNUSED_0x13):
HANDLE_OP (WASM_OP_UNUSED_0x13): HANDLE_OP (WASM_OP_UNUSED_0x14):
HANDLE_OP (WASM_OP_UNUSED_0x14): HANDLE_OP (WASM_OP_UNUSED_0x15):
HANDLE_OP (WASM_OP_UNUSED_0x15): HANDLE_OP (WASM_OP_UNUSED_0x16):
HANDLE_OP (WASM_OP_UNUSED_0x16): HANDLE_OP (WASM_OP_UNUSED_0x17):
HANDLE_OP (WASM_OP_UNUSED_0x17): HANDLE_OP (WASM_OP_UNUSED_0x18):
HANDLE_OP (WASM_OP_UNUSED_0x18): HANDLE_OP (WASM_OP_UNUSED_0x19):
HANDLE_OP (WASM_OP_UNUSED_0x19): HANDLE_OP (WASM_OP_UNUSED_0x1c):
HANDLE_OP (WASM_OP_UNUSED_0x1c): HANDLE_OP (WASM_OP_UNUSED_0x1d):
HANDLE_OP (WASM_OP_UNUSED_0x1d): HANDLE_OP (WASM_OP_UNUSED_0x1e):
HANDLE_OP (WASM_OP_UNUSED_0x1e): HANDLE_OP (WASM_OP_UNUSED_0x1f):
HANDLE_OP (WASM_OP_UNUSED_0x1f): HANDLE_OP (WASM_OP_UNUSED_0x25):
HANDLE_OP (WASM_OP_UNUSED_0x25): HANDLE_OP (WASM_OP_UNUSED_0x26):
HANDLE_OP (WASM_OP_UNUSED_0x26): HANDLE_OP (WASM_OP_UNUSED_0x27):
HANDLE_OP (WASM_OP_UNUSED_0x27): {
{ wasm_set_exception(module, "WASM interp failed: unsupported opcode.");
wasm_set_exception(module, "WASM interp failed: unsupported opcode."); goto got_exception;
goto got_exception; }
}
#endif #endif
#if WASM_ENABLE_LABELS_AS_VALUES == 0 #if WASM_ENABLE_LABELS_AS_VALUES == 0
@ -2434,8 +2310,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
ret_type = func_type->result_count ret_type = func_type->result_count
? cur_func->param_types[func_type->param_count] ? cur_func->param_types[func_type->param_count]
: VALUE_TYPE_VOID; : VALUE_TYPE_VOID;
PUSH_CSP(BLOCK_TYPE_FUNCTION, ret_type, PUSH_CSP(BLOCK_TYPE_FUNCTION, ret_type, frame_ip_end - 1);
frame_ip, NULL, frame_ip_end - 1);
wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame*)frame); wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame*)frame);
} }
@ -2459,10 +2334,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
wasm_set_exception(module, "out of bounds memory access"); wasm_set_exception(module, "out of bounds memory access");
got_exception: got_exception:
if (depths && depths != depth_buf) {
wasm_free(depths);
depths = NULL;
}
return; return;
#if WASM_ENABLE_LABELS_AS_VALUES == 0 #if WASM_ENABLE_LABELS_AS_VALUES == 0
@ -2470,7 +2341,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#else #else
FETCH_OPCODE_AND_DISPATCH (); FETCH_OPCODE_AND_DISPATCH ();
#endif #endif
} }
void void

View File

@ -270,11 +270,10 @@ check_utf8_str(const uint8* str, uint32 len)
} }
static char* static char*
const_str_set_insert(const uint8 *str, uint32 len, WASMModule *module, const_str_list_insert(const uint8 *str, uint32 len, WASMModule *module,
char* error_buf, uint32 error_buf_size) char* error_buf, uint32 error_buf_size)
{ {
HashMap *set = module->const_str_set; StringNode *node, *node_next;
char *c_str, *value;
if (!check_utf8_str(str, len)) { if (!check_utf8_str(str, len)) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
@ -283,30 +282,42 @@ const_str_set_insert(const uint8 *str, uint32 len, WASMModule *module,
return NULL; return NULL;
} }
if (!(c_str = wasm_malloc(len + 1))) { /* Search const str list */
node = module->const_str_list;
while (node) {
node_next = node->next;
if (strlen(node->str) == len
&& !memcmp(node->str, str, len))
break;
node = node_next;
}
if (node)
return node->str;
if (!(node = wasm_malloc(sizeof(StringNode) + len + 1))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"WASM module load failed: " "WASM module load failed: "
"allocate memory failed."); "allocate memory failed.");
return NULL; return NULL;
} }
bh_memcpy_s(c_str, len + 1, str, len); node->str = ((char*)node) + sizeof(StringNode);
c_str[len] = '\0'; bh_memcpy_s(node->str, len + 1, str, len);
node->str[len] = '\0';
if ((value = bh_hash_map_find(set, c_str))) { if (!module->const_str_list) {
wasm_free(c_str); /* set as head */
return value; module->const_str_list = node;
node->next = NULL;
}
else {
/* insert it */
node->next = module->const_str_list;
module->const_str_list = node;
} }
if (!bh_hash_map_insert(set, c_str, c_str)) { return node->str;
set_error_buf(error_buf, error_buf_size,
"WASM module load failed: "
"insert string to hash map failed.");
wasm_free(c_str);
return NULL;
}
return c_str;
} }
static bool static bool
@ -683,12 +694,19 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
p = p_old; p = p_old;
/* insert "env" and "wasi_unstable" to const str list */
if (!const_str_list_insert((uint8*)"env", 3, module, error_buf, error_buf_size)
|| !const_str_list_insert((uint8*)"wasi_unstable", 13, module,
error_buf, error_buf_size)) {
return false;
}
/* Scan again to read the data */ /* Scan again to read the data */
for (i = 0; i < import_count; i++) { for (i = 0; i < import_count; i++) {
/* load module name */ /* load module name */
read_leb_uint32(p, p_end, name_len); read_leb_uint32(p, p_end, name_len);
CHECK_BUF(p, p_end, name_len); CHECK_BUF(p, p_end, name_len);
if (!(module_name = const_str_set_insert if (!(module_name = const_str_list_insert
(p, name_len, module, error_buf, error_buf_size))) { (p, name_len, module, error_buf, error_buf_size))) {
return false; return false;
} }
@ -697,7 +715,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
/* load field name */ /* load field name */
read_leb_uint32(p, p_end, name_len); read_leb_uint32(p, p_end, name_len);
CHECK_BUF(p, p_end, name_len); CHECK_BUF(p, p_end, name_len);
if (!(field_name = const_str_set_insert if (!(field_name = const_str_list_insert
(p, name_len, module, error_buf, error_buf_size))) { (p, name_len, module, error_buf, error_buf_size))) {
return false; return false;
} }
@ -726,7 +744,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
if (!(import->u.function.func_ptr_linked = if (!(import->u.function.func_ptr_linked =
resolve_sym(module_name, field_name))) { resolve_sym(module_name, field_name))) {
#ifndef BUILD_AOT_COMPILER /* Output warning except running aot compiler */ #if WASM_ENABLE_WAMR_COMPILER == 0 /* Output warning except running aot compiler */
LOG_WARNING("warning: fail to link import function (%s, %s)\n", LOG_WARNING("warning: fail to link import function (%s, %s)\n",
module_name, field_name); module_name, field_name);
#endif #endif
@ -819,6 +837,39 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
return true; return true;
} }
static bool
init_function_local_offsets(WASMFunction *func,
char *error_buf, uint32 error_buf_size)
{
WASMType *param_type = func->func_type;
uint32 param_count = param_type->param_count;
uint8 *param_types = param_type->types;
uint32 local_count = func->local_count;
uint8 *local_types = func->local_types;
uint32 i, local_offset = 0;
uint64 total_size = sizeof(uint16) * ((uint64)param_count + local_count);
if (total_size >= UINT32_MAX
|| !(func->local_offsets = wasm_malloc((uint32)total_size))) {
set_error_buf(error_buf, error_buf_size,
"Load function section failed: allocate memory failed.");
return false;
}
for (i = 0; i < param_count; i++) {
func->local_offsets[i] = (uint16)local_offset;
local_offset += wasm_value_type_cell_num(param_types[i]);
}
for (i = 0; i < local_count; i++) {
func->local_offsets[param_count + i] = (uint16)local_offset;
local_offset += wasm_value_type_cell_num(local_types[i]);
}
bh_assert(local_offset == func->param_cell_num + func->local_cell_num);
return true;
}
static bool static bool
load_function_section(const uint8 *buf, const uint8 *buf_end, load_function_section(const uint8 *buf, const uint8 *buf_end,
const uint8 *buf_code, const uint8 *buf_code_end, const uint8 *buf_code, const uint8 *buf_code_end,
@ -944,6 +995,15 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
func->local_types[local_type_index++] = type; func->local_types[local_type_index++] = type;
} }
} }
func->param_cell_num = wasm_type_param_cell_num(func->func_type);
func->ret_cell_num = wasm_type_return_cell_num(func->func_type);
func->local_cell_num =
wasm_get_cell_num(func->local_types, func->local_count);
if (!init_function_local_offsets(func, error_buf, error_buf_size))
return false;
p_code = p_code_end; p_code = p_code_end;
} }
} }
@ -1134,7 +1194,7 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
for (i = 0; i < export_count; i++, export++) { for (i = 0; i < export_count; i++, export++) {
read_leb_uint32(p, p_end, str_len); read_leb_uint32(p, p_end, str_len);
CHECK_BUF(p, p_end, str_len); CHECK_BUF(p, p_end, str_len);
if (!(export->name = const_str_set_insert(p, str_len, module, if (!(export->name = const_str_list_insert(p, str_len, module,
error_buf, error_buf_size))) { error_buf, error_buf_size))) {
return false; return false;
} }
@ -1667,22 +1727,7 @@ create_module(char *error_buf, uint32 error_buf_size)
/* Set start_function to -1, means no start function */ /* Set start_function to -1, means no start function */
module->start_function = (uint32)-1; module->start_function = (uint32)-1;
if (!(module->const_str_set = bh_hash_map_create(32, false,
(HashFunc)wasm_string_hash,
(KeyEqualFunc)wasm_string_equal,
NULL,
wasm_loader_free))) {
set_error_buf(error_buf, error_buf_size,
"WASM module load failed: "
"create const string set failed.");
goto fail;
}
return module; return module;
fail:
wasm_loader_unload(module);
return NULL;
} }
WASMModule * WASMModule *
@ -1858,14 +1903,6 @@ wasm_loader_load(const uint8 *buf, uint32 size, char *error_buf, uint32 error_bu
/* Set start_function to -1, means no start function */ /* Set start_function to -1, means no start function */
module->start_function = (uint32)-1; module->start_function = (uint32)-1;
if (!(module->const_str_set =
bh_hash_map_create(32, false,
(HashFunc)wasm_string_hash,
(KeyEqualFunc)wasm_string_equal,
NULL,
wasm_loader_free)))
goto fail;
if (!load(buf, size, module, error_buf, error_buf_size)) if (!load(buf, size, module, error_buf, error_buf_size))
goto fail; goto fail;
@ -1898,8 +1935,11 @@ wasm_loader_unload(WASMModule *module)
if (module->functions) { if (module->functions) {
for (i = 0; i < module->function_count; i++) { for (i = 0; i < module->function_count; i++) {
if (module->functions[i]) if (module->functions[i]) {
if (module->functions[i]->local_offsets)
wasm_free(module->functions[i]->local_offsets);
wasm_free(module->functions[i]); wasm_free(module->functions[i]);
}
} }
wasm_free(module->functions); wasm_free(module->functions);
} }
@ -1932,8 +1972,14 @@ wasm_loader_unload(WASMModule *module)
wasm_free(module->data_segments); wasm_free(module->data_segments);
} }
if (module->const_str_set) if (module->const_str_list) {
bh_hash_map_destroy(module->const_str_set); StringNode *node = module->const_str_list, *node_next;
while (node) {
node_next = node->next;
wasm_free(node);
node = node_next;
}
}
wasm_free(module); wasm_free(module);
} }
@ -2064,9 +2110,7 @@ wasm_loader_find_block_addr(WASMModule *module,
case WASM_OP_DROP: case WASM_OP_DROP:
case WASM_OP_SELECT: case WASM_OP_SELECT:
case WASM_OP_DROP_32:
case WASM_OP_DROP_64: case WASM_OP_DROP_64:
case WASM_OP_SELECT_32:
case WASM_OP_SELECT_64: case WASM_OP_SELECT_64:
break; break;
@ -2081,8 +2125,6 @@ wasm_loader_find_block_addr(WASMModule *module,
case WASM_OP_GET_LOCAL_FAST: case WASM_OP_GET_LOCAL_FAST:
case WASM_OP_SET_LOCAL_FAST: case WASM_OP_SET_LOCAL_FAST:
case WASM_OP_TEE_LOCAL_FAST: case WASM_OP_TEE_LOCAL_FAST:
case WASM_OP_GET_GLOBAL_FAST:
case WASM_OP_SET_GLOBAL_FAST:
CHECK_BUF(p, p_end, 1); CHECK_BUF(p, p_end, 1);
p++; p++;
break; break;
@ -2570,7 +2612,7 @@ pop_type(uint8 type, uint8 **p_frame_ref, uint32 *p_stack_cell_num,
csp_num--; \ csp_num--; \
} while (0) } while (0)
#define GET_LOCAL_INDEX_AND_TYPE() do { \ #define GET_LOCAL_INDEX_TYPE_AND_OFFSET() do { \
read_leb_uint32(p, p_end, local_idx); \ read_leb_uint32(p, p_end, local_idx); \
if (local_idx >= param_count + local_count) { \ if (local_idx >= param_count + local_count) { \
set_error_buf(error_buf, error_buf_size, \ set_error_buf(error_buf, error_buf_size, \
@ -2581,6 +2623,7 @@ pop_type(uint8 type, uint8 **p_frame_ref, uint32 *p_stack_cell_num,
local_type = local_idx < param_count \ local_type = local_idx < param_count \
? param_types[local_idx] \ ? param_types[local_idx] \
: local_types[local_idx - param_count]; \ : local_types[local_idx - param_count]; \
local_offset = local_offsets[local_idx]; \
} while (0) } while (0)
#define CHECK_BR(depth) do { \ #define CHECK_BR(depth) do { \
@ -2636,7 +2679,7 @@ static bool
wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
char *error_buf, uint32 error_buf_size) char *error_buf, uint32 error_buf_size)
{ {
uint8 *p = func->code, *p_end = func->code + func->code_size; uint8 *p = func->code, *p_end = func->code + func->code_size, *p_org;
uint8 *frame_ref_bottom = NULL, *frame_ref_boundary, *frame_ref; uint8 *frame_ref_bottom = NULL, *frame_ref_boundary, *frame_ref;
BranchBlock *frame_csp_bottom = NULL, *frame_csp_boundary, *frame_csp; BranchBlock *frame_csp_bottom = NULL, *frame_csp_boundary, *frame_csp;
uint32 param_count, local_count, global_count; uint32 param_count, local_count, global_count;
@ -2644,6 +2687,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
uint32 stack_cell_num = 0, csp_num = 0; uint32 stack_cell_num = 0, csp_num = 0;
uint32 frame_ref_size, frame_csp_size; uint32 frame_ref_size, frame_csp_size;
uint8 *param_types, ret_type, *local_types, local_type, global_type; uint8 *param_types, ret_type, *local_types, local_type, global_type;
uint16 *local_offsets, local_offset;
uint32 count, i, local_idx, global_idx, depth, u32; uint32 count, i, local_idx, global_idx, depth, u32;
int32 i32, i32_const = 0; int32 i32, i32_const = 0;
int64 i64; int64 i64;
@ -2659,6 +2703,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
local_count = func->local_count; local_count = func->local_count;
local_types = func->local_types; local_types = func->local_types;
local_offsets = func->local_offsets;
frame_ref_size = 32; frame_ref_size = 32;
if (!(frame_ref_bottom = frame_ref = wasm_malloc(frame_ref_size))) { if (!(frame_ref_bottom = frame_ref = wasm_malloc(frame_ref_size))) {
@ -2946,7 +2991,6 @@ handle_next_reachable_block:
|| *(frame_ref - 1) == REF_F32) { || *(frame_ref - 1) == REF_F32) {
frame_ref--; frame_ref--;
stack_cell_num--; stack_cell_num--;
*(p - 1) = WASM_OP_DROP_32;
} }
else { else {
if (stack_cell_num <= 1) { if (stack_cell_num <= 1) {
@ -2978,7 +3022,6 @@ handle_next_reachable_block:
switch (*(frame_ref - 1)) { switch (*(frame_ref - 1)) {
case REF_I32: case REF_I32:
case REF_F32: case REF_F32:
*(p - 1) = WASM_OP_SELECT_32;
break; break;
case REF_I64_2: case REF_I64_2:
case REF_F64_2: case REF_F64_2:
@ -2995,23 +3038,70 @@ handle_next_reachable_block:
case WASM_OP_GET_LOCAL: case WASM_OP_GET_LOCAL:
{ {
GET_LOCAL_INDEX_AND_TYPE(); p_org = p - 1;
GET_LOCAL_INDEX_TYPE_AND_OFFSET();
PUSH_TYPE(local_type); PUSH_TYPE(local_type);
#if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_JIT == 0)
if (local_offset < 0x80) {
*p_org++ = WASM_OP_GET_LOCAL_FAST;
if (local_type == VALUE_TYPE_I32
|| local_type == VALUE_TYPE_F32)
*p_org++ = (uint8)local_offset;
else
*p_org++ = (uint8)(local_offset | 0x80);
while (p_org < p)
*p_org++ = WASM_OP_NOP;
}
#endif
break; break;
} }
case WASM_OP_SET_LOCAL: case WASM_OP_SET_LOCAL:
{ {
GET_LOCAL_INDEX_AND_TYPE(); p_org = p - 1;
GET_LOCAL_INDEX_TYPE_AND_OFFSET();
POP_TYPE(local_type); POP_TYPE(local_type);
#if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_JIT == 0)
if (local_offset < 0x80) {
*p_org++ = WASM_OP_SET_LOCAL_FAST;
if (local_type == VALUE_TYPE_I32
|| local_type == VALUE_TYPE_F32)
*p_org++ = (uint8)local_offset;
else
*p_org++ = (uint8)(local_offset | 0x80);
while (p_org < p)
*p_org++ = WASM_OP_NOP;
}
#endif
break; break;
} }
case WASM_OP_TEE_LOCAL: case WASM_OP_TEE_LOCAL:
{ {
GET_LOCAL_INDEX_AND_TYPE(); p_org = p - 1;
GET_LOCAL_INDEX_TYPE_AND_OFFSET();
POP_TYPE(local_type); POP_TYPE(local_type);
PUSH_TYPE(local_type); PUSH_TYPE(local_type);
#if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_JIT == 0)
if (local_offset < 0x80) {
*p_org++ = WASM_OP_TEE_LOCAL_FAST;
if (local_type == VALUE_TYPE_I32
|| local_type == VALUE_TYPE_F32)
*p_org++ = (uint8)local_offset;
else
*p_org++ = (uint8)(local_offset | 0x80);
while (p_org < p)
*p_org++ = WASM_OP_NOP;
}
#endif
break; break;
} }
@ -3466,5 +3556,7 @@ fail:
(void)u32; (void)u32;
(void)i32; (void)i32;
(void)i64; (void)i64;
(void)local_offset;
(void)p_org;
return return_value; return return_value;
} }

View File

@ -238,18 +238,13 @@ typedef enum WASMOpcode {
WASM_OP_F64_REINTERPRET_I64 = 0xbf, /* f64.reinterpret/i64 */ WASM_OP_F64_REINTERPRET_I64 = 0xbf, /* f64.reinterpret/i64 */
/* drop/select specified types*/ /* drop/select specified types*/
WASM_OP_DROP_32 = 0xc0, WASM_OP_DROP_64 = 0xc0,
WASM_OP_DROP_64 = 0xc1, WASM_OP_SELECT_64 = 0xc1,
WASM_OP_SELECT_32 = 0xc2, WASM_OP_GET_LOCAL_FAST = 0xc2,
WASM_OP_SELECT_64 = 0xc3, WASM_OP_SET_LOCAL_FAST = 0xc3,
WASM_OP_GET_LOCAL_FAST = 0xc4, WASM_OP_TEE_LOCAL_FAST = 0xc4,
WASM_OP_SET_LOCAL_FAST = 0xc5,
WASM_OP_TEE_LOCAL_FAST = 0xc6,
WASM_OP_GET_GLOBAL_FAST = 0xc7,
WASM_OP_SET_GLOBAL_FAST = 0xc8,
WASM_OP_IMPDEP1 = 0xc9, WASM_OP_IMPDEP = 0xc5
WASM_OP_IMPDEP2 = 0xca
} WASMOpcode; } WASMOpcode;
#ifdef __cplusplus #ifdef __cplusplus
@ -455,17 +450,12 @@ static const void *_name[WASM_INSTRUCTION_NUM] = { \
HANDLE_OPCODE (WASM_OP_I64_REINTERPRET_F64), /* 0xbd */ \ HANDLE_OPCODE (WASM_OP_I64_REINTERPRET_F64), /* 0xbd */ \
HANDLE_OPCODE (WASM_OP_F32_REINTERPRET_I32), /* 0xbe */ \ HANDLE_OPCODE (WASM_OP_F32_REINTERPRET_I32), /* 0xbe */ \
HANDLE_OPCODE (WASM_OP_F64_REINTERPRET_I64), /* 0xbf */ \ HANDLE_OPCODE (WASM_OP_F64_REINTERPRET_I64), /* 0xbf */ \
HANDLE_OPCODE (WASM_OP_DROP_32), /* 0xc0 */ \ HANDLE_OPCODE (WASM_OP_DROP_64), /* 0xc0 */ \
HANDLE_OPCODE (WASM_OP_DROP_64), /* 0xc1 */ \ HANDLE_OPCODE (WASM_OP_SELECT_64), /* 0xc1 */ \
HANDLE_OPCODE (WASM_OP_SELECT_32), /* 0xc2 */ \ HANDLE_OPCODE (WASM_OP_GET_LOCAL_FAST),/* 0xc2 */ \
HANDLE_OPCODE (WASM_OP_SELECT_64), /* 0xc3 */ \ HANDLE_OPCODE (WASM_OP_SET_LOCAL_FAST),/* 0xc3 */ \
HANDLE_OPCODE (WASM_OP_GET_LOCAL_FAST),/* 0xc4 */ \ HANDLE_OPCODE (WASM_OP_TEE_LOCAL_FAST),/* 0xc4 */ \
HANDLE_OPCODE (WASM_OP_SET_LOCAL_FAST),/* 0xc5 */ \ HANDLE_OPCODE (WASM_OP_IMPDEP), /* 0xc5 */ \
HANDLE_OPCODE (WASM_OP_TEE_LOCAL_FAST),/* 0xc6 */ \
HANDLE_OPCODE (WASM_OP_GET_GLOBAL_FAST),/* 0xc7 */ \
HANDLE_OPCODE (WASM_OP_SET_GLOBAL_FAST),/* 0xc8 */ \
HANDLE_OPCODE (WASM_OP_IMPDEP1), /* 0xc9 */ \
HANDLE_OPCODE (WASM_OP_IMPDEP2), /* 0xca */ \
} }
#endif /* end of _WASM_OPCODE_H */ #endif /* end of _WASM_OPCODE_H */

View File

@ -290,45 +290,10 @@ static void
functions_deinstantiate(WASMFunctionInstance *functions, uint32 count) functions_deinstantiate(WASMFunctionInstance *functions, uint32 count)
{ {
if (functions) { if (functions) {
uint32 i;
for (i = 0; i < count; i++)
if (functions[i].local_offsets)
wasm_free(functions[i].local_offsets);
wasm_free(functions); wasm_free(functions);
} }
} }
static bool
function_init_local_offsets(WASMFunctionInstance *func)
{
uint32 local_offset = 0;
WASMType *param_type = func->u.func->func_type;
uint32 param_count = param_type->param_count;
uint8 *param_types = param_type->types;
uint32 local_count = func->u.func->local_count;
uint8 *local_types = func->u.func->local_types;
uint32 i;
uint64 total_size = sizeof(uint16) * (uint64)(param_count + local_count);
if (total_size >= UINT32_MAX
|| !(func->local_offsets = wasm_malloc((uint32)total_size)))
return false;
for (i = 0; i < param_count; i++) {
func->local_offsets[i] = (uint16)local_offset;
local_offset += wasm_value_type_cell_num(param_types[i]);
}
for (i = 0; i < local_count; i++) {
func->local_offsets[param_count + i] = (uint16)local_offset;
local_offset += wasm_value_type_cell_num(local_types[i]);
}
bh_assert(local_offset == func->param_cell_num + func->local_cell_num);
return true;
}
/** /**
* Instantiate functions in a module. * Instantiate functions in a module.
*/ */
@ -379,23 +344,16 @@ functions_instantiate(const WASMModule *module,
function->is_import_func = false; function->is_import_func = false;
function->u.func = module->functions[i]; function->u.func = module->functions[i];
function->param_cell_num = function->param_cell_num = function->u.func->param_cell_num;
wasm_type_param_cell_num(function->u.func->func_type); function->ret_cell_num = function->u.func->ret_cell_num;
function->ret_cell_num = function->local_cell_num = function->u.func->local_cell_num;
wasm_type_return_cell_num(function->u.func->func_type);
function->local_cell_num =
wasm_get_cell_num(function->u.func->local_types,
function->u.func->local_count);
function->param_count = (uint16)function->u.func->func_type->param_count; function->param_count = (uint16)function->u.func->func_type->param_count;
function->local_count = (uint16)function->u.func->local_count; function->local_count = (uint16)function->u.func->local_count;
function->param_types = function->u.func->func_type->types; function->param_types = function->u.func->func_type->types;
function->local_types = function->u.func->local_types; function->local_types = function->u.func->local_types;
if (!function_init_local_offsets(function)) { function->local_offsets = function->u.func->local_offsets;
functions_deinstantiate(functions, function_count);
return NULL;
}
function++; function++;
} }

View File

@ -64,6 +64,10 @@ enum {
#define WASM_ENABLE_JIT 0 #define WASM_ENABLE_JIT 0
#endif #endif
#ifndef WASM_ENABLE_WAMR_COMPILER
#define WASM_ENABLE_WAMR_COMPILER 0
#endif
#ifndef WASM_ENABLE_LIBC_BUILTIN #ifndef WASM_ENABLE_LIBC_BUILTIN
#define WASM_ENABLE_LIBC_BUILTIN 0 #define WASM_ENABLE_LIBC_BUILTIN 0
#endif #endif

View File

@ -8,18 +8,10 @@
void bh_log_emit(const char *fmt, va_list ap) void bh_log_emit(const char *fmt, va_list ap)
{ {
//TODO: stub impl bh_vprintf_sgx(fmt, ap);
} }
/*
int bh_fprintf(FILE *stream, const char *fmt, ...)
{
return 0;
}
*/
int bh_fflush(void *stream) int bh_fflush(void *stream)
{ {
//TODO: stub impl
return 0; return 0;
} }

View File

@ -102,7 +102,9 @@ Usage: wamrc [options] -o output_file wasm_file
Use +feature to enable a feature, or -feature to disable it Use +feature to enable a feature, or -feature to disable it
For example, --cpu-features=+feature1,-feature2 For example, --cpu-features=+feature1,-feature2
Use --cpu-features=+help to list all the features supported Use --cpu-features=+help to list all the features supported
--opt-level=n Set the optimization level (0 to 3, default: 3) --opt-level=n Set the optimization level (0 to 3, default: 3, which is fastest)
--size-level=n Set the code size level (0 to 3, default: 3, which is smallest)
-sgx Generate code for SGX platform (Intel Software Guard Extention)
--format=<format> Specifies the format of the output file --format=<format> Specifies the format of the output file
The format supported: The format supported:
aot (default) AoT file aot (default) AoT file

View File

@ -57,22 +57,25 @@ set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake) include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE}) add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections -pie -fPIE")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security") set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security")
# set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion -Wsign-conversion") # set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion -Wsign-conversion")
if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch-register")
endif ()
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector-strong --param ssp-buffer-size=4")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-z,noexecstack,-z,relro,-z,now")
# These flags will lead to about 0.1x ~ 0.25x slower in interpreter mode, if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64")
# but we enable them by default to enhance security if (NOT (${CMAKE_C_COMPILER} MATCHES ".*clang.*"))
if (BUILD_TARGET MATCHES "X86_.*" OR BUILD_TARGET STREQUAL "AMD_64") set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch-register")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pie -fPIE -ftrapv -D_FORTIFY_SOURCE=2") endif ()
endif () endif ()
# The following flags are to enhance security, but it may impact performance,
# we disable them by default.
#if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64")
# set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftrapv -D_FORTIFY_SOURCE=2")
#endif ()
#set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector-strong --param ssp-buffer-size=4")
#set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-z,noexecstack,-z,relro,-z,now")
add_executable (iwasm main.c ext_lib_export.c) add_executable (iwasm main.c ext_lib_export.c)
install (TARGETS iwasm DESTINATION bin) install (TARGETS iwasm DESTINATION bin)

View File

@ -11,7 +11,7 @@ set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
add_definitions(-DWASM_ENABLE_INTERP=1) add_definitions(-DWASM_ENABLE_INTERP=1)
add_definitions(-DBUILD_AOT_COMPILER=1) add_definitions(-DWASM_ENABLE_WAMR_COMPILER=1)
# Set WAMR_BUILD_TARGET, currently values supported: # Set WAMR_BUILD_TARGET, currently values supported:
# "X86_64", "AMD_64", "X86_32", "ARM_32", "MIPS_32", "XTENSA_32" # "X86_64", "AMD_64", "X86_32", "ARM_32", "MIPS_32", "XTENSA_32"

View File

@ -28,7 +28,9 @@ print_help()
bh_printf(" Use +feature to enable a feature, or -feature to disable it\n"); bh_printf(" Use +feature to enable a feature, or -feature to disable it\n");
bh_printf(" For example, --cpu-features=+feature1,-feature2\n"); bh_printf(" For example, --cpu-features=+feature1,-feature2\n");
bh_printf(" Use --cpu-features=+help to list all the features supported\n"); bh_printf(" Use --cpu-features=+help to list all the features supported\n");
bh_printf(" --opt-level=n Set the optimization level (0 to 3, default: 3)\n"); bh_printf(" --opt-level=n Set the optimization level (0 to 3, default: 3, which is fastest)\n");
bh_printf(" --size-level=n Set the code size level (0 to 3, default: 3, which is smallest)\n");
bh_printf(" -sgx Generate code for SGX platform (Intel Software Guard Extention)\n");
bh_printf(" --format=<format> Specifies the format of the output file\n"); bh_printf(" --format=<format> Specifies the format of the output file\n");
bh_printf(" The format supported:\n"); bh_printf(" The format supported:\n");
bh_printf(" aot (default) AoT file\n"); bh_printf(" aot (default) AoT file\n");
@ -53,8 +55,10 @@ main(int argc, char *argv[])
AOTCompOption option = { 0 }; AOTCompOption option = { 0 };
char error_buf[128]; char error_buf[128];
int log_verbose_level = 2; int log_verbose_level = 2;
bool sgx_mode = false;
option.opt_level = 3; option.opt_level = 3;
option.size_level = 3;
option.output_format = AOT_FORMAT_FILE; option.output_format = AOT_FORMAT_FILE;
/* Process options. */ /* Process options. */
@ -92,6 +96,16 @@ main(int argc, char *argv[])
if (option.opt_level > 3) if (option.opt_level > 3)
option.opt_level = 3; option.opt_level = 3;
} }
else if (!strncmp(argv[0], "--size-level=", 13)) {
if (argv[0][13] == '\0')
return print_help();
option.size_level = (uint32)atoi(argv[0] + 13);
if (option.size_level > 3)
option.size_level = 3;
}
else if (!strcmp(argv[0], "-sgx")) {
sgx_mode = true;
}
else if (!strncmp(argv[0], "--format=", 9)) { else if (!strncmp(argv[0], "--format=", 9)) {
if (argv[0][9] == '\0') if (argv[0][9] == '\0')
return print_help(); return print_help();
@ -115,6 +129,9 @@ main(int argc, char *argv[])
if (argc == 0) if (argc == 0)
return print_help(); return print_help();
if (sgx_mode)
option.size_level = 1;
wasm_file_name = argv[0]; wasm_file_name = argv[0];
if (bh_memory_init_with_allocator(malloc, free)) { if (bh_memory_init_with_allocator(malloc, free)) {