|
|
@@ -189,7 +189,7 @@ failed: \
|
|
|
size_t i = 0; \
|
|
|
memset(out, 0, sizeof(Vector)); \
|
|
|
\
|
|
|
- if (!src->size) { \
|
|
|
+ if (!src || !src->size) { \
|
|
|
return; \
|
|
|
} \
|
|
|
\
|
|
|
@@ -232,6 +232,7 @@ WASM_DEFINE_VEC_OWN(store, wasm_store_delete)
|
|
|
WASM_DEFINE_VEC_OWN(module, wasm_module_delete_internal)
|
|
|
WASM_DEFINE_VEC_OWN(instance, wasm_instance_delete_internal)
|
|
|
WASM_DEFINE_VEC_OWN(extern, wasm_extern_delete)
|
|
|
+WASM_DEFINE_VEC_OWN(frame, wasm_frame_delete)
|
|
|
|
|
|
static inline bool
|
|
|
valid_module_type(uint32 module_type)
|
|
|
@@ -255,6 +256,21 @@ valid_module_type(uint32 module_type)
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
+/* conflicting declaration between aot_export.h and aot.h */
|
|
|
+#if WASM_ENABLE_AOT != 0 && WASM_ENABLE_JIT != 0
|
|
|
+bool
|
|
|
+aot_compile_wasm_file_init();
|
|
|
+
|
|
|
+void
|
|
|
+aot_compile_wasm_file_destroy();
|
|
|
+
|
|
|
+uint8*
|
|
|
+aot_compile_wasm_file(const uint8 *wasm_file_buf, uint32 wasm_file_size,
|
|
|
+ uint32 opt_level, uint32 size_level,
|
|
|
+ char *error_buf, uint32 error_buf_size,
|
|
|
+ uint32 *p_aot_file_size);
|
|
|
+#endif
|
|
|
+
|
|
|
/* Runtime Environment */
|
|
|
static void
|
|
|
wasm_engine_delete_internal(wasm_engine_t *engine)
|
|
|
@@ -264,6 +280,10 @@ wasm_engine_delete_internal(wasm_engine_t *engine)
|
|
|
wasm_runtime_free(engine);
|
|
|
}
|
|
|
|
|
|
+#if WASM_ENABLE_AOT != 0 && WASM_ENABLE_JIT != 0
|
|
|
+ aot_compile_wasm_file_destroy();
|
|
|
+#endif
|
|
|
+
|
|
|
wasm_runtime_destroy();
|
|
|
}
|
|
|
|
|
|
@@ -311,6 +331,12 @@ wasm_engine_new_internal(mem_alloc_type_t type, const MemAllocOption *opts)
|
|
|
bh_log_set_verbose_level(3);
|
|
|
#endif
|
|
|
|
|
|
+#if WASM_ENABLE_AOT != 0 && WASM_ENABLE_JIT != 0
|
|
|
+ if (!aot_compile_wasm_file_init()) {
|
|
|
+ goto failed;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
/* create wasm_engine_t */
|
|
|
if (!(engine = malloc_internal(sizeof(wasm_engine_t)))) {
|
|
|
goto failed;
|
|
|
@@ -1289,10 +1315,106 @@ wasm_val_same(const wasm_val_t *v1, const wasm_val_t *v2)
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+static wasm_frame_t *
|
|
|
+wasm_frame_new(wasm_instance_t *instance,
|
|
|
+ size_t module_offset,
|
|
|
+ uint32 func_index,
|
|
|
+ size_t func_offset)
|
|
|
+{
|
|
|
+ wasm_frame_t *frame;
|
|
|
+
|
|
|
+ if (!(frame = malloc_internal(sizeof(wasm_frame_t)))) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ frame->instance = instance;
|
|
|
+ frame->module_offset = module_offset;
|
|
|
+ frame->func_index = func_index;
|
|
|
+ frame->func_offset = func_offset;
|
|
|
+ return frame;
|
|
|
+}
|
|
|
+
|
|
|
+own wasm_frame_t *
|
|
|
+wasm_frame_copy(const wasm_frame_t *src)
|
|
|
+{
|
|
|
+ if (!src) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ return wasm_frame_new(src->instance, src->module_offset, src->func_index,
|
|
|
+ src->func_offset);
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+wasm_frame_delete(own wasm_frame_t *frame)
|
|
|
+{
|
|
|
+ if (!frame) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ wasm_runtime_free(frame);
|
|
|
+}
|
|
|
+
|
|
|
+struct wasm_instance_t *
|
|
|
+wasm_frame_instance(const wasm_frame_t *frame)
|
|
|
+{
|
|
|
+ return frame ? frame->instance : NULL;
|
|
|
+}
|
|
|
+
|
|
|
+size_t
|
|
|
+wasm_frame_module_offset(const wasm_frame_t *frame)
|
|
|
+{
|
|
|
+ return frame ? frame->module_offset : 0;
|
|
|
+}
|
|
|
+
|
|
|
+uint32_t
|
|
|
+wasm_frame_func_index(const wasm_frame_t *frame)
|
|
|
+{
|
|
|
+ return frame ? frame->func_index : 0;
|
|
|
+}
|
|
|
+
|
|
|
+size_t
|
|
|
+wasm_frame_func_offset(const wasm_frame_t *frame)
|
|
|
+{
|
|
|
+ return frame ? frame->func_offset : 0;
|
|
|
+}
|
|
|
+
|
|
|
static wasm_trap_t *
|
|
|
-wasm_trap_new_internal(const char *string)
|
|
|
+wasm_trap_new_internal(WASMModuleInstanceCommon *inst_comm_rt,
|
|
|
+ const char *default_error_info)
|
|
|
{
|
|
|
wasm_trap_t *trap;
|
|
|
+ const char *error_info = NULL;
|
|
|
+ wasm_instance_vec_t *instances;
|
|
|
+ wasm_instance_t *frame_instance = NULL;
|
|
|
+ uint32 i;
|
|
|
+
|
|
|
+ if (!singleton_engine || !singleton_engine->stores
|
|
|
+ || !singleton_engine->stores->num_elems) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+#if WASM_ENABLE_INTERP != 0
|
|
|
+ if (inst_comm_rt->module_type == Wasm_Module_Bytecode) {
|
|
|
+ if (!(error_info =
|
|
|
+ wasm_get_exception((WASMModuleInstance *)inst_comm_rt))) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+#if WASM_ENABLE_AOT != 0
|
|
|
+ if (inst_comm_rt->module_type == Wasm_Module_AoT) {
|
|
|
+ if (!(error_info =
|
|
|
+ aot_get_exception((AOTModuleInstance *)inst_comm_rt))) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+ if (!error_info && !(error_info = default_error_info)) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
|
|
|
if (!(trap = malloc_internal(sizeof(wasm_trap_t)))) {
|
|
|
return NULL;
|
|
|
@@ -1302,11 +1424,39 @@ wasm_trap_new_internal(const char *string)
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
|
- wasm_name_new_from_string(trap->message, string);
|
|
|
- if (strlen(string) && !trap->message->data) {
|
|
|
+ wasm_name_new_from_string_nt(trap->message, error_info);
|
|
|
+ if (strlen(error_info) && !trap->message->data) {
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
|
+#if WASM_ENABLE_DUMP_CALL_STACK != 0
|
|
|
+#if WASM_ENABLE_INTERP != 0
|
|
|
+ if (inst_comm_rt->module_type == Wasm_Module_Bytecode) {
|
|
|
+ trap->frames = ((WASMModuleInstance *)inst_comm_rt)->frames;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+#endif /* WASM_ENABLE_DUMP_CALL_STACK != 0 */
|
|
|
+
|
|
|
+ /* allow a NULL frames list */
|
|
|
+ if (!trap->frames) {
|
|
|
+ return trap;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!(instances = singleton_engine->stores->data[0]->instances)) {
|
|
|
+ goto failed;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < instances->num_elems; i++) {
|
|
|
+ if (instances->data[i]->inst_comm_rt == inst_comm_rt) {
|
|
|
+ frame_instance = instances->data[i];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < trap->frames->num_elems; i++) {
|
|
|
+ (((wasm_frame_t *)trap->frames->data) + i)->instance = frame_instance;
|
|
|
+ }
|
|
|
+
|
|
|
return trap;
|
|
|
failed:
|
|
|
wasm_trap_delete(trap);
|
|
|
@@ -1342,6 +1492,7 @@ wasm_trap_delete(wasm_trap_t *trap)
|
|
|
}
|
|
|
|
|
|
DEINIT_VEC(trap->message, wasm_byte_vec_delete);
|
|
|
+ /* reuse frames of WASMModuleInstance, do not free it here */
|
|
|
|
|
|
wasm_runtime_free(trap);
|
|
|
}
|
|
|
@@ -1356,6 +1507,65 @@ wasm_trap_message(const wasm_trap_t *trap, own wasm_message_t *out)
|
|
|
wasm_byte_vec_copy(out, trap->message);
|
|
|
}
|
|
|
|
|
|
+own wasm_frame_t *
|
|
|
+wasm_trap_origin(const wasm_trap_t *trap)
|
|
|
+{
|
|
|
+ wasm_frame_t *latest_frame;
|
|
|
+
|
|
|
+ if (!trap || !trap->frames || !trap->frames->num_elems) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* first frame is the latest frame */
|
|
|
+ latest_frame = (wasm_frame_t *)trap->frames->data;
|
|
|
+ return wasm_frame_copy(latest_frame);
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+wasm_trap_trace(const wasm_trap_t *trap, own wasm_frame_vec_t *out)
|
|
|
+{
|
|
|
+ uint32 i;
|
|
|
+
|
|
|
+ if (!trap || !out) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!trap->frames || !trap->frames->num_elems) {
|
|
|
+ wasm_frame_vec_new_empty(out);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ wasm_frame_vec_new_uninitialized(out, trap->frames->num_elems);
|
|
|
+ if (out->size && !out->data) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < trap->frames->num_elems; i++) {
|
|
|
+ wasm_frame_t *frame;
|
|
|
+
|
|
|
+ frame = ((wasm_frame_t *)trap->frames->data) + i;
|
|
|
+
|
|
|
+ if (!(out->data[i] =
|
|
|
+ wasm_frame_new(frame->instance, frame->module_offset,
|
|
|
+ frame->func_index, frame->func_offset))) {
|
|
|
+ goto failed;
|
|
|
+ }
|
|
|
+ out->num_elems++;
|
|
|
+ }
|
|
|
+
|
|
|
+ return;
|
|
|
+failed:
|
|
|
+ for (i = 0; i < out->num_elems; i++) {
|
|
|
+ if (out->data[i]) {
|
|
|
+ wasm_runtime_free(out->data[i]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (out->data) {
|
|
|
+ wasm_runtime_free(out->data);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
struct wasm_module_ex_t {
|
|
|
struct WASMModuleCommon *module_comm_rt;
|
|
|
wasm_byte_vec_t *binary;
|
|
|
@@ -1386,6 +1596,10 @@ wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)
|
|
|
{
|
|
|
char error_buf[128] = { 0 };
|
|
|
wasm_module_ex_t *module_ex = NULL;
|
|
|
+#if WASM_ENABLE_AOT != 0 && WASM_ENABLE_JIT != 0
|
|
|
+ uint8 *aot_file_buf = NULL;
|
|
|
+ uint32 aot_file_size;
|
|
|
+#endif
|
|
|
|
|
|
bh_assert(singleton_engine);
|
|
|
|
|
|
@@ -1401,12 +1615,35 @@ wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)
|
|
|
|
|
|
INIT_VEC(module_ex->binary, wasm_byte_vec_new, binary->size, binary->data);
|
|
|
|
|
|
- module_ex->module_comm_rt = wasm_runtime_load(
|
|
|
- (uint8 *)module_ex->binary->data, (uint32)module_ex->binary->size,
|
|
|
- error_buf, (uint32)sizeof(error_buf));
|
|
|
- if (!(module_ex->module_comm_rt)) {
|
|
|
- LOG_ERROR(error_buf);
|
|
|
- goto failed;
|
|
|
+#if WASM_ENABLE_AOT != 0 && WASM_ENABLE_JIT != 0
|
|
|
+ if (get_package_type((uint8 *)module_ex->binary->data,
|
|
|
+ (uint32)module_ex->binary->size)
|
|
|
+ == Wasm_Module_Bytecode) {
|
|
|
+ if (!(aot_file_buf = aot_compile_wasm_file(
|
|
|
+ (uint8 *)module_ex->binary->data,
|
|
|
+ (uint32)module_ex->binary->size, 3, 3, error_buf,
|
|
|
+ (uint32)sizeof(error_buf), &aot_file_size))) {
|
|
|
+ LOG_ERROR(error_buf);
|
|
|
+ goto failed;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!(module_ex->module_comm_rt =
|
|
|
+ wasm_runtime_load(aot_file_buf, aot_file_size, error_buf,
|
|
|
+ (uint32)sizeof(error_buf)))) {
|
|
|
+ LOG_ERROR(error_buf);
|
|
|
+ goto failed;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+#endif
|
|
|
+ {
|
|
|
+ module_ex->module_comm_rt = wasm_runtime_load(
|
|
|
+ (uint8 *)module_ex->binary->data, (uint32)module_ex->binary->size,
|
|
|
+ error_buf, (uint32)sizeof(error_buf));
|
|
|
+ if (!(module_ex->module_comm_rt)) {
|
|
|
+ LOG_ERROR(error_buf);
|
|
|
+ goto failed;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/* add it to a watching list in store */
|
|
|
@@ -2255,12 +2492,13 @@ failed:
|
|
|
if (argv != argv_buf)
|
|
|
wasm_runtime_free(argv);
|
|
|
|
|
|
+ /* trap -> exception -> trap */
|
|
|
if (wasm_runtime_get_exception(func->inst_comm_rt)) {
|
|
|
- return wasm_trap_new_internal(
|
|
|
- wasm_runtime_get_exception(func->inst_comm_rt));
|
|
|
+ return wasm_trap_new_internal(func->inst_comm_rt, NULL);
|
|
|
}
|
|
|
else {
|
|
|
- return wasm_trap_new_internal("wasm_func_call failed");
|
|
|
+ return wasm_trap_new_internal(func->inst_comm_rt,
|
|
|
+ "wasm_func_call failed");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -3446,8 +3684,8 @@ wasm_instance_new(wasm_store_t *store,
|
|
|
own wasm_trap_t **traps)
|
|
|
{
|
|
|
char error_buf[128] = { 0 };
|
|
|
- const uint32 stack_size = 16 * 1024;
|
|
|
- const uint32 heap_size = 16 * 1024;
|
|
|
+ const uint32 stack_size = 32 * 1024;
|
|
|
+ const uint32 heap_size = 32 * 1024;
|
|
|
uint32 import_count = 0;
|
|
|
wasm_instance_t *instance = NULL;
|
|
|
uint32 i = 0;
|