diff --git a/libdyld/dyld.c b/libdyld/dyld.c index ad8b0ebd..aacfa9fb 100644 --- a/libdyld/dyld.c +++ b/libdyld/dyld.c @@ -61,7 +61,20 @@ static const struct name name_heap_end = NAME_FROM_CSTR_LITERAL("__heap_end"); static const struct name name_main_object = NAME_FROM_CSTR_LITERAL("
"); +#if defined(TOYWASM_ENABLE_WASM_EXCEPTION_HANDLING) +/* + * cf. + * https://github.com/llvm/llvm-project/blob/96c907dbcebdfbc88f73e097270d171bb83ec3cf/llvm/lib/CodeGen/AsmPrinter/WasmException.cpp#L29-L32 + */ +static const struct name name_c_longjmp = + NAME_FROM_CSTR_LITERAL("__c_longjmp"); +static const struct name name_cpp_exception = + NAME_FROM_CSTR_LITERAL("__cpp_exception"); + +static const uint32_t num_shared_entries = 7; +#else static const uint32_t num_shared_entries = 5; +#endif /* * __wasm_apply_data_relocs is generated by wasm-ld. @@ -893,6 +906,15 @@ dyld_create_shared_resources(struct dyld *d) d->heap_base.type = &globaltype_i32_mut; d->heap_end.type = &globaltype_i32_mut; +#if defined(TOYWASM_ENABLE_WASM_EXCEPTION_HANDLING) + ret = functype_from_string("(i)", &d->c_longjmp_ft); + if (ret != 0) { + goto fail; + } + d->c_longjmp.type = d->c_longjmp_ft; + d->cpp_exception.type = d->c_longjmp_ft; +#endif + struct import_object *imp; ret = import_object_alloc(num_shared_entries, &imp); if (ret != 0) { @@ -931,6 +953,20 @@ dyld_create_shared_resources(struct dyld *d) e->u.global = &d->heap_end; e++; +#if defined(TOYWASM_ENABLE_WASM_EXCEPTION_HANDLING) + e->module_name = &name_env; + e->name = &name_c_longjmp; + e->type = EXTERNTYPE_TAG; + e->u.tag = &d->c_longjmp; + e++; + + e->module_name = &name_env; + e->name = &name_cpp_exception; + e->type = EXTERNTYPE_TAG; + e->u.tag = &d->cpp_exception; + e++; +#endif + assert(e == imp->entries + num_shared_entries); imp->next = d->shared_import_obj; d->shared_import_obj = imp; @@ -1332,6 +1368,11 @@ dyld_clear(struct dyld *d) free((void *)it->name.data); /* discard const */ } VEC_FREE(d->dynobjs); +#endif +#if defined(TOYWASM_ENABLE_WASM_EXCEPTION_HANDLING) + if (d->c_longjmp_ft != NULL) { + functype_free(d->c_longjmp_ft); + } #endif memset(d, 0, sizeof(*d)); } diff --git a/libdyld/dyld.h b/libdyld/dyld.h index 847e1756..152f30f9 100644 --- a/libdyld/dyld.h +++ b/libdyld/dyld.h @@ -47,6 +47,11 @@ struct dyld { struct globalinst *stack_pointer; struct globalinst heap_base; struct globalinst heap_end; +#if defined(TOYWASM_ENABLE_WASM_EXCEPTION_HANDLING) + struct functype *c_longjmp_ft; + struct taginst c_longjmp; + struct taginst cpp_exception; +#endif union { struct {