summaryrefslogtreecommitdiff
path: root/src/wasm
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm')
-rw-r--r--src/wasm/wasm-binary.cpp11
-rw-r--r--src/wasm/wasm-ir-builder.cpp4
-rw-r--r--src/wasm/wasm-validator.cpp8
-rw-r--r--src/wasm/wasm.cpp10
4 files changed, 11 insertions, 22 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 73718e636..21842e19b 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -7042,6 +7042,7 @@ bool WasmBinaryReader::maybeVisitSIMDLoadStoreLane(Expression*& out,
}
void WasmBinaryReader::visitSelect(Select* curr, uint8_t code) {
+ Type annotated = Type::none;
if (code == BinaryConsts::SelectWithType) {
size_t numTypes = getU32LEB();
std::vector<Type> types;
@@ -7052,15 +7053,15 @@ void WasmBinaryReader::visitSelect(Select* curr, uint8_t code) {
}
types.push_back(t);
}
- curr->type = Type(types);
+ annotated = Type(types);
}
curr->condition = popNonVoidExpression();
curr->ifFalse = popNonVoidExpression();
curr->ifTrue = popNonVoidExpression();
- if (code == BinaryConsts::SelectWithType) {
- curr->finalize(curr->type);
- } else {
- curr->finalize();
+ curr->finalize();
+ if (code == BinaryConsts::SelectWithType &&
+ !Type::isSubType(curr->type, annotated)) {
+ throwError("select type does not match annotation");
}
}
diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp
index a73c7f2ac..54cd0149e 100644
--- a/src/wasm/wasm-ir-builder.cpp
+++ b/src/wasm/wasm-ir-builder.cpp
@@ -1412,9 +1412,7 @@ Result<> IRBuilder::makeBinary(BinaryOp op) {
Result<> IRBuilder::makeSelect(std::optional<Type> type) {
Select curr;
CHECK_ERR(visitSelect(&curr));
- auto* built =
- type ? builder.makeSelect(curr.condition, curr.ifTrue, curr.ifFalse, *type)
- : builder.makeSelect(curr.condition, curr.ifTrue, curr.ifFalse);
+ auto* built = builder.makeSelect(curr.condition, curr.ifTrue, curr.ifFalse);
if (type && !Type::isSubType(built->type, *type)) {
return Err{"select type does not match expected type"};
}
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 339a3c7a1..516bb86e1 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -3671,10 +3671,10 @@ static void validateBinaryenIR(Module& wasm, ValidationInfo& info) {
auto oldType = curr->type;
ReFinalizeNode().visit(curr);
auto newType = curr->type;
- // It's ok for types to be further refinable, but they must admit a
- // superset of the values allowed by the most precise possible type, i.e.
- // they must not be strict subtypes of or unrelated to the refined type.
- if (!Type::isSubType(newType, oldType)) {
+ // It's ok for control flow structures to be further refinable, but all
+ // other instructions must have the most-precise possible types.
+ if (oldType != newType && !(Properties::isControlFlowStructure(curr) &&
+ Type::isSubType(newType, oldType))) {
std::ostringstream ss;
ss << "stale type found in " << scope << " on " << curr
<< "\n(marked as " << oldType << ", should be " << newType << ")\n";
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index a1ac076e0..f89ef80c2 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -777,16 +777,6 @@ void Binary::finalize() {
}
}
-void Select::finalize(Type type_) {
- assert(ifTrue && ifFalse);
- if (ifTrue->type == Type::unreachable || ifFalse->type == Type::unreachable ||
- condition->type == Type::unreachable) {
- type = Type::unreachable;
- } else {
- type = type_;
- }
-}
-
void Select::finalize() {
assert(ifTrue && ifFalse);
if (ifTrue->type == Type::unreachable || ifFalse->type == Type::unreachable ||