diff options
author | Thomas Lively <tlively@google.com> | 2024-08-21 15:05:22 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-21 15:05:22 -0700 |
commit | 692e55c14bd3055b1aae49681bb8e62c757c678d (patch) | |
tree | 1b25a10166b1cd2dea159f3f59e02dde361a7636 /src | |
parent | 99db0d9c7c33bcea7b7730bb5684f41176146f83 (diff) | |
download | binaryen-692e55c14bd3055b1aae49681bb8e62c757c678d.tar.gz binaryen-692e55c14bd3055b1aae49681bb8e62c757c678d.tar.bz2 binaryen-692e55c14bd3055b1aae49681bb8e62c757c678d.zip |
Add a string lowering mode disallowing non-UTF-8 strings (#6861)
The best way to lower strings is via the "magic imports" API that uses
the names of imported string globals as their values. This approach only
works for valid UTF-8 strings, though. The existing
string-lowering-magic-imports pass falls back to putting non-UTF-8
strings in a JSON custom section, but this requires the runtime to
support that custom section for correctness. To help catch errors early
when runtimes do not support the strings custom section, add a new pass
that uses magic imports and raises an error if there are any invalid
strings.
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/StringLowering.cpp | 21 | ||||
-rw-r--r-- | src/passes/pass.cpp | 4 | ||||
-rw-r--r-- | src/passes/passes.h | 1 |
3 files changed, 24 insertions, 2 deletions
diff --git a/src/passes/StringLowering.cpp b/src/passes/StringLowering.cpp index fa5c1c9a8..92e3268dc 100644 --- a/src/passes/StringLowering.cpp +++ b/src/passes/StringLowering.cpp @@ -194,8 +194,16 @@ struct StringLowering : public StringGathering { // instead of emitting them into the JSON custom section. bool useMagicImports; - StringLowering(bool useMagicImports = false) - : useMagicImports(useMagicImports) {} + // Whether to throw a fatal error on non-UTF8 strings that would not be able + // to use the "magic import" mechanism. Only usable in conjunction with magic + // imports. + bool assertUTF8; + + StringLowering(bool useMagicImports = false, bool assertUTF8 = false) + : useMagicImports(useMagicImports), assertUTF8(assertUTF8) { + // If we are asserting valid UTF-8, we must be using magic imports. + assert(!assertUTF8 || useMagicImports); + } void run(Module* module) override { if (!module->features.has(FeatureSet::Strings)) { @@ -238,6 +246,12 @@ struct StringLowering : public StringGathering { global->module = "'"; global->base = Name(utf8.str()); } else { + if (assertUTF8) { + std::stringstream escaped; + String::printEscaped(escaped, utf8.str()); + Fatal() << "Cannot lower non-UTF-16 string " << escaped.str() + << '\n'; + } global->module = "string.const"; global->base = std::to_string(jsonImportIndex); if (first) { @@ -534,5 +548,8 @@ struct StringLowering : public StringGathering { Pass* createStringGatheringPass() { return new StringGathering(); } Pass* createStringLoweringPass() { return new StringLowering(); } Pass* createStringLoweringMagicImportPass() { return new StringLowering(true); } +Pass* createStringLoweringMagicImportAssertPass() { + return new StringLowering(true, true); +} } // namespace wasm diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index ccfc7b728..35d2f6779 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -503,6 +503,10 @@ void PassRegistry::registerPasses() { "string-lowering-magic-imports", "same as string-lowering, but encodes well-formed strings as magic imports", createStringLoweringMagicImportPass); + registerPass("string-lowering-magic-imports-assert", + "same as string-lowering-magic-imports, but raise a fatal error " + "if there are invalid strings", + createStringLoweringMagicImportAssertPass); registerPass( "strip", "deprecated; same as strip-debug", createStripDebugPass); registerPass("stack-check", diff --git a/src/passes/passes.h b/src/passes/passes.h index 9fcb5f95f..a95365676 100644 --- a/src/passes/passes.h +++ b/src/passes/passes.h @@ -158,6 +158,7 @@ Pass* createStackCheckPass(); Pass* createStringGatheringPass(); Pass* createStringLoweringPass(); Pass* createStringLoweringMagicImportPass(); +Pass* createStringLoweringMagicImportAssertPass(); Pass* createStripDebugPass(); Pass* createStripDWARFPass(); Pass* createStripProducersPass(); |