diff --git a/src/typing-asm.cc b/src/typing-asm.cc index 26a8544236..e8c013a337 100644 --- a/src/typing-asm.cc +++ b/src/typing-asm.cc @@ -540,20 +540,22 @@ void AsmTyper::VisitConditional(Conditional* expr) { expr->then_expression(), expected_type_, "conditional then branch type mismatch with enclosing expression")); Type* then_type = StorageType(computed_type_); - if (intish_ != 0 || !then_type->Is(cache_.kAsmComparable)) { - FAIL(expr->then_expression(), "invalid type in ? then expression"); - } + int then_intish = intish_; RECURSE(VisitWithExpectation( expr->else_expression(), expected_type_, "conditional else branch type mismatch with enclosing expression")); Type* else_type = StorageType(computed_type_); - if (intish_ != 0 || !else_type->Is(cache_.kAsmComparable)) { - FAIL(expr->else_expression(), "invalid type in ? else expression"); - } + int else_intish = intish_; - if (!then_type->Is(else_type) || !else_type->Is(then_type)) { - FAIL(expr, "then and else expressions in ? must have the same type"); + if (then_intish != 0 || else_intish != 0 || + !((then_type->Is(cache_.kAsmInt) && else_type->Is(cache_.kAsmInt)) || + (then_type->Is(cache_.kAsmFloat) && else_type->Is(cache_.kAsmFloat)) || + (then_type->Is(cache_.kAsmDouble) && + else_type->Is(cache_.kAsmDouble)))) { + FAIL(expr, + "then and else expressions in ? must have the same type " + "and be int, float, or double"); } RECURSE(IntersectResult(expr, then_type)); @@ -1379,20 +1381,25 @@ void AsmTyper::VisitCompareOperation(CompareOperation* expr) { VisitWithExpectation(expr->left(), Type::Number(), "left comparison operand expected to be number")); Type* left_type = computed_type_; - if (!left_type->Is(cache_.kAsmComparable)) { - FAIL(expr->left(), "bad type on left side of comparison"); - } + int left_intish = intish_; RECURSE( VisitWithExpectation(expr->right(), Type::Number(), "right comparison operand expected to be number")); Type* right_type = computed_type_; - if (!right_type->Is(cache_.kAsmComparable)) { - FAIL(expr->right(), "bad type on right side of comparison"); - } + int right_intish = intish_; - if (!left_type->Is(right_type) && !right_type->Is(left_type)) { - FAIL(expr, "left and right side of comparison must match"); + if (left_intish != 0 || right_intish != 0 || + !((left_type->Is(cache_.kAsmUnsigned) && + right_type->Is(cache_.kAsmUnsigned)) || + (left_type->Is(cache_.kAsmSigned) && + right_type->Is(cache_.kAsmSigned)) || + (left_type->Is(cache_.kAsmFloat) && right_type->Is(cache_.kAsmFloat)) || + (left_type->Is(cache_.kAsmDouble) && + right_type->Is(cache_.kAsmDouble)))) { + FAIL(expr, + "left and right side of comparison must match type " + "and be signed, unsigned, float, or double"); } RECURSE(IntersectResult(expr, cache_.kAsmSigned)); diff --git a/src/typing-asm.h b/src/typing-asm.h index 09eacaa0ae..129bf99997 100644 --- a/src/typing-asm.h +++ b/src/typing-asm.h @@ -121,7 +121,7 @@ class AsmTyper : public AstVisitor { AstTypeBounds bounds_; - static const int kErrorMessageLimit = 100; + static const int kErrorMessageLimit = 150; char error_message_[kErrorMessageLimit]; static const int kMaxUncombinedAdditiveSteps = 1 << 20; diff --git a/test/cctest/test-asm-validator.cc b/test/cctest/test-asm-validator.cc index acbe9dac6f..d08ca6a2ed 100644 --- a/test/cctest/test-asm-validator.cc +++ b/test/cctest/test-asm-validator.cc @@ -1138,7 +1138,8 @@ TEST(TernaryMismatchInt32Float64) { CHECK_FUNC_ERROR( "function bar() { var x = 1; var y = 0.0; return (1 ? x : y)|0; }\n" "function foo() { bar(); }", - "asm: line 1: then and else expressions in ? must have the same type\n"); + "asm: line 1: then and else expressions in ? must have the same type " + "and be int, float, or double\n"); } @@ -1146,7 +1147,8 @@ TEST(TernaryMismatchIntish) { CHECK_FUNC_ERROR( "function bar() { var x = 1; var y = 0; return (1 ? x + x : y)|0; }\n" "function foo() { bar(); }", - "asm: line 1: invalid type in ? then expression\n"); + "asm: line 1: then and else expressions in ? must have the same type " + "and be int, float, or double\n"); } @@ -1154,7 +1156,8 @@ TEST(TernaryMismatchInt32Float32) { CHECK_FUNC_ERROR( "function bar() { var x = 1; var y = 2.0; return (x?fround(y):x)|0; }\n" "function foo() { bar(); }", - "asm: line 1: then and else expressions in ? must have the same type\n"); + "asm: line 1: then and else expressions in ? must have the same type " + "and be int, float, or double\n"); } @@ -1359,7 +1362,8 @@ TEST(CompareToStringLeft) { CHECK_FUNC_ERROR( "function bar() { var x = 1; return ('hi' > x)|0; }\n" "function foo() { bar(); }", - "asm: line 1: bad type on left side of comparison\n"); + "asm: line 1: left and right side of comparison must match type " + "and be signed, unsigned, float, or double\n"); } @@ -1367,7 +1371,8 @@ TEST(CompareToStringRight) { CHECK_FUNC_ERROR( "function bar() { var x = 1; return (x < 'hi')|0; }\n" "function foo() { bar(); }", - "asm: line 1: bad type on right side of comparison\n"); + "asm: line 1: left and right side of comparison must match type " + "and be signed, unsigned, float, or double\n"); } @@ -1375,7 +1380,8 @@ TEST(CompareMismatchInt32Float64) { CHECK_FUNC_ERROR( "function bar() { var x = 1; var y = 2.0; return (x < y)|0; }\n" "function foo() { bar(); }", - "asm: line 1: left and right side of comparison must match\n"); + "asm: line 1: left and right side of comparison must match type " + "and be signed, unsigned, float, or double\n"); } @@ -1383,7 +1389,8 @@ TEST(CompareMismatchInt32Uint32) { CHECK_FUNC_ERROR( "function bar() { var x = 1; var y = 2; return ((x|0) < (y>>>0))|0; }\n" "function foo() { bar(); }", - "asm: line 1: left and right side of comparison must match\n"); + "asm: line 1: left and right side of comparison must match type " + "and be signed, unsigned, float, or double\n"); } @@ -1391,7 +1398,8 @@ TEST(CompareMismatchInt32Float32) { CHECK_FUNC_ERROR( "function bar() { var x = 1; var y = 2.0; return (x < fround(y))|0; }\n" "function foo() { bar(); }", - "asm: line 1: left and right side of comparison must match\n"); + "asm: line 1: left and right side of comparison must match type " + "and be signed, unsigned, float, or double\n"); } TEST(FunctionRepeated) { diff --git a/test/mjsunit/regress/regress-wasm-crbug-599413.js b/test/mjsunit/regress/regress-wasm-crbug-599413.js new file mode 100644 index 0000000000..acc3995437 --- /dev/null +++ b/test/mjsunit/regress/regress-wasm-crbug-599413.js @@ -0,0 +1,20 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --expose-wasm + +function __f_100() { + "use asm"; + function __f_76() { + var __v_39 = 0; + outer: while (1) { + while (__v_39 == 4294967295) { + } + } + } + return {__f_76: __f_76}; +} +assertThrows(function() { + Wasm.instantiateModuleFromAsm(__f_100.toString()); +}); diff --git a/test/mjsunit/wasm/asm-wasm.js b/test/mjsunit/wasm/asm-wasm.js index 4391e039eb..b4a9a81dc8 100644 --- a/test/mjsunit/wasm/asm-wasm.js +++ b/test/mjsunit/wasm/asm-wasm.js @@ -145,7 +145,7 @@ function TestWhileSimple() { function caller() { var x = 0; - while(x < 5) { + while((x|0) < 5) { x = (x + 1)|0; } return x|0; @@ -162,7 +162,7 @@ function TestWhileWithoutBraces() { function caller() { var x = 0; - while(x <= 3) + while((x|0) <= 3) x = (x + 1)|0; return x|0; } @@ -178,7 +178,7 @@ function TestReturnInWhile() { function caller() { var x = 0; - while(x < 10) { + while((x|0) < 10) { x = (x + 6)|0; return x|0; } @@ -196,7 +196,7 @@ function TestReturnInWhileWithoutBraces() { function caller() { var x = 0; - while(x < 5) + while((x|0) < 5) return 7; return x|0; } @@ -318,7 +318,7 @@ function TestBreakInBlock() { var x = 0; abc: { x = 10; - if (x == 10) { + if ((x|0) == 10) { break abc; } x = 20; @@ -339,7 +339,7 @@ function TestBreakInNamedWhile() { var x = 0; outer: while (1) { x = (x + 1)|0; - while (x == 11) { + while ((x|0) == 11) { break outer; } } @@ -358,9 +358,9 @@ function TestContinue() { function caller() { var x = 5; var ret = 0; - while (x >= 0) { + while ((x|0) >= 0) { x = (x - 1)|0; - if (x == 2) { + if ((x|0) == 2) { continue; } ret = (ret - 1)|0; @@ -381,11 +381,11 @@ function TestContinueInNamedWhile() { var x = 5; var y = 0; var ret = 0; - outer: while (x > 0) { + outer: while ((x|0) > 0) { x = (x - 1)|0; y = 0; - while (y < 5) { - if (x == 3) { + while ((y|0) < 5) { + if ((x|0) == 3) { continue outer; } ret = (ret + 1)|0; @@ -420,7 +420,7 @@ function TestNotEquals() { function caller() { var a = 3; - if (a != 2) { + if ((a|0) != 2) { return 21; } return 0; @@ -458,7 +458,7 @@ function TestMixedAdd() { var c = 0; c = ((a>>>0) + b)|0; if ((c >>> 0) > (0>>>0)) { - if (c < 0) { + if ((c|0) < 0) { return 23; } } @@ -733,7 +733,7 @@ function TestForLoop() { function caller() { var ret = 0; var i = 0; - for (i = 2; i <= 10; i = (i+1)|0) { + for (i = 2; (i|0) <= 10; i = (i+1)|0) { ret = (ret + i) | 0; } return ret|0; @@ -751,7 +751,7 @@ function TestForLoopWithoutInit() { function caller() { var ret = 0; var i = 0; - for (; i < 10; i = (i+1)|0) { + for (; (i|0) < 10; i = (i+1)|0) { ret = (ret + 10) | 0; } return ret|0; @@ -771,7 +771,7 @@ function TestForLoopWithoutCondition() { var i = 0; for (i=1;; i = (i+1)|0) { ret = (ret + i) | 0; - if (i == 11) { + if ((i|0) == 11) { break; } } @@ -789,7 +789,7 @@ function TestForLoopWithoutNext() { function caller() { var i = 0; - for (i=1; i < 41;) { + for (i=1; (i|0) < 41;) { i = (i + 1) | 0; } return i|0; @@ -806,7 +806,7 @@ function TestForLoopWithoutBody() { function caller() { var i = 0; - for (i=1; i < 45 ; i = (i+1)|0) { + for (i=1; (i|0) < 45 ; i = (i+1)|0) { } return i|0; } @@ -826,7 +826,7 @@ function TestDoWhile() { do { ret = (ret + ret)|0; i = (i + 1)|0; - } while (i < 2); + } while ((i|0) < 2); return ret|0; } @@ -841,7 +841,7 @@ function TestConditional() { function caller() { var x = 1; - return ((x > 0) ? 41 : 71)|0; + return (((x|0) > 0) ? 41 : 71)|0; } return {caller:caller}; @@ -911,8 +911,8 @@ function TestFunctionTableMultipleFunctions() { } function caller() { - if (function_table[0&1](50) == 51) { - if (function_table[1&1](60) == 62) { + if ((function_table[0&1](50)|0) == 51) { + if ((function_table[1&1](60)|0) == 62) { return 73; } } @@ -953,9 +953,9 @@ function TestFunctionTable() { fun_id = fun_id|0; arg1 = arg1|0; arg2 = arg2|0; - if (table_id == 0) { + if ((table_id|0) == 0) { return funBin[fun_id&3](arg1, arg2)|0; - } else if (table_id == 1) { + } else if ((table_id|0) == 1) { return fun[fun_id&0](arg1)|0; } return 0;