From b83450ed1fd98cec4453024f57f892b31851ea50 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 11 Oct 2022 11:16:14 -0500 Subject: Make `Name` a pointer, length pair (#5122) With the goal of supporting null characters (i.e. zero bytes) in strings. Rewrite the underlying interned `IString` to store a `std::string_view` rather than a `const char*`, reduce the number of map lookups necessary to intern a string, and present a more immutable interface. Most importantly, replace the `c_str()` method that returned a `const char*` with a `toString()` method that returns a `std::string`. This new method can correctly handle strings containing null characters. A `const char*` can still be had by calling `data()` on the `std::string_view`, although this usage should be discouraged. This change is NFC in spirit, although not in practice. It does not intend to support any particular new functionality, but it is probably now possible to use strings containing null characters in at least some cases. At least one parser bug is also incidentally fixed. Follow-on PRs will explicitly support and test strings containing nulls for particular use cases. The C API still uses `const char*` to represent strings. As strings containing nulls become better supported by the rest of Binaryen, this will no longer be sufficient. Updating the C and JS APIs to use pointer, length pairs is left as future work. --- src/tools/wasm2js.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/tools/wasm2js.cpp') diff --git a/src/tools/wasm2js.cpp b/src/tools/wasm2js.cpp index 7cecb5f6d..a6430fe12 100644 --- a/src/tools/wasm2js.cpp +++ b/src/tools/wasm2js.cpp @@ -834,7 +834,7 @@ void AssertionEmitter::emit() { )"; Builder wasmBuilder(sexpBuilder.getModule()); - Name asmModule = std::string("ret") + ASM_FUNC.str; + Name asmModule = std::string("ret") + ASM_FUNC.toString(); // Track the last built module. Module wasm; for (size_t i = 0; i < root.size(); ++i) { @@ -843,11 +843,11 @@ void AssertionEmitter::emit() { e[0]->str() == Name("module")) { ModuleUtils::clearModule(wasm); std::stringstream funcNameS; - funcNameS << ASM_FUNC.c_str() << i; + funcNameS << ASM_FUNC << i; std::stringstream moduleNameS; - moduleNameS << "ret" << ASM_FUNC.c_str() << i; - Name funcName(funcNameS.str().c_str()); - asmModule = Name(moduleNameS.str().c_str()); + moduleNameS << "ret" << ASM_FUNC << i; + Name funcName(funcNameS.str()); + asmModule = Name(moduleNameS.str()); options.applyFeatures(wasm); SExpressionWasmBuilder builder(wasm, e, options.profile); emitWasm(wasm, out, flags, options.passOptions, funcName); @@ -857,13 +857,13 @@ void AssertionEmitter::emit() { std::cerr << "skipping " << e << std::endl; continue; } - Name testFuncName(IString(("check" + std::to_string(i)).c_str(), false)); + Name testFuncName("check" + std::to_string(i)); bool isInvoke = (e[0]->str() == Name("invoke")); bool isReturn = (e[0]->str() == Name("assert_return")); bool isReturnNan = (e[0]->str() == Name("assert_return_nan")); if (isInvoke) { emitInvokeFunc(wasmBuilder, wasm, e, testFuncName, asmModule); - out << testFuncName.str << "();\n"; + out << testFuncName << "();\n"; continue; } // Otherwise, this is some form of assertion. @@ -875,7 +875,7 @@ void AssertionEmitter::emit() { emitAssertTrapFunc(wasmBuilder, wasm, e, testFuncName, asmModule); } - out << "if (!" << testFuncName.str << "()) throw 'assertion failed: " << e + out << "if (!" << testFuncName << "()) throw 'assertion failed: " << e << "';\n"; } } -- cgit v1.2.3