Implement Exception Handling for classic interpreter (#3096)
This PR adds the initial support for WASM exception handling: * Inside the classic interpreter only: * Initial handling of Tags * Initial handling of Exceptions based on W3C Exception Proposal * Import and Export of Exceptions and Tags * Add `cmake -DWAMR_BUILD_EXCE_HANDLING=1/0` option to enable/disable the feature, and by default it is disabled * Update the wamr-test-suites scripts to test the feature * Additional CI/CD changes to validate the exception spec proposal cases Refer to: https://github.com/bytecodealliance/wasm-micro-runtime/issues/1884587513f3c68bebfe9ad759bccdfed8Signed-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:
@ -732,6 +732,101 @@ functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
|
||||
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.
|
||||
*/
|
||||
@ -931,6 +1026,52 @@ export_functions_instantiate(const WASMModule *module,
|
||||
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
|
||||
static void
|
||||
export_globals_deinstantiate(WASMExportGlobInstance *globals)
|
||||
@ -1720,6 +1861,9 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
||||
module_inst->table_count = module->import_table_count + module->table_count;
|
||||
module_inst->e->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 */
|
||||
module_inst->export_func_count = get_export_count(module, EXPORT_KIND_FUNC);
|
||||
@ -1728,11 +1872,15 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
||||
get_export_count(module, EXPORT_KIND_TABLE);
|
||||
module_inst->export_memory_count =
|
||||
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 =
|
||||
get_export_count(module, EXPORT_KIND_GLOBAL);
|
||||
#endif
|
||||
|
||||
/* Instantiate memories/tables/functions */
|
||||
/* Instantiate memories/tables/functions/tags */
|
||||
if ((module_inst->memory_count > 0
|
||||
&& !(module_inst->memories =
|
||||
memories_instantiate(module, module_inst, parent, heap_size,
|
||||
@ -1748,6 +1896,15 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
||||
&& !(module_inst->export_functions = export_functions_instantiate(
|
||||
module, module_inst, module_inst->export_func_count,
|
||||
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
|
||||
|| (module_inst->export_global_count > 0
|
||||
&& !(module_inst->export_globals = export_globals_instantiate(
|
||||
@ -1765,7 +1922,6 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
||||
) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (global_count > 0) {
|
||||
/* Initialize the global data */
|
||||
global_data = module_inst->global_data;
|
||||
@ -2188,8 +2344,16 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst)
|
||||
tables_deinstantiate(module_inst);
|
||||
functions_deinstantiate(module_inst->e->functions,
|
||||
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);
|
||||
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
|
||||
export_globals_deinstantiate(module_inst->export_globals);
|
||||
#endif
|
||||
@ -2270,6 +2434,21 @@ wasm_lookup_table(const WASMModuleInstance *module_inst, const char *name)
|
||||
(void)module_inst->export_tables;
|
||||
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
|
||||
|
||||
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
||||
|
||||
Reference in New Issue
Block a user