diff options
Diffstat (limited to 'src/wasm')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 11 | ||||
-rw-r--r-- | src/wasm/wasm-ir-builder.cpp | 4 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 8 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 10 |
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 || |