Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 8 additions & 22 deletions src/ir/type-updating.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,12 @@ namespace wasm {

GlobalTypeRewriter::GlobalTypeRewriter(Module& wasm) : wasm(wasm) {}

void GlobalTypeRewriter::update(
const std::vector<HeapType>& additionalPrivateTypes) {
mapTypes(rebuildTypes(
getSortedTypes(getPrivatePredecessors(additionalPrivateTypes))));
void GlobalTypeRewriter::update() {
mapTypes(rebuildTypes(getSortedTypes(getPrivatePredecessors())));
}

GlobalTypeRewriter::PredecessorGraph GlobalTypeRewriter::getPrivatePredecessors(
const std::vector<HeapType>& additionalPrivateTypes) {
GlobalTypeRewriter::PredecessorGraph
GlobalTypeRewriter::getPrivatePredecessors() {
// 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
Expand All @@ -45,31 +43,19 @@ GlobalTypeRewriter::PredecessorGraph GlobalTypeRewriter::getPrivatePredecessors(
ModuleUtils::TypeInclusion::UsedIRTypes,
ModuleUtils::VisibilityHandling::FindVisibility);

std::unordered_set<HeapType> additionalSet(additionalPrivateTypes.begin(),
additionalPrivateTypes.end());

// Check if a type is private, given the info for it.
auto isPublicGivenInfo = [&](HeapType type, auto& info) {
return info.visibility != ModuleUtils::Visibility::Private &&
!additionalSet.count(type);
};

// Check if a type is private, looking for its info (if there is none, it is
// not private).
// Check if a type is private, by looking up its info.
auto isPublic = [&](HeapType type) {
auto it = typeInfo.find(type);
if (it == typeInfo.end()) {
return false;
}
return isPublicGivenInfo(type, it->second);
assert(it != typeInfo.end());
return it->second.visibility == ModuleUtils::Visibility::Public;
};

// For each type, note all the predecessors it must have, i.e., that must
// appear before it. That includes supertypes and described types.
std::vector<std::pair<HeapType, SmallVector<HeapType, 1>>> preds;
preds.reserve(typeInfo.size());
for (auto& [type, info] : typeInfo) {
if (isPublicGivenInfo(type, info)) {
if (info.visibility == ModuleUtils::Visibility::Public) {
continue;
}
preds.push_back({type, {}});
Expand Down
31 changes: 9 additions & 22 deletions src/ir/type-updating.h
Original file line number Diff line number Diff line change
Expand Up @@ -356,10 +356,8 @@ class GlobalTypeRewriter {
// the module.
//
// 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 (e.g. in closed world if a pass
// knows a type is safe to modify despite being public, it can add it).
void update(const std::vector<HeapType>& additionalPrivateTypes = {});
// external ABI).
void update();

using TypeMap = std::unordered_map<HeapType, HeapType>;

Expand Down Expand Up @@ -419,10 +417,7 @@ class GlobalTypeRewriter {

// Helper for the repeating pattern of just updating Signature types using a
// map of old heap type => new Signature.
static void
updateSignatures(const SignatureUpdates& updates,
Module& wasm,
const std::vector<HeapType>& additionalPrivateTypes = {}) {
static void updateSignatures(const SignatureUpdates& updates, Module& wasm) {
if (updates.empty()) {
return;
}
Expand All @@ -431,11 +426,9 @@ class GlobalTypeRewriter {
const SignatureUpdates& updates;

public:
SignatureRewriter(Module& wasm,
const SignatureUpdates& updates,
const std::vector<HeapType>& additionalPrivateTypes)
SignatureRewriter(Module& wasm, const SignatureUpdates& updates)
: GlobalTypeRewriter(wasm), updates(updates) {
update(additionalPrivateTypes);
update();
}

void modifySignature(HeapType oldSignatureType, Signature& sig) override {
Expand All @@ -445,19 +438,16 @@ class GlobalTypeRewriter {
sig.results = getTempType(iter->second.results);
}
}
} rewriter(wasm, updates, additionalPrivateTypes);
} rewriter(wasm, updates);
}

protected:
// Return the graph matching each private type to its private predecessors.
PredecessorGraph getPrivatePredecessors(
const std::vector<HeapType>& additionalPrivateTypes = {});
PredecessorGraph getPrivatePredecessors();

// 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().
//
// See above regarding private types.
TypeMap rebuildTypes(std::vector<HeapType> types);

private:
Expand All @@ -478,13 +468,10 @@ class TypeMapper : public GlobalTypeRewriter {
TypeMapper(Module& wasm, const TypeUpdates& mapping)
: GlobalTypeRewriter(wasm), mapping(mapping) {}

// 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 = {}) {
void map() {
// Update the internals of types (struct fields, signatures, etc.) to
// refer to the merged types.
auto newMapping = rebuildTypes(
getSortedTypes(getPrivatePredecessors(additionalPrivateTypes)));
auto newMapping = rebuildTypes(getSortedTypes(getPrivatePredecessors()));

// 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
Expand Down
Loading