diff --git a/js/src/jit-test/tests/wasm/regress/misc-control-flow.js b/js/src/jit-test/tests/wasm/regress/misc-control-flow.js index e0264f76f9d0..6aea6e9b0fbb 100644 --- a/js/src/jit-test/tests/wasm/regress/misc-control-flow.js +++ b/js/src/jit-test/tests/wasm/regress/misc-control-flow.js @@ -202,7 +202,7 @@ wasmFailValidateText(` (br_table 1 0 (i32.const 15)) ) ) -)`, /br_table targets must all have the same value type/); +)`, /br_table operand must be subtype of all target types/); wasmFailValidateText(` (module @@ -212,7 +212,7 @@ wasmFailValidateText(` (br_table 1 0 (i32.const 15)) ) ) -)`, /br_table targets must all have the same value type/); +)`, /br_table operand must be subtype of all target types/); wasmValidateText(` (module diff --git a/js/src/jit-test/tests/wasm/spec/unreached-invalid.wast.js b/js/src/jit-test/tests/wasm/spec/unreached-invalid.wast.js index 2aec2cedc987..21628995d0f6 100644 --- a/js/src/jit-test/tests/wasm/spec/unreached-invalid.wast.js +++ b/js/src/jit-test/tests/wasm/spec/unreached-invalid.wast.js @@ -260,74 +260,71 @@ assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60 // unreached-invalid.wast:526 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x02\x7d\x00\x41\x01\x0e\x02\x00\x01\x00\x0b\x1a\x0b\x0b"); -// unreached-invalid.wast:538 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x7c\x02\x7d\x00\x41\x01\x0e\x02\x00\x01\x01\x0b\x1a\x44\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x1a\x0b"); - -// unreached-invalid.wast:553 +// unreached-invalid.wast:539 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x03\x02\x40\x00\x0b\x0b\x0b"); -// unreached-invalid.wast:559 +// unreached-invalid.wast:545 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x40\x02\x40\x00\x0b\x0b\x0b"); -// unreached-invalid.wast:565 +// unreached-invalid.wast:551 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x7e\x42\x00\x02\x40\x00\x0b\x0b\x0b"); -// unreached-invalid.wast:571 +// unreached-invalid.wast:557 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x40\x41\x03\x02\x40\x42\x01\x00\x0b\x0b\x41\x09\x0b"); -// unreached-invalid.wast:578 +// unreached-invalid.wast:564 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x40\x41\x03\x02\x40\x0c\x01\x0b\x0b\x0b"); -// unreached-invalid.wast:584 +// unreached-invalid.wast:570 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x7f\x02\x40\x41\x00\x0c\x01\x0b\x0b\x0b"); -// unreached-invalid.wast:590 +// unreached-invalid.wast:576 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x7f\x42\x00\x02\x40\x41\x00\x0c\x01\x0b\x0b\x0b"); -// unreached-invalid.wast:597 +// unreached-invalid.wast:583 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x40\x02\x40\x41\x03\x02\x40\x0c\x02\x0b\x0b\x0b\x0b"); -// unreached-invalid.wast:603 +// unreached-invalid.wast:589 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x7f\x02\x40\x02\x40\x41\x00\x0c\x02\x0b\x0b\x0b\x0b"); -// unreached-invalid.wast:609 +// unreached-invalid.wast:595 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x7f\x02\x7e\x42\x00\x02\x40\x41\x00\x0c\x02\x0b\x0b\x0b\x0b"); -// unreached-invalid.wast:617 +// unreached-invalid.wast:603 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x02\x40\x41\x03\x02\x40\x42\x01\x0c\x01\x0b\x0b\x41\x09\x0b"); -// unreached-invalid.wast:624 +// unreached-invalid.wast:610 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x03\x02\x40\x0f\x0b\x0b\x0b"); -// unreached-invalid.wast:630 +// unreached-invalid.wast:616 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x02\x40\x41\x00\x0f\x0b\x0b\x0b"); -// unreached-invalid.wast:636 +// unreached-invalid.wast:622 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x7e\x42\x00\x02\x40\x41\x00\x0f\x0b\x0b\x0b"); -// unreached-invalid.wast:642 +// unreached-invalid.wast:628 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x41\x03\x02\x40\x42\x01\x41\x00\x0f\x0b\x0b\x41\x09\x0b"); -// unreached-invalid.wast:650 +// unreached-invalid.wast:636 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x03\x40\x41\x03\x02\x40\x00\x0b\x0b\x0b"); -// unreached-invalid.wast:656 +// unreached-invalid.wast:642 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x03\x40\x02\x40\x00\x0b\x0b\x0b"); -// unreached-invalid.wast:662 +// unreached-invalid.wast:648 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x03\x7e\x42\x00\x02\x40\x00\x0b\x0b\x0b"); -// unreached-invalid.wast:669 +// unreached-invalid.wast:655 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x03\x40\x01\x0c\x00\x0b\x0b"); -// unreached-invalid.wast:675 +// unreached-invalid.wast:661 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x03\x40\x41\x00\x0c\x00\x0b\x0b"); -// unreached-invalid.wast:682 +// unreached-invalid.wast:668 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x01\x01\x7f\x00\x22\x00\x0b"); -// unreached-invalid.wast:689 +// unreached-invalid.wast:675 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x7f\x02\x40\x00\x41\x00\x0d\x01\x0b\x41\x00\x0b\x0b"); -// unreached-invalid.wast:700 +// unreached-invalid.wast:686 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x00\x0d\x00\xad\x0b"); diff --git a/js/src/wasm/WasmBaselineCompile.cpp b/js/src/wasm/WasmBaselineCompile.cpp index 7daf1f932562..f98b99dd9296 100644 --- a/js/src/wasm/WasmBaselineCompile.cpp +++ b/js/src/wasm/WasmBaselineCompile.cpp @@ -9556,7 +9556,7 @@ bool BaseCompiler::emitSelect() { BranchState b(&done); emitBranchSetup(&b); - switch (NonTVarToValType(type).code()) { + switch (NonBottomToValType(type).code()) { case ValType::I32: { RegI32 r, rs; pop2xI32(&r, &rs); diff --git a/js/src/wasm/WasmOpIter.h b/js/src/wasm/WasmOpIter.h index 4d5cb5883182..1d04445043de 100644 --- a/js/src/wasm/WasmOpIter.h +++ b/js/src/wasm/WasmOpIter.h @@ -69,7 +69,7 @@ class StackType { Ref = uint8_t(ValType::Ref), NullRef = uint8_t(ValType::NullRef), - TVar = uint8_t(TypeCode::Limit), + Bottom = uint8_t(TypeCode::Limit), }; StackType() : tc_(InvalidPackedTypeCode()) {} @@ -86,7 +86,7 @@ class StackType { bool isNumeric() const { switch (code()) { - case Code::TVar: + case Code::Bottom: case Code::I32: case Code::I64: case Code::F32: @@ -111,8 +111,8 @@ class StackType { bool operator!=(Code that) const { return !(*this == that); } }; -static inline ValType NonTVarToValType(StackType type) { - MOZ_ASSERT(type != StackType::TVar); +static inline ValType NonBottomToValType(StackType type) { + MOZ_ASSERT(type != StackType::Bottom); return ValType(type.packed()); } @@ -246,7 +246,7 @@ class TypeAndValue { mozilla::Pair tv_; public: - TypeAndValue() : tv_(StackType::TVar, Value()) {} + TypeAndValue() : tv_(StackType::Bottom, Value()) {} explicit TypeAndValue(StackType type) : tv_(type, Value()) {} explicit TypeAndValue(ValType type) : tv_(StackType(type), Value()) {} TypeAndValue(StackType type, Value value) : tv_(type, value) {} @@ -307,6 +307,8 @@ class MOZ_STACK_CLASS OpIter : private Policy { MOZ_MUST_USE bool popWithType(ExprType expectedType, Value* value); MOZ_MUST_USE bool topWithType(ExprType expectedType, Value* value); MOZ_MUST_USE bool topWithType(ValType valType, Value* value); + MOZ_MUST_USE bool topIsType(ValType expectedType, StackType* actualType, + Value* value); MOZ_MUST_USE bool pushControl(LabelKind kind, ExprType type); MOZ_MUST_USE bool checkStackAtEndOfBlock(ExprType* type, Value* value); @@ -315,6 +317,7 @@ class MOZ_STACK_CLASS OpIter : private Policy { MOZ_MUST_USE bool checkBranchValue(uint32_t relativeDepth, ExprType* type, Value* value); MOZ_MUST_USE bool checkBrTableEntry(uint32_t* relativeDepth, + uint32_t* branchValueArity, ExprType* branchValueType, Value* branchValue); @@ -339,6 +342,11 @@ class MOZ_STACK_CLASS OpIter : private Policy { controlStack_.back().setPolymorphicBase(); } + // Compute a type that is a supertype of one and two. This type is not + // guaranteed to be minimal; there may be a more specific supertype of one + // and two that this type is a supertype of. + inline bool weakMeet(ExprType one, ExprType two, ExprType* result) const; + inline bool checkIsSubtypeOf(ValType lhs, ValType rhs); public: @@ -525,6 +533,22 @@ class MOZ_STACK_CLASS OpIter : private Policy { bool controlStackEmpty() const { return controlStack_.empty(); } }; +template +inline bool OpIter::weakMeet(ExprType one, ExprType two, + ExprType* result) const { + if (MOZ_LIKELY(one == two)) { + *result = one; + return true; + } + + if (one.isReference() && two.isReference()) { + *result = ExprType::AnyRef; + return true; + } + + return false; +} + template inline bool OpIter::checkIsSubtypeOf(ValType actual, ValType expected) { if (actual == expected) { @@ -577,9 +601,9 @@ inline bool OpIter::failEmptyStack() { : fail("popping value from outside block"); } -// This function pops exactly one value from the stack, yielding TVar types in +// This function pops exactly one value from the stack, yielding Bottom types in // various cases and therefore making it the caller's responsibility to do the -// right thing for StackType::TVar. Prefer (pop|top)WithType. +// right thing for StackType::Bottom. Prefer (pop|top)WithType. template inline bool OpIter::popStackType(StackType* type, Value* value) { ControlStackEntry& block = controlStack_.back(); @@ -590,7 +614,7 @@ inline bool OpIter::popStackType(StackType* type, Value* value) { // dummy value of any type; it won't be used since we're in unreachable // code. if (block.polymorphicBase()) { - *type = StackType::TVar; + *type = StackType::Bottom; *value = Value(); // Maintain the invariant that, after a pop, there is always memory @@ -617,8 +641,8 @@ inline bool OpIter::popWithType(ValType expectedType, Value* value) { return false; } - return stackType == StackType::TVar || - checkIsSubtypeOf(NonTVarToValType(stackType), expectedType); + return stackType == StackType::Bottom || + checkIsSubtypeOf(NonBottomToValType(stackType), expectedType); } // This function pops as many types from the stack as determined by the given @@ -635,7 +659,8 @@ inline bool OpIter::popWithType(ExprType expectedType, Value* value) { return popWithType(NonVoidToValType(expectedType), value); } -// This function is just an optimization of popWithType + push. +// This function is equivalent to: popWithType(expectedType); +// push(expectedType); template inline bool OpIter::topWithType(ValType expectedType, Value* value) { ControlStackEntry& block = controlStack_.back(); @@ -661,13 +686,13 @@ inline bool OpIter::topWithType(ValType expectedType, Value* value) { TypeAndValue& observed = valueStack_.back(); - if (observed.type() == StackType::TVar) { + if (observed.type() == StackType::Bottom) { observed.typeRef() = StackType(expectedType); *value = Value(); return true; } - if (!checkIsSubtypeOf(NonTVarToValType(observed.type()), expectedType)) { + if (!checkIsSubtypeOf(NonBottomToValType(observed.type()), expectedType)) { return false; } @@ -685,6 +710,44 @@ inline bool OpIter::topWithType(ExprType expectedType, Value* value) { return topWithType(NonVoidToValType(expectedType), value); } +// This function checks that the top of the stack is a subtype of expectedType +// and returns the value if so. +template +inline bool OpIter::topIsType(ValType expectedType, + StackType* actualType, Value* value) { + ControlStackEntry& block = controlStack_.back(); + + MOZ_ASSERT(valueStack_.length() >= block.valueStackStart()); + if (valueStack_.length() == block.valueStackStart()) { + // If the base of this block's stack is polymorphic, then we can just + // pull out a dummy value of the expected type; it won't be used since + // we're in unreachable code. + if (block.polymorphicBase()) { + *actualType = StackType::Bottom; + *value = Value(); + return true; + } + + return failEmptyStack(); + } + + TypeAndValue& observed = valueStack_.back(); + + if (observed.type() == StackType::Bottom) { + *actualType = StackType::Bottom; + *value = Value(); + return true; + } + + if (!checkIsSubtypeOf(NonBottomToValType(observed.type()), expectedType)) { + return false; + } + + *actualType = observed.type(); + *value = observed.value(); + return true; +} + template inline bool OpIter::pushControl(LabelKind kind, ExprType type) { return controlStack_.emplaceBack(kind, type, valueStack_.length()); @@ -969,32 +1032,66 @@ inline bool OpIter::readBrIf(uint32_t* relativeDepth, ExprType* type, return checkBranchValue(*relativeDepth, type, value); } +#define UNKNOWN_ARITY UINT32_MAX + template inline bool OpIter::checkBrTableEntry(uint32_t* relativeDepth, + uint32_t* branchValueArity, ExprType* branchValueType, Value* branchValue) { if (!readVarU32(relativeDepth)) { return false; } + ControlStackEntry* block = nullptr; + if (!getControl(*relativeDepth, &block)) { + return false; + } + // For the first encountered branch target, do a normal branch value type - // check which will change *branchValueType to a non-sentinel value. For all - // subsequent branch targets, check that the branch target matches the - // now-known branch value type. + // check which will change *branchValueArity and *branchValueType to a + // non-sentinel value. For all subsequent branch targets, check that the + // branch target arity and type matches the now-known branch value arity + // and type. This will need to change with multi-value. + uint32_t labelTypeArity = IsVoid(block->branchTargetType()) ? 0 : 1; + + if (*branchValueArity == UNKNOWN_ARITY) { + *branchValueArity = labelTypeArity; + } else if (*branchValueArity != labelTypeArity) { + return fail("br_table operand must be subtype of all target types"); + } + + // If the label types are void, no need to check type on the stack + if (labelTypeArity == 0) { + *branchValueType = ExprType::Void; + *branchValue = Value(); + return true; + } + + // Check that the value on the stack is a subtype of the label + StackType actualBranchValueType; + if (!topIsType(NonVoidToValType(block->branchTargetType()), + &actualBranchValueType, branchValue)) { + return false; + } + + // If the value on the stack is the bottom type, it will by definition be a + // subtype of every possible label type. This also implies that the label + // types may not have a subtype relation, and so we cannot report a branch + // value type. Fortunately this only happens in unreachable code, where we + // don't use the branch value type. + if (actualBranchValueType == StackType::Bottom) { + *branchValueType = ExprType::Limit; + return true; + } + + // Compute the branch value type in all other cases if (*branchValueType == ExprType::Limit) { - if (!checkBranchValue(*relativeDepth, branchValueType, branchValue)) { - return false; - } - } else { - ControlStackEntry* block = nullptr; - if (!getControl(*relativeDepth, &block)) { - return false; - } - - if (*branchValueType != block->branchTargetType()) { - return fail("br_table targets must all have the same value type"); - } + *branchValueType = block->branchTargetType(); + } else if (!weakMeet(*branchValueType, block->branchTargetType(), + branchValueType)) { + return fail("br_table operand must be subtype of all target types"); } return true; @@ -1024,24 +1121,29 @@ inline bool OpIter::readBrTable(Uint32Vector* depths, return false; } + uint32_t branchValueArity = UNKNOWN_ARITY; *branchValueType = ExprType::Limit; for (uint32_t i = 0; i < tableLength; i++) { - if (!checkBrTableEntry(&(*depths)[i], branchValueType, branchValue)) { + if (!checkBrTableEntry(&(*depths)[i], &branchValueArity, branchValueType, + branchValue)) { return false; } } - if (!checkBrTableEntry(defaultDepth, branchValueType, branchValue)) { + if (!checkBrTableEntry(defaultDepth, &branchValueArity, branchValueType, + branchValue)) { return false; } - MOZ_ASSERT(*branchValueType != ExprType::Limit); + MOZ_ASSERT(branchValueArity != UNKNOWN_ARITY); afterUnconditionalBranch(); return true; } +#undef UNKNOWN_ARITY + template inline bool OpIter::readUnreachable() { MOZ_ASSERT(Classify(op_) == OpKind::Unreachable); @@ -1315,9 +1417,9 @@ inline bool OpIter::readSelect(StackType* type, Value* trueValue, return fail("select operand types must be numeric"); } - if (falseType.code() == StackType::TVar) { + if (falseType.code() == StackType::Bottom) { *type = trueType; - } else if (trueType.code() == StackType::TVar || falseType == trueType) { + } else if (trueType.code() == StackType::Bottom || falseType == trueType) { *type = falseType; } else { return fail("select operand types must match"); diff --git a/testing/web-platform/mozilla/tests/wasm/js/unreached-invalid.wast.js b/testing/web-platform/mozilla/tests/wasm/js/unreached-invalid.wast.js index fc31e735a2d7..0f260a05eb64 100644 --- a/testing/web-platform/mozilla/tests/wasm/js/unreached-invalid.wast.js +++ b/testing/web-platform/mozilla/tests/wasm/js/unreached-invalid.wast.js @@ -261,76 +261,73 @@ assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60 // unreached-invalid.wast:526 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x02\x7d\x00\x41\x01\x0e\x02\x00\x01\x00\x0b\x1a\x0b\x0b"); -// unreached-invalid.wast:538 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x7c\x02\x7d\x00\x41\x01\x0e\x02\x00\x01\x01\x0b\x1a\x44\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x1a\x0b"); - -// unreached-invalid.wast:553 +// unreached-invalid.wast:539 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x03\x02\x40\x00\x0b\x0b\x0b"); -// unreached-invalid.wast:559 +// unreached-invalid.wast:545 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x40\x02\x40\x00\x0b\x0b\x0b"); -// unreached-invalid.wast:565 +// unreached-invalid.wast:551 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x7e\x42\x00\x02\x40\x00\x0b\x0b\x0b"); -// unreached-invalid.wast:571 +// unreached-invalid.wast:557 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x40\x41\x03\x02\x40\x42\x01\x00\x0b\x0b\x41\x09\x0b"); -// unreached-invalid.wast:578 +// unreached-invalid.wast:564 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x40\x41\x03\x02\x40\x0c\x01\x0b\x0b\x0b"); -// unreached-invalid.wast:584 +// unreached-invalid.wast:570 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x7f\x02\x40\x41\x00\x0c\x01\x0b\x0b\x0b"); -// unreached-invalid.wast:590 +// unreached-invalid.wast:576 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x7f\x42\x00\x02\x40\x41\x00\x0c\x01\x0b\x0b\x0b"); -// unreached-invalid.wast:597 +// unreached-invalid.wast:583 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x40\x02\x40\x41\x03\x02\x40\x0c\x02\x0b\x0b\x0b\x0b"); -// unreached-invalid.wast:603 +// unreached-invalid.wast:589 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x7f\x02\x40\x02\x40\x41\x00\x0c\x02\x0b\x0b\x0b\x0b"); -// unreached-invalid.wast:609 +// unreached-invalid.wast:595 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x7f\x02\x7e\x42\x00\x02\x40\x41\x00\x0c\x02\x0b\x0b\x0b\x0b"); -// unreached-invalid.wast:617 +// unreached-invalid.wast:603 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x02\x40\x41\x03\x02\x40\x42\x01\x0c\x01\x0b\x0b\x41\x09\x0b"); -// unreached-invalid.wast:624 +// unreached-invalid.wast:610 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x03\x02\x40\x0f\x0b\x0b\x0b"); -// unreached-invalid.wast:630 +// unreached-invalid.wast:616 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x02\x40\x41\x00\x0f\x0b\x0b\x0b"); -// unreached-invalid.wast:636 +// unreached-invalid.wast:622 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x7e\x42\x00\x02\x40\x41\x00\x0f\x0b\x0b\x0b"); -// unreached-invalid.wast:642 +// unreached-invalid.wast:628 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x41\x03\x02\x40\x42\x01\x41\x00\x0f\x0b\x0b\x41\x09\x0b"); -// unreached-invalid.wast:650 +// unreached-invalid.wast:636 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x03\x40\x41\x03\x02\x40\x00\x0b\x0b\x0b"); -// unreached-invalid.wast:656 +// unreached-invalid.wast:642 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x03\x40\x02\x40\x00\x0b\x0b\x0b"); -// unreached-invalid.wast:662 +// unreached-invalid.wast:648 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x03\x7e\x42\x00\x02\x40\x00\x0b\x0b\x0b"); -// unreached-invalid.wast:669 +// unreached-invalid.wast:655 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x03\x40\x01\x0c\x00\x0b\x0b"); -// unreached-invalid.wast:675 +// unreached-invalid.wast:661 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x03\x40\x41\x00\x0c\x00\x0b\x0b"); -// unreached-invalid.wast:682 +// unreached-invalid.wast:668 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x01\x01\x7f\x00\x22\x00\x0b"); -// unreached-invalid.wast:689 +// unreached-invalid.wast:675 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x7f\x02\x40\x00\x41\x00\x0d\x01\x0b\x41\x00\x0b\x0b"); -// unreached-invalid.wast:700 +// unreached-invalid.wast:686 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x00\x0d\x00\xad\x0b"); reinitializeRegistry(); })();