mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-15 06:01:14 +00:00
PR2 Exception Handling Support (#2785)
This PR continues the work from #2382 and updates the exception handling support: * Inside the classic interpreter only: * Bug fixes and naming convention improvements * Import and Export of Exceptions and Tags * Remove the dependency on multi-module * Additional CI /CD changes to validate ENABLE_EXCE_HANDLING switch builds OK on all platforms Refer to https://github.com/bytecodealliance/wasm-micro-runtime/issues/1884. Signed-off-by: Ricardo Aguilar <ricardoaguilar@siemens.com> Co-authored-by: Chris Woods <chris.woods@siemens.com> Co-authored-by: Rene Ermler <rene.ermler@siemens.com> Co-authored-by: Trenner Thomas <trenner.thomas@siemens.com>
This commit is contained in:
parent
59f4dd4c05
commit
59bccdfed8
|
@ -14,13 +14,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WASM_ENABLE_EXCE_HANDLING != 0
|
|
||||||
#define _EXCEWARNING \
|
|
||||||
LOG_WARNING /* for exception handling misbehavior logging */
|
|
||||||
#define _EXCEVERBOSE \
|
|
||||||
LOG_VERBOSE /* more excessive tracing of tagbrowsing and stack pointers */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Value Type */
|
/** Value Type */
|
||||||
#define VALUE_TYPE_I32 0x7F
|
#define VALUE_TYPE_I32 0x7F
|
||||||
#define VALUE_TYPE_I64 0X7E
|
#define VALUE_TYPE_I64 0X7E
|
||||||
|
@ -223,15 +216,18 @@ typedef struct WASMFunctionImport {
|
||||||
|
|
||||||
#if WASM_ENABLE_TAGS != 0
|
#if WASM_ENABLE_TAGS != 0
|
||||||
typedef struct WASMTagImport {
|
typedef struct WASMTagImport {
|
||||||
|
char *module_name;
|
||||||
|
char *field_name;
|
||||||
uint8 attribute; /* the type of the tag (numerical) */
|
uint8 attribute; /* the type of the tag (numerical) */
|
||||||
uint32 type; /* the type of the catch function (numerical)*/
|
uint32 type; /* the type of the catch function (numerical)*/
|
||||||
WASMType *tag_type;
|
WASMType *tag_type;
|
||||||
uint32 tag_index_linked;
|
void *tag_ptr_linked;
|
||||||
|
|
||||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||||
/* imported function pointer after linked */
|
/* imported tag pointer after linked */
|
||||||
/* TODO: remove if not needed */
|
|
||||||
WASMModule *import_module;
|
WASMModule *import_module;
|
||||||
WASMTag *import_tag_linked;
|
WASMTag *import_tag_linked;
|
||||||
|
uint32 import_tag_index_linked;
|
||||||
#endif
|
#endif
|
||||||
} WASMTagImport;
|
} WASMTagImport;
|
||||||
#endif
|
#endif
|
||||||
|
@ -340,6 +336,7 @@ struct WASMFunction {
|
||||||
struct WASMTag {
|
struct WASMTag {
|
||||||
uint8 attribute; /* the attribute property of the tag (expected to be 0) */
|
uint8 attribute; /* the attribute property of the tag (expected to be 0) */
|
||||||
uint32 type; /* the type of the tag (expected valid inden in type table) */
|
uint32 type; /* the type of the tag (expected valid inden in type table) */
|
||||||
|
WASMType *tag_type;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -505,7 +502,7 @@ struct WASMModule {
|
||||||
WASMTable *tables;
|
WASMTable *tables;
|
||||||
WASMMemory *memories;
|
WASMMemory *memories;
|
||||||
#if WASM_ENABLE_TAGS != 0
|
#if WASM_ENABLE_TAGS != 0
|
||||||
WASMTag *tags;
|
WASMTag **tags;
|
||||||
#endif
|
#endif
|
||||||
WASMGlobal *globals;
|
WASMGlobal *globals;
|
||||||
WASMExport *exports;
|
WASMExport *exports;
|
||||||
|
|
|
@ -1272,7 +1272,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
|
|
||||||
/* get tag type */
|
/* get tag type */
|
||||||
uint8 tag_type_index =
|
uint8 tag_type_index =
|
||||||
module->module->tags[exception_tag_index].type;
|
module->module->tags[exception_tag_index]->type;
|
||||||
uint32 cell_num_to_copy =
|
uint32 cell_num_to_copy =
|
||||||
wasm_types[tag_type_index]->param_cell_num;
|
wasm_types[tag_type_index]->param_cell_num;
|
||||||
|
|
||||||
|
@ -1291,9 +1291,35 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
{
|
{
|
||||||
read_leb_int32(frame_ip, frame_ip_end, exception_tag_index);
|
read_leb_int32(frame_ip, frame_ip_end, exception_tag_index);
|
||||||
|
|
||||||
/* landig pad for the rethrow ? */
|
/* landing pad for the rethrow ? */
|
||||||
find_a_catch_handler:
|
find_a_catch_handler:
|
||||||
{
|
{
|
||||||
|
WASMType *tag_type = NULL;
|
||||||
|
uint32 cell_num_to_copy = 0;
|
||||||
|
if (IS_INVALID_TAGINDEX(exception_tag_index)) {
|
||||||
|
/*
|
||||||
|
* invalid exception index,
|
||||||
|
* generated if a submodule throws an exception
|
||||||
|
* that has not been imported here
|
||||||
|
*
|
||||||
|
* This should result in a branch to the CATCH_ALL block,
|
||||||
|
* if there is one
|
||||||
|
*/
|
||||||
|
tag_type = NULL;
|
||||||
|
cell_num_to_copy = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (module->e->tags[exception_tag_index].is_import_tag) {
|
||||||
|
tag_type = module->e->tags[exception_tag_index]
|
||||||
|
.u.tag_import->tag_type;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tag_type = module->e->tags[exception_tag_index]
|
||||||
|
.u.tag->tag_type;
|
||||||
|
}
|
||||||
|
cell_num_to_copy = tag_type->param_cell_num;
|
||||||
|
}
|
||||||
|
|
||||||
/* browse through frame stack */
|
/* browse through frame stack */
|
||||||
uint32 relative_depth = 0;
|
uint32 relative_depth = 0;
|
||||||
do {
|
do {
|
||||||
|
@ -1309,7 +1335,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
/*
|
/*
|
||||||
* skip that blocks in search
|
* skip that blocks in search
|
||||||
* BLOCK, IF and LOOP do not contain handlers and
|
* BLOCK, IF and LOOP do not contain handlers and
|
||||||
* cannot catch exceptions blocks marked as CATCH or
|
* cannot catch exceptions.
|
||||||
|
* blocks marked as CATCH or
|
||||||
* CATCH_ALL did already caugth an exception and can
|
* CATCH_ALL did already caugth an exception and can
|
||||||
* only be a target for RETHROW, but cannot catch an
|
* only be a target for RETHROW, but cannot catch an
|
||||||
* exception again
|
* exception again
|
||||||
|
@ -1347,34 +1374,20 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
UNWIND_CSP(relative_depth,
|
UNWIND_CSP(relative_depth,
|
||||||
LABEL_TYPE_CATCH);
|
LABEL_TYPE_CATCH);
|
||||||
|
|
||||||
/* transfer exception values */
|
|
||||||
uint8 tag_type_index =
|
|
||||||
module->module
|
|
||||||
->tags[exception_tag_index]
|
|
||||||
.type;
|
|
||||||
uint32 cell_num_to_copy =
|
|
||||||
wasm_types[tag_type_index]
|
|
||||||
->param_cell_num;
|
|
||||||
/* push exception_tag_index and
|
/* push exception_tag_index and
|
||||||
* exception values for rethrow */
|
* exception values for rethrow */
|
||||||
PUSH_I32(exception_tag_index);
|
PUSH_I32(exception_tag_index);
|
||||||
if (cell_num_to_copy > 0) {
|
word_copy(frame_sp,
|
||||||
word_copy(
|
frame_sp_old
|
||||||
frame_sp,
|
- cell_num_to_copy,
|
||||||
frame_sp_old
|
cell_num_to_copy);
|
||||||
- cell_num_to_copy,
|
|
||||||
cell_num_to_copy);
|
|
||||||
}
|
|
||||||
frame_sp += cell_num_to_copy;
|
frame_sp += cell_num_to_copy;
|
||||||
/* push exception values for catch
|
/* push exception values for catch
|
||||||
*/
|
*/
|
||||||
if (cell_num_to_copy > 0) {
|
word_copy(frame_sp,
|
||||||
word_copy(
|
frame_sp_old
|
||||||
frame_sp,
|
- cell_num_to_copy,
|
||||||
frame_sp_old
|
cell_num_to_copy);
|
||||||
- cell_num_to_copy,
|
|
||||||
cell_num_to_copy);
|
|
||||||
}
|
|
||||||
frame_sp += cell_num_to_copy;
|
frame_sp += cell_num_to_copy;
|
||||||
|
|
||||||
/* advance to handler */
|
/* advance to handler */
|
||||||
|
@ -1403,21 +1416,11 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
/* unwind to delegated frame */
|
/* unwind to delegated frame */
|
||||||
frame_csp -= lookup_depth;
|
frame_csp -= lookup_depth;
|
||||||
|
|
||||||
/* transfer exception values */
|
|
||||||
uint8 tag_type_index =
|
|
||||||
module->module
|
|
||||||
->tags[exception_tag_index]
|
|
||||||
.type;
|
|
||||||
uint32 cell_num_to_copy =
|
|
||||||
wasm_types[tag_type_index]
|
|
||||||
->param_cell_num;
|
|
||||||
/* push exception values for catch */
|
/* push exception values for catch */
|
||||||
if (cell_num_to_copy > 0) {
|
word_copy(frame_sp,
|
||||||
word_copy(frame_sp,
|
frame_sp_old
|
||||||
frame_sp_old
|
- cell_num_to_copy,
|
||||||
- cell_num_to_copy,
|
cell_num_to_copy);
|
||||||
cell_num_to_copy);
|
|
||||||
}
|
|
||||||
frame_sp += cell_num_to_copy;
|
frame_sp += cell_num_to_copy;
|
||||||
|
|
||||||
/* tag_index is already stored in
|
/* tag_index is already stored in
|
||||||
|
@ -1439,25 +1442,11 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
/* push exception_tag_index and
|
/* push exception_tag_index and
|
||||||
* exception values for rethrow */
|
* exception values for rethrow */
|
||||||
PUSH_I32(exception_tag_index);
|
PUSH_I32(exception_tag_index);
|
||||||
if (exception_tag_index
|
word_copy(frame_sp,
|
||||||
!= (int32_t)0xFFFFFFFF) {
|
frame_sp_old
|
||||||
/* transfer exception values */
|
- cell_num_to_copy,
|
||||||
uint8 tag_type_index =
|
cell_num_to_copy);
|
||||||
module->module
|
frame_sp += cell_num_to_copy;
|
||||||
->tags[exception_tag_index]
|
|
||||||
.type;
|
|
||||||
uint32 cell_num_to_copy =
|
|
||||||
wasm_types[tag_type_index]
|
|
||||||
->param_cell_num;
|
|
||||||
if (cell_num_to_copy > 0) {
|
|
||||||
word_copy(
|
|
||||||
frame_sp,
|
|
||||||
frame_sp_old
|
|
||||||
- cell_num_to_copy,
|
|
||||||
cell_num_to_copy);
|
|
||||||
}
|
|
||||||
frame_sp += cell_num_to_copy;
|
|
||||||
}
|
|
||||||
/* catch_all has no exception values */
|
/* catch_all has no exception values */
|
||||||
|
|
||||||
/* advance to handler */
|
/* advance to handler */
|
||||||
|
@ -1469,7 +1458,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
"unexpected handler type");
|
"unexpected handler type");
|
||||||
goto got_exception;
|
goto got_exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
handler_number++;
|
handler_number++;
|
||||||
}
|
}
|
||||||
/* exception not catched in this frame */
|
/* exception not catched in this frame */
|
||||||
|
@ -1481,29 +1469,16 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
uint32 *frame_sp_old = frame_sp;
|
uint32 *frame_sp_old = frame_sp;
|
||||||
|
|
||||||
UNWIND_CSP(relative_depth, LABEL_TYPE_FUNCTION);
|
UNWIND_CSP(relative_depth, LABEL_TYPE_FUNCTION);
|
||||||
if (exception_tag_index
|
|
||||||
>= (int32_t)module->module->tag_count) {
|
|
||||||
wasm_set_exception(module, "invalid tag index");
|
|
||||||
goto got_exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* transfer exception values */
|
|
||||||
uint8 tag_type_index =
|
|
||||||
module->module->tags[exception_tag_index].type;
|
|
||||||
uint32 cell_num_to_copy =
|
|
||||||
wasm_types[tag_type_index]->param_cell_num;
|
|
||||||
/* push exception values for catch
|
/* push exception values for catch
|
||||||
* The values are copied to the CALLER FRAME
|
* The values are copied to the CALLER FRAME
|
||||||
* (prev_frame->sp) same behvior ad WASM_OP_RETURN
|
* (prev_frame->sp) same behvior ad WASM_OP_RETURN
|
||||||
*/
|
*/
|
||||||
if (cell_num_to_copy > 0) {
|
word_copy(prev_frame->sp,
|
||||||
word_copy(prev_frame->sp,
|
frame_sp_old - cell_num_to_copy,
|
||||||
frame_sp_old - cell_num_to_copy,
|
cell_num_to_copy);
|
||||||
cell_num_to_copy);
|
|
||||||
}
|
|
||||||
prev_frame->sp += cell_num_to_copy;
|
prev_frame->sp += cell_num_to_copy;
|
||||||
*((int32 *)(prev_frame->sp)) = exception_tag_index;
|
*((int32 *)(prev_frame->sp)) = exception_tag_index;
|
||||||
(int32 *)(prev_frame->sp++);
|
prev_frame->sp++;
|
||||||
|
|
||||||
/* mark frame as raised exception */
|
/* mark frame as raised exception */
|
||||||
wasm_set_exception(module,
|
wasm_set_exception(module,
|
||||||
|
@ -4314,37 +4289,37 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
/* fix framesp */
|
/* fix framesp */
|
||||||
UPDATE_ALL_FROM_FRAME();
|
UPDATE_ALL_FROM_FRAME();
|
||||||
|
|
||||||
uint32 import_exception =
|
uint32 import_exception;
|
||||||
0xFFFFFFFF; /* initialize imported exception index to be
|
/* initialize imported exception index to be invalid */
|
||||||
invalid */
|
SET_INVALID_TAGINDEX(import_exception);
|
||||||
|
|
||||||
/* pull external exception */
|
/* pull external exception */
|
||||||
uint32 ext_exception = POP_I32();
|
uint32 ext_exception = POP_I32();
|
||||||
|
|
||||||
WASMModule *im_mod = cur_func->u.func_import->import_module;
|
|
||||||
|
|
||||||
/* external function came back with an exception or trap */
|
/* external function came back with an exception or trap */
|
||||||
/* lookup exception in import tags */
|
/* lookup exception in import tags */
|
||||||
uint32 import_tag_index;
|
WASMTagInstance *tag = module->e->tags;
|
||||||
for (import_tag_index = 0;
|
for (uint32 t = 0; t < module->module->import_tag_count;
|
||||||
import_tag_index < module->module->import_tag_count;
|
tag++, t++) {
|
||||||
import_tag_index++) {
|
|
||||||
WASMTagImport *im_tag =
|
|
||||||
&(module->module->import_tags[import_tag_index]
|
|
||||||
.u.tag);
|
|
||||||
|
|
||||||
/* compare the module and the external index with the
|
/* compare the module and the external index with the
|
||||||
* imort tag data */
|
* imort tag data */
|
||||||
if ((im_mod == im_tag->import_module)
|
if ((cur_func->u.func_import->import_module
|
||||||
&& (ext_exception == im_tag->tag_index_linked)) {
|
== tag->u.tag_import->import_module)
|
||||||
|
&& (ext_exception
|
||||||
|
== tag->u.tag_import
|
||||||
|
->import_tag_index_linked)) {
|
||||||
/* set the import_exception to the import tag */
|
/* set the import_exception to the import tag */
|
||||||
import_exception = import_tag_index;
|
import_exception = t;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* push the internal exception index to stack,
|
* excange the thrown exception (index valid in submodule)
|
||||||
* or 0xffffffff in case, the external exception
|
* with the imported exception index (valid in this module)
|
||||||
* is not in the import list
|
* if the module did not import the exception,
|
||||||
|
* that results in a "INVALID_TAGINDEX", that triggers
|
||||||
|
* an CATCH_ALL block, if there is one.
|
||||||
*/
|
*/
|
||||||
PUSH_I32(import_exception);
|
PUSH_I32(import_exception);
|
||||||
}
|
}
|
||||||
|
|
|
@ -697,7 +697,6 @@ wasm_loader_find_export(const WASMModule *module, const char *module_name,
|
||||||
WASMExport *export =
|
WASMExport *export =
|
||||||
loader_find_export((WASMModuleCommon *)module, module_name, field_name,
|
loader_find_export((WASMModuleCommon *)module, module_name, field_name,
|
||||||
export_kind, error_buf, error_buf_size);
|
export_kind, error_buf, error_buf_size);
|
||||||
;
|
|
||||||
return export;
|
return export;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -888,6 +887,58 @@ wasm_loader_resolve_global(const char *module_name, const char *global_name,
|
||||||
return global;
|
return global;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WASM_ENABLE_TAGS != 0
|
||||||
|
static WASMTag *
|
||||||
|
wasm_loader_resolve_tag(const char *module_name, const char *tag_name,
|
||||||
|
const WASMType *expected_tag_type,
|
||||||
|
uint32 *linked_tag_index, char *error_buf,
|
||||||
|
uint32 error_buf_size)
|
||||||
|
{
|
||||||
|
WASMModuleCommon *module_reg;
|
||||||
|
WASMTag *tag = NULL;
|
||||||
|
WASMExport *export = NULL;
|
||||||
|
WASMModule *module = NULL;
|
||||||
|
|
||||||
|
module_reg = wasm_runtime_find_module_registered(module_name);
|
||||||
|
if (!module_reg || module_reg->module_type != Wasm_Module_Bytecode) {
|
||||||
|
LOG_DEBUG("can not find a module named %s for tag %s", module_name,
|
||||||
|
tag_name);
|
||||||
|
set_error_buf(error_buf, error_buf_size, "unknown import");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
module = (WASMModule *)module_reg;
|
||||||
|
export =
|
||||||
|
wasm_loader_find_export(module, module_name, tag_name, EXPORT_KIND_TAG,
|
||||||
|
error_buf, error_buf_size);
|
||||||
|
if (!export) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* resolve tag type and tag */
|
||||||
|
if (export->index < module->import_tag_count) {
|
||||||
|
/* importing an imported tag from the submodule */
|
||||||
|
tag = module->import_tags[export->index].u.tag.import_tag_linked;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* importing an section tag from the submodule */
|
||||||
|
tag = module->tags[export->index - module->import_tag_count];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check function type */
|
||||||
|
if (!wasm_type_equal(expected_tag_type, tag->tag_type)) {
|
||||||
|
LOG_DEBUG("%s.%s failed the type check", module_name, tag_name);
|
||||||
|
set_error_buf(error_buf, error_buf_size, "incompatible import type");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (linked_tag_index != NULL) {
|
||||||
|
*linked_tag_index = export->index;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif /* end of WASM_ENABLE_MULTI_MODULE */
|
#endif /* end of WASM_ENABLE_MULTI_MODULE */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -1227,86 +1278,76 @@ load_tag_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
WASMTagImport *tag, /* structure to fill */
|
WASMTagImport *tag, /* structure to fill */
|
||||||
char *error_buf, uint32 error_buf_size)
|
char *error_buf, uint32 error_buf_size)
|
||||||
{
|
{
|
||||||
WASMExport *export = 0;
|
/* attribute and type of the import statement */
|
||||||
WASMModule *sub_module = NULL;
|
uint8 declare_tag_attribute;
|
||||||
uint32 i;
|
uint32 declare_type_index;
|
||||||
|
|
||||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
|
||||||
if (!wasm_runtime_is_built_in_module(sub_module_name)) {
|
|
||||||
sub_module = load_depended_module(parent_module, sub_module_name,
|
|
||||||
error_buf, error_buf_size);
|
|
||||||
if (!sub_module) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
WASMModuleCommon *module_reg =
|
|
||||||
wasm_runtime_find_module_registered(sub_module_name);
|
|
||||||
if (!module_reg) {
|
|
||||||
set_error_buf(error_buf, error_buf_size,
|
|
||||||
"load_tag_import: registered module not found");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
sub_module = (WASMModule *)module_reg;
|
|
||||||
|
|
||||||
export = sub_module->exports;
|
|
||||||
for (i = 0; i < sub_module->export_count; i++, export ++) {
|
|
||||||
|
|
||||||
if (export->kind == EXPORT_KIND_TAG
|
|
||||||
&& strcmp(export->name, tag_name) == 0) {
|
|
||||||
WASMTag *imp_tag = (WASMTag *)&sub_module->tags[export->index];
|
|
||||||
WASMType *imp_tag_type =
|
|
||||||
(WASMType *)sub_module->types[imp_tag->type];
|
|
||||||
/* fill import tag*/
|
|
||||||
tag->tag_index_linked = export->index;
|
|
||||||
tag->tag_type = (WASMType *)sub_module->types[imp_tag->type];
|
|
||||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
|
||||||
tag->import_module = (WASMModule *)module_reg;
|
|
||||||
tag->import_tag_linked = &sub_module->tags[export->index];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8 tag_attribute;
|
|
||||||
uint32 tag_type;
|
|
||||||
const uint8 *p = *p_buf, *p_end = buf_end;
|
const uint8 *p = *p_buf, *p_end = buf_end;
|
||||||
|
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||||
|
WASMModule *sub_module = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* get the one byte attribute */
|
/* get the one byte attribute */
|
||||||
CHECK_BUF(p, p_end, 1);
|
CHECK_BUF(p, p_end, 1);
|
||||||
tag_attribute = read_uint8(p);
|
declare_tag_attribute = read_uint8(p);
|
||||||
if (tag_attribute != 0) {
|
if (declare_tag_attribute != 0) {
|
||||||
set_error_buf(error_buf, error_buf_size, "unknown tag attribute");
|
set_error_buf(error_buf, error_buf_size, "unknown tag attribute");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get type */
|
/* get type */
|
||||||
read_leb_uint32(p, p_end, tag_type);
|
read_leb_uint32(p, p_end, declare_type_index);
|
||||||
/* compare against module->types */
|
/* compare against module->types */
|
||||||
if (tag_type >= parent_module->type_count) {
|
if (declare_type_index >= parent_module->type_count) {
|
||||||
set_error_buf(error_buf, error_buf_size, "unknown tag type");
|
set_error_buf(error_buf, error_buf_size, "unknown tag type");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check, that the type of the referred tag returns void */
|
WASMType *declare_tag_type = parent_module->types[declare_type_index];
|
||||||
WASMType *func_type = (WASMType *)parent_module->types[tag_type];
|
|
||||||
if (func_type->result_count != 0) {
|
/* check, that the type of the declared tag returns void */
|
||||||
|
if (declare_tag_type->result_count != 0) {
|
||||||
set_error_buf(error_buf, error_buf_size,
|
set_error_buf(error_buf, error_buf_size,
|
||||||
"tag type signature does not return void");
|
"tag type signature does not return void");
|
||||||
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||||
|
if (!wasm_runtime_is_built_in_module(sub_module_name)) {
|
||||||
|
sub_module = (WASMModule *)wasm_runtime_load_depended_module(
|
||||||
|
(WASMModuleCommon *)parent_module, sub_module_name, error_buf,
|
||||||
|
error_buf_size);
|
||||||
|
if (!sub_module) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* wasm_loader_resolve_tag checks, that the imported tag
|
||||||
|
* and the declared tag have the same type
|
||||||
|
*/
|
||||||
|
uint32 linked_tag_index = 0;
|
||||||
|
WASMTag *linked_tag = wasm_loader_resolve_tag(
|
||||||
|
sub_module_name, tag_name, declare_tag_type,
|
||||||
|
&linked_tag_index /* out */, error_buf, error_buf_size);
|
||||||
|
if (linked_tag) {
|
||||||
|
tag->import_module = sub_module;
|
||||||
|
tag->import_tag_linked = linked_tag;
|
||||||
|
tag->import_tag_index_linked = linked_tag_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/* store to module tag declarations */
|
/* store to module tag declarations */
|
||||||
tag->attribute = tag_attribute;
|
tag->attribute = declare_tag_attribute;
|
||||||
tag->type = tag_type;
|
tag->type = declare_type_index;
|
||||||
|
|
||||||
|
tag->module_name = (char *)sub_module_name;
|
||||||
|
tag->field_name = (char *)tag_name;
|
||||||
|
tag->tag_type = declare_tag_type;
|
||||||
|
|
||||||
*p_buf = p;
|
*p_buf = p;
|
||||||
(void)parent_module;
|
(void)parent_module;
|
||||||
|
|
||||||
LOG_VERBOSE("Load tag import success\n");
|
LOG_VERBOSE("Load tag import success\n");
|
||||||
return true;
|
|
||||||
|
|
||||||
|
return true;
|
||||||
fail:
|
fail:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2671,28 +2712,30 @@ load_tag_section(const uint8 *buf, const uint8 *buf_end, const uint8 *buf_code,
|
||||||
const uint8 *buf_code_end, WASMModule *module, char *error_buf,
|
const uint8 *buf_code_end, WASMModule *module, char *error_buf,
|
||||||
uint32 error_buf_size)
|
uint32 error_buf_size)
|
||||||
{
|
{
|
||||||
LOG_VERBOSE("In %s\n", __FUNCTION__);
|
(void)buf_code;
|
||||||
|
(void)buf_code_end;
|
||||||
|
|
||||||
const uint8 *p = buf, *p_end = buf_end;
|
const uint8 *p = buf, *p_end = buf_end;
|
||||||
size_t total_size = 0;
|
size_t total_size = 0;
|
||||||
/* number of tags defined in the section */
|
/* number of tags defined in the section */
|
||||||
uint32 section_tag_count = 0;
|
uint32 section_tag_count = 0;
|
||||||
uint8 tag_attribute;
|
uint8 tag_attribute;
|
||||||
uint32 tag_type;
|
uint32 tag_type;
|
||||||
|
WASMTag *tag = NULL;
|
||||||
|
|
||||||
/* get tag count */
|
/* get tag count */
|
||||||
read_leb_uint32(p, p_end, section_tag_count);
|
read_leb_uint32(p, p_end, section_tag_count);
|
||||||
module->tag_count = module->import_tag_count + section_tag_count;
|
module->tag_count = section_tag_count;
|
||||||
|
|
||||||
if (section_tag_count) {
|
if (section_tag_count) {
|
||||||
total_size = sizeof(WASMTag) * module->tag_count;
|
total_size = sizeof(WASMTag *) * module->tag_count;
|
||||||
if (!(module->tags =
|
if (!(module->tags =
|
||||||
loader_malloc(total_size, error_buf, error_buf_size))) {
|
loader_malloc(total_size, error_buf, error_buf_size))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* load each tag, imported tags precede the tags */
|
/* load each tag, imported tags precede the tags */
|
||||||
uint32 tag_index;
|
uint32 tag_index;
|
||||||
for (tag_index = module->import_tag_count;
|
for (tag_index = 0; tag_index < section_tag_count; tag_index++) {
|
||||||
tag_index < module->tag_count; tag_index++) {
|
|
||||||
|
|
||||||
/* get the one byte attribute */
|
/* get the one byte attribute */
|
||||||
CHECK_BUF(p, p_end, 1);
|
CHECK_BUF(p, p_end, 1);
|
||||||
|
@ -2716,9 +2759,15 @@ load_tag_section(const uint8 *buf, const uint8 *buf_end, const uint8 *buf_code,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(tag = module->tags[tag_index] = loader_malloc(
|
||||||
|
sizeof(WASMTag), error_buf, error_buf_size))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* store to module tag declarations */
|
/* store to module tag declarations */
|
||||||
module->tags[tag_index].attribute = tag_attribute;
|
tag->attribute = tag_attribute;
|
||||||
module->tags[tag_index].type = tag_type;
|
tag->type = tag_type;
|
||||||
|
tag->tag_type = func_type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4414,6 +4463,16 @@ wasm_loader_unload(WASMModule *module)
|
||||||
if (module->memories)
|
if (module->memories)
|
||||||
wasm_runtime_free(module->memories);
|
wasm_runtime_free(module->memories);
|
||||||
|
|
||||||
|
#if WASM_ENABLE_TAGS != 0
|
||||||
|
if (module->tags) {
|
||||||
|
for (i = 0; i < module->tag_count; i++) {
|
||||||
|
if (module->tags[i])
|
||||||
|
wasm_runtime_free(module->tags[i]);
|
||||||
|
}
|
||||||
|
wasm_runtime_free(module->tags);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (module->globals)
|
if (module->globals)
|
||||||
wasm_runtime_free(module->globals);
|
wasm_runtime_free(module->globals);
|
||||||
|
|
||||||
|
@ -7095,7 +7154,6 @@ check_block_stack(WASMLoaderContext *loader_ctx, BranchBlock *block,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check stack cell num equals return cell num */
|
|
||||||
if (available_stack_cell != return_cell_num) {
|
if (available_stack_cell != return_cell_num) {
|
||||||
#if WASM_ENABLE_EXCE_HANDLING != 0
|
#if WASM_ENABLE_EXCE_HANDLING != 0
|
||||||
/* testspec: this error message format is expected by try_catch.wast */
|
/* testspec: this error message format is expected by try_catch.wast */
|
||||||
|
@ -7597,30 +7655,58 @@ re_scan:
|
||||||
|
|
||||||
/* check validity of tag_index against module->tag_count */
|
/* check validity of tag_index against module->tag_count */
|
||||||
/* check tag index is within the tag index space */
|
/* check tag index is within the tag index space */
|
||||||
if (tag_index >= module->tag_count) {
|
if (tag_index >= module->import_tag_count + module->tag_count) {
|
||||||
set_error_buf(error_buf, error_buf_size,
|
snprintf(error_buf, error_buf_size, "unknown tag %d",
|
||||||
"unknown tag index");
|
tag_index);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the index of the type stored in the tag declaration */
|
/* the tag_type is stored in either the WASMTag (section tags)
|
||||||
uint8 tag_type_index = module->tags[tag_index].type;
|
* or WASMTagImport (import tag) */
|
||||||
|
WASMType *tag_type = NULL;
|
||||||
/* check validity of tag_type_index */
|
if (tag_index < module->import_tag_count) {
|
||||||
if (tag_type_index >= module->type_count) {
|
tag_type = module->import_tags[tag_index].u.tag.tag_type;
|
||||||
set_error_buf(error_buf, error_buf_size,
|
}
|
||||||
"unknown tag type index");
|
else {
|
||||||
goto fail;
|
tag_type =
|
||||||
|
module->tags[tag_index - module->import_tag_count]
|
||||||
|
->tag_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check, that the type of the referred tag returns void */
|
if (tag_type->result_count != 0) {
|
||||||
WASMType *func_type = (WASMType *)module->types[tag_type_index];
|
|
||||||
if (func_type->result_count != 0) {
|
|
||||||
set_error_buf(error_buf, error_buf_size,
|
set_error_buf(error_buf, error_buf_size,
|
||||||
"tag type signature does not return void");
|
"tag type signature does not return void");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 available_stack_cell =
|
||||||
|
(int32)(loader_ctx->stack_cell_num
|
||||||
|
- cur_block->stack_cell_num);
|
||||||
|
|
||||||
|
/* Check stack values match return types by comparing tag param
|
||||||
|
* types with stack cells */
|
||||||
|
uint8 *frame_ref = loader_ctx->frame_ref;
|
||||||
|
for (int tti = (int32)tag_type->param_count - 1; tti >= 0;
|
||||||
|
tti--) {
|
||||||
|
if (!check_stack_top_values(frame_ref, available_stack_cell,
|
||||||
|
tag_type->types[tti], error_buf,
|
||||||
|
error_buf_size)) {
|
||||||
|
snprintf(error_buf, error_buf_size,
|
||||||
|
"type mismatch: instruction requires [%s] but "
|
||||||
|
"stack has [%s]",
|
||||||
|
tag_type->param_count > 0
|
||||||
|
? type2str(tag_type->types[tti])
|
||||||
|
: "",
|
||||||
|
available_stack_cell > 0
|
||||||
|
? type2str(*(loader_ctx->frame_ref - 1))
|
||||||
|
: "");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
frame_ref -= wasm_value_type_cell_num(tag_type->types[tti]);
|
||||||
|
available_stack_cell -=
|
||||||
|
wasm_value_type_cell_num(tag_type->types[tti]);
|
||||||
|
}
|
||||||
|
|
||||||
/* throw is stack polymorphic */
|
/* throw is stack polymorphic */
|
||||||
(void)label_type;
|
(void)label_type;
|
||||||
RESET_STACK();
|
RESET_STACK();
|
||||||
|
@ -7683,23 +7769,25 @@ re_scan:
|
||||||
|
|
||||||
/* check validity of tag_index against module->tag_count */
|
/* check validity of tag_index against module->tag_count */
|
||||||
/* check tag index is within the tag index space */
|
/* check tag index is within the tag index space */
|
||||||
if (tag_index >= module->tag_count) {
|
if (tag_index >= module->import_tag_count + module->tag_count) {
|
||||||
|
LOG_VERBOSE("In %s, unknown tag at WASM_OP_CATCH\n",
|
||||||
|
__FUNCTION__);
|
||||||
set_error_buf(error_buf, error_buf_size, "unknown tag");
|
set_error_buf(error_buf, error_buf_size, "unknown tag");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the index of the type stored in the tag declaration */
|
/* the tag_type is stored in either the WASMTag (section tags)
|
||||||
uint8 tag_type_index = module->tags[tag_index].type;
|
* or WASMTagImport (import tag) */
|
||||||
|
WASMType *func_type = NULL;
|
||||||
/* check validity of tag_type_index */
|
if (tag_index < module->import_tag_count) {
|
||||||
if (tag_type_index >= module->type_count) {
|
func_type = module->import_tags[tag_index].u.tag.tag_type;
|
||||||
set_error_buf(error_buf, error_buf_size,
|
}
|
||||||
"unknown tag type index");
|
else {
|
||||||
goto fail;
|
func_type =
|
||||||
|
module->tags[tag_index - module->import_tag_count]
|
||||||
|
->tag_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check, that the type of the referred tag returns void */
|
|
||||||
WASMType *func_type = module->types[tag_type_index];
|
|
||||||
if (func_type->result_count != 0) {
|
if (func_type->result_count != 0) {
|
||||||
set_error_buf(error_buf, error_buf_size,
|
set_error_buf(error_buf, error_buf_size,
|
||||||
"tag type signature does not return void");
|
"tag type signature does not return void");
|
||||||
|
@ -7717,7 +7805,7 @@ re_scan:
|
||||||
|
|
||||||
BlockType new_block_type;
|
BlockType new_block_type;
|
||||||
new_block_type.is_value_type = false;
|
new_block_type.is_value_type = false;
|
||||||
new_block_type.u.type = module->types[tag_type_index];
|
new_block_type.u.type = func_type;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* replace frame_csp by LABEL_TYPE_CATCH
|
* replace frame_csp by LABEL_TYPE_CATCH
|
||||||
|
|
|
@ -738,6 +738,101 @@ functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
|
||||||
return functions;
|
return functions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WASM_ENABLE_TAGS != 0
|
||||||
|
/**
|
||||||
|
* Destroy tags instances.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
tags_deinstantiate(WASMTagInstance *tags, void **import_tag_ptrs)
|
||||||
|
{
|
||||||
|
if (tags) {
|
||||||
|
wasm_runtime_free(tags);
|
||||||
|
}
|
||||||
|
if (import_tag_ptrs) {
|
||||||
|
wasm_runtime_free(import_tag_ptrs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate tags in a module.
|
||||||
|
*/
|
||||||
|
static WASMTagInstance *
|
||||||
|
tags_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
|
||||||
|
char *error_buf, uint32 error_buf_size)
|
||||||
|
{
|
||||||
|
WASMImport *import;
|
||||||
|
uint32 i, tag_count = module->import_tag_count + module->tag_count;
|
||||||
|
uint64 total_size = sizeof(WASMTagInstance) * (uint64)tag_count;
|
||||||
|
WASMTagInstance *tags, *tag;
|
||||||
|
|
||||||
|
if (!(tags = runtime_malloc(total_size, error_buf, error_buf_size))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
total_size = sizeof(void *) * (uint64)module->import_tag_count;
|
||||||
|
if (total_size > 0
|
||||||
|
&& !(module_inst->e->import_tag_ptrs =
|
||||||
|
runtime_malloc(total_size, error_buf, error_buf_size))) {
|
||||||
|
wasm_runtime_free(tags);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* instantiate tags from import section */
|
||||||
|
tag = tags;
|
||||||
|
import = module->import_tags;
|
||||||
|
for (i = 0; i < module->import_tag_count; i++, import++) {
|
||||||
|
tag->is_import_tag = true;
|
||||||
|
tag->u.tag_import = &import->u.tag;
|
||||||
|
tag->type = import->u.tag.type;
|
||||||
|
tag->attribute = import->u.tag.attribute;
|
||||||
|
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||||
|
if (import->u.tag.import_module) {
|
||||||
|
if (!(tag->import_module_inst = get_sub_module_inst(
|
||||||
|
module_inst, import->u.tag.import_module))) {
|
||||||
|
set_error_buf(error_buf, error_buf_size, "unknown tag");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(tag->import_tag_inst =
|
||||||
|
wasm_lookup_tag(tag->import_module_inst,
|
||||||
|
import->u.tag.field_name, NULL))) {
|
||||||
|
set_error_buf(error_buf, error_buf_size, "unknown tag");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the imported tag to current instance */
|
||||||
|
module_inst->e->import_tag_ptrs[i] =
|
||||||
|
tag->u.tag_import->import_tag_linked;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
tag++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* instantiate tags from tag section */
|
||||||
|
for (i = 0; i < module->tag_count; i++) {
|
||||||
|
tag->is_import_tag = false;
|
||||||
|
tag->type = module->tags[i]->type;
|
||||||
|
tag->u.tag = module->tags[i];
|
||||||
|
|
||||||
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
|
/* tag->const_cell_num = function->u.func->const_cell_num; */
|
||||||
|
#endif
|
||||||
|
tag++;
|
||||||
|
}
|
||||||
|
bh_assert((uint32)(tag - tags) == tag_count);
|
||||||
|
|
||||||
|
return tags;
|
||||||
|
|
||||||
|
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||||
|
fail:
|
||||||
|
tags_deinstantiate(tags, module_inst->e->import_tag_ptrs);
|
||||||
|
/* clean up */
|
||||||
|
module_inst->e->import_tag_ptrs = NULL;
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy global instances.
|
* Destroy global instances.
|
||||||
*/
|
*/
|
||||||
|
@ -937,6 +1032,52 @@ export_functions_instantiate(const WASMModule *module,
|
||||||
return export_funcs;
|
return export_funcs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WASM_ENABLE_TAGS != 0
|
||||||
|
/**
|
||||||
|
* Destroy export function instances.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
export_tags_deinstantiate(WASMExportTagInstance *tags)
|
||||||
|
{
|
||||||
|
if (tags)
|
||||||
|
wasm_runtime_free(tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate export functions in a module.
|
||||||
|
*/
|
||||||
|
static WASMExportTagInstance *
|
||||||
|
export_tags_instantiate(const WASMModule *module,
|
||||||
|
WASMModuleInstance *module_inst,
|
||||||
|
uint32 export_tag_count, char *error_buf,
|
||||||
|
uint32 error_buf_size)
|
||||||
|
{
|
||||||
|
WASMExportTagInstance *export_tags, *export_tag;
|
||||||
|
WASMExport *export = module->exports;
|
||||||
|
uint32 i;
|
||||||
|
uint64 total_size =
|
||||||
|
sizeof(WASMExportTagInstance) * (uint64)export_tag_count;
|
||||||
|
|
||||||
|
if (!(export_tag = export_tags =
|
||||||
|
runtime_malloc(total_size, error_buf, error_buf_size))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < module->export_count; i++, export ++)
|
||||||
|
if (export->kind == EXPORT_KIND_TAG) {
|
||||||
|
export_tag->name = export->name;
|
||||||
|
|
||||||
|
bh_assert((uint32)(module_inst->export_tags));
|
||||||
|
|
||||||
|
export_tag->tag = &module_inst->e->tags[export->index];
|
||||||
|
export_tag++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bh_assert((uint32)(export_tag - export_tags) == export_tag_count);
|
||||||
|
return export_tags;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||||
static void
|
static void
|
||||||
export_globals_deinstantiate(WASMExportGlobInstance *globals)
|
export_globals_deinstantiate(WASMExportGlobInstance *globals)
|
||||||
|
@ -1693,6 +1834,9 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
||||||
module_inst->table_count = module->import_table_count + module->table_count;
|
module_inst->table_count = module->import_table_count + module->table_count;
|
||||||
module_inst->e->function_count =
|
module_inst->e->function_count =
|
||||||
module->import_function_count + module->function_count;
|
module->import_function_count + module->function_count;
|
||||||
|
#if WASM_ENABLE_TAGS != 0
|
||||||
|
module_inst->e->tag_count = module->import_tag_count + module->tag_count;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* export */
|
/* export */
|
||||||
module_inst->export_func_count = get_export_count(module, EXPORT_KIND_FUNC);
|
module_inst->export_func_count = get_export_count(module, EXPORT_KIND_FUNC);
|
||||||
|
@ -1701,11 +1845,15 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
||||||
get_export_count(module, EXPORT_KIND_TABLE);
|
get_export_count(module, EXPORT_KIND_TABLE);
|
||||||
module_inst->export_memory_count =
|
module_inst->export_memory_count =
|
||||||
get_export_count(module, EXPORT_KIND_MEMORY);
|
get_export_count(module, EXPORT_KIND_MEMORY);
|
||||||
|
#if WASM_ENABLE_TAGS != 0
|
||||||
|
module_inst->e->export_tag_count =
|
||||||
|
get_export_count(module, EXPORT_KIND_TAG);
|
||||||
|
#endif
|
||||||
module_inst->export_global_count =
|
module_inst->export_global_count =
|
||||||
get_export_count(module, EXPORT_KIND_GLOBAL);
|
get_export_count(module, EXPORT_KIND_GLOBAL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Instantiate memories/tables/functions */
|
/* Instantiate memories/tables/functions/tags */
|
||||||
if ((module_inst->memory_count > 0
|
if ((module_inst->memory_count > 0
|
||||||
&& !(module_inst->memories =
|
&& !(module_inst->memories =
|
||||||
memories_instantiate(module, module_inst, parent, heap_size,
|
memories_instantiate(module, module_inst, parent, heap_size,
|
||||||
|
@ -1721,6 +1869,15 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
||||||
&& !(module_inst->export_functions = export_functions_instantiate(
|
&& !(module_inst->export_functions = export_functions_instantiate(
|
||||||
module, module_inst, module_inst->export_func_count,
|
module, module_inst, module_inst->export_func_count,
|
||||||
error_buf, error_buf_size)))
|
error_buf, error_buf_size)))
|
||||||
|
#if WASM_ENABLE_TAGS != 0
|
||||||
|
|| (module_inst->e->tag_count > 0
|
||||||
|
&& !(module_inst->e->tags = tags_instantiate(
|
||||||
|
module, module_inst, error_buf, error_buf_size)))
|
||||||
|
|| (module_inst->e->export_tag_count > 0
|
||||||
|
&& !(module_inst->e->export_tags = export_tags_instantiate(
|
||||||
|
module, module_inst, module_inst->e->export_tag_count,
|
||||||
|
error_buf, error_buf_size)))
|
||||||
|
#endif
|
||||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||||
|| (module_inst->export_global_count > 0
|
|| (module_inst->export_global_count > 0
|
||||||
&& !(module_inst->export_globals = export_globals_instantiate(
|
&& !(module_inst->export_globals = export_globals_instantiate(
|
||||||
|
@ -1738,7 +1895,6 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
||||||
) {
|
) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (global_count > 0) {
|
if (global_count > 0) {
|
||||||
/* Initialize the global data */
|
/* Initialize the global data */
|
||||||
global_data = module_inst->global_data;
|
global_data = module_inst->global_data;
|
||||||
|
@ -2161,8 +2317,16 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst)
|
||||||
tables_deinstantiate(module_inst);
|
tables_deinstantiate(module_inst);
|
||||||
functions_deinstantiate(module_inst->e->functions,
|
functions_deinstantiate(module_inst->e->functions,
|
||||||
module_inst->e->function_count);
|
module_inst->e->function_count);
|
||||||
|
#if WASM_ENABLE_TAGS != 0
|
||||||
|
tags_deinstantiate(module_inst->e->tags, module_inst->e->import_tag_ptrs);
|
||||||
|
#endif
|
||||||
|
|
||||||
globals_deinstantiate(module_inst->e->globals);
|
globals_deinstantiate(module_inst->e->globals);
|
||||||
export_functions_deinstantiate(module_inst->export_functions);
|
export_functions_deinstantiate(module_inst->export_functions);
|
||||||
|
#if WASM_ENABLE_TAGS != 0
|
||||||
|
export_tags_deinstantiate(module_inst->e->export_tags);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||||
export_globals_deinstantiate(module_inst->export_globals);
|
export_globals_deinstantiate(module_inst->export_globals);
|
||||||
#endif
|
#endif
|
||||||
|
@ -2236,6 +2400,21 @@ wasm_lookup_table(const WASMModuleInstance *module_inst, const char *name)
|
||||||
(void)module_inst->export_tables;
|
(void)module_inst->export_tables;
|
||||||
return module_inst->tables[0];
|
return module_inst->tables[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WASM_ENABLE_TAGS != 0
|
||||||
|
WASMTagInstance *
|
||||||
|
wasm_lookup_tag(const WASMModuleInstance *module_inst, const char *name,
|
||||||
|
const char *signature)
|
||||||
|
{
|
||||||
|
uint32 i;
|
||||||
|
for (i = 0; i < module_inst->e->export_tag_count; i++)
|
||||||
|
if (!strcmp(module_inst->e->export_tags[i].name, name))
|
||||||
|
return module_inst->e->export_tags[i].tag;
|
||||||
|
(void)signature;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
||||||
|
|
|
@ -27,6 +27,9 @@ typedef struct WASMFunctionInstance WASMFunctionInstance;
|
||||||
typedef struct WASMMemoryInstance WASMMemoryInstance;
|
typedef struct WASMMemoryInstance WASMMemoryInstance;
|
||||||
typedef struct WASMTableInstance WASMTableInstance;
|
typedef struct WASMTableInstance WASMTableInstance;
|
||||||
typedef struct WASMGlobalInstance WASMGlobalInstance;
|
typedef struct WASMGlobalInstance WASMGlobalInstance;
|
||||||
|
#if WASM_ENABLE_TAGS != 0
|
||||||
|
typedef struct WASMTagInstance WASMTagInstance;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When LLVM JIT, WAMR compiler or AOT is enabled, we should ensure that
|
* When LLVM JIT, WAMR compiler or AOT is enabled, we should ensure that
|
||||||
|
@ -183,6 +186,30 @@ struct WASMFunctionInstance {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if WASM_ENABLE_TAGS != 0
|
||||||
|
struct WASMTagInstance {
|
||||||
|
bool is_import_tag;
|
||||||
|
/* tag attribute */
|
||||||
|
uint8 attribute;
|
||||||
|
/* tag type index */
|
||||||
|
uint32 type;
|
||||||
|
union {
|
||||||
|
WASMTagImport *tag_import;
|
||||||
|
WASMTag *tag;
|
||||||
|
} u;
|
||||||
|
|
||||||
|
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||||
|
WASMModuleInstance *import_module_inst;
|
||||||
|
WASMTagInstance *import_tag_inst;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if WASM_ENABLE_EXCE_HANDLING != 0
|
||||||
|
#define INVALID_TAGINDEX ((uint32)0xFFFFFFFF)
|
||||||
|
#define SET_INVALID_TAGINDEX(tag) (tag = INVALID_TAGINDEX)
|
||||||
|
#define IS_INVALID_TAGINDEX(tag) ((tag & INVALID_TAGINDEX) == INVALID_TAGINDEX)
|
||||||
|
#endif
|
||||||
typedef struct WASMExportFuncInstance {
|
typedef struct WASMExportFuncInstance {
|
||||||
char *name;
|
char *name;
|
||||||
WASMFunctionInstance *function;
|
WASMFunctionInstance *function;
|
||||||
|
@ -203,6 +230,13 @@ typedef struct WASMExportMemInstance {
|
||||||
WASMMemoryInstance *memory;
|
WASMMemoryInstance *memory;
|
||||||
} WASMExportMemInstance;
|
} WASMExportMemInstance;
|
||||||
|
|
||||||
|
#if WASM_ENABLE_TAGS != 0
|
||||||
|
typedef struct WASMExportTagInstance {
|
||||||
|
char *name;
|
||||||
|
WASMTagInstance *tag;
|
||||||
|
} WASMExportTagInstance;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* wasm-c-api import function info */
|
/* wasm-c-api import function info */
|
||||||
typedef struct CApiFuncImport {
|
typedef struct CApiFuncImport {
|
||||||
/* host func pointer after linked */
|
/* host func pointer after linked */
|
||||||
|
@ -249,6 +283,14 @@ typedef struct WASMModuleInstanceExtra {
|
||||||
WASMTableInstance **table_insts_linked;
|
WASMTableInstance **table_insts_linked;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if WASM_ENABLE_TAGS != 0
|
||||||
|
uint32 tag_count;
|
||||||
|
uint32 export_tag_count;
|
||||||
|
WASMTagInstance *tags;
|
||||||
|
WASMExportTagInstance *export_tags;
|
||||||
|
void **import_tag_ptrs;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if WASM_ENABLE_MEMORY_PROFILING != 0
|
#if WASM_ENABLE_MEMORY_PROFILING != 0
|
||||||
uint32 max_aux_stack_used;
|
uint32 max_aux_stack_used;
|
||||||
#endif
|
#endif
|
||||||
|
@ -440,6 +482,13 @@ wasm_lookup_memory(const WASMModuleInstance *module_inst, const char *name);
|
||||||
|
|
||||||
WASMTableInstance *
|
WASMTableInstance *
|
||||||
wasm_lookup_table(const WASMModuleInstance *module_inst, const char *name);
|
wasm_lookup_table(const WASMModuleInstance *module_inst, const char *name);
|
||||||
|
|
||||||
|
#if WASM_ENABLE_TAGS != 0
|
||||||
|
WASMTagInstance *
|
||||||
|
wasm_lookup_tag(const WASMModuleInstance *module_inst, const char *name,
|
||||||
|
const char *signature);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -50,6 +50,7 @@ SPEC_TEST_DIR = "spec/test/core"
|
||||||
WAST2WASM_CMD = exe_file_path("./wabt/out/gcc/Release/wat2wasm")
|
WAST2WASM_CMD = exe_file_path("./wabt/out/gcc/Release/wat2wasm")
|
||||||
SPEC_INTERPRETER_CMD = "spec/interpreter/wasm"
|
SPEC_INTERPRETER_CMD = "spec/interpreter/wasm"
|
||||||
WAMRC_CMD = "../../../wamr-compiler/build/wamrc"
|
WAMRC_CMD = "../../../wamr-compiler/build/wamrc"
|
||||||
|
EXCE_HANDLING_DIR = "exception-handling/test/core"
|
||||||
|
|
||||||
|
|
||||||
class TargetAction(argparse.Action):
|
class TargetAction(argparse.Action):
|
||||||
|
@ -84,12 +85,6 @@ def ignore_the_case(
|
||||||
eh_flag=False,
|
eh_flag=False,
|
||||||
qemu_flag=False,
|
qemu_flag=False,
|
||||||
):
|
):
|
||||||
# print(f"case_name {case_name}\n")
|
|
||||||
if eh_flag:
|
|
||||||
if case_name in [ "tag", "try_catch", "rethrow", "try_delegate" ]:
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
|
|
||||||
if case_name in ["comments", "inline-module", "names"]:
|
if case_name in ["comments", "inline-module", "names"]:
|
||||||
return True
|
return True
|
||||||
|
@ -138,10 +133,6 @@ def ignore_the_case(
|
||||||
|
|
||||||
|
|
||||||
def preflight_check(aot_flag, eh_flag):
|
def preflight_check(aot_flag, eh_flag):
|
||||||
global SPEC_TEST_DIR
|
|
||||||
if eh_flag:
|
|
||||||
SPEC_TEST_DIR="exception-handling/test/core"
|
|
||||||
|
|
||||||
if not pathlib.Path(SPEC_TEST_DIR).resolve().exists():
|
if not pathlib.Path(SPEC_TEST_DIR).resolve().exists():
|
||||||
print(f"Can not find {SPEC_TEST_DIR}")
|
print(f"Can not find {SPEC_TEST_DIR}")
|
||||||
return False
|
return False
|
||||||
|
@ -154,6 +145,10 @@ def preflight_check(aot_flag, eh_flag):
|
||||||
print(f"Can not find {WAMRC_CMD}")
|
print(f"Can not find {WAMRC_CMD}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
if eh_flag and not pathlib.Path(EXCE_HANDLING_DIR).resolve().exists():
|
||||||
|
print(f"Can not find {EXCE_HANDLING_DIR}")
|
||||||
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@ -297,10 +292,6 @@ def test_suite(
|
||||||
log="",
|
log="",
|
||||||
no_pty=False,
|
no_pty=False,
|
||||||
):
|
):
|
||||||
global SPEC_TEST_DIR
|
|
||||||
if eh_flag:
|
|
||||||
SPEC_TEST_DIR="exception-handling/test/core"
|
|
||||||
|
|
||||||
suite_path = pathlib.Path(SPEC_TEST_DIR).resolve()
|
suite_path = pathlib.Path(SPEC_TEST_DIR).resolve()
|
||||||
if not suite_path.exists():
|
if not suite_path.exists():
|
||||||
print(f"can not find spec test cases at {suite_path}")
|
print(f"can not find spec test cases at {suite_path}")
|
||||||
|
@ -315,6 +306,15 @@ def test_suite(
|
||||||
gc_case_list = sorted(suite_path.glob("gc/*.wast"))
|
gc_case_list = sorted(suite_path.glob("gc/*.wast"))
|
||||||
case_list.extend(gc_case_list)
|
case_list.extend(gc_case_list)
|
||||||
|
|
||||||
|
if eh_flag:
|
||||||
|
eh_path = pathlib.Path(EXCE_HANDLING_DIR).resolve()
|
||||||
|
if not eh_path.exists():
|
||||||
|
print(f"can not find spec test cases at {eh_path}")
|
||||||
|
return False
|
||||||
|
eh_case_list = sorted(eh_path.glob("*.wast"))
|
||||||
|
eh_case_list_include = [test for test in eh_case_list if test.stem in ["throw", "tag", "try_catch", "rethrow", "try_delegate"]]
|
||||||
|
case_list.extend(eh_case_list_include)
|
||||||
|
|
||||||
# ignore based on command line options
|
# ignore based on command line options
|
||||||
filtered_case_list = []
|
filtered_case_list = []
|
||||||
for case_path in case_list:
|
for case_path in case_list:
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
diff --git a/test/core/try_catch.wast b/test/core/try_catch.wast
|
||||||
|
index 2a0e9ff6..f243489d 100644
|
||||||
|
--- a/test/core/try_catch.wast
|
||||||
|
+++ b/test/core/try_catch.wast
|
||||||
|
@@ -203,7 +203,6 @@
|
||||||
|
|
||||||
|
(assert_return (invoke "catch-param-i32" (i32.const 5)) (i32.const 5))
|
||||||
|
|
||||||
|
-(assert_return (invoke "catch-imported") (i32.const 2))
|
||||||
|
|
||||||
|
(assert_return (invoke "catchless-try" (i32.const 0)) (i32.const 0))
|
||||||
|
(assert_return (invoke "catchless-try" (i32.const 1)) (i32.const 1))
|
||||||
|
@@ -231,7 +230,6 @@
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
-(assert_return (invoke "imported-mismatch") (i32.const 3))
|
||||||
|
|
||||||
|
(assert_malformed
|
||||||
|
(module quote "(module (func (catch_all)))")
|
|
@ -427,6 +427,26 @@ function spec_test()
|
||||||
git apply ../../spec-test-script/thread_proposal_fix_atomic_case.patch
|
git apply ../../spec-test-script/thread_proposal_fix_atomic_case.patch
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ ${ENABLE_EH} == 1 ]; then
|
||||||
|
echo "checkout exception-handling test cases"
|
||||||
|
popd
|
||||||
|
if [ ! -d "exception-handling" ];then
|
||||||
|
echo "exception-handling not exist, clone it from github"
|
||||||
|
git clone -b master --single-branch https://github.com/WebAssembly/exception-handling
|
||||||
|
fi
|
||||||
|
pushd exception-handling
|
||||||
|
|
||||||
|
# restore and clean everything
|
||||||
|
git reset --hard 51c721661b671bb7dc4b3a3acb9e079b49778d36
|
||||||
|
|
||||||
|
if [[ ${ENABLE_MULTI_MODULE} == 0 ]]; then
|
||||||
|
git apply ../../spec-test-script/exception_handling.patch
|
||||||
|
fi
|
||||||
|
|
||||||
|
popd
|
||||||
|
echo $(pwd)
|
||||||
|
fi
|
||||||
|
|
||||||
# update GC cases
|
# update GC cases
|
||||||
if [[ ${ENABLE_GC} == 1 ]]; then
|
if [[ ${ENABLE_GC} == 1 ]]; then
|
||||||
echo "checkout spec for GC proposal"
|
echo "checkout spec for GC proposal"
|
||||||
|
@ -465,6 +485,10 @@ function spec_test()
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ 1 == ${ENABLE_EH} ]]; then
|
||||||
|
ARGS_FOR_SPEC_TEST+="-e "
|
||||||
|
fi
|
||||||
|
|
||||||
# sgx only enable in interp mode and aot mode
|
# sgx only enable in interp mode and aot mode
|
||||||
if [[ ${SGX_OPT} == "--sgx" ]];then
|
if [[ ${SGX_OPT} == "--sgx" ]];then
|
||||||
if [[ $1 == 'classic-interp' || $1 == 'fast-interp' || $1 == 'aot' || $1 == 'fast-jit' ]]; then
|
if [[ $1 == 'classic-interp' || $1 == 'fast-interp' || $1 == 'aot' || $1 == 'fast-jit' ]]; then
|
||||||
|
@ -527,88 +551,6 @@ function spec_test()
|
||||||
echo -e "\nFinish spec tests" | tee -a ${REPORT_DIR}/spec_test_report.txt
|
echo -e "\nFinish spec tests" | tee -a ${REPORT_DIR}/spec_test_report.txt
|
||||||
}
|
}
|
||||||
|
|
||||||
function exception_test()
|
|
||||||
{
|
|
||||||
echo "Now start exception tests"
|
|
||||||
touch ${REPORT_DIR}/exception_test_report.txt
|
|
||||||
|
|
||||||
cd ${WORK_DIR}
|
|
||||||
if [ ! -d "exception-handling" ];then
|
|
||||||
echo "exception-handling not exist, clone it from github"
|
|
||||||
git clone -b master --single-branch https://github.com/WebAssembly/exception-handling
|
|
||||||
fi
|
|
||||||
|
|
||||||
pushd exception-handling
|
|
||||||
|
|
||||||
# restore and clean everything
|
|
||||||
git reset --hard HEAD
|
|
||||||
|
|
||||||
popd
|
|
||||||
echo $(pwd)
|
|
||||||
|
|
||||||
if [ ${WABT_BINARY_RELEASE} == "YES" ]; then
|
|
||||||
echo "download a binary release and install"
|
|
||||||
local WAT2WASM=${WORK_DIR}/wabt/out/gcc/Release/wat2wasm
|
|
||||||
if [ ! -f ${WAT2WASM} ]; then
|
|
||||||
case ${PLATFORM} in
|
|
||||||
linux)
|
|
||||||
WABT_PLATFORM=ubuntu
|
|
||||||
;;
|
|
||||||
darwin)
|
|
||||||
WABT_PLATFORM=macos
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "wabt platform for ${PLATFORM} in unknown"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
if [ ! -f /tmp/wabt-1.0.31-${WABT_PLATFORM}.tar.gz ]; then
|
|
||||||
wget \
|
|
||||||
https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-${WABT_PLATFORM}.tar.gz \
|
|
||||||
-P /tmp
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd /tmp \
|
|
||||||
&& tar zxf wabt-1.0.31-${WABT_PLATFORM}.tar.gz \
|
|
||||||
&& mkdir -p ${WORK_DIR}/wabt/out/gcc/Release/ \
|
|
||||||
&& install wabt-1.0.31/bin/wa* ${WORK_DIR}/wabt/out/gcc/Release/ \
|
|
||||||
&& cd -
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "download source code and compile and install"
|
|
||||||
if [ ! -d "wabt" ];then
|
|
||||||
echo "wabt not exist, clone it from github"
|
|
||||||
git clone --recursive https://github.com/WebAssembly/wabt
|
|
||||||
fi
|
|
||||||
echo "upate wabt"
|
|
||||||
cd wabt
|
|
||||||
git pull
|
|
||||||
git reset --hard origin/main
|
|
||||||
cd ..
|
|
||||||
make -C wabt gcc-release -j 4
|
|
||||||
fi
|
|
||||||
|
|
||||||
ln -sf ${WORK_DIR}/../spec-test-script/all.py .
|
|
||||||
ln -sf ${WORK_DIR}/../spec-test-script/runtest.py .
|
|
||||||
|
|
||||||
local ARGS_FOR_SPEC_TEST="-e --no_clean_up "
|
|
||||||
|
|
||||||
# set log directory
|
|
||||||
ARGS_FOR_SPEC_TEST+="--log ${REPORT_DIR}"
|
|
||||||
|
|
||||||
cd ${WORK_DIR}
|
|
||||||
echo "python3 ./all.py ${ARGS_FOR_SPEC_TEST} | tee -a ${REPORT_DIR}/exception_test_report.txt"
|
|
||||||
python3 ./all.py ${ARGS_FOR_SPEC_TEST} | tee -a ${REPORT_DIR}/exception_test_report.txt
|
|
||||||
if [[ ${PIPESTATUS[0]} -ne 0 ]];then
|
|
||||||
echo -e "\nspec tests FAILED" | tee -a ${REPORT_DIR}/exception_test_report.txt
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
cd -
|
|
||||||
|
|
||||||
echo -e "\nFinish exception tests" | tee -a ${REPORT_DIR}/exception_test_report.txt
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function wasi_test()
|
function wasi_test()
|
||||||
{
|
{
|
||||||
echo "Now start wasi tests"
|
echo "Now start wasi tests"
|
||||||
|
@ -916,7 +858,6 @@ function trigger()
|
||||||
if [[ ${ENABLE_EH} == 1 ]]; then
|
if [[ ${ENABLE_EH} == 1 ]]; then
|
||||||
EXTRA_COMPILE_FLAGS+=" -DWAMR_BUILD_EXCE_HANDLING=1"
|
EXTRA_COMPILE_FLAGS+=" -DWAMR_BUILD_EXCE_HANDLING=1"
|
||||||
EXTRA_COMPILE_FLAGS+=" -DWAMR_BUILD_TAIL_CALL=1"
|
EXTRA_COMPILE_FLAGS+=" -DWAMR_BUILD_TAIL_CALL=1"
|
||||||
EXTRA_COMPILE_FLAGS+=" -DWAMR_BUILD_MULTI_MODULE=1"
|
|
||||||
fi
|
fi
|
||||||
echo "SANITIZER IS" $WAMR_BUILD_SANITIZER
|
echo "SANITIZER IS" $WAMR_BUILD_SANITIZER
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user