diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 00a22ffff..4515e4a9e 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -2205,28 +2205,6 @@ aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count) } #endif /* end of OS_ENABLE_HW_BOUND_CHECK */ -bool -aot_is_wasm_type_equal(AOTModuleInstance *module_inst, uint32 type1_idx, - uint32 type2_idx) -{ - WASMType *type1, *type2; - AOTModule *module = (AOTModule *)module_inst->aot_module.ptr; - - if (type1_idx >= module->func_type_count - || type2_idx >= module->func_type_count) { - aot_set_exception(module_inst, "type index out of bounds"); - return false; - } - - if (type1_idx == type2_idx) - return true; - - type1 = module->func_types[type1_idx]; - type2 = module->func_types[type2_idx]; - - return wasm_type_equal(type1, type2); -} - bool aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, uint32 *argv) diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index ef3568fd8..f9823896b 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -633,9 +633,6 @@ aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count); * * @return true if equal, false otherwise */ -bool -aot_is_wasm_type_equal(AOTModuleInstance *module_inst, uint32 type1_idx, - uint32 type2_idx); /** * Invoke native function from aot code diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index 49961b089..1da303d85 100644 --- a/core/iwasm/interpreter/wasm.h +++ b/core/iwasm/interpreter/wasm.h @@ -122,6 +122,7 @@ typedef struct WASMType { uint16 result_count; uint16 param_cell_num; uint16 ret_cell_num; + uint16 ref_count; /* types of params and results */ uint8 types[1]; } WASMType; @@ -612,6 +613,9 @@ wasm_value_type_cell_num_outside(uint8 value_type) inline static bool wasm_type_equal(const WASMType *type1, const WASMType *type2) { + if (type1 == type2) { + return true; + } return (type1->param_count == type2->param_count && type1->result_count == type2->result_count && memcmp(type1->types, type2->types, diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index 24071cf18..9df1df08c 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -1391,7 +1391,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, tbl_inst = wasm_get_table_inst(module, tbl_idx); val = POP_I32(); - if (val < 0 || val >= (int32)tbl_inst->cur_size) { + if ((uint32)val >= tbl_inst->cur_size) { wasm_set_exception(module, "undefined element"); goto got_exception; } @@ -1419,10 +1419,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, 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)) { + + if (cur_type != cur_func_type) { wasm_set_exception(module, "indirect call type mismatch"); goto got_exception; } + #if WASM_ENABLE_TAIL_CALL != 0 if (opcode == WASM_OP_RETURN_CALL_INDIRECT) goto call_func_from_return_call; diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index 49cbce5ca..6fad303e2 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -1316,7 +1316,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, val = GET_OPERAND(uint32, I32, 0); frame_ip += 2; - if (val < 0 || val >= (int32)tbl_inst->cur_size) { + if ((uint32)val >= tbl_inst->cur_size) { wasm_set_exception(module, "undefined element"); goto got_exception; } @@ -1344,10 +1344,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, 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)) { + + if (cur_type != cur_func_type) { wasm_set_exception(module, "indirect call type mismatch"); goto got_exception; } + #if WASM_ENABLE_TAIL_CALL != 0 if (opcode == WASM_OP_RETURN_CALL_INDIRECT) goto call_func_from_return_call; diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index 658aa005a..cf106c8af 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -415,6 +415,19 @@ const_str_list_insert(const uint8 *str, uint32 len, WASMModule *module, return node->str; } +static void +destroy_wasm_type(WASMType *type) +{ + if (type->ref_count > 1) { + /* The type is referenced by other types + of current wasm module */ + type->ref_count--; + return; + } + + wasm_runtime_free(type); +} + static bool load_init_expr(const uint8 **p_buf, const uint8 *buf_end, InitializerExpression *init_expr, uint8 type, char *error_buf, @@ -582,6 +595,7 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, } /* Resolve param types and result types */ + type->ref_count = 1; type->param_count = (uint16)param_count; type->result_count = (uint16)result_count; for (j = 0; j < param_count; j++) { @@ -611,6 +625,21 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, } type->param_cell_num = (uint16)param_cell_num; type->ret_cell_num = (uint16)ret_cell_num; + + /* If there is already a same type created, use it instead */ + for (j = 0; j < i; j++) { + if (wasm_type_equal(type, module->types[j])) { + if (module->types[j]->ref_count == UINT16_MAX) { + set_error_buf(error_buf, error_buf_size, + "wasm type's ref count too large"); + return false; + } + destroy_wasm_type(type); + module->types[i] = module->types[j]; + module->types[j]->ref_count++; + break; + } + } } } @@ -3729,7 +3758,7 @@ wasm_loader_unload(WASMModule *module) if (module->types) { for (i = 0; i < module->type_count; i++) { if (module->types[i]) - wasm_runtime_free(module->types[i]); + destroy_wasm_type(module->types[i]); } wasm_runtime_free(module->types); } diff --git a/core/iwasm/interpreter/wasm_mini_loader.c b/core/iwasm/interpreter/wasm_mini_loader.c index b1a1380cc..c7c83d226 100644 --- a/core/iwasm/interpreter/wasm_mini_loader.c +++ b/core/iwasm/interpreter/wasm_mini_loader.c @@ -248,6 +248,19 @@ const_str_list_insert(const uint8 *str, uint32 len, WASMModule *module, return node->str; } +static void +destroy_wasm_type(WASMType *type) +{ + if (type->ref_count > 1) { + /* The type is referenced by other types + of current wasm module */ + type->ref_count--; + return; + } + + wasm_runtime_free(type); +} + static bool load_init_expr(const uint8 **p_buf, const uint8 *buf_end, InitializerExpression *init_expr, uint8 type, char *error_buf, @@ -372,6 +385,7 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, } /* Resolve param types and result types */ + type->ref_count = 1; type->param_count = (uint16)param_count; type->result_count = (uint16)result_count; for (j = 0; j < param_count; j++) { @@ -394,6 +408,17 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, && ret_cell_num <= UINT16_MAX); type->param_cell_num = (uint16)param_cell_num; type->ret_cell_num = (uint16)ret_cell_num; + + /* If there is already a same type created, use it instead */ + for (j = 0; j < i; ++j) { + if (wasm_type_equal(type, j)) { + bh_assert(module->types[j]->ref_count != UINT16_MAX); + destroy_wasm_type(type); + module->types[i] = module->types[j]; + module->types[j]->ref_count++; + break; + } + } } } @@ -2400,7 +2425,7 @@ wasm_loader_unload(WASMModule *module) if (module->types) { for (i = 0; i < module->type_count; i++) { if (module->types[i]) - wasm_runtime_free(module->types[i]); + destroy_wasm_type(module->types[i]); } wasm_runtime_free(module->types); } diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 02284f3aa..f66c06602 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -787,13 +787,13 @@ globals_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, if (!(global->import_module_inst = get_sub_module_inst( module_inst, global_import->import_module))) { set_error_buf(error_buf, error_buf_size, "unknown global"); - return NULL; + goto fail; } if (!(global->import_global_inst = wasm_lookup_global( global->import_module_inst, global_import->field_name))) { set_error_buf(error_buf, error_buf_size, "unknown global"); - return NULL; + goto fail; } /* The linked global instance has been initialized, we @@ -829,7 +829,7 @@ globals_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, if (init_expr->init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) { if (!check_global_init_expr(module, init_expr->u.global_index, error_buf, error_buf_size)) { - return NULL; + goto fail; } bh_memcpy_s( @@ -853,6 +853,9 @@ globals_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, *p_global_data_size = global_data_offset; (void)module_inst; return globals; +fail: + wasm_runtime_free(globals); + return NULL; } /** @@ -2663,7 +2666,7 @@ call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 elem_idx, else cur_func_type = func_inst->u.func->func_type; - if (!wasm_type_equal(cur_type, cur_func_type)) { + if (cur_type != cur_func_type) { wasm_set_exception(module_inst, "indirect call type mismatch"); goto got_exception; }