diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/type-updating.cpp | 7 | ||||
-rw-r--r-- | src/ir/type-updating.h | 13 | ||||
-rw-r--r-- | src/passes/StringLowering.cpp | 16 |
3 files changed, 31 insertions, 5 deletions
diff --git a/src/ir/type-updating.cpp b/src/ir/type-updating.cpp index fb701f64a..12a8c7c36 100644 --- a/src/ir/type-updating.cpp +++ b/src/ir/type-updating.cpp @@ -30,7 +30,8 @@ GlobalTypeRewriter::GlobalTypeRewriter(Module& wasm) : wasm(wasm) {} void GlobalTypeRewriter::update() { mapTypes(rebuildTypes()); } -GlobalTypeRewriter::TypeMap GlobalTypeRewriter::rebuildTypes() { +GlobalTypeRewriter::TypeMap GlobalTypeRewriter::rebuildTypes( + const std::vector<HeapType>& additionalPrivateTypes) { // Find the heap types that are not publicly observable. Even in a closed // world scenario, don't modify public types because we assume that they may // be reflected on or used for linking. Figure out where each private type @@ -39,6 +40,10 @@ GlobalTypeRewriter::TypeMap GlobalTypeRewriter::rebuildTypes() { Index i = 0; auto privateTypes = ModuleUtils::getPrivateHeapTypes(wasm); + for (auto t : additionalPrivateTypes) { + privateTypes.push_back(t); + } + // Topological sort to have supertypes first, but we have to account for the // fact that we may be replacing the supertypes to get the order correct. struct SupertypesFirst diff --git a/src/ir/type-updating.h b/src/ir/type-updating.h index ae247b6c7..1626b40bd 100644 --- a/src/ir/type-updating.h +++ b/src/ir/type-updating.h @@ -426,7 +426,12 @@ protected: // Builds new types after updating their contents using the hooks below and // returns a map from the old types to the modified types. Used internally in // update(). - TypeMap rebuildTypes(); + // + // This only operates on private types (so as not to modify the module's + // external ABI). It takes as a parameter a list of public types to consider + // private, which allows more flexibility. + TypeMap + rebuildTypes(const std::vector<HeapType>& additionalPrivateTypes = {}); private: TypeBuilder typeBuilder; @@ -446,10 +451,12 @@ public: TypeMapper(Module& wasm, const TypeUpdates& mapping) : GlobalTypeRewriter(wasm), mapping(mapping) {} - void map() { + // As rebuildTypes, this can take an optional set of additional types to + // consider private (and therefore to modify). + void map(const std::vector<HeapType>& additionalPrivateTypes = {}) { // Update the internals of types (struct fields, signatures, etc.) to // refer to the merged types. - auto newMapping = rebuildTypes(); + auto newMapping = rebuildTypes(additionalPrivateTypes); // Compose the user-provided mapping from old types to other old types with // the new mapping from old types to new types. `newMapping` will become diff --git a/src/passes/StringLowering.cpp b/src/passes/StringLowering.cpp index bdecf648a..f9930d946 100644 --- a/src/passes/StringLowering.cpp +++ b/src/passes/StringLowering.cpp @@ -232,13 +232,27 @@ struct StringLowering : public StringGathering { void updateTypes(Module* module) { TypeMapper::TypeUpdates updates; + // There is no difference between strings and views with imported strings: // they are all just JS strings, so they all turn into externref. updates[HeapType::string] = HeapType::ext; updates[HeapType::stringview_wtf8] = HeapType::ext; updates[HeapType::stringview_wtf16] = HeapType::ext; updates[HeapType::stringview_iter] = HeapType::ext; - TypeMapper(*module, updates).map(); + + // We consider all types that use strings as modifiable, which means we + // mark them as non-private. That is, we are doing something TypeMapper + // normally does not, as we are changing the external interface/ABI of the + // module: we are changing that ABI from using strings to externs. + auto publicTypes = ModuleUtils::getPublicHeapTypes(*module); + std::vector<HeapType> stringUsers; + for (auto t : publicTypes) { + if (Type(t, Nullable).getFeatures().hasStrings()) { + stringUsers.push_back(t); + } + } + + TypeMapper(*module, updates).map(stringUsers); } // Imported string functions. |