summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ir/module-utils.cpp5
-rw-r--r--src/wasm-type.h14
-rw-r--r--src/wasm/wasm-type.cpp23
-rw-r--r--src/wasm/wasm-validator.cpp6
4 files changed, 47 insertions, 1 deletions
diff --git a/src/ir/module-utils.cpp b/src/ir/module-utils.cpp
index 2b2f51323..ed147053b 100644
--- a/src/ir/module-utils.cpp
+++ b/src/ir/module-utils.cpp
@@ -506,6 +506,11 @@ InsertOrderedSet<HeapType> getPublicTypeSet(Module& wasm) {
WASM_UNREACHABLE("unexpected export kind");
}
+ // Ignorable public types are public.
+ for (auto type : getIgnorablePublicTypes()) {
+ notePublic(type);
+ }
+
// Find all the other public types reachable from directly publicized types.
std::vector<HeapType> workList(publicTypes.begin(), publicTypes.end());
while (workList.size()) {
diff --git a/src/wasm-type.h b/src/wasm-type.h
index 927e37845..d97bdeba3 100644
--- a/src/wasm-type.h
+++ b/src/wasm-type.h
@@ -661,6 +661,20 @@ struct TypeBuilder {
void dump();
};
+// We consider certain specific types to always be public, to allow closed-
+// world to operate even if they escape. Specifically, "plain old data" types
+// like array of i8 and i16, which are used to represent strings, may cross
+// the boundary in Web environments.
+//
+// These are "ignorable as public", because we do not error on them being
+// public. That is, we
+//
+// 1. Consider them public, so that passes that do not operate on public types
+// do not in fact operate on them, and
+// 2. Are ok with them being public in the validator.
+//
+std::unordered_set<HeapType> getIgnorablePublicTypes();
+
std::ostream& operator<<(std::ostream&, Type);
std::ostream& operator<<(std::ostream&, Type::Printed);
std::ostream& operator<<(std::ostream&, HeapType);
diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp
index ba38231b6..4ce72582c 100644
--- a/src/wasm/wasm-type.cpp
+++ b/src/wasm/wasm-type.cpp
@@ -2580,6 +2580,29 @@ void TypeBuilder::dump() {
}
}
+std::unordered_set<HeapType> getIgnorablePublicTypes() {
+ auto array8 = Array(Field(Field::i8, Mutable));
+ auto array16 = Array(Field(Field::i16, Mutable));
+ TypeBuilder builder(4);
+ // We handle final and non-final here, but should remove one of them
+ // eventually TODO
+ builder[0] = array8;
+ builder[0].setOpen(false);
+ builder[1] = array16;
+ builder[1].setOpen(false);
+ builder[2] = array8;
+ builder[2].setOpen(true);
+ builder[3] = array16;
+ builder[3].setOpen(true);
+ auto result = builder.build();
+ assert(result);
+ std::unordered_set<HeapType> ret;
+ for (auto type : *result) {
+ ret.insert(type);
+ }
+ return ret;
+}
+
} // namespace wasm
namespace std {
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 2d00c4b67..3baaacb16 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -3726,8 +3726,12 @@ static void validateClosedWorldInterface(Module& module, ValidationInfo& info) {
}
}
+ // 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 (!publicFuncTypes.count(type)) {
+ if (!publicFuncTypes.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();