From 8e6fb55ff0d40c5d22c3f66fbec43229ca439dcd Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Wed, 13 Apr 2022 15:48:40 -0700 Subject: [PATCH] Remove signature mangling from wasm2c output This effectively means that we no longer support imports that are overloaded by signature only, which is not something that we need to support in order to support the core wasm spec. This feature is available in the JS embedding but there is no good reason (AFAICT) to support it in wasm2c, and this simplifies the generated code. Fixes #1858 --- src/c-writer.cc | 37 ++++-------------------------------- test/run-spec-wasm2c.py | 14 +------------- test/spec-wasm2c-prefix.c | 18 ++++++++---------- wasm2c/README.md | 17 ++++++++--------- wasm2c/examples/fac/fac.c | 4 ++-- wasm2c/examples/fac/fac.h | 2 +- wasm2c/examples/fac/main.c | 4 ++-- wasm2c/examples/rot13/main.c | 14 +++++++------- 8 files changed, 33 insertions(+), 77 deletions(-) diff --git a/src/c-writer.cc b/src/c-writer.cc index e2bef4a352..8ef32383e1 100644 --- a/src/c-writer.cc +++ b/src/c-writer.cc @@ -161,12 +161,8 @@ class CWriter { static std::string Deref(const std::string&); static char MangleType(Type); - static std::string MangleTypes(const TypeVector&); static std::string MangleMultivalueTypes(const TypeVector&); static std::string MangleName(std::string_view); - static std::string MangleFuncName(std::string_view, - const TypeVector& param_types, - const TypeVector& result_types); static std::string MangleGlobalName(std::string_view, Type); static std::string LegalizeName(std::string_view); static std::string ExportName(std::string_view mangled_name); @@ -395,18 +391,6 @@ char CWriter::MangleType(Type type) { } } -// static -std::string CWriter::MangleTypes(const TypeVector& types) { - if (types.empty()) - return std::string("v"); - - std::string result; - for (auto type : types) { - result += MangleType(type); - } - return result; -} - // static std::string CWriter::MangleMultivalueTypes(const TypeVector& types) { assert(types.size() >= 2); @@ -436,14 +420,6 @@ std::string CWriter::MangleName(std::string_view name) { return result; } -// static -std::string CWriter::MangleFuncName(std::string_view name, - const TypeVector& param_types, - const TypeVector& result_types) { - std::string sig = MangleTypes(result_types) + MangleTypes(param_types); - return MangleName(name) + MangleName(sig); -} - // static std::string CWriter::MangleGlobalName(std::string_view name, Type type) { std::string sig(1, MangleType(type)); @@ -889,12 +865,9 @@ void CWriter::WriteImports() { switch (import->kind()) { case ExternalKind::Func: { const Func& func = cast(import)->func; - WriteFuncDeclaration( - func.decl, - DefineImportName( - func.name, import->module_name, - MangleFuncName(import->field_name, func.decl.sig.param_types, - func.decl.sig.result_types))); + WriteFuncDeclaration(func.decl, + DefineImportName(func.name, import->module_name, + MangleName(import->field_name))); Write(";"); break; } @@ -1177,9 +1150,7 @@ void CWriter::WriteExports(WriteExportsKind kind) { switch (export_->kind) { case ExternalKind::Func: { const Func* func = module_->GetFunc(export_->var); - mangled_name = - ExportName(MangleFuncName(export_->name, func->decl.sig.param_types, - func->decl.sig.result_types)); + mangled_name = ExportName(MangleName(export_->name)); internal_name = func->name; if (kind != WriteExportsKind::Initializers) { WriteFuncDeclaration(func->decl, Deref(mangled_name)); diff --git a/test/run-spec-wasm2c.py b/test/run-spec-wasm2c.py index 7ecdc5f8d1..e9594b67f1 100755 --- a/test/run-spec-wasm2c.py +++ b/test/run-spec-wasm2c.py @@ -311,24 +311,12 @@ def _Compare(self, num, const): def _CompareList(self, consts): return ' && '.join(self._Compare(num, const) for num, const in enumerate(consts)) - def _ActionSig(self, action, expected): - type_ = action['type'] - result_types = [result['type'] for result in expected] - arg_types = [arg['type'] for arg in action.get('args', [])] - if type_ == 'invoke': - return MangleTypes(result_types) + MangleTypes(arg_types) - elif type_ == 'get': - return MangleType(result_types[0]) - else: - raise Error('Unexpected action type: %s' % type_) - def _Action(self, command): action = command['action'] expected = command['expected'] type_ = action['type'] mangled_module_name = self.GetModulePrefix(action.get('module')) - field = (mangled_module_name + MangleName(action['field']) + - MangleName(self._ActionSig(action, expected))) + field = mangled_module_name + MangleName(action['field']) if type_ == 'invoke': return '%s(%s)' % (field, self._ConstantList(action.get('args', []))) elif type_ == 'get': diff --git a/test/spec-wasm2c-prefix.c b/test/spec-wasm2c-prefix.c index bad8f647b4..4415be6f07 100644 --- a/test/spec-wasm2c-prefix.c +++ b/test/spec-wasm2c-prefix.c @@ -235,18 +235,16 @@ static wasm_rt_memory_t spectest_memory; static uint32_t spectest_global_i32 = 666; static uint64_t spectest_global_i64 = 666l; -void (*Z_spectestZ_printZ_vv)(void) = &spectest_print; -void (*Z_spectestZ_print_i32Z_vi)(uint32_t) = &spectest_print_i32; -void (*Z_spectestZ_print_f32Z_vf)(float) = &spectest_print_f32; -void (*Z_spectestZ_print_i32_f32Z_vif)(uint32_t, - float) = &spectest_print_i32_f32; -void (*Z_spectestZ_print_f64Z_vd)(double) = &spectest_print_f64; -void (*Z_spectestZ_print_f64_f64Z_vdd)(double, - double) = &spectest_print_f64_f64; +void (*Z_spectestZ_print)(void) = &spectest_print; +void (*Z_spectestZ_print_i32)(uint32_t) = &spectest_print_i32; +void (*Z_spectestZ_print_f32)(float) = &spectest_print_f32; +void (*Z_spectestZ_print_i32_f32)(uint32_t, float) = &spectest_print_i32_f32; +void (*Z_spectestZ_print_f64)(double) = &spectest_print_f64; +void (*Z_spectestZ_print_f64_f64)(double, double) = &spectest_print_f64_f64; wasm_rt_table_t* Z_spectestZ_table = &spectest_table; wasm_rt_memory_t* Z_spectestZ_memory = &spectest_memory; -uint32_t* Z_spectestZ_global_i32Z_i = &spectest_global_i32; -uint64_t* Z_spectestZ_global_i64Z_j = &spectest_global_i64; +uint32_t* Z_spectestZ_global_i32 = &spectest_global_i32; +uint64_t* Z_spectestZ_global_i64 = &spectest_global_i64; static void init_spectest_module(void) { wasm_rt_allocate_memory(&spectest_memory, 1, 2); diff --git a/wasm2c/README.md b/wasm2c/README.md index 3e335c742b..b68fe57aee 100644 --- a/wasm2c/README.md +++ b/wasm2c/README.md @@ -48,21 +48,21 @@ files. To actually use our fac module, we'll use create a new file, `main.c`, that include `fac.h`, initializes the module, and calls `fac`. -`wasm2c` generates a few symbols for us, `init` and `Z_facZ_ii`. `init` -initializes the module, and `Z_facZ_ii` is our exported `fac` function, but +`wasm2c` generates a few symbols for us, `init` and `Z_fac`. `init` +initializes the module, and `Z_fac` is our exported `fac` function, but [name-mangled](https://en.wikipedia.org/wiki/Name_mangling) to include the function signature. We can define `WASM_RT_MODULE_PREFIX` before including `fac.h` to generate these symbols with a prefix, in case we already have a symbol called `init` (or -even `Z_facZ_ii`!) Note that you'll have to compile `fac.c` with this macro +even `Z_fac`!) Note that you'll have to compile `fac.c` with this macro too, for this to work. ```c #include #include -/* Uncomment this to define fac_init and fac_Z_facZ_ii instead. */ +/* Uncomment this to define fac_init and fac_Z_fac instead. */ /* #define WASM_RT_MODULE_PREFIX fac_ */ #include "fac.h" @@ -83,7 +83,7 @@ int main(int argc, char** argv) { init(); /* Call `fac`, using the mangled name. */ - u32 result = Z_facZ_ii(x); + u32 result = Z_fac(x); /* Print the result. */ printf("fac(%u) -> %u\n", x, result); @@ -138,7 +138,7 @@ extern "C" { extern void WASM_RT_ADD_PREFIX(init)(void); /* export: 'fac' */ -extern u32 (*WASM_RT_ADD_PREFIX(Z_facZ_ii))(u32); +extern u32 (*WASM_RT_ADD_PREFIX(Z_fac))(u32); #ifdef __cplusplus } #endif @@ -345,15 +345,14 @@ the module can be used: extern void WASM_RT_ADD_PREFIX(init)(void); /* export: 'fac' */ -extern u32 (*WASM_RT_ADD_PREFIX(Z_facZ_ii))(u32); +extern u32 (*WASM_RT_ADD_PREFIX(Z_fac))(u32); ``` All exported names use `WASM_RT_ADD_PREFIX` (as described above) to allow the symbols to placed in a namespace as decided by the embedder. All symbols are also mangled so they include the types of the function signature. -In our example, `Z_facZ_ii` is the mangling for a function named `fac` that -takes one `i32` parameter and returns one `i32` result. +In our example, `Z_fac` is the mangling for a function named `fac`. ## A quick look at `fac.c` diff --git a/wasm2c/examples/fac/fac.c b/wasm2c/examples/fac/fac.c index 945c9967e6..b307d0894d 100644 --- a/wasm2c/examples/fac/fac.c +++ b/wasm2c/examples/fac/fac.c @@ -332,11 +332,11 @@ static void init_table(void) { } /* export: 'fac' */ -u32 (*WASM_RT_ADD_PREFIX(Z_facZ_ii))(u32); +u32 (*WASM_RT_ADD_PREFIX(Z_fac))(u32); static void init_exports(void) { /* export: 'fac' */ - WASM_RT_ADD_PREFIX(Z_facZ_ii) = (&w2c_fac); + WASM_RT_ADD_PREFIX(Z_fac) = (&w2c_fac); } void WASM_RT_ADD_PREFIX(init)(void) { diff --git a/wasm2c/examples/fac/fac.h b/wasm2c/examples/fac/fac.h index 41c50d4d4d..9a6a9abaf7 100644 --- a/wasm2c/examples/fac/fac.h +++ b/wasm2c/examples/fac/fac.h @@ -35,7 +35,7 @@ typedef double f64; extern void WASM_RT_ADD_PREFIX(init)(void); /* export: 'fac' */ -extern u32 (*WASM_RT_ADD_PREFIX(Z_facZ_ii))(u32); +extern u32 (*WASM_RT_ADD_PREFIX(Z_fac))(u32); #ifdef __cplusplus } #endif diff --git a/wasm2c/examples/fac/main.c b/wasm2c/examples/fac/main.c index 55255b5d9a..fe79aa947a 100644 --- a/wasm2c/examples/fac/main.c +++ b/wasm2c/examples/fac/main.c @@ -1,7 +1,7 @@ #include #include -/* Uncomment this to define fac_init and fac_Z_facZ_ii instead. */ +/* Uncomment this to define fac_init and fac_Z_fac instead. */ /* #define WASM_RT_MODULE_PREFIX fac_ */ #include "fac.h" @@ -22,7 +22,7 @@ int main(int argc, char** argv) { init(); /* Call `fac`, using the mangled name. */ - u32 result = Z_facZ_ii(x); + u32 result = Z_fac(x); /* Print the result. */ printf("fac(%u) -> %u\n", x, result); diff --git a/wasm2c/examples/rot13/main.c b/wasm2c/examples/rot13/main.c index 19ec799eb9..516329a66f 100644 --- a/wasm2c/examples/rot13/main.c +++ b/wasm2c/examples/rot13/main.c @@ -17,15 +17,15 @@ #include #include -/* Uncomment this to define rot13_init rot13_Z_rot13Z_vv instead. */ +/* Uncomment this to define rot13_init rot13_Z_rot13 instead. */ /* #define WASM_RT_MODULE_PREFIX rot13_ */ #include "rot13.h" /* Define the imports as declared in rot13.h. */ wasm_rt_memory_t (*Z_hostZ_mem); -u32 (*Z_hostZ_fill_bufZ_iii)(u32, u32); -void (*Z_hostZ_buf_doneZ_vii)(u32, u32); +u32 (*Z_hostZ_fill_buf)(u32, u32); +void (*Z_hostZ_buf_done)(u32, u32); /* Define the implementations of the imports. */ static wasm_rt_memory_t s_memory; @@ -49,10 +49,10 @@ int main(int argc, char** argv) { /* Provide the imports expected by the module: "host.mem", "host.fill_buf" * and "host.buf_done". Their mangled names are `Z_hostZ_mem`, - * `Z_hostZ_fill_bufZ_iii` and `Z_hostZ_buf_doneZ_vii`. */ + * `Z_hostZ_fill_bufZ_iii` and `Z_hostZ_buf_done`. */ Z_hostZ_mem = &s_memory; - Z_hostZ_fill_bufZ_iii = &fill_buf; - Z_hostZ_buf_doneZ_vii = &buf_done; + Z_hostZ_fill_buf = &fill_buf; + Z_hostZ_buf_done = &buf_done; /* Call `rot13` on each argument, using the mangled name. */ while (argc > 1) { @@ -60,7 +60,7 @@ int main(int argc, char** argv) { argc--; argv++; s_input = argv[0]; - Z_rot13Z_vv(); + Z_rot13(); } /* Free the Wasm runtime state. */