Enable shared memory && add pthread support (#282)
This commit is contained in:
@ -939,6 +939,18 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
#define CHECK_SUSPEND_FLAGS() do { \
|
||||
if (exec_env->suspend_flags != 0) { \
|
||||
if (exec_env->suspend_flags & 0x01) { \
|
||||
/* terminate current thread */ \
|
||||
return; \
|
||||
} \
|
||||
/* TODO: support suspend and breakpoint */ \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||
|
||||
#define HANDLE_OP(opcode) HANDLE_##opcode
|
||||
@ -989,6 +1001,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
uint32 local_idx, local_offset, global_idx;
|
||||
uint8 local_type, *global_addr;
|
||||
uint32 cache_index;
|
||||
int32 aux_stack_top_global_idx = -1;
|
||||
|
||||
/* If the aux stack information is resolved,
|
||||
we will check the aux stack boundary */
|
||||
if (module->module->llvm_aux_stack_size) {
|
||||
aux_stack_top_global_idx = module->module->llvm_aux_stack_global_index;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||
#define HANDLE_OPCODE(op) &&HANDLE_##op
|
||||
@ -1103,11 +1122,17 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
HANDLE_OP_END ();
|
||||
|
||||
HANDLE_OP (WASM_OP_BR):
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
CHECK_SUSPEND_FLAGS();
|
||||
#endif
|
||||
read_leb_uint32(frame_ip, frame_ip_end, depth);
|
||||
POP_CSP_N(depth);
|
||||
HANDLE_OP_END ();
|
||||
|
||||
HANDLE_OP (WASM_OP_BR_IF):
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
CHECK_SUSPEND_FLAGS();
|
||||
#endif
|
||||
read_leb_uint32(frame_ip, frame_ip_end, depth);
|
||||
cond = (uint32)POP_I32();
|
||||
if (cond)
|
||||
@ -1115,6 +1140,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
HANDLE_OP_END ();
|
||||
|
||||
HANDLE_OP (WASM_OP_BR_TABLE):
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
CHECK_SUSPEND_FLAGS();
|
||||
#endif
|
||||
read_leb_uint32(frame_ip, frame_ip_end, count);
|
||||
if (count <= BR_TABLE_TMP_BUF_LEN)
|
||||
depths = depth_buf;
|
||||
@ -1150,6 +1178,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
goto return_func;
|
||||
|
||||
HANDLE_OP (WASM_OP_CALL):
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
CHECK_SUSPEND_FLAGS();
|
||||
#endif
|
||||
read_leb_uint32(frame_ip, frame_ip_end, fidx);
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
if (fidx >= module->function_count) {
|
||||
@ -1166,6 +1197,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
WASMType *cur_type, *cur_func_type;
|
||||
WASMTableInstance *cur_table_inst;
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
CHECK_SUSPEND_FLAGS();
|
||||
#endif
|
||||
|
||||
/**
|
||||
* type check. compiler will make sure all like
|
||||
* (call_indirect (type $x) (i32.const 1))
|
||||
@ -1406,6 +1441,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
|
||||
switch (global->type) {
|
||||
case VALUE_TYPE_I32:
|
||||
/* Check aux stack boundary */
|
||||
if ((global_idx == (uint32)aux_stack_top_global_idx)
|
||||
&& (*(uint32*)(frame_sp - 1) < exec_env->aux_stack_boundary))
|
||||
goto out_of_bounds;
|
||||
case VALUE_TYPE_F32:
|
||||
*(int32*)global_addr = POP_I32();
|
||||
break;
|
||||
|
||||
@ -877,6 +877,18 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
#define CHECK_SUSPEND_FLAGS() do { \
|
||||
if (exec_env->suspend_flags != 0) { \
|
||||
if (exec_env->suspend_flags & 0x01) { \
|
||||
/* terminate current thread */ \
|
||||
return; \
|
||||
} \
|
||||
/* TODO: support suspend and breakpoint */ \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_OPCODE_COUNTER != 0
|
||||
typedef struct OpcodeInfo {
|
||||
char *name;
|
||||
@ -978,6 +990,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
uint8 *maddr = NULL;
|
||||
uint32 local_idx, local_offset, global_idx;
|
||||
uint8 opcode, local_type, *global_addr;
|
||||
int32 aux_stack_top_global_idx = -1;
|
||||
|
||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||
#define HANDLE_OPCODE(op) &&HANDLE_##op
|
||||
@ -991,6 +1004,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* If the aux stack information is resolved,
|
||||
we will check the aux stack boundary */
|
||||
if (module->module->llvm_aux_stack_size) {
|
||||
aux_stack_top_global_idx = module->module->llvm_aux_stack_global_index;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_LABELS_AS_VALUES == 0
|
||||
while (frame_ip < frame_ip_end) {
|
||||
opcode = *frame_ip++;
|
||||
@ -1024,10 +1043,16 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
HANDLE_OP_END ();
|
||||
|
||||
HANDLE_OP (WASM_OP_BR):
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
CHECK_SUSPEND_FLAGS();
|
||||
#endif
|
||||
RECOVER_BR_INFO();
|
||||
HANDLE_OP_END ();
|
||||
|
||||
HANDLE_OP (WASM_OP_BR_IF):
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
CHECK_SUSPEND_FLAGS();
|
||||
#endif
|
||||
cond = frame_lp[GET_OFFSET()];
|
||||
|
||||
if (cond)
|
||||
@ -1039,6 +1064,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
HANDLE_OP_END ();
|
||||
|
||||
HANDLE_OP (WASM_OP_BR_TABLE):
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
CHECK_SUSPEND_FLAGS();
|
||||
#endif
|
||||
count = GET_OPERAND(uint32, 0);
|
||||
didx = GET_OPERAND(uint32, 2);
|
||||
frame_ip += 4;
|
||||
@ -1064,6 +1092,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
WASMType *cur_type, *cur_func_type;
|
||||
WASMTableInstance *cur_table_inst;
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
CHECK_SUSPEND_FLAGS();
|
||||
#endif
|
||||
|
||||
tidx = GET_OPERAND(int32, 0);
|
||||
val = GET_OPERAND(int32, 2);
|
||||
frame_ip += 4;
|
||||
@ -1245,6 +1277,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
|
||||
switch (global->type) {
|
||||
case VALUE_TYPE_I32:
|
||||
/* Check aux stack boundary */
|
||||
if ((global_idx == (uint32)aux_stack_top_global_idx)
|
||||
&& (frame_lp[addr1] < exec_env->aux_stack_boundary))
|
||||
goto out_of_bounds;
|
||||
case VALUE_TYPE_F32:
|
||||
*(int32*)global_addr = frame_lp[addr1];
|
||||
break;
|
||||
@ -2482,6 +2518,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
goto call_func_from_entry;
|
||||
|
||||
HANDLE_OP (WASM_OP_CALL):
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
CHECK_SUSPEND_FLAGS();
|
||||
#endif
|
||||
fidx = frame_lp[GET_OFFSET()];
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
if (fidx >= module->function_count) {
|
||||
|
||||
@ -1117,6 +1117,12 @@ load_table(const uint8 **p_buf, const uint8 *buf_end, WASMTable *table,
|
||||
else
|
||||
table->max_size = 0x10000;
|
||||
|
||||
if ((table->flags & 1) && table->init_size > table->max_size) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"size minimum must not be greater than maximum");
|
||||
return false;
|
||||
}
|
||||
|
||||
*p_buf = p;
|
||||
return true;
|
||||
}
|
||||
@ -2349,8 +2355,6 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
||||
WASMGlobal *llvm_stack_top_global = NULL, *global;
|
||||
uint32 llvm_data_end = UINT32_MAX, llvm_heap_base = UINT32_MAX;
|
||||
uint32 llvm_stack_top = UINT32_MAX, global_index, i;
|
||||
uint32 data_end_global_index = UINT32_MAX;
|
||||
uint32 heap_base_global_index = UINT32_MAX;
|
||||
uint32 stack_top_global_index = UINT32_MAX;
|
||||
BlockAddr *block_addr_cache;
|
||||
uint64 total_size;
|
||||
@ -2462,67 +2466,93 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
||||
wasm_runtime_free(block_addr_cache);
|
||||
|
||||
/* Resolve llvm auxiliary data/stack/heap info and reset memory info */
|
||||
if (!module->possible_memory_grow) {
|
||||
export = module->exports;
|
||||
for (i = 0; i < module->export_count; i++, export++) {
|
||||
if (export->kind == EXPORT_KIND_GLOBAL) {
|
||||
if (!strcmp(export->name, "__heap_base")) {
|
||||
global_index = export->index - module->import_global_count;
|
||||
global = module->globals + global_index;
|
||||
if (global->type == VALUE_TYPE_I32
|
||||
&& !global->is_mutable
|
||||
&& global->init_expr.init_expr_type ==
|
||||
INIT_EXPR_TYPE_I32_CONST) {
|
||||
heap_base_global_index = global_index;
|
||||
llvm_heap_base_global = global;
|
||||
llvm_heap_base = global->init_expr.u.i32;
|
||||
LOG_VERBOSE("found llvm __heap_base global, value: %d\n",
|
||||
llvm_heap_base);
|
||||
}
|
||||
}
|
||||
else if (!strcmp(export->name, "__data_end")) {
|
||||
global_index = export->index - module->import_global_count;
|
||||
global = module->globals + global_index;
|
||||
if (global->type == VALUE_TYPE_I32
|
||||
&& !global->is_mutable
|
||||
&& global->init_expr.init_expr_type ==
|
||||
INIT_EXPR_TYPE_I32_CONST) {
|
||||
data_end_global_index = global_index;
|
||||
llvm_data_end_global = global;
|
||||
llvm_data_end = global->init_expr.u.i32;
|
||||
LOG_VERBOSE("found llvm __data_end global, value: %d\n",
|
||||
llvm_data_end);
|
||||
|
||||
llvm_data_end = align_uint(llvm_data_end, 16);
|
||||
}
|
||||
}
|
||||
|
||||
if (llvm_data_end_global && llvm_heap_base_global) {
|
||||
if ((data_end_global_index == heap_base_global_index + 1
|
||||
&& (int32)data_end_global_index > 1)
|
||||
|| (heap_base_global_index == data_end_global_index + 1
|
||||
&& (int32)heap_base_global_index > 1)) {
|
||||
global_index =
|
||||
data_end_global_index < heap_base_global_index
|
||||
? data_end_global_index - 1 : heap_base_global_index - 1;
|
||||
global = module->globals + global_index;
|
||||
if (global->type == VALUE_TYPE_I32
|
||||
&& global->is_mutable
|
||||
&& global->init_expr.init_expr_type ==
|
||||
INIT_EXPR_TYPE_I32_CONST) {
|
||||
llvm_stack_top_global = global;
|
||||
llvm_stack_top = global->init_expr.u.i32;
|
||||
stack_top_global_index = global_index;
|
||||
LOG_VERBOSE("found llvm stack top global, "
|
||||
"value: %d, global index: %d\n",
|
||||
llvm_stack_top, global_index);
|
||||
}
|
||||
}
|
||||
break;
|
||||
export = module->exports;
|
||||
for (i = 0; i < module->export_count; i++, export++) {
|
||||
if (export->kind == EXPORT_KIND_GLOBAL) {
|
||||
if (!strcmp(export->name, "__heap_base")) {
|
||||
global_index = export->index - module->import_global_count;
|
||||
global = module->globals + global_index;
|
||||
if (global->type == VALUE_TYPE_I32
|
||||
&& !global->is_mutable
|
||||
&& global->init_expr.init_expr_type ==
|
||||
INIT_EXPR_TYPE_I32_CONST) {
|
||||
llvm_heap_base_global = global;
|
||||
llvm_heap_base = global->init_expr.u.i32;
|
||||
LOG_VERBOSE("found llvm __heap_base global, value: %d\n",
|
||||
llvm_heap_base);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(export->name, "__data_end")) {
|
||||
global_index = export->index - module->import_global_count;
|
||||
global = module->globals + global_index;
|
||||
if (global->type == VALUE_TYPE_I32
|
||||
&& !global->is_mutable
|
||||
&& global->init_expr.init_expr_type ==
|
||||
INIT_EXPR_TYPE_I32_CONST) {
|
||||
llvm_data_end_global = global;
|
||||
llvm_data_end = global->init_expr.u.i32;
|
||||
LOG_VERBOSE("found llvm __data_end global, value: %d\n",
|
||||
llvm_data_end);
|
||||
|
||||
llvm_data_end = align_uint(llvm_data_end, 16);
|
||||
}
|
||||
}
|
||||
|
||||
/* For module compiled with -pthread option, the global is:
|
||||
[0] stack_top <-- 0
|
||||
[1] tls_pointer
|
||||
[2] tls_size
|
||||
[3] data_end <-- 3
|
||||
[4] global_base
|
||||
[5] heap_base <-- 5
|
||||
[6] dso_handle
|
||||
|
||||
For module compiled without -pthread option:
|
||||
[0] stack_top <-- 0
|
||||
[1] data_end <-- 1
|
||||
[2] global_base
|
||||
[3] heap_base <-- 3
|
||||
[4] dso_handle
|
||||
*/
|
||||
if (llvm_data_end_global && llvm_heap_base_global) {
|
||||
/* Resolve aux stack top global */
|
||||
for (global_index = 0; global_index < module->global_count; global_index++) {
|
||||
global = module->globals + global_index;
|
||||
if (global != llvm_data_end_global
|
||||
&& global != llvm_heap_base_global
|
||||
&& global->type == VALUE_TYPE_I32
|
||||
&& global->is_mutable
|
||||
&& global->init_expr.init_expr_type ==
|
||||
INIT_EXPR_TYPE_I32_CONST
|
||||
&& (global->init_expr.u.i32 ==
|
||||
llvm_heap_base_global->init_expr.u.i32
|
||||
|| global->init_expr.u.i32 ==
|
||||
llvm_data_end_global->init_expr.u.i32)) {
|
||||
llvm_stack_top_global = global;
|
||||
llvm_stack_top = global->init_expr.u.i32;
|
||||
stack_top_global_index = global_index;
|
||||
LOG_VERBOSE("found llvm stack top global, "
|
||||
"value: %d, global index: %d\n",
|
||||
llvm_stack_top, global_index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
module->llvm_aux_data_end = llvm_data_end;
|
||||
module->llvm_aux_stack_bottom = llvm_stack_top;
|
||||
module->llvm_aux_stack_size = llvm_stack_top > llvm_data_end
|
||||
? llvm_stack_top - llvm_data_end
|
||||
: llvm_stack_top;
|
||||
module->llvm_aux_stack_global_index = stack_top_global_index;
|
||||
LOG_VERBOSE("aux stack bottom: %d, size: %d\n",
|
||||
module->llvm_aux_stack_bottom,
|
||||
module->llvm_aux_stack_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!module->possible_memory_grow) {
|
||||
if (llvm_data_end_global
|
||||
&& llvm_heap_base_global
|
||||
&& llvm_stack_top_global
|
||||
@ -2557,16 +2587,6 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
||||
LOG_VERBOSE("reset memory size to %d\n", shrunk_memory_size);
|
||||
}
|
||||
}
|
||||
|
||||
module->llvm_aux_data_end = llvm_data_end;
|
||||
module->llvm_aux_stack_bottom = llvm_stack_top;
|
||||
module->llvm_aux_stack_size = llvm_stack_top > llvm_data_end
|
||||
? llvm_stack_top - llvm_data_end
|
||||
: llvm_stack_top;
|
||||
module->llvm_aux_stack_global_index = stack_top_global_index;
|
||||
LOG_VERBOSE("aux stack bottom: %d, size: %d\n",
|
||||
module->llvm_aux_stack_bottom,
|
||||
module->llvm_aux_stack_size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3485,6 +3505,7 @@ fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
check_stack_top_values(uint8 *frame_ref, int32 stack_cell_num, uint8 type,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
|
||||
@ -1545,67 +1545,76 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
||||
wasm_runtime_free(block_addr_cache);
|
||||
|
||||
/* Resolve llvm auxiliary data/stack/heap info and reset memory info */
|
||||
if (!module->possible_memory_grow) {
|
||||
export = module->exports;
|
||||
for (i = 0; i < module->export_count; i++, export++) {
|
||||
if (export->kind == EXPORT_KIND_GLOBAL) {
|
||||
if (!strcmp(export->name, "__heap_base")) {
|
||||
global_index = export->index - module->import_global_count;
|
||||
global = module->globals + global_index;
|
||||
if (global->type == VALUE_TYPE_I32
|
||||
&& !global->is_mutable
|
||||
&& global->init_expr.init_expr_type ==
|
||||
INIT_EXPR_TYPE_I32_CONST) {
|
||||
heap_base_global_index = global_index;
|
||||
llvm_heap_base_global = global;
|
||||
llvm_heap_base = global->init_expr.u.i32;
|
||||
LOG_VERBOSE("found llvm __heap_base global, value: %d\n",
|
||||
llvm_heap_base);
|
||||
}
|
||||
}
|
||||
else if (!strcmp(export->name, "__data_end")) {
|
||||
global_index = export->index - module->import_global_count;
|
||||
global = module->globals + global_index;
|
||||
if (global->type == VALUE_TYPE_I32
|
||||
&& !global->is_mutable
|
||||
&& global->init_expr.init_expr_type ==
|
||||
INIT_EXPR_TYPE_I32_CONST) {
|
||||
data_end_global_index = global_index;
|
||||
llvm_data_end_global = global;
|
||||
llvm_data_end = global->init_expr.u.i32;
|
||||
LOG_VERBOSE("found llvm __data_end global, value: %d\n",
|
||||
llvm_data_end);
|
||||
|
||||
llvm_data_end = align_uint(llvm_data_end, 16);
|
||||
}
|
||||
}
|
||||
|
||||
if (llvm_data_end_global && llvm_heap_base_global) {
|
||||
if ((data_end_global_index == heap_base_global_index + 1
|
||||
&& (int32)data_end_global_index > 1)
|
||||
|| (heap_base_global_index == data_end_global_index + 1
|
||||
&& (int32)heap_base_global_index > 1)) {
|
||||
global_index =
|
||||
data_end_global_index < heap_base_global_index
|
||||
? data_end_global_index - 1 : heap_base_global_index - 1;
|
||||
global = module->globals + global_index;
|
||||
if (global->type == VALUE_TYPE_I32
|
||||
&& global->is_mutable
|
||||
&& global->init_expr.init_expr_type ==
|
||||
INIT_EXPR_TYPE_I32_CONST) {
|
||||
llvm_stack_top_global = global;
|
||||
llvm_stack_top = global->init_expr.u.i32;
|
||||
stack_top_global_index = global_index;
|
||||
LOG_VERBOSE("found llvm stack top global, "
|
||||
"value: %d, global index: %d\n",
|
||||
llvm_stack_top, global_index);
|
||||
}
|
||||
}
|
||||
break;
|
||||
export = module->exports;
|
||||
for (i = 0; i < module->export_count; i++, export++) {
|
||||
if (export->kind == EXPORT_KIND_GLOBAL) {
|
||||
if (!strcmp(export->name, "__heap_base")) {
|
||||
global_index = export->index - module->import_global_count;
|
||||
global = module->globals + global_index;
|
||||
if (global->type == VALUE_TYPE_I32
|
||||
&& !global->is_mutable
|
||||
&& global->init_expr.init_expr_type ==
|
||||
INIT_EXPR_TYPE_I32_CONST) {
|
||||
heap_base_global_index = global_index;
|
||||
llvm_heap_base_global = global;
|
||||
llvm_heap_base = global->init_expr.u.i32;
|
||||
LOG_VERBOSE("found llvm __heap_base global, value: %d\n",
|
||||
llvm_heap_base);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(export->name, "__data_end")) {
|
||||
global_index = export->index - module->import_global_count;
|
||||
global = module->globals + global_index;
|
||||
if (global->type == VALUE_TYPE_I32
|
||||
&& !global->is_mutable
|
||||
&& global->init_expr.init_expr_type ==
|
||||
INIT_EXPR_TYPE_I32_CONST) {
|
||||
data_end_global_index = global_index;
|
||||
llvm_data_end_global = global;
|
||||
llvm_data_end = global->init_expr.u.i32;
|
||||
LOG_VERBOSE("found llvm __data_end global, value: %d\n",
|
||||
llvm_data_end);
|
||||
|
||||
llvm_data_end = align_uint(llvm_data_end, 16);
|
||||
}
|
||||
}
|
||||
|
||||
if (llvm_data_end_global && llvm_heap_base_global) {
|
||||
if ((data_end_global_index == heap_base_global_index + 1
|
||||
&& (int32)data_end_global_index > 1)
|
||||
|| (heap_base_global_index == data_end_global_index + 1
|
||||
&& (int32)heap_base_global_index > 1)) {
|
||||
global_index =
|
||||
data_end_global_index < heap_base_global_index
|
||||
? data_end_global_index - 1 : heap_base_global_index - 1;
|
||||
global = module->globals + global_index;
|
||||
if (global->type == VALUE_TYPE_I32
|
||||
&& global->is_mutable
|
||||
&& global->init_expr.init_expr_type ==
|
||||
INIT_EXPR_TYPE_I32_CONST) {
|
||||
llvm_stack_top_global = global;
|
||||
llvm_stack_top = global->init_expr.u.i32;
|
||||
stack_top_global_index = global_index;
|
||||
LOG_VERBOSE("found llvm stack top global, "
|
||||
"value: %d, global index: %d\n",
|
||||
llvm_stack_top, global_index);
|
||||
}
|
||||
}
|
||||
module->llvm_aux_data_end = llvm_data_end;
|
||||
module->llvm_aux_stack_bottom = llvm_stack_top;
|
||||
module->llvm_aux_stack_size = llvm_stack_top > llvm_data_end
|
||||
? llvm_stack_top - llvm_data_end
|
||||
: llvm_stack_top;
|
||||
module->llvm_aux_stack_global_index = stack_top_global_index;
|
||||
LOG_VERBOSE("aux stack bottom: %d, size: %d\n",
|
||||
module->llvm_aux_stack_bottom,
|
||||
module->llvm_aux_stack_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!module->possible_memory_grow) {
|
||||
if (llvm_data_end_global
|
||||
&& llvm_heap_base_global
|
||||
&& llvm_stack_top_global
|
||||
@ -1640,16 +1649,6 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
||||
LOG_VERBOSE("reset memory size to %d\n", shrunk_memory_size);
|
||||
}
|
||||
}
|
||||
|
||||
module->llvm_aux_data_end = llvm_data_end;
|
||||
module->llvm_aux_stack_bottom = llvm_stack_top;
|
||||
module->llvm_aux_stack_size = llvm_stack_top > llvm_data_end
|
||||
? llvm_stack_top - llvm_data_end
|
||||
: llvm_stack_top;
|
||||
module->llvm_aux_stack_global_index = stack_top_global_index;
|
||||
LOG_VERBOSE("aux stack bottom: %d, size: %d\n",
|
||||
module->llvm_aux_stack_bottom,
|
||||
module->llvm_aux_stack_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -10,6 +10,9 @@
|
||||
#include "bh_log.h"
|
||||
#include "mem_alloc.h"
|
||||
#include "../common/wasm_runtime_common.h"
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
#include "../common/wasm_shared_memory.h"
|
||||
#endif
|
||||
|
||||
static void
|
||||
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
|
||||
@ -86,6 +89,19 @@ memories_deinstantiate(WASMModuleInstance *module_inst,
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
if (memories[i]->owner != module_inst)
|
||||
continue;
|
||||
#endif
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (memories[i]->is_shared) {
|
||||
int32 ref_count =
|
||||
shared_memory_dec_reference(
|
||||
(WASMModuleCommon *)module_inst->module);
|
||||
bh_assert(ref_count >= 0);
|
||||
|
||||
/* if the reference count is not zero,
|
||||
don't free the memory */
|
||||
if (ref_count > 0)
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (memories[i]->heap_handle) {
|
||||
mem_allocator_destroy(memories[i]->heap_handle);
|
||||
@ -99,16 +115,45 @@ memories_deinstantiate(WASMModuleInstance *module_inst,
|
||||
}
|
||||
|
||||
static WASMMemoryInstance*
|
||||
memory_instantiate(uint32 num_bytes_per_page,
|
||||
memory_instantiate(WASMModuleInstance *module_inst,
|
||||
uint32 num_bytes_per_page,
|
||||
uint32 init_page_count, uint32 max_page_count,
|
||||
uint32 heap_size,
|
||||
uint32 heap_size, uint32 flags,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
WASMMemoryInstance *memory;
|
||||
uint64 total_size = offsetof(WASMMemoryInstance, base_addr) +
|
||||
(uint64)heap_size +
|
||||
uint64 heap_and_inst_size = offsetof(WASMMemoryInstance, base_addr) +
|
||||
(uint64)heap_size;
|
||||
uint64 total_size = heap_and_inst_size +
|
||||
num_bytes_per_page * (uint64)init_page_count;
|
||||
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
bool is_shared_memory = flags & 0x02 ? true : false;
|
||||
|
||||
/* shared memory */
|
||||
if (is_shared_memory) {
|
||||
WASMSharedMemNode *node =
|
||||
wasm_module_get_shared_memory(
|
||||
(WASMModuleCommon *)module_inst->module);
|
||||
/* If the memory of this module has been instantiated,
|
||||
return the memory instance directly */
|
||||
if (node) {
|
||||
uint32 ref_count;
|
||||
ref_count = shared_memory_inc_reference(
|
||||
(WASMModuleCommon *)module_inst->module);
|
||||
bh_assert(ref_count > 0);
|
||||
memory = shared_memory_get_memory_inst(node);
|
||||
bh_assert(memory);
|
||||
|
||||
(void)ref_count;
|
||||
return memory;
|
||||
}
|
||||
/* Allocate max page for shared memory */
|
||||
total_size = heap_and_inst_size +
|
||||
num_bytes_per_page * (uint64)max_page_count;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allocate memory space, addr data and global data */
|
||||
if (!(memory = runtime_malloc(total_size,
|
||||
error_buf, error_buf_size))) {
|
||||
@ -121,8 +166,17 @@ memory_instantiate(uint32 num_bytes_per_page,
|
||||
|
||||
memory->heap_data = memory->base_addr;
|
||||
memory->memory_data = memory->heap_data + heap_size;
|
||||
memory->end_addr = memory->memory_data +
|
||||
num_bytes_per_page * memory->cur_page_count;
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (is_shared_memory) {
|
||||
memory->end_addr = memory->memory_data +
|
||||
num_bytes_per_page * memory->max_page_count;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
memory->end_addr = memory->memory_data +
|
||||
num_bytes_per_page * memory->cur_page_count;
|
||||
}
|
||||
|
||||
bh_assert(memory->end_addr - (uint8*)memory == (uint32)total_size);
|
||||
|
||||
@ -134,10 +188,20 @@ memory_instantiate(uint32 num_bytes_per_page,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_SPEC_TEST == 0
|
||||
memory->heap_base_offset = -(int32)heap_size;
|
||||
#else
|
||||
memory->heap_base_offset = 0;
|
||||
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (is_shared_memory) {
|
||||
memory->is_shared = true;
|
||||
if (!shared_memory_set_memory_inst(
|
||||
(WASMModuleCommon *)module_inst->module, memory)) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate memory failed:"
|
||||
"allocate memory failed.");
|
||||
wasm_runtime_free(memory);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return memory;
|
||||
}
|
||||
@ -169,6 +233,7 @@ memories_instantiate(const WASMModule *module,
|
||||
uint32 num_bytes_per_page = import->u.memory.num_bytes_per_page;
|
||||
uint32 init_page_count = import->u.memory.init_page_count;
|
||||
uint32 max_page_count = import->u.memory.max_page_count;
|
||||
uint32 flags = import->u.memory.flags;
|
||||
uint32 actual_heap_size = heap_size;
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
@ -197,8 +262,9 @@ memories_instantiate(const WASMModule *module,
|
||||
#endif
|
||||
{
|
||||
if (!(memory = memories[mem_index++] = memory_instantiate(
|
||||
num_bytes_per_page, init_page_count, max_page_count,
|
||||
actual_heap_size, error_buf, error_buf_size))) {
|
||||
module_inst, num_bytes_per_page, init_page_count,
|
||||
max_page_count, actual_heap_size, flags,
|
||||
error_buf, error_buf_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate memory failed: "
|
||||
"allocate memory failed.");
|
||||
@ -213,10 +279,12 @@ memories_instantiate(const WASMModule *module,
|
||||
/* instantiate memories from memory section */
|
||||
for (i = 0; i < module->memory_count; i++) {
|
||||
if (!(memory = memories[mem_index++] =
|
||||
memory_instantiate(module->memories[i].num_bytes_per_page,
|
||||
memory_instantiate(module_inst,
|
||||
module->memories[i].num_bytes_per_page,
|
||||
module->memories[i].init_page_count,
|
||||
module->memories[i].max_page_count,
|
||||
heap_size, error_buf, error_buf_size))) {
|
||||
heap_size, module->memories[i].flags,
|
||||
error_buf, error_buf_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate memory failed: "
|
||||
"allocate memory failed.");
|
||||
@ -236,7 +304,7 @@ memories_instantiate(const WASMModule *module,
|
||||
* for wasm code
|
||||
*/
|
||||
if (!(memory = memories[mem_index++] =
|
||||
memory_instantiate(0, 0, 0, heap_size,
|
||||
memory_instantiate(module_inst, 0, 0, 0, heap_size, 0,
|
||||
error_buf, error_buf_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate memory failed: "
|
||||
@ -792,6 +860,36 @@ execute_post_inst_function(WASMModuleInstance *module_inst)
|
||||
0, NULL);
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
static bool
|
||||
execute_memory_init_function(WASMModuleInstance *module_inst)
|
||||
{
|
||||
WASMFunctionInstance *memory_init_func = NULL;
|
||||
WASMType *memory_init_func_type;
|
||||
uint32 i;
|
||||
|
||||
for (i = 0; i < module_inst->export_func_count; i++)
|
||||
if (!strcmp(module_inst->export_functions[i].name, "__wasm_call_ctors")) {
|
||||
memory_init_func = module_inst->export_functions[i].function;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!memory_init_func)
|
||||
/* Not found */
|
||||
return true;
|
||||
|
||||
memory_init_func_type = memory_init_func->u.func->func_type;
|
||||
if (memory_init_func_type->param_count != 0
|
||||
|| memory_init_func_type->result_count != 0)
|
||||
/* Not a valid function type, ignore it */
|
||||
return true;
|
||||
|
||||
return wasm_create_exec_env_and_call_function(module_inst,
|
||||
memory_init_func,
|
||||
0, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool
|
||||
execute_start_function(WASMModuleInstance *module_inst)
|
||||
{
|
||||
@ -819,7 +917,7 @@ sub_module_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
|
||||
while (sub_module_list_node) {
|
||||
WASMModule *sub_module = (WASMModule*)sub_module_list_node->module;
|
||||
WASMModuleInstance *sub_module_inst = wasm_instantiate(
|
||||
sub_module, stack_size, heap_size, error_buf, error_buf_size);
|
||||
sub_module, false, stack_size, heap_size, error_buf, error_buf_size);
|
||||
if (!sub_module_inst) {
|
||||
LOG_DEBUG("instantiate %s failed",
|
||||
sub_module_list_node->module_name);
|
||||
@ -833,7 +931,7 @@ sub_module_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
|
||||
if (!sub_module_inst_list_node) {
|
||||
LOG_DEBUG("Malloc WASMSubModInstNode failed, SZ:%d",
|
||||
sizeof(WASMSubModInstNode));
|
||||
wasm_deinstantiate(sub_module_inst);
|
||||
wasm_deinstantiate(sub_module_inst, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -859,7 +957,7 @@ sub_module_deinstantiate(WASMModuleInstance *module_inst)
|
||||
while (node) {
|
||||
WASMSubModInstNode *next_node = bh_list_elem_next(node);
|
||||
bh_list_remove(list, node);
|
||||
wasm_deinstantiate(node->module_inst);
|
||||
wasm_deinstantiate(node->module_inst, false);
|
||||
node = next_node;
|
||||
}
|
||||
}
|
||||
@ -869,7 +967,7 @@ sub_module_deinstantiate(WASMModuleInstance *module_inst)
|
||||
* Instantiate module
|
||||
*/
|
||||
WASMModuleInstance*
|
||||
wasm_instantiate(WASMModule *module,
|
||||
wasm_instantiate(WASMModule *module, bool is_sub_inst,
|
||||
uint32 stack_size, uint32 heap_size,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
@ -887,10 +985,6 @@ wasm_instantiate(WASMModule *module,
|
||||
|
||||
/* Check heap size */
|
||||
heap_size = align_uint(heap_size, 8);
|
||||
if (heap_size == 0)
|
||||
heap_size = APP_HEAP_SIZE_DEFAULT;
|
||||
if (heap_size < APP_HEAP_SIZE_MIN)
|
||||
heap_size = APP_HEAP_SIZE_MIN;
|
||||
if (heap_size > APP_HEAP_SIZE_MAX)
|
||||
heap_size = APP_HEAP_SIZE_MAX;
|
||||
|
||||
@ -904,6 +998,8 @@ wasm_instantiate(WASMModule *module,
|
||||
|
||||
memset(module_inst, 0, (uint32)sizeof(WASMModuleInstance));
|
||||
|
||||
module_inst->module = module;
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
module_inst->sub_module_inst_list =
|
||||
&module_inst->sub_module_inst_list_head;
|
||||
@ -911,7 +1007,7 @@ wasm_instantiate(WASMModule *module,
|
||||
error_buf, error_buf_size);
|
||||
if (!ret) {
|
||||
LOG_DEBUG("build a sub module list failed");
|
||||
wasm_deinstantiate(module_inst);
|
||||
wasm_deinstantiate(module_inst, false);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
@ -922,7 +1018,7 @@ wasm_instantiate(WASMModule *module,
|
||||
module,
|
||||
module_inst,
|
||||
&global_data_size, error_buf, error_buf_size))) {
|
||||
wasm_deinstantiate(module_inst);
|
||||
wasm_deinstantiate(module_inst, false);
|
||||
return NULL;
|
||||
}
|
||||
module_inst->global_count = global_count;
|
||||
@ -946,7 +1042,7 @@ wasm_instantiate(WASMModule *module,
|
||||
if (global_count > 0) {
|
||||
if (!(module_inst->global_data = runtime_malloc
|
||||
(global_data_size, error_buf, error_buf_size))) {
|
||||
wasm_deinstantiate(module_inst);
|
||||
wasm_deinstantiate(module_inst, false);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -978,7 +1074,7 @@ wasm_instantiate(WASMModule *module,
|
||||
error_buf, error_buf_size)))
|
||||
#endif
|
||||
) {
|
||||
wasm_deinstantiate(module_inst);
|
||||
wasm_deinstantiate(module_inst, false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -989,7 +1085,7 @@ wasm_instantiate(WASMModule *module,
|
||||
*/
|
||||
if (!globals_instantiate_fix(globals, module,
|
||||
error_buf, error_buf_size)) {
|
||||
wasm_deinstantiate(module_inst);
|
||||
wasm_deinstantiate(module_inst, false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1063,7 +1159,7 @@ wasm_instantiate(WASMModule *module,
|
||||
memory_size);
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"data segment does not fit.");
|
||||
wasm_deinstantiate(module_inst);
|
||||
wasm_deinstantiate(module_inst, false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1075,7 +1171,7 @@ wasm_instantiate(WASMModule *module,
|
||||
set_error_buf(
|
||||
error_buf, error_buf_size,
|
||||
"Instantiate module failed: data segment does not fit.");
|
||||
wasm_deinstantiate(module_inst);
|
||||
wasm_deinstantiate(module_inst, false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1121,7 +1217,7 @@ wasm_instantiate(WASMModule *module,
|
||||
table_seg->base_offset.u.i32, table->cur_size);
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"elements segment does not fit");
|
||||
wasm_deinstantiate(module_inst);
|
||||
wasm_deinstantiate(module_inst, false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1132,7 +1228,7 @@ wasm_instantiate(WASMModule *module,
|
||||
table_seg->base_offset.u.i32, length, table->cur_size);
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"elements segment does not fit");
|
||||
wasm_deinstantiate(module_inst);
|
||||
wasm_deinstantiate(module_inst, false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1149,18 +1245,22 @@ wasm_instantiate(WASMModule *module,
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
if (!wasm_runtime_init_wasi((WASMModuleInstanceCommon*)module_inst,
|
||||
module->wasi_args.dir_list,
|
||||
module->wasi_args.dir_count,
|
||||
module->wasi_args.map_dir_list,
|
||||
module->wasi_args.map_dir_count,
|
||||
module->wasi_args.env,
|
||||
module->wasi_args.env_count,
|
||||
module->wasi_args.argv,
|
||||
module->wasi_args.argc,
|
||||
error_buf, error_buf_size)) {
|
||||
wasm_deinstantiate(module_inst);
|
||||
return NULL;
|
||||
/* The sub-instance will get the wasi_ctx from main-instance */
|
||||
if (!is_sub_inst) {
|
||||
if (heap_size > 0
|
||||
&& !wasm_runtime_init_wasi((WASMModuleInstanceCommon*)module_inst,
|
||||
module->wasi_args.dir_list,
|
||||
module->wasi_args.dir_count,
|
||||
module->wasi_args.map_dir_list,
|
||||
module->wasi_args.map_dir_count,
|
||||
module->wasi_args.env,
|
||||
module->wasi_args.env_count,
|
||||
module->wasi_args.argv,
|
||||
module->wasi_args.argc,
|
||||
error_buf, error_buf_size)) {
|
||||
wasm_deinstantiate(module_inst, false);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1171,8 +1271,6 @@ wasm_instantiate(WASMModule *module,
|
||||
&module_inst->functions[module->start_function];
|
||||
}
|
||||
|
||||
module_inst->module = module;
|
||||
|
||||
/* module instance type */
|
||||
module_inst->module_type = Wasm_Module_Bytecode;
|
||||
|
||||
@ -1190,16 +1288,36 @@ wasm_instantiate(WASMModule *module,
|
||||
|| !execute_start_function(module_inst)) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
module_inst->cur_exception);
|
||||
wasm_deinstantiate(module_inst);
|
||||
wasm_deinstantiate(module_inst, false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
if (!module->is_wasi_module) {
|
||||
#endif
|
||||
/* Only execute the memory init function for main instance because
|
||||
the data segments will be dropped once initialized.
|
||||
*/
|
||||
if (!is_sub_inst) {
|
||||
if (!execute_memory_init_function(module_inst)) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
module_inst->cur_exception);
|
||||
wasm_deinstantiate(module_inst, false);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
(void)global_data_end;
|
||||
return module_inst;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_deinstantiate(WASMModuleInstance *module_inst)
|
||||
wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst)
|
||||
{
|
||||
if (!module_inst)
|
||||
return;
|
||||
@ -1213,7 +1331,9 @@ wasm_deinstantiate(WASMModuleInstance *module_inst)
|
||||
wasi contex are allocated from app heap, and if app heap is freed,
|
||||
these fields will be set to NULL, we cannot free their internal data
|
||||
which may allocated from global heap. */
|
||||
wasm_runtime_destroy_wasi((WASMModuleInstanceCommon*)module_inst);
|
||||
/* Only destroy wasi ctx in the main module instance */
|
||||
if (!is_sub_inst)
|
||||
wasm_runtime_destroy_wasi((WASMModuleInstanceCommon*)module_inst);
|
||||
#endif
|
||||
|
||||
if (module_inst->memory_count > 0)
|
||||
@ -1299,8 +1419,9 @@ wasm_create_exec_env_and_call_function(WASMModuleInstance *module_inst,
|
||||
WASMExecEnv *exec_env;
|
||||
bool ret;
|
||||
|
||||
if (!(exec_env = wasm_exec_env_create((WASMModuleInstanceCommon*)module_inst,
|
||||
module_inst->default_wasm_stack_size))) {
|
||||
if (!(exec_env = wasm_exec_env_create(
|
||||
(WASMModuleInstanceCommon*)module_inst,
|
||||
module_inst->default_wasm_stack_size))) {
|
||||
wasm_set_exception(module_inst, "allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
@ -1518,6 +1639,15 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
|
||||
return false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (memory->is_shared) {
|
||||
/* For shared memory, we have reserved the maximum spaces during
|
||||
instantiate, only change the cur_page_count here */
|
||||
memory->cur_page_count = total_page_count;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (heap_size > 0) {
|
||||
/* Destroy heap's lock firstly, if its memory is re-allocated,
|
||||
we cannot access its lock again. */
|
||||
@ -1612,3 +1742,66 @@ wasm_call_indirect(WASMExecEnv *exec_env,
|
||||
got_exception:
|
||||
return false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
bool
|
||||
wasm_set_aux_stack(WASMExecEnv *exec_env,
|
||||
uint32 start_offset, uint32 size)
|
||||
{
|
||||
WASMModuleInstance *module_inst =
|
||||
(WASMModuleInstance*)exec_env->module_inst;
|
||||
|
||||
uint32 stack_top_idx =
|
||||
module_inst->module->llvm_aux_stack_global_index;
|
||||
uint32 data_end =
|
||||
module_inst->module->llvm_aux_data_end;
|
||||
uint32 stack_bottom =
|
||||
module_inst->module->llvm_aux_stack_bottom;
|
||||
bool is_stack_before_data =
|
||||
stack_bottom < data_end ? true : false;
|
||||
|
||||
/* Check the aux stack space, currently we don't allocate space in heap */
|
||||
if ((is_stack_before_data && (size > start_offset))
|
||||
|| ((!is_stack_before_data) && (start_offset - data_end < size)))
|
||||
return false;
|
||||
|
||||
if (stack_bottom) {
|
||||
/* The aux stack top is a wasm global,
|
||||
set the initial value for the global */
|
||||
uint8 *global_addr =
|
||||
module_inst->global_data +
|
||||
module_inst->globals[stack_top_idx].data_offset;
|
||||
*(int32*)global_addr = start_offset;
|
||||
/* The aux stack boundary is a constant value,
|
||||
set the value to exec_env */
|
||||
exec_env->aux_stack_boundary = start_offset - size;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_get_aux_stack(WASMExecEnv *exec_env,
|
||||
uint32 *start_offset, uint32 *size)
|
||||
{
|
||||
WASMModuleInstance *module_inst =
|
||||
(WASMModuleInstance*)exec_env->module_inst;
|
||||
|
||||
/* The aux stack information is resolved in loader
|
||||
and store in module */
|
||||
uint32 stack_bottom =
|
||||
module_inst->module->llvm_aux_stack_bottom;
|
||||
uint32 total_aux_stack_size =
|
||||
module_inst->module->llvm_aux_stack_size;
|
||||
|
||||
if (stack_bottom != 0 && total_aux_stack_size != 0) {
|
||||
if (start_offset)
|
||||
*start_offset = stack_bottom;
|
||||
if (size)
|
||||
*size = total_aux_stack_size;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
@ -22,6 +22,10 @@ typedef struct WASMTableInstance WASMTableInstance;
|
||||
typedef struct WASMGlobalInstance WASMGlobalInstance;
|
||||
|
||||
typedef struct WASMMemoryInstance {
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
/* shared memory flag */
|
||||
bool is_shared;
|
||||
#endif
|
||||
/* Number bytes per page */
|
||||
uint32 num_bytes_per_page;
|
||||
/* Current page count */
|
||||
@ -269,12 +273,12 @@ void
|
||||
wasm_unload(WASMModule *module);
|
||||
|
||||
WASMModuleInstance *
|
||||
wasm_instantiate(WASMModule *module,
|
||||
wasm_instantiate(WASMModule *module, bool is_sub_inst,
|
||||
uint32 stack_size, uint32 heap_size,
|
||||
char *error_buf, uint32 error_buf_size);
|
||||
|
||||
void
|
||||
wasm_deinstantiate(WASMModuleInstance *module_inst);
|
||||
wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst);
|
||||
|
||||
WASMFunctionInstance *
|
||||
wasm_lookup_function(const WASMModuleInstance *module_inst,
|
||||
@ -358,6 +362,16 @@ wasm_call_indirect(WASMExecEnv *exec_env,
|
||||
uint32_t element_indices,
|
||||
uint32_t argc, uint32_t argv[]);
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
bool
|
||||
wasm_set_aux_stack(WASMExecEnv *exec_env,
|
||||
uint32 start_offset, uint32 size);
|
||||
|
||||
bool
|
||||
wasm_get_aux_stack(WASMExecEnv *exec_env,
|
||||
uint32 *start_offset, uint32 *size);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user