summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-validator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm/wasm-validator.cpp')
-rw-r--r--src/wasm/wasm-validator.cpp39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 16b6f5314..726c70c7c 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -61,6 +61,7 @@ struct ValidationInfo {
bool validateWeb;
bool validateGlobally;
bool quiet;
+ bool closedWorld;
std::atomic<bool> valid;
@@ -3500,6 +3501,32 @@ 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.
+ std::unordered_set<HeapType> publicFuncTypes;
+ ModuleUtils::iterImportedFunctions(
+ module, [&](Function* func) { publicFuncTypes.insert(func->type); });
+ for (auto& ex : module.exports) {
+ if (ex->kind == ExternalKind::Function) {
+ publicFuncTypes.insert(module.getFunction(ex->value)->type);
+ }
+ }
+
+ for (auto type : ModuleUtils::getPublicHeapTypes(module)) {
+ if (!publicFuncTypes.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.
@@ -3508,6 +3535,7 @@ 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 wasm logic validation
PassRunner runner(&module);
FunctionValidator(module, &info).validate(&runner);
@@ -3522,6 +3550,9 @@ bool WasmValidator::validate(Module& module, Flags flags) {
validateTags(module, info);
validateModule(module, info);
validateFeatures(module, info);
+ if (info.closedWorld) {
+ validateClosedWorldInterface(module, info);
+ }
}
// validate additional internal IR details when in pass-debug mode
if (PassRunner::getPassDebug()) {
@@ -3537,6 +3568,14 @@ bool WasmValidator::validate(Module& module, Flags flags) {
return info.valid.load();
}
+bool WasmValidator::validate(Module& module, const PassOptions& options) {
+ Flags flags = options.validateGlobally ? Globally : Minimal;
+ if (options.closedWorld) {
+ flags |= ClosedWorld;
+ }
+ return validate(module, flags);
+}
+
bool WasmValidator::validate(Function* func, Module& module, Flags flags) {
ValidationInfo info(module);
info.validateWeb = (flags & Web) != 0;