mirror of
				https://github.com/bytecodealliance/wasm-micro-runtime.git
				synced 2025-10-31 05:11:19 +00:00 
			
		
		
		
	Refine aot stack overflow check and enhance wasm loader malformed checks (#248)
And separate global data from wasm memory instance
This commit is contained in:
		
							parent
							
								
									d381b0fdec
								
							
						
					
					
						commit
						e8e45aeecd
					
				|  | @ -1959,12 +1959,14 @@ aot_load_from_comp_data(AOTCompData *comp_data, AOTCompContext *comp_ctx, | ||||||
| 
 | 
 | ||||||
|     module->start_func_index = comp_data->start_func_index; |     module->start_func_index = comp_data->start_func_index; | ||||||
|     if (comp_data->start_func_index != (uint32)-1) { |     if (comp_data->start_func_index != (uint32)-1) { | ||||||
|         bh_assert(comp_data->start_func_index >= module->import_func_count |         bh_assert(comp_data->start_func_index < module->import_func_count | ||||||
|                   && comp_data->start_func_index < module->import_func_count |                                                 + module->func_count); | ||||||
|                                                    + module->func_count); |         /* TODO: fix issue that start func cannot be import func */ | ||||||
|         module->start_function = |         if (comp_data->start_func_index >= module->import_func_count) { | ||||||
|             module->func_ptrs[comp_data->start_func_index |             module->start_function = | ||||||
|                               - module->import_func_count]; |                 module->func_ptrs[comp_data->start_func_index | ||||||
|  |                                   - module->import_func_count]; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|         module->start_function = NULL; |         module->start_function = NULL; | ||||||
|  |  | ||||||
|  | @ -897,6 +897,15 @@ aot_call_indirect(WASMExecEnv *exec_env, | ||||||
|     void *attachment = NULL; |     void *attachment = NULL; | ||||||
|     char buf[128]; |     char buf[128]; | ||||||
| 
 | 
 | ||||||
|  |     /* this function is called from native code, so exec_env->handle and
 | ||||||
|  |        exec_env->native_stack_boundary must have been set, we don't set | ||||||
|  |        it again */ | ||||||
|  | 
 | ||||||
|  |     if ((uint8*)&module_inst < exec_env->native_stack_boundary) { | ||||||
|  |         aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW); | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     if (table_elem_idx >= table_size) { |     if (table_elem_idx >= table_size) { | ||||||
|         aot_set_exception_with_id(module_inst, EXCE_UNDEFINED_ELEMENT); |         aot_set_exception_with_id(module_inst, EXCE_UNDEFINED_ELEMENT); | ||||||
|         return false; |         return false; | ||||||
|  | @ -941,15 +950,6 @@ aot_call_indirect(WASMExecEnv *exec_env, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /* this function is called from native code, so exec_env->handle and
 |  | ||||||
|        exec_env->native_stack_boundary must have been set, we don't set |  | ||||||
|        it again */ |  | ||||||
| 
 |  | ||||||
|     if ((uint8*)&module_inst < exec_env->native_stack_boundary) { |  | ||||||
|         aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW); |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return wasm_runtime_invoke_native(exec_env, func_ptr, |     return wasm_runtime_invoke_native(exec_env, func_ptr, | ||||||
|                                       func_type, signature, attachment, |                                       func_type, signature, attachment, | ||||||
|                                       argv, argc, argv); |                                       argv, argc, argv); | ||||||
|  |  | ||||||
|  | @ -327,6 +327,8 @@ aot_create_funcs(const WASMModule *module) | ||||||
|     /* Resolve local variable info and code info */ |     /* Resolve local variable info and code info */ | ||||||
|     funcs[i]->local_count = func->local_count; |     funcs[i]->local_count = func->local_count; | ||||||
|     funcs[i]->local_types = func->local_types; |     funcs[i]->local_types = func->local_types; | ||||||
|  |     funcs[i]->param_cell_num = func->param_cell_num; | ||||||
|  |     funcs[i]->local_cell_num = func->local_cell_num; | ||||||
|     funcs[i]->code = func->code; |     funcs[i]->code = func->code; | ||||||
|     funcs[i]->code_size = func->code_size; |     funcs[i]->code_size = func->code_size; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -98,6 +98,8 @@ typedef struct AOTFunc { | ||||||
|   uint32 func_type_index; |   uint32 func_type_index; | ||||||
|   uint32 local_count; |   uint32 local_count; | ||||||
|   uint8 *local_types; |   uint8 *local_types; | ||||||
|  |   uint16 param_cell_num; | ||||||
|  |   uint16 local_cell_num; | ||||||
|   uint32 code_size; |   uint32 code_size; | ||||||
|   uint8 *code; |   uint8 *code; | ||||||
| } AOTFunc; | } AOTFunc; | ||||||
|  |  | ||||||
|  | @ -256,11 +256,25 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static bool | static bool | ||||||
| check_stack_boundary(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) | check_stack_boundary(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, | ||||||
|  |                      uint32 callee_cell_num) | ||||||
| { | { | ||||||
|     LLVMBasicBlockRef block_curr = LLVMGetInsertBlock(comp_ctx->builder); |     LLVMBasicBlockRef block_curr = LLVMGetInsertBlock(comp_ctx->builder); | ||||||
|     LLVMBasicBlockRef check_stack; |     LLVMBasicBlockRef check_stack; | ||||||
|     LLVMValueRef cmp; |     LLVMValueRef callee_local_size, stack_bound, cmp; | ||||||
|  | 
 | ||||||
|  |     if (!(callee_local_size = I32_CONST(callee_cell_num * 4))) { | ||||||
|  |         aot_set_last_error("llvm build const failed."); | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (!(stack_bound = LLVMBuildInBoundsGEP(comp_ctx->builder, | ||||||
|  |                                              func_ctx->native_stack_bound, | ||||||
|  |                                              &callee_local_size, 1, | ||||||
|  |                                              "stack_bound"))) { | ||||||
|  |         aot_set_last_error("llvm build inbound gep failed."); | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     if (!(check_stack = LLVMAppendBasicBlockInContext(comp_ctx->context, |     if (!(check_stack = LLVMAppendBasicBlockInContext(comp_ctx->context, | ||||||
|                                                       func_ctx->func, |                                                       func_ctx->func, | ||||||
|  | @ -272,7 +286,7 @@ check_stack_boundary(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) | ||||||
|     LLVMMoveBasicBlockAfter(check_stack, block_curr); |     LLVMMoveBasicBlockAfter(check_stack, block_curr); | ||||||
| 
 | 
 | ||||||
|     if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntULT, |     if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntULT, | ||||||
|                               func_ctx->last_alloca, func_ctx->native_stack_bound, |                               func_ctx->last_alloca, stack_bound, | ||||||
|                               "cmp"))) { |                               "cmp"))) { | ||||||
|         aot_set_last_error("llvm build icmp failed."); |         aot_set_last_error("llvm build icmp failed."); | ||||||
|         return false; |         return false; | ||||||
|  | @ -297,11 +311,13 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, | ||||||
|     uint32 func_count = comp_ctx->func_ctx_count, param_cell_num = 0; |     uint32 func_count = comp_ctx->func_ctx_count, param_cell_num = 0; | ||||||
|     AOTFuncContext **func_ctxes = comp_ctx->func_ctxes; |     AOTFuncContext **func_ctxes = comp_ctx->func_ctxes; | ||||||
|     AOTFuncType *func_type; |     AOTFuncType *func_type; | ||||||
|  |     AOTFunc *aot_func; | ||||||
|     LLVMTypeRef *param_types = NULL, ret_type; |     LLVMTypeRef *param_types = NULL, ret_type; | ||||||
|     LLVMValueRef *param_values = NULL, value_ret = NULL, func; |     LLVMValueRef *param_values = NULL, value_ret = NULL, func; | ||||||
|     LLVMValueRef import_func_idx, res; |     LLVMValueRef import_func_idx, res; | ||||||
|     int32 i, j = 0, param_count; |     int32 i, j = 0, param_count; | ||||||
|     uint64 total_size; |     uint64 total_size; | ||||||
|  |     uint32 callee_cell_num; | ||||||
|     uint8 wasm_ret_type; |     uint8 wasm_ret_type; | ||||||
|     bool ret = false; |     bool ret = false; | ||||||
| 
 | 
 | ||||||
|  | @ -379,8 +395,10 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|         func = func_ctxes[func_idx - import_func_count]->func; |         func = func_ctxes[func_idx - import_func_count]->func; | ||||||
|  |         aot_func = func_ctxes[func_idx - import_func_count]->aot_func; | ||||||
|  |         callee_cell_num = aot_func->param_cell_num + aot_func->local_cell_num + 1; | ||||||
| 
 | 
 | ||||||
|         if (!check_stack_boundary(comp_ctx, func_ctx)) |         if (!check_stack_boundary(comp_ctx, func_ctx, callee_cell_num)) | ||||||
|             goto fail; |             goto fail; | ||||||
| 
 | 
 | ||||||
|         /* Call the function */ |         /* Call the function */ | ||||||
|  |  | ||||||
|  | @ -901,7 +901,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, | ||||||
|   uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0; |   uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0; | ||||||
|   uint32 total_mem_size = memory ? num_bytes_per_page * memory->cur_page_count |   uint32 total_mem_size = memory ? num_bytes_per_page * memory->cur_page_count | ||||||
|                                    - heap_base_offset : 0; |                                    - heap_base_offset : 0; | ||||||
|   uint8 *global_data = memory ? memory->global_data : NULL; |   uint8 *global_data = module->global_data; | ||||||
|   WASMTableInstance *table = module->default_table; |   WASMTableInstance *table = module->default_table; | ||||||
|   WASMGlobalInstance *globals = module->globals; |   WASMGlobalInstance *globals = module->globals; | ||||||
|   uint8 opcode_IMPDEP = WASM_OP_IMPDEP; |   uint8 opcode_IMPDEP = WASM_OP_IMPDEP; | ||||||
|  | @ -1521,7 +1521,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, | ||||||
|           memory = module->default_memory; |           memory = module->default_memory; | ||||||
|           total_mem_size = num_bytes_per_page * memory->cur_page_count |           total_mem_size = num_bytes_per_page * memory->cur_page_count | ||||||
|                            - heap_base_offset; |                            - heap_base_offset; | ||||||
|           global_data = memory->global_data; |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         (void)reserved; |         (void)reserved; | ||||||
|  |  | ||||||
|  | @ -893,7 +893,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, | ||||||
|   uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0; |   uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0; | ||||||
|   uint32 total_mem_size = memory ? num_bytes_per_page * memory->cur_page_count |   uint32 total_mem_size = memory ? num_bytes_per_page * memory->cur_page_count | ||||||
|                                    - heap_base_offset : 0; |                                    - heap_base_offset : 0; | ||||||
|   uint8 *global_data = memory ? memory->global_data : NULL; |   uint8 *global_data = module->global_data; | ||||||
|   WASMTableInstance *table = module->default_table; |   WASMTableInstance *table = module->default_table; | ||||||
|   WASMGlobalInstance *globals = module->globals; |   WASMGlobalInstance *globals = module->globals; | ||||||
|   uint8 opcode_IMPDEP = WASM_OP_IMPDEP; |   uint8 opcode_IMPDEP = WASM_OP_IMPDEP; | ||||||
|  | @ -1429,7 +1429,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, | ||||||
|           memory = module->default_memory; |           memory = module->default_memory; | ||||||
|           total_mem_size = num_bytes_per_page * memory->cur_page_count |           total_mem_size = num_bytes_per_page * memory->cur_page_count | ||||||
|                            - heap_base_offset; |                            - heap_base_offset; | ||||||
|           global_data = memory->global_data; |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         (void)reserved; |         (void)reserved; | ||||||
|  |  | ||||||
|  | @ -467,6 +467,18 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static bool | ||||||
|  | check_table_max_size(uint32 init_size, uint32 max_size, | ||||||
|  |                      char *error_buf, uint32 error_buf_size) | ||||||
|  | { | ||||||
|  |     if (max_size < init_size) { | ||||||
|  |         set_error_buf(error_buf, error_buf_size, | ||||||
|  |                       "size minimum must not be greater than maximum"); | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static bool | static bool | ||||||
| load_table_import(const uint8 **p_buf, const uint8 *buf_end, | load_table_import(const uint8 **p_buf, const uint8 *buf_end, | ||||||
|                   WASMTableImport *table, |                   WASMTableImport *table, | ||||||
|  | @ -480,8 +492,12 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end, | ||||||
|     bh_assert(table->elem_type == TABLE_ELEM_TYPE_ANY_FUNC); |     bh_assert(table->elem_type == TABLE_ELEM_TYPE_ANY_FUNC); | ||||||
|     read_leb_uint32(p, p_end, table->flags); |     read_leb_uint32(p, p_end, table->flags); | ||||||
|     read_leb_uint32(p, p_end, table->init_size); |     read_leb_uint32(p, p_end, table->init_size); | ||||||
|     if (table->flags & 1) |     if (table->flags & 1) { | ||||||
|         read_leb_uint32(p, p_end, table->max_size); |         read_leb_uint32(p, p_end, table->max_size); | ||||||
|  |         if (!check_table_max_size(table->init_size, table->max_size, | ||||||
|  |                                   error_buf, error_buf_size)) | ||||||
|  |             return false; | ||||||
|  |     } | ||||||
|     else |     else | ||||||
|         table->max_size = 0x10000; |         table->max_size = 0x10000; | ||||||
| 
 | 
 | ||||||
|  | @ -573,8 +589,12 @@ load_table(const uint8 **p_buf, const uint8 *buf_end, WASMTable *table, | ||||||
|     bh_assert(table->elem_type == TABLE_ELEM_TYPE_ANY_FUNC); |     bh_assert(table->elem_type == TABLE_ELEM_TYPE_ANY_FUNC); | ||||||
|     read_leb_uint32(p, p_end, table->flags); |     read_leb_uint32(p, p_end, table->flags); | ||||||
|     read_leb_uint32(p, p_end, table->init_size); |     read_leb_uint32(p, p_end, table->init_size); | ||||||
|     if (table->flags & 1) |     if (table->flags & 1) { | ||||||
|         read_leb_uint32(p, p_end, table->max_size); |         read_leb_uint32(p, p_end, table->max_size); | ||||||
|  |         if (!check_table_max_size(table->init_size, table->max_size, | ||||||
|  |                                   error_buf, error_buf_size)) | ||||||
|  |             return false; | ||||||
|  |     } | ||||||
|     else |     else | ||||||
|         table->max_size = 0x10000; |         table->max_size = 0x10000; | ||||||
| 
 | 
 | ||||||
|  | @ -1065,7 +1085,6 @@ load_table_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, | ||||||
|     WASMTable *table; |     WASMTable *table; | ||||||
| 
 | 
 | ||||||
|     read_leb_uint32(p, p_end, table_count); |     read_leb_uint32(p, p_end, table_count); | ||||||
|     bh_assert(table_count == 1); |  | ||||||
| 
 | 
 | ||||||
|     if (table_count) { |     if (table_count) { | ||||||
|         if (table_count > 1) { |         if (table_count > 1) { | ||||||
|  | @ -2419,6 +2438,7 @@ typedef struct BranchBlock { | ||||||
|     uint8 block_type; |     uint8 block_type; | ||||||
|     uint8 return_type; |     uint8 return_type; | ||||||
|     bool is_block_reachable; |     bool is_block_reachable; | ||||||
|  |     bool skip_else_branch; | ||||||
|     uint8 *start_addr; |     uint8 *start_addr; | ||||||
|     uint8 *else_addr; |     uint8 *else_addr; | ||||||
|     uint8 *end_addr; |     uint8 *end_addr; | ||||||
|  | @ -2590,10 +2610,13 @@ check_stack_pop(WASMLoaderContext *ctx, uint8 type, | ||||||
|                 char *error_buf, uint32 error_buf_size, |                 char *error_buf, uint32 error_buf_size, | ||||||
|                 const char *type_str) |                 const char *type_str) | ||||||
| { | { | ||||||
|  |     uint32 block_stack_cell_num = ctx->stack_cell_num | ||||||
|  |                                   - (ctx->frame_csp - 1)->stack_cell_num; | ||||||
|  | 
 | ||||||
|     if (((type == VALUE_TYPE_I32 || type == VALUE_TYPE_F32) |     if (((type == VALUE_TYPE_I32 || type == VALUE_TYPE_F32) | ||||||
|          && ctx->stack_cell_num < 1) |          && block_stack_cell_num < 1) | ||||||
|         || ((type == VALUE_TYPE_I64 || type == VALUE_TYPE_F64) |         || ((type == VALUE_TYPE_I64 || type == VALUE_TYPE_F64) | ||||||
|             && ctx->stack_cell_num < 2)) { |             && block_stack_cell_num < 2)) { | ||||||
|         set_error_buf(error_buf, error_buf_size, |         set_error_buf(error_buf, error_buf_size, | ||||||
|                       "WASM module load failed: " |                       "WASM module load failed: " | ||||||
|                       "type mismatch: expect data but stack was empty"); |                       "type mismatch: expect data but stack was empty"); | ||||||
|  | @ -2766,7 +2789,17 @@ static bool | ||||||
| wasm_loader_pop_frame_csp(WASMLoaderContext *ctx, | wasm_loader_pop_frame_csp(WASMLoaderContext *ctx, | ||||||
|                           char *error_buf, uint32 error_buf_size) |                           char *error_buf, uint32 error_buf_size) | ||||||
| { | { | ||||||
|  |     uint8 block_return_type; | ||||||
|  | 
 | ||||||
|     CHECK_CSP_POP(); |     CHECK_CSP_POP(); | ||||||
|  | 
 | ||||||
|  |     block_return_type = (ctx->frame_csp - 1)->return_type; | ||||||
|  |     if (!wasm_loader_pop_frame_ref(ctx, block_return_type, | ||||||
|  |                                    error_buf, error_buf_size) | ||||||
|  |         || !wasm_loader_push_frame_ref(ctx, block_return_type, | ||||||
|  |                                        error_buf, error_buf_size)) | ||||||
|  |         goto fail; | ||||||
|  | 
 | ||||||
|     ctx->frame_csp--; |     ctx->frame_csp--; | ||||||
|     ctx->csp_num--; |     ctx->csp_num--; | ||||||
|     return true; |     return true; | ||||||
|  | @ -3476,7 +3509,6 @@ fail: | ||||||
|         goto fail;                                              \ |         goto fail;                                              \ | ||||||
|   } while (0) |   } while (0) | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| #define GET_LOCAL_INDEX_TYPE_AND_OFFSET() 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) {   \ | ||||||
|  | @ -3515,11 +3547,6 @@ check_memory(WASMModule *module, | ||||||
|       goto fail;                                                    \ |       goto fail;                                                    \ | ||||||
|   } while (0) |   } while (0) | ||||||
| 
 | 
 | ||||||
| #if WASM_ENABLE_FAST_INTERP != 0 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| #endif /* WASM_ENABLE_FAST_INTERP */ |  | ||||||
| 
 |  | ||||||
| static bool | static bool | ||||||
| is_block_type_valid(uint8 type) | is_block_type_valid(uint8 type) | ||||||
| { | { | ||||||
|  | @ -3538,6 +3565,44 @@ is_block_type_valid(uint8 type) | ||||||
|         }                                                                   \ |         }                                                                   \ | ||||||
|     } while (0) |     } while (0) | ||||||
| 
 | 
 | ||||||
|  | static BranchBlock * | ||||||
|  | check_branch_block(WASMLoaderContext *loader_ctx, | ||||||
|  |                    uint8 **p_buf, uint8 *buf_end, | ||||||
|  |                    char *error_buf, uint32 error_buf_size) | ||||||
|  | { | ||||||
|  |     uint8 *p = *p_buf, *p_end = buf_end; | ||||||
|  |     BranchBlock *frame_csp_tmp; | ||||||
|  |     uint32 depth; | ||||||
|  | 
 | ||||||
|  |     read_leb_uint32(p, p_end, depth); | ||||||
|  |     CHECK_BR(depth); | ||||||
|  |     frame_csp_tmp = loader_ctx->frame_csp - depth - 1; | ||||||
|  | #if WASM_ENABLE_FAST_INTERP != 0 | ||||||
|  |     emit_br_info(frame_csp_tmp); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     *p_buf = p; | ||||||
|  |     return frame_csp_tmp; | ||||||
|  | fail: | ||||||
|  |     return NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static bool | ||||||
|  | check_branch_block_ret(WASMLoaderContext *loader_ctx, | ||||||
|  |                        BranchBlock *frame_csp_tmp, | ||||||
|  |                        char *error_buf, uint32 error_buf_size) | ||||||
|  | { | ||||||
|  |     frame_csp_tmp->is_block_reachable = true; | ||||||
|  |     if (frame_csp_tmp->block_type != BLOCK_TYPE_LOOP) { | ||||||
|  |         uint8 block_return_type = frame_csp_tmp->return_type; | ||||||
|  |         POP_TYPE(block_return_type); | ||||||
|  |         PUSH_TYPE(block_return_type); | ||||||
|  |     } | ||||||
|  |     return true; | ||||||
|  | fail: | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static bool | static bool | ||||||
| wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, | wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, | ||||||
|                              BlockAddr *block_addr_cache, |                              BlockAddr *block_addr_cache, | ||||||
|  | @ -3547,7 +3612,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, | ||||||
|     uint32 param_count, local_count, global_count; |     uint32 param_count, local_count, global_count; | ||||||
|     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; |     uint16 *local_offsets, local_offset; | ||||||
|     uint32 count, i, local_idx, global_idx, depth, u32, align, mem_offset; |     uint32 count, i, local_idx, global_idx, u32, align, mem_offset; | ||||||
|     uint32 cache_index, item_index; |     uint32 cache_index, item_index; | ||||||
|     int32 i32, i32_const = 0; |     int32 i32, i32_const = 0; | ||||||
|     int64 i64; |     int64 i64; | ||||||
|  | @ -3555,6 +3620,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, | ||||||
|     bool return_value = false, is_i32_const = false; |     bool return_value = false, is_i32_const = false; | ||||||
|     BlockAddr *cache_items; |     BlockAddr *cache_items; | ||||||
|     WASMLoaderContext *loader_ctx; |     WASMLoaderContext *loader_ctx; | ||||||
|  |     BranchBlock *frame_csp_tmp; | ||||||
| #if WASM_ENABLE_FAST_INTERP != 0 | #if WASM_ENABLE_FAST_INTERP != 0 | ||||||
|     uint8 *func_const_end, *func_const; |     uint8 *func_const_end, *func_const; | ||||||
|     int16 operand_offset; |     int16 operand_offset; | ||||||
|  | @ -3657,32 +3723,32 @@ re_scan: | ||||||
|                 if (!is_i32_const) |                 if (!is_i32_const) | ||||||
|                     (loader_ctx->frame_csp - 1)->is_block_reachable = true; |                     (loader_ctx->frame_csp - 1)->is_block_reachable = true; | ||||||
|                 else { |                 else { | ||||||
|                     if (!i32_const) { |                     cache_index = ((uintptr_t)(loader_ctx->frame_csp - 1)->start_addr) | ||||||
|                         cache_index = ((uintptr_t)(loader_ctx->frame_csp - 1)->start_addr) |                                    & (uintptr_t)(BLOCK_ADDR_CACHE_SIZE - 1); | ||||||
|                                       & (uintptr_t)(BLOCK_ADDR_CACHE_SIZE - 1); |                     cache_items = block_addr_cache | ||||||
|                         cache_items = block_addr_cache + |                                   + BLOCK_ADDR_CONFLICT_SIZE * cache_index; | ||||||
|                                       BLOCK_ADDR_CONFLICT_SIZE * cache_index; |                     for (item_index = 0; item_index < BLOCK_ADDR_CONFLICT_SIZE; | ||||||
|                         for (item_index = 0; item_index < BLOCK_ADDR_CONFLICT_SIZE; |                          item_index++) { | ||||||
|                              item_index++) { |                         if (cache_items[item_index].start_addr == | ||||||
|                             if (cache_items[item_index].start_addr == |                                 (loader_ctx->frame_csp - 1)->start_addr) { | ||||||
|                                                 (loader_ctx->frame_csp - 1)->start_addr) { |                             (loader_ctx->frame_csp - 1)->else_addr = | ||||||
|                                 (loader_ctx->frame_csp - 1)->else_addr = |                                 cache_items[item_index].else_addr; | ||||||
|                                             cache_items[item_index].else_addr; |                             (loader_ctx->frame_csp - 1)->end_addr = | ||||||
|                                 (loader_ctx->frame_csp - 1)->end_addr = |                                 cache_items[item_index].end_addr; | ||||||
|                                             cache_items[item_index].end_addr; |                             break; | ||||||
|                                 break; |  | ||||||
|                             } |  | ||||||
|                         } |                         } | ||||||
|                         if (item_index == BLOCK_ADDR_CONFLICT_SIZE |                     } | ||||||
|                             && !wasm_loader_find_block_addr(block_addr_cache, |                     if (item_index == BLOCK_ADDR_CONFLICT_SIZE | ||||||
|                                                            (loader_ctx->frame_csp - 1)->start_addr, |                         && !wasm_loader_find_block_addr(block_addr_cache, | ||||||
|                                                            p_end, |                                         (loader_ctx->frame_csp - 1)->start_addr, | ||||||
|                                                            (loader_ctx->frame_csp - 1)->block_type, |                                         p_end, | ||||||
|                                                            &(loader_ctx->frame_csp - 1)->else_addr, |                                         (loader_ctx->frame_csp - 1)->block_type, | ||||||
|                                                            &(loader_ctx->frame_csp - 1)->end_addr, |                                         &(loader_ctx->frame_csp - 1)->else_addr, | ||||||
|                                                            error_buf, error_buf_size)) |                                         &(loader_ctx->frame_csp - 1)->end_addr, | ||||||
|                             goto fail; |                                         error_buf, error_buf_size)) | ||||||
|  |                         goto fail; | ||||||
| 
 | 
 | ||||||
|  |                     if (!i32_const) { | ||||||
|                         if ((loader_ctx->frame_csp - 1)->else_addr) { |                         if ((loader_ctx->frame_csp - 1)->else_addr) { | ||||||
| #if WASM_ENABLE_FAST_INTERP != 0 | #if WASM_ENABLE_FAST_INTERP != 0 | ||||||
|                             loader_ctx->frame_offset = loader_ctx->frame_offset_bottom + |                             loader_ctx->frame_offset = loader_ctx->frame_offset_bottom + | ||||||
|  | @ -3698,6 +3764,10 @@ re_scan: | ||||||
|                         is_i32_const = false; |                         is_i32_const = false; | ||||||
|                         continue; |                         continue; | ||||||
|                     } |                     } | ||||||
|  |                     else { | ||||||
|  |                         /* The else branch cannot be reached, ignored it. */ | ||||||
|  |                         (loader_ctx->frame_csp - 1)->skip_else_branch = true; | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|                 break; |                 break; | ||||||
| 
 | 
 | ||||||
|  | @ -3710,6 +3780,16 @@ re_scan: | ||||||
|                     goto fail; |                     goto fail; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|  |                 if ((loader_ctx->frame_csp - 1)->skip_else_branch) { | ||||||
|  |                     /* The else branch is ignored. */ | ||||||
|  |                     is_i32_const = false; | ||||||
|  |                     p = (loader_ctx->frame_csp - 1)->end_addr; | ||||||
|  | #if WASM_ENABLE_FAST_INTERP != 0 | ||||||
|  |                     skip_label(); | ||||||
|  | #endif | ||||||
|  |                     continue; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|                 (loader_ctx->frame_csp - 1)->else_addr = p - 1; |                 (loader_ctx->frame_csp - 1)->else_addr = p - 1; | ||||||
|                 loader_ctx->stack_cell_num = (loader_ctx->frame_csp - 1)->stack_cell_num; |                 loader_ctx->stack_cell_num = (loader_ctx->frame_csp - 1)->stack_cell_num; | ||||||
|                 loader_ctx->frame_ref = loader_ctx->frame_ref_bottom + |                 loader_ctx->frame_ref = loader_ctx->frame_ref_bottom + | ||||||
|  | @ -3748,9 +3828,6 @@ re_scan: | ||||||
|             { |             { | ||||||
|                 POP_CSP(); |                 POP_CSP(); | ||||||
| 
 | 
 | ||||||
|                 POP_TYPE(loader_ctx->frame_csp->return_type); |  | ||||||
|                 PUSH_TYPE(loader_ctx->frame_csp->return_type); |  | ||||||
| 
 |  | ||||||
| #if WASM_ENABLE_FAST_INTERP != 0 | #if WASM_ENABLE_FAST_INTERP != 0 | ||||||
|                 skip_label(); |                 skip_label(); | ||||||
|                 // copy the result to the block return address
 |                 // copy the result to the block return address
 | ||||||
|  | @ -3800,16 +3877,13 @@ re_scan: | ||||||
| 
 | 
 | ||||||
|             case WASM_OP_BR: |             case WASM_OP_BR: | ||||||
|             { |             { | ||||||
| #if WASM_ENABLE_FAST_INTERP != 0 |                 if (!(frame_csp_tmp = check_branch_block(loader_ctx, &p, p_end, | ||||||
|                 BranchBlock *frame_csp_tmp; |                                                          error_buf, error_buf_size))) | ||||||
| #endif |                     goto fail; | ||||||
|                 read_leb_uint32(p, p_end, depth); |  | ||||||
|                 CHECK_BR(depth); |  | ||||||
| 
 | 
 | ||||||
| #if WASM_ENABLE_FAST_INTERP != 0 |                 if (!check_branch_block_ret(loader_ctx, frame_csp_tmp, | ||||||
|                 frame_csp_tmp = loader_ctx->frame_csp - depth - 1; |                                             error_buf, error_buf_size)) | ||||||
|                 emit_br_info(frame_csp_tmp); |                     goto fail; | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| handle_next_reachable_block: | handle_next_reachable_block: | ||||||
|                 for (i = 1; i <= loader_ctx->csp_num; i++) |                 for (i = 1; i <= loader_ctx->csp_num; i++) | ||||||
|  | @ -3870,31 +3944,25 @@ handle_next_reachable_block: | ||||||
| 
 | 
 | ||||||
|             case WASM_OP_BR_IF: |             case WASM_OP_BR_IF: | ||||||
|             { |             { | ||||||
| #if WASM_ENABLE_FAST_INTERP != 0 |  | ||||||
|                 BranchBlock *frame_csp_tmp; |  | ||||||
| #endif |  | ||||||
|                 read_leb_uint32(p, p_end, depth); |  | ||||||
|                 POP_I32(); |                 POP_I32(); | ||||||
|                 CHECK_BR(depth); | 
 | ||||||
| #if WASM_ENABLE_FAST_INTERP != 0 |                 if (!(frame_csp_tmp = check_branch_block(loader_ctx, &p, p_end, | ||||||
|                 frame_csp_tmp = loader_ctx->frame_csp - depth - 1; |                                                          error_buf, error_buf_size))) | ||||||
|                 emit_br_info(frame_csp_tmp); |                     goto fail; | ||||||
| #endif | 
 | ||||||
|                 if (!is_i32_const) |                 if (!is_i32_const || i32_const) { | ||||||
|                     (loader_ctx->frame_csp - (depth + 1))->is_block_reachable = true; |                     /* The branch can be reached */ | ||||||
|                 else { |                     if (!check_branch_block_ret(loader_ctx, frame_csp_tmp, | ||||||
|                     if (i32_const) |                                                 error_buf, error_buf_size)) | ||||||
|                         goto handle_next_reachable_block; |                         goto fail; | ||||||
|                 } |                 } | ||||||
|  |                 if (is_i32_const && i32_const) | ||||||
|  |                     goto handle_next_reachable_block; | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             case WASM_OP_BR_TABLE: |             case WASM_OP_BR_TABLE: | ||||||
|             { |             { | ||||||
| #if WASM_ENABLE_FAST_INTERP != 0 |  | ||||||
|                 BranchBlock *frame_csp_tmp; |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
|                 read_leb_uint32(p, p_end, count); |                 read_leb_uint32(p, p_end, count); | ||||||
| #if WASM_ENABLE_FAST_INTERP != 0 | #if WASM_ENABLE_FAST_INTERP != 0 | ||||||
|                 emit_const(count); |                 emit_const(count); | ||||||
|  | @ -3903,12 +3971,13 @@ handle_next_reachable_block: | ||||||
| 
 | 
 | ||||||
|                 /* TODO: check the const */ |                 /* TODO: check the const */ | ||||||
|                 for (i = 0; i <= count; i++) { |                 for (i = 0; i <= count; i++) { | ||||||
|                     read_leb_uint32(p, p_end, depth); |                     if (!(frame_csp_tmp = check_branch_block(loader_ctx, &p, p_end, | ||||||
|                     CHECK_BR(depth); |                                                         error_buf, error_buf_size))) | ||||||
| #if WASM_ENABLE_FAST_INTERP != 0 |                         goto fail; | ||||||
|                     frame_csp_tmp = loader_ctx->frame_csp - depth - 1; | 
 | ||||||
|                     emit_br_info(frame_csp_tmp); |                     if (!check_branch_block_ret(loader_ctx, frame_csp_tmp, | ||||||
| #endif |                                                 error_buf, error_buf_size)) | ||||||
|  |                         goto fail; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 goto handle_next_reachable_block; |                 goto handle_next_reachable_block; | ||||||
|  | @ -4037,10 +4106,12 @@ handle_next_reachable_block: | ||||||
|             case WASM_OP_DROP: |             case WASM_OP_DROP: | ||||||
|             case WASM_OP_DROP_64: |             case WASM_OP_DROP_64: | ||||||
|             { |             { | ||||||
|                 if (loader_ctx->stack_cell_num <= 0) { |                 if (loader_ctx->stack_cell_num | ||||||
|  |                      - (loader_ctx->frame_csp - 1)->stack_cell_num <= 0) { | ||||||
|                     set_error_buf(error_buf, error_buf_size, |                     set_error_buf(error_buf, error_buf_size, | ||||||
|                                   "WASM loader prepare bytecode failed: " |                                   "WASM loader prepare bytecode failed: " | ||||||
|                                   "opcode drop was found but stack was empty"); |                                   "type mismatch, opcode drop was found " | ||||||
|  |                                   "but stack was empty"); | ||||||
|                     goto fail; |                     goto fail; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|  | @ -4057,10 +4128,12 @@ handle_next_reachable_block: | ||||||
| #endif | #endif | ||||||
|                 } |                 } | ||||||
|                 else { |                 else { | ||||||
|                     if (loader_ctx->stack_cell_num <= 1) { |                     if (loader_ctx->stack_cell_num | ||||||
|  |                         - (loader_ctx->frame_csp - 1)->stack_cell_num <= 0) { | ||||||
|                         set_error_buf(error_buf, error_buf_size, |                         set_error_buf(error_buf, error_buf_size, | ||||||
|                                       "WASM loader prepare bytecode failed: " |                                       "WASM loader prepare bytecode failed: " | ||||||
|                                       "opcode drop was found but stack was empty"); |                                       "type mismatch, opcode drop was found " | ||||||
|  |                                       "but stack was empty"); | ||||||
|                         goto fail; |                         goto fail; | ||||||
|                     } |                     } | ||||||
|                     loader_ctx->frame_ref -= 2; |                     loader_ctx->frame_ref -= 2; | ||||||
|  |  | ||||||
|  | @ -60,15 +60,13 @@ memories_deinstantiate(WASMMemoryInstance **memories, uint32 count) | ||||||
| static WASMMemoryInstance* | static WASMMemoryInstance* | ||||||
| memory_instantiate(uint32 num_bytes_per_page, | memory_instantiate(uint32 num_bytes_per_page, | ||||||
|                    uint32 init_page_count, uint32 max_page_count, |                    uint32 init_page_count, uint32 max_page_count, | ||||||
|                    uint32 global_data_size, |  | ||||||
|                    uint32 heap_size, |                    uint32 heap_size, | ||||||
|                    char *error_buf, uint32 error_buf_size) |                    char *error_buf, uint32 error_buf_size) | ||||||
| { | { | ||||||
|     WASMMemoryInstance *memory; |     WASMMemoryInstance *memory; | ||||||
|     uint64 total_size = offsetof(WASMMemoryInstance, base_addr) + |     uint64 total_size = offsetof(WASMMemoryInstance, base_addr) + | ||||||
|                         (uint64)heap_size + |                         (uint64)heap_size + | ||||||
|                         num_bytes_per_page * (uint64)init_page_count + |                         num_bytes_per_page * (uint64)init_page_count; | ||||||
|                         global_data_size; |  | ||||||
| 
 | 
 | ||||||
|     /* Allocate memory space, addr data and global data */ |     /* Allocate memory space, addr data and global data */ | ||||||
|     if (total_size >= UINT32_MAX |     if (total_size >= UINT32_MAX | ||||||
|  | @ -85,10 +83,8 @@ memory_instantiate(uint32 num_bytes_per_page, | ||||||
| 
 | 
 | ||||||
|     memory->heap_data = memory->base_addr; |     memory->heap_data = memory->base_addr; | ||||||
|     memory->memory_data = memory->heap_data + heap_size; |     memory->memory_data = memory->heap_data + heap_size; | ||||||
|     memory->global_data = memory->memory_data + |     memory->end_addr = memory->memory_data + | ||||||
|                           num_bytes_per_page * memory->cur_page_count; |                           num_bytes_per_page * memory->cur_page_count; | ||||||
|     memory->global_data_size = global_data_size; |  | ||||||
|     memory->end_addr = memory->global_data + global_data_size; |  | ||||||
| 
 | 
 | ||||||
|     bh_assert(memory->end_addr - (uint8*)memory == (uint32)total_size); |     bh_assert(memory->end_addr - (uint8*)memory == (uint32)total_size); | ||||||
| 
 | 
 | ||||||
|  | @ -112,7 +108,7 @@ memory_instantiate(uint32 num_bytes_per_page, | ||||||
|  */ |  */ | ||||||
| static WASMMemoryInstance** | static WASMMemoryInstance** | ||||||
| memories_instantiate(const WASMModule *module, | memories_instantiate(const WASMModule *module, | ||||||
|                      uint32 global_data_size, uint32 heap_size, |                      uint32 heap_size, | ||||||
|                      char *error_buf, uint32 error_buf_size) |                      char *error_buf, uint32 error_buf_size) | ||||||
| { | { | ||||||
|     WASMImport *import; |     WASMImport *import; | ||||||
|  | @ -121,9 +117,6 @@ memories_instantiate(const WASMModule *module, | ||||||
|     uint64 total_size; |     uint64 total_size; | ||||||
|     WASMMemoryInstance **memories, *memory; |     WASMMemoryInstance **memories, *memory; | ||||||
| 
 | 
 | ||||||
|     if (memory_count == 0 && global_data_size > 0) |  | ||||||
|         memory_count = 1; |  | ||||||
| 
 |  | ||||||
|     total_size = sizeof(WASMMemoryInstance*) * (uint64)memory_count; |     total_size = sizeof(WASMMemoryInstance*) * (uint64)memory_count; | ||||||
| 
 | 
 | ||||||
|     if (total_size >= UINT32_MAX |     if (total_size >= UINT32_MAX | ||||||
|  | @ -143,7 +136,6 @@ memories_instantiate(const WASMModule *module, | ||||||
|                     memory_instantiate(import->u.memory.num_bytes_per_page, |                     memory_instantiate(import->u.memory.num_bytes_per_page, | ||||||
|                                        import->u.memory.init_page_count, |                                        import->u.memory.init_page_count, | ||||||
|                                        import->u.memory. max_page_count, |                                        import->u.memory. max_page_count, | ||||||
|                                        global_data_size, |  | ||||||
|                                        heap_size, error_buf, error_buf_size))) { |                                        heap_size, error_buf, error_buf_size))) { | ||||||
|             set_error_buf(error_buf, error_buf_size, |             set_error_buf(error_buf, error_buf_size, | ||||||
|                          "Instantiate memory failed: " |                          "Instantiate memory failed: " | ||||||
|  | @ -159,7 +151,6 @@ memories_instantiate(const WASMModule *module, | ||||||
|                     memory_instantiate(module->memories[i].num_bytes_per_page, |                     memory_instantiate(module->memories[i].num_bytes_per_page, | ||||||
|                                        module->memories[i].init_page_count, |                                        module->memories[i].init_page_count, | ||||||
|                                        module->memories[i].max_page_count, |                                        module->memories[i].max_page_count, | ||||||
|                                        global_data_size, |  | ||||||
|                                        heap_size, error_buf, error_buf_size))) { |                                        heap_size, error_buf, error_buf_size))) { | ||||||
|             set_error_buf(error_buf, error_buf_size, |             set_error_buf(error_buf, error_buf_size, | ||||||
|                           "Instantiate memory failed: " |                           "Instantiate memory failed: " | ||||||
|  | @ -172,8 +163,8 @@ memories_instantiate(const WASMModule *module, | ||||||
|     if (mem_index == 0) { |     if (mem_index == 0) { | ||||||
|         /* no import memory and define memory, but has global variables */ |         /* no import memory and define memory, but has global variables */ | ||||||
|         if (!(memory = memories[mem_index++] = |         if (!(memory = memories[mem_index++] = | ||||||
|                     memory_instantiate(0, 0, 0, global_data_size, |                     memory_instantiate(0, 0, 0, heap_size, | ||||||
|                                        heap_size, error_buf, error_buf_size))) { |                                        error_buf, error_buf_size))) { | ||||||
|             set_error_buf(error_buf, error_buf_size, |             set_error_buf(error_buf, error_buf_size, | ||||||
|                           "Instantiate memory failed: " |                           "Instantiate memory failed: " | ||||||
|                           "allocate memory failed.\n"); |                           "allocate memory failed.\n"); | ||||||
|  | @ -608,11 +599,20 @@ wasm_instantiate(WASMModule *module, | ||||||
|         module->import_function_count + module->function_count; |         module->import_function_count + module->function_count; | ||||||
|     module_inst->export_func_count = get_export_function_count(module); |     module_inst->export_func_count = get_export_function_count(module); | ||||||
| 
 | 
 | ||||||
|  |     if (global_count > 0) { | ||||||
|  |         if (!(module_inst->global_data = | ||||||
|  |                     wasm_runtime_malloc(global_data_size))) { | ||||||
|  |             wasm_deinstantiate(module_inst); | ||||||
|  |             return NULL; | ||||||
|  |         } | ||||||
|  |         memset(module_inst->global_data, 0, global_data_size); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /* Instantiate memories/tables/functions */ |     /* Instantiate memories/tables/functions */ | ||||||
|     if (((module_inst->memory_count > 0 || global_count > 0) |     if ((module_inst->memory_count > 0 | ||||||
|          && !(module_inst->memories = |          && !(module_inst->memories = | ||||||
|              memories_instantiate(module, global_data_size, |                 memories_instantiate(module, heap_size, | ||||||
|                                   heap_size, error_buf, error_buf_size))) |                                      error_buf, error_buf_size))) | ||||||
|         || (module_inst->table_count > 0 |         || (module_inst->table_count > 0 | ||||||
|             && !(module_inst->tables = tables_instantiate(module, |             && !(module_inst->tables = tables_instantiate(module, | ||||||
|                                                           error_buf, |                                                           error_buf, | ||||||
|  | @ -629,13 +629,8 @@ wasm_instantiate(WASMModule *module, | ||||||
|         return NULL; |         return NULL; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (module_inst->memory_count || global_count > 0) { |     if (global_count > 0) { | ||||||
|         WASMMemoryInstance *memory; |         /* fix globals */ | ||||||
| 
 |  | ||||||
|         memory = module_inst->default_memory = module_inst->memories[0]; |  | ||||||
|         memory_data = module_inst->default_memory->memory_data; |  | ||||||
| 
 |  | ||||||
|         /* fix import memoryBase */ |  | ||||||
|         if (!globals_instantiate_fix(globals, module, module_inst, |         if (!globals_instantiate_fix(globals, module, module_inst, | ||||||
|                                      error_buf, error_buf_size)) { |                                      error_buf, error_buf_size)) { | ||||||
|             wasm_deinstantiate(module_inst); |             wasm_deinstantiate(module_inst); | ||||||
|  | @ -643,7 +638,7 @@ wasm_instantiate(WASMModule *module, | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /* Initialize the global data */ |         /* Initialize the global data */ | ||||||
|         global_data = memory->global_data; |         global_data = module_inst->global_data; | ||||||
|         global_data_end = global_data + global_data_size; |         global_data_end = global_data + global_data_size; | ||||||
|         global = globals; |         global = globals; | ||||||
|         for (i = 0; i < global_count; i++, global++) { |         for (i = 0; i < global_count; i++, global++) { | ||||||
|  | @ -665,8 +660,16 @@ wasm_instantiate(WASMModule *module, | ||||||
|         } |         } | ||||||
|         bh_assert(global_data == global_data_end); |         bh_assert(global_data == global_data_end); | ||||||
| 
 | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (module_inst->memory_count) { | ||||||
|  |         WASMMemoryInstance *memory; | ||||||
|  | 
 | ||||||
|  |         memory = module_inst->default_memory = module_inst->memories[0]; | ||||||
|  |         memory_data = module_inst->default_memory->memory_data; | ||||||
|  | 
 | ||||||
|         /* Initialize the memory data with data segment section */ |         /* Initialize the memory data with data segment section */ | ||||||
|         if (module_inst->default_memory->cur_page_count > 0) { |         if (memory->cur_page_count > 0) { | ||||||
|             for (i = 0; i < module->data_seg_count; i++) { |             for (i = 0; i < module->data_seg_count; i++) { | ||||||
|                 data_seg = module->data_segments[i]; |                 data_seg = module->data_segments[i]; | ||||||
|                 bh_assert(data_seg->memory_index == 0); |                 bh_assert(data_seg->memory_index == 0); | ||||||
|  | @ -685,8 +688,8 @@ wasm_instantiate(WASMModule *module, | ||||||
| 
 | 
 | ||||||
|                 base_offset = (uint32)data_seg->base_offset.u.i32; |                 base_offset = (uint32)data_seg->base_offset.u.i32; | ||||||
|                 length = data_seg->data_length; |                 length = data_seg->data_length; | ||||||
|                 memory_size = module_inst->default_memory->num_bytes_per_page |                 memory_size = memory->num_bytes_per_page | ||||||
|                               * module_inst->default_memory->cur_page_count; |                               * memory->cur_page_count; | ||||||
| 
 | 
 | ||||||
|                 if (length > 0 |                 if (length > 0 | ||||||
|                     && (base_offset >= memory_size |                     && (base_offset >= memory_size | ||||||
|  | @ -825,6 +828,9 @@ wasm_deinstantiate(WASMModuleInstance *module_inst) | ||||||
|     globals_deinstantiate(module_inst->globals); |     globals_deinstantiate(module_inst->globals); | ||||||
|     export_functions_deinstantiate(module_inst->export_functions); |     export_functions_deinstantiate(module_inst->export_functions); | ||||||
| 
 | 
 | ||||||
|  |     if (module_inst->global_data) | ||||||
|  |         wasm_runtime_free(module_inst->global_data); | ||||||
|  | 
 | ||||||
|     wasm_runtime_free(module_inst); |     wasm_runtime_free(module_inst); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -1057,14 +1063,11 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count) | ||||||
| { | { | ||||||
|     WASMMemoryInstance *memory = module->default_memory, *new_memory; |     WASMMemoryInstance *memory = module->default_memory, *new_memory; | ||||||
|     uint32 heap_size = memory->memory_data - memory->heap_data; |     uint32 heap_size = memory->memory_data - memory->heap_data; | ||||||
|     uint32 old_page_count = memory->cur_page_count; |  | ||||||
|     uint32 total_size_old = memory->end_addr - (uint8*)memory; |     uint32 total_size_old = memory->end_addr - (uint8*)memory; | ||||||
|     uint32 total_page_count = inc_page_count + memory->cur_page_count; |     uint32 total_page_count = inc_page_count + memory->cur_page_count; | ||||||
|     uint64 total_size = offsetof(WASMMemoryInstance, base_addr) |     uint64 total_size = offsetof(WASMMemoryInstance, base_addr) | ||||||
|                         + (uint64)heap_size |                         + (uint64)heap_size | ||||||
|                         + memory->num_bytes_per_page * (uint64)total_page_count |                         + memory->num_bytes_per_page * (uint64)total_page_count; | ||||||
|                         + memory->global_data_size; |  | ||||||
|     uint8 *global_data_old; |  | ||||||
|     void *heap_handle_old = memory->heap_handle; |     void *heap_handle_old = memory->heap_handle; | ||||||
| 
 | 
 | ||||||
|     if (inc_page_count <= 0) |     if (inc_page_count <= 0) | ||||||
|  | @ -1111,17 +1114,8 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count) | ||||||
|     new_memory->cur_page_count = total_page_count; |     new_memory->cur_page_count = total_page_count; | ||||||
|     new_memory->heap_data = new_memory->base_addr; |     new_memory->heap_data = new_memory->base_addr; | ||||||
|     new_memory->memory_data = new_memory->base_addr + heap_size; |     new_memory->memory_data = new_memory->base_addr + heap_size; | ||||||
|     new_memory->global_data = new_memory->memory_data + |     new_memory->end_addr = new_memory->memory_data + | ||||||
|                               new_memory->num_bytes_per_page * total_page_count; |                             new_memory->num_bytes_per_page * total_page_count; | ||||||
|     new_memory->end_addr = new_memory->global_data + new_memory->global_data_size; |  | ||||||
| 
 |  | ||||||
|     global_data_old = new_memory->memory_data + |  | ||||||
|                               new_memory->num_bytes_per_page * old_page_count; |  | ||||||
| 
 |  | ||||||
|     /* Copy global data */ |  | ||||||
|     bh_memcpy_s(new_memory->global_data, new_memory->global_data_size, |  | ||||||
|                 global_data_old, new_memory->global_data_size); |  | ||||||
|     memset(global_data_old, 0, new_memory->global_data_size); |  | ||||||
| 
 | 
 | ||||||
|     module->memories[0] = module->default_memory = new_memory; |     module->memories[0] = module->default_memory = new_memory; | ||||||
|     return true; |     return true; | ||||||
|  |  | ||||||
|  | @ -33,17 +33,12 @@ typedef struct WASMMemoryInstance { | ||||||
|     /* Memory data */ |     /* Memory data */ | ||||||
|     uint8 *memory_data; |     uint8 *memory_data; | ||||||
| 
 | 
 | ||||||
|     /* Global data of global instances */ |  | ||||||
|     uint8 *global_data; |  | ||||||
|     uint32 global_data_size; |  | ||||||
| 
 |  | ||||||
|     /* End address of memory */ |     /* End address of memory */ | ||||||
|     uint8 *end_addr; |     uint8 *end_addr; | ||||||
| 
 | 
 | ||||||
|     /* Base address, the layout is:
 |     /* Base address, the layout is:
 | ||||||
|        heap_data + memory data + global data |        heap_data + memory data | ||||||
|        memory data init size is: num_bytes_per_page * cur_page_count |        memory data init size is: num_bytes_per_page * cur_page_count | ||||||
|        global data size is calculated in module instantiating |  | ||||||
|        Note: when memory is re-allocated, the heap data and memory data |        Note: when memory is re-allocated, the heap data and memory data | ||||||
|              must be copied to new memory also. |              must be copied to new memory also. | ||||||
|      */ |      */ | ||||||
|  | @ -127,6 +122,8 @@ typedef struct WASMModuleInstance { | ||||||
| 
 | 
 | ||||||
|     WASMMemoryInstance *default_memory; |     WASMMemoryInstance *default_memory; | ||||||
|     WASMTableInstance *default_table; |     WASMTableInstance *default_table; | ||||||
|  |     /* Global data of global instances */ | ||||||
|  |     uint8 *global_data; | ||||||
| 
 | 
 | ||||||
|     WASMFunctionInstance *start_function; |     WASMFunctionInstance *start_function; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -37,10 +37,8 @@ extern "C" { | ||||||
| #define BH_PLATFORM_ANDROID | #define BH_PLATFORM_ANDROID | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #define _STACK_SIZE_ADJUSTMENT (32 * 1024) |  | ||||||
| 
 |  | ||||||
| /* Stack size of applet threads's native part.  */ | /* Stack size of applet threads's native part.  */ | ||||||
| #define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024 + _STACK_SIZE_ADJUSTMENT) | #define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024) | ||||||
| 
 | 
 | ||||||
| /* Default thread priority */ | /* Default thread priority */ | ||||||
| #define BH_THREAD_DEFAULT_PRIORITY 0 | #define BH_THREAD_DEFAULT_PRIORITY 0 | ||||||
|  |  | ||||||
|  | @ -233,7 +233,8 @@ uint8 *os_thread_get_stack_boundary() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (addr) |     if (addr) | ||||||
|         return (uint8*)addr + _STACK_SIZE_ADJUSTMENT; |         /* Reserved 4 KB for safety */ | ||||||
|  |         return (uint8*)addr + 4 * 1024; | ||||||
|     else |     else | ||||||
|         return NULL; |         return NULL; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -37,10 +37,8 @@ extern "C" { | ||||||
| #define BH_PLATFORM_DARWIN | #define BH_PLATFORM_DARWIN | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #define _STACK_SIZE_ADJUSTMENT (32 * 1024) |  | ||||||
| 
 |  | ||||||
| /* Stack size of applet threads's native part.  */ | /* Stack size of applet threads's native part.  */ | ||||||
| #define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024 + _STACK_SIZE_ADJUSTMENT) | #define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024) | ||||||
| 
 | 
 | ||||||
| /* Default thread priority */ | /* Default thread priority */ | ||||||
| #define BH_THREAD_DEFAULT_PRIORITY 0 | #define BH_THREAD_DEFAULT_PRIORITY 0 | ||||||
|  |  | ||||||
|  | @ -37,10 +37,8 @@ extern "C" { | ||||||
| #define BH_PLATFORM_LINUX | #define BH_PLATFORM_LINUX | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #define _STACK_SIZE_ADJUSTMENT (32 * 1024) |  | ||||||
| 
 |  | ||||||
| /* Stack size of applet threads's native part.  */ | /* Stack size of applet threads's native part.  */ | ||||||
| #define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024 + _STACK_SIZE_ADJUSTMENT) | #define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024) | ||||||
| 
 | 
 | ||||||
| /* Default thread priority */ | /* Default thread priority */ | ||||||
| #define BH_THREAD_DEFAULT_PRIORITY 0 | #define BH_THREAD_DEFAULT_PRIORITY 0 | ||||||
|  |  | ||||||
|  | @ -36,10 +36,8 @@ extern "C" { | ||||||
| #define BH_PLATFORM_VXWORKS | #define BH_PLATFORM_VXWORKS | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #define _STACK_SIZE_ADJUSTMENT (32 * 1024) |  | ||||||
| 
 |  | ||||||
| /* Stack size of applet threads's native part.  */ | /* Stack size of applet threads's native part.  */ | ||||||
| #define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024 + _STACK_SIZE_ADJUSTMENT) | #define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024) | ||||||
| 
 | 
 | ||||||
| /* Default thread priority */ | /* Default thread priority */ | ||||||
| #define BH_THREAD_DEFAULT_PRIORITY 0 | #define BH_THREAD_DEFAULT_PRIORITY 0 | ||||||
|  |  | ||||||
|  | @ -74,7 +74,7 @@ host_interface interface = { | ||||||
| 
 | 
 | ||||||
| timer_ctx_t timer_ctx; | timer_ctx_t timer_ctx; | ||||||
| 
 | 
 | ||||||
| static char global_heap_buf[370 * 1024] = { 0 }; | static char global_heap_buf[368 * 1024] = { 0 }; | ||||||
| 
 | 
 | ||||||
| static NativeSymbol native_symbols[] = { | static NativeSymbol native_symbols[] = { | ||||||
|     EXPORT_WASM_API_WITH_SIG(display_input_read, "(*)i"), |     EXPORT_WASM_API_WITH_SIG(display_input_read, "(*)i"), | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 wenyongh
						wenyongh