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

@ -270,11 +270,10 @@ check_utf8_str(const uint8* str, uint32 len)
}
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)
{
HashMap *set = module->const_str_set;
char *c_str, *value;
StringNode *node, *node_next;
if (!check_utf8_str(str, len)) {
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;
}
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,
"WASM module load failed: "
"allocate memory failed.");
return NULL;
}
bh_memcpy_s(c_str, len + 1, str, len);
c_str[len] = '\0';
node->str = ((char*)node) + sizeof(StringNode);
bh_memcpy_s(node->str, len + 1, str, len);
node->str[len] = '\0';
if ((value = bh_hash_map_find(set, c_str))) {
wasm_free(c_str);
return value;
if (!module->const_str_list) {
/* set as head */
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)) {
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;
return node->str;
}
static bool
@ -683,12 +694,19 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
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 */
for (i = 0; i < import_count; i++) {
/* load module name */
read_leb_uint32(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))) {
return false;
}
@ -697,7 +715,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
/* load field name */
read_leb_uint32(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))) {
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 =
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",
module_name, field_name);
#endif
@ -819,6 +837,39 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
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
load_function_section(const uint8 *buf, const uint8 *buf_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->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;
}
}
@ -1134,7 +1194,7 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
for (i = 0; i < export_count; i++, export++) {
read_leb_uint32(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))) {
return false;
}
@ -1667,22 +1727,7 @@ create_module(char *error_buf, uint32 error_buf_size)
/* Set start_function to -1, means no start function */
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;
fail:
wasm_loader_unload(module);
return NULL;
}
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 */
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))
goto fail;
@ -1898,8 +1935,11 @@ wasm_loader_unload(WASMModule *module)
if (module->functions) {
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);
}
@ -1932,8 +1972,14 @@ wasm_loader_unload(WASMModule *module)
wasm_free(module->data_segments);
}
if (module->const_str_set)
bh_hash_map_destroy(module->const_str_set);
if (module->const_str_list) {
StringNode *node = module->const_str_list, *node_next;
while (node) {
node_next = node->next;
wasm_free(node);
node = node_next;
}
}
wasm_free(module);
}
@ -2064,9 +2110,7 @@ wasm_loader_find_block_addr(WASMModule *module,
case WASM_OP_DROP:
case WASM_OP_SELECT:
case WASM_OP_DROP_32:
case WASM_OP_DROP_64:
case WASM_OP_SELECT_32:
case WASM_OP_SELECT_64:
break;
@ -2081,8 +2125,6 @@ wasm_loader_find_block_addr(WASMModule *module,
case WASM_OP_GET_LOCAL_FAST:
case WASM_OP_SET_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);
p++;
break;
@ -2570,7 +2612,7 @@ pop_type(uint8 type, uint8 **p_frame_ref, uint32 *p_stack_cell_num,
csp_num--; \
} 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); \
if (local_idx >= param_count + local_count) { \
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 \
? param_types[local_idx] \
: local_types[local_idx - param_count]; \
local_offset = local_offsets[local_idx]; \
} while (0)
#define CHECK_BR(depth) do { \
@ -2636,7 +2679,7 @@ static bool
wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
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;
BranchBlock *frame_csp_bottom = NULL, *frame_csp_boundary, *frame_csp;
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 frame_ref_size, frame_csp_size;
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;
int32 i32, i32_const = 0;
int64 i64;
@ -2659,6 +2703,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
local_count = func->local_count;
local_types = func->local_types;
local_offsets = func->local_offsets;
frame_ref_size = 32;
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--;
stack_cell_num--;
*(p - 1) = WASM_OP_DROP_32;
}
else {
if (stack_cell_num <= 1) {
@ -2978,7 +3022,6 @@ handle_next_reachable_block:
switch (*(frame_ref - 1)) {
case REF_I32:
case REF_F32:
*(p - 1) = WASM_OP_SELECT_32;
break;
case REF_I64_2:
case REF_F64_2:
@ -2995,23 +3038,70 @@ handle_next_reachable_block:
case WASM_OP_GET_LOCAL:
{
GET_LOCAL_INDEX_AND_TYPE();
p_org = p - 1;
GET_LOCAL_INDEX_TYPE_AND_OFFSET();
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;
}
case WASM_OP_SET_LOCAL:
{
GET_LOCAL_INDEX_AND_TYPE();
p_org = p - 1;
GET_LOCAL_INDEX_TYPE_AND_OFFSET();
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;
}
case WASM_OP_TEE_LOCAL:
{
GET_LOCAL_INDEX_AND_TYPE();
p_org = p - 1;
GET_LOCAL_INDEX_TYPE_AND_OFFSET();
POP_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;
}
@ -3466,5 +3556,7 @@ fail:
(void)u32;
(void)i32;
(void)i64;
(void)local_offset;
(void)p_org;
return return_value;
}