diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/module-utils.cpp | 5 | ||||
-rw-r--r-- | src/wasm-type.h | 14 | ||||
-rw-r--r-- | src/wasm/wasm-type.cpp | 23 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 6 |
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(); |