summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pass.h8
-rw-r--r--src/passes/AbstractTypeRefining.cpp10
-rw-r--r--src/passes/GlobalTypeOptimization.cpp14
-rw-r--r--src/wasm/wasm-validator.cpp51
4 files changed, 25 insertions, 58 deletions
diff --git a/src/pass.h b/src/pass.h
index 8d81fce8e..daed8b6ab 100644
--- a/src/pass.h
+++ b/src/pass.h
@@ -212,14 +212,6 @@ struct PassOptions {
// but we also want to keep types of things on the boundary unchanged. For
// example, we should not change an exported function's signature, as the
// outside may need that type to properly call the export.
- //
- // * Since the goal of closedWorld is to optimize types aggressively but
- // types on the module boundary cannot be changed, we assume the producer
- // has made a mistake and we consider it a validation error if any user
- // defined types besides the types of imported or exported functions
- // themselves appear on the module boundary. For example, no user defined
- // struct type may be a parameter or result of an exported function. This
- // error may be relaxed or made more configurable in the future.
bool closedWorld = false;
// Whether to try to preserve debug info through, which are special calls.
bool debugInfo = false;
diff --git a/src/passes/AbstractTypeRefining.cpp b/src/passes/AbstractTypeRefining.cpp
index 313ad5f4d..509448851 100644
--- a/src/passes/AbstractTypeRefining.cpp
+++ b/src/passes/AbstractTypeRefining.cpp
@@ -106,6 +106,16 @@ struct AbstractTypeRefining : public Pass {
}
}
+ // Assume all public types are created, which makes them non-abstract and
+ // hence ignored below.
+ // TODO: In principle we could assume such types are not created outside the
+ // module, given closed world, but we'd also need to make sure that
+ // we don't need to make any changes to public types that refer to
+ // them.
+ for (auto type : ModuleUtils::getPublicHeapTypes(*module)) {
+ createdTypes.insert(type);
+ }
+
SubTypes subTypes(*module);
// Compute createdTypesOrSubTypes by starting with the created types and
diff --git a/src/passes/GlobalTypeOptimization.cpp b/src/passes/GlobalTypeOptimization.cpp
index 1f0da2595..74107f9cd 100644
--- a/src/passes/GlobalTypeOptimization.cpp
+++ b/src/passes/GlobalTypeOptimization.cpp
@@ -198,6 +198,20 @@ struct GlobalTypeOptimization : public Pass {
continue;
}
+ // The propagation analysis ensures we update immutability in all
+ // supers and subs in concert, but it does not take into account
+ // visibility, so do that here: we can only become immutable if the
+ // parent can as well.
+ auto super = type.getDeclaredSuperType();
+ if (super && !canBecomeImmutable.count(*super)) {
+ // No entry in canBecomeImmutable means nothing in the parent can
+ // become immutable. We don't need to check the specific field index,
+ // because visibility affects them all equally (i.e., if it is public
+ // then no field can be changed, and if it is private then this field
+ // can be changed, and perhaps more).
+ continue;
+ }
+
// No set exists. Mark it as something we can make immutable.
auto& vec = canBecomeImmutable[type];
vec.resize(i + 1);
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 0184e3284..d1ca5220c 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -63,7 +63,6 @@ struct ValidationInfo {
bool validateWeb;
bool validateGlobally;
bool quiet;
- bool closedWorld;
std::atomic<bool> valid;
@@ -4135,46 +4134,6 @@ static void validateFeatures(Module& module, ValidationInfo& info) {
}
}
-static void validateClosedWorldInterface(Module& module, ValidationInfo& info) {
- // Error if there are any publicly exposed heap types beyond the types of
- // publicly exposed functions. Note that we must include all types in the rec
- // groups that are used, as if a type if public then all types in its rec
- // group are as well.
- std::unordered_set<RecGroup> publicRecGroups;
- ModuleUtils::iterImportedFunctions(module, [&](Function* func) {
- publicRecGroups.insert(func->type.getRecGroup());
- });
- for (auto& ex : module.exports) {
- if (ex->kind == ExternalKind::Function) {
- publicRecGroups.insert(module.getFunction(ex->value)->type.getRecGroup());
- }
- }
-
- std::unordered_set<HeapType> publicTypes;
- for (auto& group : publicRecGroups) {
- for (auto type : group) {
- publicTypes.insert(type);
- }
- }
-
- // Ignorable public types are public, but we can ignore them for purposes of
- // erroring here: It is always ok that they are public.
- auto ignorable = getIgnorablePublicTypes();
-
- for (auto type : ModuleUtils::getPublicHeapTypes(module)) {
- if (!publicTypes.count(type) && !ignorable.count(type)) {
- auto name = type.toString();
- if (auto it = module.typeNames.find(type); it != module.typeNames.end()) {
- name = it->second.name.toString();
- }
- info.fail("publicly exposed type disallowed with a closed world: $" +
- name,
- type,
- nullptr);
- }
- }
-}
-
// TODO: If we want the validator to be part of libwasm rather than libpasses,
// then Using PassRunner::getPassDebug causes a circular dependence. We should
// fix that, perhaps by moving some of the pass infrastructure into libsupport.
@@ -4183,7 +4142,6 @@ bool WasmValidator::validate(Module& module, Flags flags) {
info.validateWeb = (flags & Web) != 0;
info.validateGlobally = (flags & Globally) != 0;
info.quiet = (flags & Quiet) != 0;
- info.closedWorld = (flags & ClosedWorld) != 0;
// Parallel function validation.
PassRunner runner(&module);
@@ -4210,9 +4168,6 @@ bool WasmValidator::validate(Module& module, Flags flags) {
validateStart(module, info);
validateModuleMaps(module, info);
validateFeatures(module, info);
- if (info.closedWorld) {
- validateClosedWorldInterface(module, info);
- }
}
// Validate additional internal IR details when in pass-debug mode.
@@ -4231,11 +4186,7 @@ bool WasmValidator::validate(Module& module, Flags flags) {
}
bool WasmValidator::validate(Module& module, const PassOptions& options) {
- Flags flags = options.validateGlobally ? Globally : Minimal;
- if (options.closedWorld) {
- flags |= ClosedWorld;
- }
- return validate(module, flags);
+ return validate(module, options.validateGlobally ? Globally : Minimal);
}
bool WasmValidator::validate(Function* func, Module& module, Flags flags) {