diff --git a/src/passes/StringLifting.cpp b/src/passes/StringLifting.cpp index 58e2d28882e..07b7fdd7bcd 100644 --- a/src/passes/StringLifting.cpp +++ b/src/passes/StringLifting.cpp @@ -79,41 +79,45 @@ struct StringLifting : public Pass { } // Imported strings may also be found in the string section. - for (auto& section : module->customSections) { - if (section.name == "string.consts") { - // We found the string consts section. Parse it. - auto copy = section.data; - json::Value array; - array.parse(copy.data(), json::Value::WTF16); - if (!array.isArray()) { + auto stringSectionIter = std::find_if( + module->customSections.begin(), + module->customSections.end(), + [&](CustomSection& section) { return section.name == "string.consts"; }); + if (stringSectionIter != module->customSections.end()) { + // We found the string consts section. Parse it. + auto& section = *stringSectionIter; + auto copy = section.data; + json::Value array; + array.parse(copy.data(), json::Value::WTF16); + if (!array.isArray()) { + Fatal() << "StringLifting: string.const section should be a JSON array"; + } + + // We have the array of constants from the section. Find globals that + // refer to it. + for (auto& global : module->globals) { + if (!global->imported() || global->module != "string.const") { + continue; + } + // The index in the array is the basename. + Index index = std::stoi(std::string(global->base.str)); + if (index >= array.size()) { + Fatal() << "StringLifting: bad index in string.const section"; + } + auto item = array[index]; + if (!item->isString()) { Fatal() - << "StringLifting: string.const section should be a JSON array"; + << "StringLifting: string.const section entry is not a string"; } - - // We have the array of constants from the section. Find globals that - // refer to it. - for (auto& global : module->globals) { - if (!global->imported() || global->module != "string.const") { - continue; - } - // The index in the array is the basename. - Index index = std::stoi(std::string(global->base.str)); - if (index >= array.size()) { - Fatal() << "StringLifting: bad index in string.const section"; - } - auto item = array[index]; - if (!item->isString()) { - Fatal() - << "StringLifting: string.const section entry is not a string"; - } - if (importedStrings.count(global->name)) { - Fatal() - << "StringLifting: string.const section tramples other const"; - } - importedStrings[global->name] = item->getIString(); + if (importedStrings.count(global->name)) { + Fatal() << "StringLifting: string.const section tramples other const"; } - break; + importedStrings[global->name] = item->getIString(); } + + // Remove the custom section: After lifting it has no purpose (and could + // cause problems with repeated lifting/lowering). + module->customSections.erase(stringSectionIter); } auto array16 = Type(Array(Field(Field::i16, Mutable)), Nullable); diff --git a/test/lit/passes/string-lifting-section-erase.wast b/test/lit/passes/string-lifting-section-erase.wast new file mode 100644 index 00000000000..70e59e7c3c7 --- /dev/null +++ b/test/lit/passes/string-lifting-section-erase.wast @@ -0,0 +1,23 @@ +;; Test that the section vanishes after lifting. + +(module + (func $strings + ;; These strings cannot appear as magic imports, and will definitely go in + ;; the strings section. + (drop + (string.const "unpaired high surrogate \ED\A0\80 ") + ) + (drop + (string.const "unpaired low surrogate \ED\BD\88 ") + ) + ) +) + +;; Lower into the section. We should see the section. +;; RUN: wasm-opt %s -all --string-lowering -S -o - | filecheck %s --check-prefix=LOWER +;; LOWER: custom section + +;; Also lift. Now no section should appear. +;; RUN: wasm-opt %s -all --string-lowering --string-lifting -S -o - | filecheck %s --check-prefix=AND_LIFT +;; AND_LIFT-NOT: custom section +