diff --git a/implementation-contributed/v8/intl/intl.status b/implementation-contributed/v8/intl/intl.status index c04d962ce8..4823b16ca0 100644 --- a/implementation-contributed/v8/intl/intl.status +++ b/implementation-contributed/v8/intl/intl.status @@ -31,6 +31,13 @@ 'overrides/caching': [PASS, FAIL], 'date-format/constructor-order': [FAIL], + + # https://bugs.chromium.org/p/v8/issues/detail?id=6891 + 'segmenter/segment': [FAIL], + 'segmenter/segment-iterator': [FAIL], + 'segmenter/segment-iterator-following': [FAIL], + 'segmenter/segment-iterator-next': [FAIL], + 'segmenter/segment-iterator-preceding': [FAIL], }], # ALWAYS ['variant == no_wasm_traps', { diff --git a/implementation-contributed/v8/intl/segmenter/constructor.js b/implementation-contributed/v8/intl/segmenter/constructor.js index db36c19d28..655bb100df 100644 --- a/implementation-contributed/v8/intl/segmenter/constructor.js +++ b/implementation-contributed/v8/intl/segmenter/constructor.js @@ -1,5 +1,5 @@ // Copyright 2018 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-lineBreakStyle license that can be +// Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Flags: --harmony-intl-segmenter diff --git a/implementation-contributed/v8/intl/segmenter/resolved-options.js b/implementation-contributed/v8/intl/segmenter/resolved-options.js index 7f9b7abb23..2e2a910ddb 100644 --- a/implementation-contributed/v8/intl/segmenter/resolved-options.js +++ b/implementation-contributed/v8/intl/segmenter/resolved-options.js @@ -1,5 +1,5 @@ // Copyright 2018 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-lineBreakStyle license that can be +// Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Flags: --harmony-intl-segmenter diff --git a/implementation-contributed/v8/intl/segmenter/segment-iterator-following.js b/implementation-contributed/v8/intl/segmenter/segment-iterator-following.js new file mode 100644 index 0000000000..a28d6c31d1 --- /dev/null +++ b/implementation-contributed/v8/intl/segmenter/segment-iterator-following.js @@ -0,0 +1,17 @@ +// Copyright 2018 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: --harmony-intl-segmenter + +const segmenter = new Intl.Segmenter(); +const text = "Hello World, Test 123! Foo Bar. How are you?"; +const iter = segmenter.segment(text); + +assertEquals("function", typeof iter.following); + +// 1.5.3.2 %SegmentIteratorPrototype%.following( [ from ] ) +// 3.b If from >= iterator.[[SegmentIteratorString]], throw a RangeError exception. +assertDoesNotThrow(() => iter.following(text.length - 1)); +assertThrows(() => iter.following(text.length), RangeError); +assertThrows(() => iter.following(text.length + 1), RangeError); diff --git a/implementation-contributed/v8/intl/segmenter/segment-iterator-next.js b/implementation-contributed/v8/intl/segmenter/segment-iterator-next.js new file mode 100644 index 0000000000..9aa40494ca --- /dev/null +++ b/implementation-contributed/v8/intl/segmenter/segment-iterator-next.js @@ -0,0 +1,11 @@ +// Copyright 2018 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: --harmony-intl-segmenter + +const segmenter = new Intl.Segmenter(); +const text = "Hello World, Test 123! Foo Bar. How are you?"; +const iter = segmenter.segment(text); + +assertEquals("function", typeof iter.next); diff --git a/implementation-contributed/v8/intl/segmenter/segment-iterator-preceding.js b/implementation-contributed/v8/intl/segmenter/segment-iterator-preceding.js new file mode 100644 index 0000000000..07d73376f2 --- /dev/null +++ b/implementation-contributed/v8/intl/segmenter/segment-iterator-preceding.js @@ -0,0 +1,21 @@ +// Copyright 2018 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: --harmony-intl-segmenter + +const segmenter = new Intl.Segmenter(); +const text = "Hello World, Test 123! Foo Bar. How are you?"; +const iter = segmenter.segment(text); + +assertEquals("function", typeof iter.preceding); + +// 1.5.3.3 %SegmentIteratorPrototype%.preceding( [ from ] ) +// 3.b If ... from = 0, throw a RangeError exception. +assertThrows(() => iter.preceding(0), RangeError); + +// 1.5.3.3 %SegmentIteratorPrototype%.preceding( [ from ] ) +// 3.b If from > iterator.[[SegmentIteratorString]] ... , throw a RangeError exception. +assertDoesNotThrow(() => iter.preceding(text.length - 1)); +assertDoesNotThrow(() => iter.preceding(text.length)); +assertThrows(() => iter.preceding(text.length + 1), RangeError); diff --git a/implementation-contributed/v8/intl/segmenter/segment-iterator.js b/implementation-contributed/v8/intl/segmenter/segment-iterator.js new file mode 100644 index 0000000000..0d0c31b405 --- /dev/null +++ b/implementation-contributed/v8/intl/segmenter/segment-iterator.js @@ -0,0 +1,13 @@ +// Copyright 2018 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: --harmony-intl-segmenter + +const segmenter = new Intl.Segmenter(); +const text = "Hello World, Test 123! Foo Bar. How are you?"; +const iter = segmenter.segment(text); + +assertEquals("number", typeof iter.position); +assertEquals(0, iter.position); +assertEquals("strig", typeof iter.breakType); diff --git a/implementation-contributed/v8/intl/segmenter/segment.js b/implementation-contributed/v8/intl/segmenter/segment.js new file mode 100644 index 0000000000..ca17c5040d --- /dev/null +++ b/implementation-contributed/v8/intl/segmenter/segment.js @@ -0,0 +1,7 @@ +// Copyright 2018 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: --harmony-intl-segmenter + +assertEquals("function", typeof Intl.Segmenter.prototype.segment); diff --git a/implementation-contributed/v8/mjsunit/compiler/context-sensitivity.js b/implementation-contributed/v8/mjsunit/compiler/context-sensitivity.js new file mode 100644 index 0000000000..1f0f1f274a --- /dev/null +++ b/implementation-contributed/v8/mjsunit/compiler/context-sensitivity.js @@ -0,0 +1,550 @@ +// Copyright 2018 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: --allow-natives-syntax + +const object1 = {[Symbol.toPrimitive]() { return 1; }}; +const thrower = {[Symbol.toPrimitive]() { throw new Error(); }}; + +// Test that JSAdd is not context-sensitive. +(function() { + function bar(fn) { + return fn(1); + } + + function foo(x) { + return bar(y => y + x); + } + + assertEquals(1, foo(0)); + assertEquals(2, foo(object1)); + assertThrows(() => foo(thrower)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(1, foo(0)); + assertEquals(2, foo(object1)); + assertThrows(() => foo(thrower)); +})(); + +// Test that JSSubtract is not context-sensitive. +(function() { + function bar(fn) { + return fn(1); + } + + function foo(x) { + return bar(y => y - x); + } + + assertEquals(1, foo(0)); + assertEquals(0, foo(object1)); + assertThrows(() => foo(thrower)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(1, foo(0)); + assertEquals(0, foo(object1)); + assertThrows(() => foo(thrower)); +})(); + +// Test that JSMultiply is not context-sensitive. +(function() { + function bar(fn) { + return fn(1); + } + + function foo(x) { + return bar(y => y * x); + } + + assertEquals(1, foo(1)); + assertEquals(1, foo(object1)); + assertThrows(() => foo(thrower)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(1, foo(1)); + assertEquals(1, foo(object1)); + assertThrows(() => foo(thrower)); +})(); + +// Test that JSDivide is not context-sensitive. +(function() { + function bar(fn) { + return fn(1); + } + + function foo(x) { + return bar(y => y / x); + } + + assertEquals(1, foo(1)); + assertEquals(1, foo(object1)); + assertThrows(() => foo(thrower)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(1, foo(1)); + assertEquals(1, foo(object1)); + assertThrows(() => foo(thrower)); +})(); + +// Test that JSModulus is not context-sensitive. +(function() { + function bar(fn) { + return fn(1); + } + + function foo(x) { + return bar(y => y % x); + } + + assertEquals(0, foo(1)); + assertEquals(0, foo(object1)); + assertThrows(() => foo(thrower)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(0, foo(1)); + assertEquals(0, foo(object1)); + assertThrows(() => foo(thrower)); +})(); + +// Test that JSExponentiate is not context-sensitive. +(function() { + function bar(fn) { + return fn(1); + } + + function foo(x) { + return bar(y => y ** x); + } + + assertEquals(1, foo(1)); + assertEquals(1, foo(object1)); + assertThrows(() => foo(thrower)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(1, foo(1)); + assertEquals(1, foo(object1)); + assertThrows(() => foo(thrower)); +})(); + +// Test that JSBitwiseOr is not context-sensitive. +(function() { + function bar(fn) { + return fn(1); + } + + function foo(x) { + return bar(y => y | x); + } + + assertEquals(1, foo(1)); + assertEquals(1, foo(object1)); + assertThrows(() => foo(thrower)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(1, foo(1)); + assertEquals(1, foo(object1)); + assertThrows(() => foo(thrower)); +})(); + +// Test that JSBitwiseAnd is not context-sensitive. +(function() { + function bar(fn) { + return fn(1); + } + + function foo(x) { + return bar(y => y & x); + } + + assertEquals(1, foo(1)); + assertEquals(1, foo(object1)); + assertThrows(() => foo(thrower)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(1, foo(1)); + assertEquals(1, foo(object1)); + assertThrows(() => foo(thrower)); +})(); + +// Test that JSBitwiseXor is not context-sensitive. +(function() { + function bar(fn) { + return fn(1); + } + + function foo(x) { + return bar(y => y ^ x); + } + + assertEquals(0, foo(1)); + assertEquals(0, foo(object1)); + assertThrows(() => foo(thrower)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(0, foo(1)); + assertEquals(0, foo(object1)); + assertThrows(() => foo(thrower)); +})(); + +// Test that JSShiftLeft is not context-sensitive. +(function() { + function bar(fn) { + return fn(1); + } + + function foo(x) { + return bar(y => y << x); + } + + assertEquals(2, foo(1)); + assertEquals(2, foo(object1)); + assertThrows(() => foo(thrower)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(2, foo(1)); + assertEquals(2, foo(object1)); + assertThrows(() => foo(thrower)); +})(); + +// Test that JSShiftRight is not context-sensitive. +(function() { + function bar(fn) { + return fn(1); + } + + function foo(x) { + return bar(y => y >> x); + } + + assertEquals(0, foo(1)); + assertEquals(0, foo(object1)); + assertThrows(() => foo(thrower)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(0, foo(1)); + assertEquals(0, foo(object1)); + assertThrows(() => foo(thrower)); +})(); + +// Test that JSShiftRightLogical is not context-sensitive. +(function() { + function bar(fn) { + return fn(1); + } + + function foo(x) { + return bar(y => y >>> x); + } + + assertEquals(0, foo(1)); + assertEquals(0, foo(object1)); + assertThrows(() => foo(thrower)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(0, foo(1)); + assertEquals(0, foo(object1)); + assertThrows(() => foo(thrower)); +})(); + +// Test that JSEqual is not context-sensitive. +(function() { + function bar(fn) { + return fn(1); + } + + function foo(x) { + return bar(y => y == x); + } + + assertFalse(foo(0)); + assertTrue(foo(object1)); + assertThrows(() => foo(thrower)); + %OptimizeFunctionOnNextCall(foo); + assertFalse(foo(0)); + assertTrue(foo(object1)); + assertThrows(() => foo(thrower)); +})(); + +// Test that JSLessThan is not context-sensitive. +(function() { + function bar(fn) { + return fn(1); + } + + function foo(x) { + return bar(y => y < x); + } + + assertFalse(foo(0)); + assertFalse(foo(object1)); + assertThrows(() => foo(thrower)); + %OptimizeFunctionOnNextCall(foo); + assertFalse(foo(0)); + assertFalse(foo(object1)); + assertThrows(() => foo(thrower)); +})(); + +// Test that JSGreaterThan is not context-sensitive. +(function() { + function bar(fn) { + return fn(1); + } + + function foo(x) { + return bar(y => x > y); + } + + assertFalse(foo(0)); + assertFalse(foo(object1)); + assertThrows(() => foo(thrower)); + %OptimizeFunctionOnNextCall(foo); + assertFalse(foo(0)); + assertFalse(foo(object1)); + assertThrows(() => foo(thrower)); +})(); + +// Test that JSLessThanOrEqual is not context-sensitive. +(function() { + function bar(fn) { + return fn(1); + } + + function foo(x) { + return bar(y => y <= x); + } + + assertFalse(foo(0)); + assertTrue(foo(object1)); + assertThrows(() => foo(thrower)); + %OptimizeFunctionOnNextCall(foo); + assertFalse(foo(0)); + assertTrue(foo(object1)); + assertThrows(() => foo(thrower)); +})(); + +// Test that JSGreaterThanOrEqual is not context-sensitive. +(function() { + function bar(fn) { + return fn(1); + } + + function foo(x) { + return bar(y => x >= y); + } + + assertFalse(foo(0)); + assertTrue(foo(object1)); + assertThrows(() => foo(thrower)); + %OptimizeFunctionOnNextCall(foo); + assertFalse(foo(0)); + assertTrue(foo(object1)); + assertThrows(() => foo(thrower)); +})(); + +// Test that JSInstanceOf is not context-sensitive. +(function() { + function bar(fn) { + return fn({}); + } + + function foo(c) { + return bar(o => o instanceof c); + } + + assertTrue(foo(Object)); + assertFalse(foo(Array)); + assertThrows(() => foo({[Symbol.hasInstance]() { throw new Error(); }})); + %OptimizeFunctionOnNextCall(foo); + assertTrue(foo(Object)); + assertFalse(foo(Array)); + assertThrows(() => foo({[Symbol.hasInstance]() { throw new Error(); }})); +})(); + +// Test that JSBitwiseNot is not context-sensitive. +(function() { + function bar(fn) { + return fn(); + } + + function foo(x) { + return bar(() => ~x); + } + + assertEquals(0, foo(-1)); + assertEquals(~1, foo(object1)); + assertThrows(() => foo(thrower)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(0, foo(-1)); + assertEquals(~1, foo(object1)); + assertThrows(() => foo(thrower)); +})(); + +// Test that JSNegate is not context-sensitive. +(function() { + function bar(fn) { + return fn(); + } + + function foo(x) { + return bar(() => -x); + } + + assertEquals(1, foo(-1)); + assertEquals(-1, foo(object1)); + assertThrows(() => foo(thrower)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(1, foo(-1)); + assertEquals(-1, foo(object1)); + assertThrows(() => foo(thrower)); +})(); + +// Test that JSIncrement is not context-sensitive. +(function() { + function bar(fn) { + return fn(); + } + + function foo(x) { + return bar(() => ++x); + } + + assertEquals(1, foo(0)); + assertEquals(2, foo(object1)); + assertThrows(() => foo(thrower)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(1, foo(0)); + assertEquals(2, foo(object1)); + assertThrows(() => foo(thrower)); +})(); + +// Test that JSDecrement is not context-sensitive. +(function() { + function bar(fn) { + return fn(); + } + + function foo(x) { + return bar(() => --x); + } + + assertEquals(1, foo(2)); + assertEquals(0, foo(object1)); + assertThrows(() => foo(thrower)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(1, foo(2)); + assertEquals(0, foo(object1)); + assertThrows(() => foo(thrower)); +})(); + +// Test that JSCreateArguments[UnmappedArguments] is not context-sensitive. +(function() { + function bar(fn) { + return fn(); + } + + function foo() { + "use strict"; + return bar(() => arguments)[0]; + } + + assertEquals(0, foo(0, 1)); + assertEquals(1, foo(1, 2)); + assertEquals(undefined, foo()); + %OptimizeFunctionOnNextCall(foo); + assertEquals(0, foo(0, 1)); + assertEquals(1, foo(1, 2)); + assertEquals(undefined, foo()); +})(); + +// Test that JSCreateArguments[RestParameters] is not context-sensitive. +(function() { + function bar(fn) { + return fn(); + } + + function foo(...args) { + return bar(() => args)[0]; + } + + assertEquals(0, foo(0, 1)); + assertEquals(1, foo(1, 2)); + assertEquals(undefined, foo()); + %OptimizeFunctionOnNextCall(foo); + assertEquals(0, foo(0, 1)); + assertEquals(1, foo(1, 2)); + assertEquals(undefined, foo()); +})(); + +// Test that JSLoadGlobal/JSStoreGlobal are not context-sensitive. +(function(global) { + var actualValue = 'Some value'; + + Object.defineProperty(global, 'globalValue', { + configurable: true, + enumerable: true, + get: function() { + return actualValue; + }, + set: function(v) { + actualValue = v; + } + }); + + function bar(fn) { + return fn(); + } + + function foo(v) { + return bar(() => { + const o = globalValue; + globalValue = v; + return o; + }); + } + + assertEquals('Some value', foo('Another value')); + assertEquals('Another value', actualValue); + assertEquals('Another value', foo('Some value')); + assertEquals('Some value', actualValue); + %OptimizeFunctionOnNextCall(foo); + assertEquals('Some value', foo('Another value')); + assertEquals('Another value', actualValue); + assertEquals('Another value', foo('Some value')); + assertEquals('Some value', actualValue); +})(this); + +// Test that for..in is not context-sensitive. +(function() { + function bar(fn) { + return fn(); + } + + function foo(o) { + return bar(() => { + var s = ""; + for (var k in o) { s += k; } + return s; + }); + } + + assertEquals('abc', foo({a: 1, b: 2, c: 3})); + assertEquals('ab', foo(Object.create({a: 1, b: 2}))); + %OptimizeFunctionOnNextCall(foo); + assertEquals('abc', foo({a: 1, b: 2, c: 3})); + assertEquals("ab", foo(Object.create({a:1, b:2}))); +})(); + +// Test that most generator operations are not context-sensitive. +(function() { + function bar(fn) { + let s = undefined; + for (const x of fn()) { + if (s === undefined) s = x; + else s += x; + } + return s; + } + + function foo(x, y, z) { + return bar(function*() { + yield x; + yield y; + yield z; + }); + } + + assertEquals(6, foo(1, 2, 3)); + assertEquals("abc", foo("a", "b", "c")); + %OptimizeFunctionOnNextCall(foo); + assertEquals(6, foo(1, 2, 3)); + assertEquals("abc", foo("a", "b", "c")); +})(); diff --git a/implementation-contributed/v8/mjsunit/compiler/escape-analysis-arguments.js b/implementation-contributed/v8/mjsunit/compiler/escape-analysis-arguments.js index f520167e19..65e736c706 100644 --- a/implementation-contributed/v8/mjsunit/compiler/escape-analysis-arguments.js +++ b/implementation-contributed/v8/mjsunit/compiler/escape-analysis-arguments.js @@ -185,3 +185,56 @@ %OptimizeFunctionOnNextCall(f); f(); f(); })(); + +// Test variable index access to strict arguments +// with up to 2 elements. +(function testArgumentsVariableIndexStrict() { + function g() { + "use strict"; + var s = 0; + for (var i = 0; i < arguments.length; ++i) s += arguments[i]; + return s; + } + + function f(x, y) { + // (a) arguments[i] is dead code since arguments.length is 0. + const a = g(); + // (b) arguments[i] always yields the first element. + const b = g(x); + // (c) arguments[i] can yield either x or y. + const c = g(x, y); + return a + b + c; + } + + assertEquals(4, f(1, 2)); + assertEquals(5, f(2, 1)); + %OptimizeFunctionOnNextCall(f); + assertEquals(4, f(1, 2)); + assertEquals(5, f(2, 1)); +})(); + +// Test variable index access to sloppy arguments +// with up to 2 elements. +(function testArgumentsVariableIndexSloppy() { + function g() { + var s = 0; + for (var i = 0; i < arguments.length; ++i) s += arguments[i]; + return s; + } + + function f(x, y) { + // (a) arguments[i] is dead code since arguments.length is 0. + const a = g(); + // (b) arguments[i] always yields the first element. + const b = g(x); + // (c) arguments[i] can yield either x or y. + const c = g(x, y); + return a + b + c; + } + + assertEquals(4, f(1, 2)); + assertEquals(5, f(2, 1)); + %OptimizeFunctionOnNextCall(f); + assertEquals(4, f(1, 2)); + assertEquals(5, f(2, 1)); +})(); diff --git a/implementation-contributed/v8/mjsunit/compiler/escape-analysis-array.js b/implementation-contributed/v8/mjsunit/compiler/escape-analysis-array.js new file mode 100644 index 0000000000..2c44fa8c9b --- /dev/null +++ b/implementation-contributed/v8/mjsunit/compiler/escape-analysis-array.js @@ -0,0 +1,32 @@ +// Copyright 2018 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: --allow-natives-syntax + +// Test variable index access to array with 1 element. +(function testOneElementArrayVariableIndex() { + function f(i) { + const a = new Array("first"); + return a[i]; + } + + assertEquals("first", f(0)); + assertEquals("first", f(0)); + %OptimizeFunctionOnNextCall(f); + assertEquals("first", f(0)); +})(); + +// Test variable index access to array with 2 elements. +(function testTwoElementArrayVariableIndex() { + function f(i) { + const a = new Array("first", "second"); + return a[i]; + } + + assertEquals("first", f(0)); + assertEquals("second", f(1)); + %OptimizeFunctionOnNextCall(f); + assertEquals("first", f(0)); + assertEquals("second", f(1)); +})(); diff --git a/implementation-contributed/v8/mjsunit/compiler/escape-analysis-rest-parameters.js b/implementation-contributed/v8/mjsunit/compiler/escape-analysis-rest-parameters.js new file mode 100644 index 0000000000..2ac1253a18 --- /dev/null +++ b/implementation-contributed/v8/mjsunit/compiler/escape-analysis-rest-parameters.js @@ -0,0 +1,31 @@ +// Copyright 2018 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: --allow-natives-syntax + +// Test variable index access to rest parameters +// with up to 2 elements. +(function testRestParametersVariableIndex() { + function g(...args) { + let s = 0; + for (let i = 0; i < args.length; ++i) s += args[i]; + return s; + } + + function f(x, y) { + // (a) args[i] is dead code since args.length is 0. + const a = g(); + // (b) args[i] always yields the first element. + const b = g(x); + // (c) args[i] can yield either x or y. + const c = g(x, y); + return a + b + c; + } + + assertEquals(4, f(1, 2)); + assertEquals(5, f(2, 1)); + %OptimizeFunctionOnNextCall(f); + assertEquals(4, f(1, 2)); + assertEquals(5, f(2, 1)); +})(); diff --git a/implementation-contributed/v8/mjsunit/compiler/redundancy-elimination.js b/implementation-contributed/v8/mjsunit/compiler/redundancy-elimination.js index d1bed70d6a..1e5185adb7 100644 --- a/implementation-contributed/v8/mjsunit/compiler/redundancy-elimination.js +++ b/implementation-contributed/v8/mjsunit/compiler/redundancy-elimination.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --allow-natives-syntax +// Flags: --allow-natives-syntax --opt // Test the RedundancyElimination::ReduceSpeculativeNumberOperation() // TurboFan optimization for the case of SpeculativeNumberAdd with @@ -132,3 +132,63 @@ %OptimizeFunctionOnNextCall(foo); assertEquals(3, foo([1, 2], 1)); })(); + +// Test the RedundancyElimination::ReduceSpeculativeNumberComparison() +// TurboFan optimization for the case of SpeculativeNumberEqual. +(function() { + function foo(a, i) { + const x = a[i]; + if (i === 0) return x; + return i; + } + + assertEquals(1, foo([1, 2], 0)); + assertEquals(1, foo([1, 2], 1)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(1, foo([1, 2], 0)); + assertEquals(1, foo([1, 2], 1)); + // Even passing -0 should not deoptimize and + // of course still pass the equality test above. + assertEquals(9, foo([9, 2], -0)); + assertOptimized(foo); +})(); + +// Test the RedundancyElimination::ReduceSpeculativeNumberComparison() +// TurboFan optimization for the case of SpeculativeNumberLessThan. +(function() { + function foo(a, i) { + const x = a[i]; + if (i < 1) return x; + return i; + } + + assertEquals(1, foo([1, 2], 0)); + assertEquals(1, foo([1, 2], 1)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(1, foo([1, 2], 0)); + assertEquals(1, foo([1, 2], 1)); + // Even passing -0 should not deoptimize and + // of course still pass the equality test above. + assertEquals(9, foo([9, 2], -0)); + assertOptimized(foo); +})(); + +// Test the RedundancyElimination::ReduceSpeculativeNumberComparison() +// TurboFan optimization for the case of SpeculativeNumberLessThanOrEqual. +(function() { + function foo(a, i) { + const x = a[i]; + if (i <= 0) return x; + return i; + } + + assertEquals(1, foo([1, 2], 0)); + assertEquals(1, foo([1, 2], 1)); + %OptimizeFunctionOnNextCall(foo); + assertEquals(1, foo([1, 2], 0)); + assertEquals(1, foo([1, 2], 1)); + // Even passing -0 should not deoptimize and + // of course still pass the equality test above. + assertEquals(9, foo([9, 2], -0)); + assertOptimized(foo); +})(); diff --git a/implementation-contributed/v8/mjsunit/compiler/stress-deopt-count-2.js b/implementation-contributed/v8/mjsunit/compiler/stress-deopt-count-2.js index 918b4e00ad..641a9e8180 100644 --- a/implementation-contributed/v8/mjsunit/compiler/stress-deopt-count-2.js +++ b/implementation-contributed/v8/mjsunit/compiler/stress-deopt-count-2.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --allow-natives-syntax --opt --no-always-opt --deopt-every-n-times=3 +// Flags: --allow-natives-syntax --opt --no-always-opt --deopt-every-n-times=6 // Check that stress deopt count resets correctly @@ -14,34 +14,34 @@ function f(x) { f(1); %OptimizeFunctionOnNextCall(f); -// stress_deopt_count == 3 +// stress_deopt_count == 6 + +f(1); +assertOptimized(f, undefined, undefined, false); + +// stress_deopt_count == 4 f(1); assertOptimized(f, undefined, undefined, false); // stress_deopt_count == 2 -f(1); -assertOptimized(f, undefined, undefined, false); - -// stress_deopt_count == 1 - f(1); // deopt & counter reset assertUnoptimized(f, undefined, undefined, false); -// stress_deopt_count == 3 +// stress_deopt_count == 6 %OptimizeFunctionOnNextCall(f); f(1); assertOptimized(f, undefined, undefined, false); -// stress_deopt_count == 2 +// stress_deopt_count == 4 f(1); assertOptimized(f, undefined, undefined, false); -// stress_deopt_count == 1 +// stress_deopt_count == 2 f(1); // deopt & counter reset diff --git a/implementation-contributed/v8/mjsunit/es6/string-iterator2.js b/implementation-contributed/v8/mjsunit/es6/string-iterator2.js index 2c23a4aa76..6bfd51a815 100644 --- a/implementation-contributed/v8/mjsunit/es6/string-iterator2.js +++ b/implementation-contributed/v8/mjsunit/es6/string-iterator2.js @@ -4,7 +4,9 @@ // Flags: --allow-natives-syntax --no-stress-opt -// Tests for primitive strings. +// Tests for spreading primitive strings. + +assertEquals([...''], []); var str = 'ott'; assertEquals(['o', 't', 't'], [...str]); diff --git a/implementation-contributed/v8/mjsunit/regress/regress-892858.js b/implementation-contributed/v8/mjsunit/regress/regress-892858.js new file mode 100644 index 0000000000..ec921e3d43 --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/regress-892858.js @@ -0,0 +1,32 @@ +// Copyright 2018 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +async function foo() { + await Promise.resolve(42); +} + +foo(); diff --git a/implementation-contributed/v8/mjsunit/regress/regress-arrow-single-expression-eval.js b/implementation-contributed/v8/mjsunit/regress/regress-arrow-single-expression-eval.js new file mode 100644 index 0000000000..83a9ca1a56 --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/regress-arrow-single-expression-eval.js @@ -0,0 +1,5 @@ +// Copyright 2018 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. + +((x=1) => eval("var x = 10"))(); diff --git a/implementation-contributed/v8/mjsunit/smi-mul.js b/implementation-contributed/v8/mjsunit/smi-mul.js index de10d3c3fb..12d206abec 100644 --- a/implementation-contributed/v8/mjsunit/smi-mul.js +++ b/implementation-contributed/v8/mjsunit/smi-mul.js @@ -27,34 +27,41 @@ // Flags: --allow-natives-syntax --opt --noalways-opt -(function() { - function mul(a, b) { - return a * b; - } +function mul(a, b) { + return a * b; +} - mul(-1, 2); - mul(-1, 2); - %OptimizeFunctionOnNextCall(mul); - assertEquals(-2, mul(-1, 2)); - assertOptimized(mul); - // Deopt on minus zero. - assertEquals(-0, mul(-1, 0)); - assertUnoptimized(mul); -})(); +mul(-1, 2); +mul(-1, 2); +%OptimizeFunctionOnNextCall(mul); +assertEquals(-2, mul(-1, 2)); +assertOptimized(mul); -(function() { - function mul2(a, b) { - return a * b; - } +// Deopt on minus zero. +assertEquals(-0, mul(-1, 0)); +assertUnoptimized(mul); - mul2(-1, 2); - mul2(-1, 2); - %OptimizeFunctionOnNextCall(mul2); - assertEquals(-2, mul2(-1, 2)); - assertOptimized(mul2); - // Deopt on 2^31. - assertEquals(1 << 31, mul2(-(1 << 31), -1)); +function mul2(a, b) { + return a * b; +} + +mul2(-1, 2); +mul2(-1, 2); +%OptimizeFunctionOnNextCall(mul2); + +// 2^30 is a smi boundary on arm and ia32. +var two_30 = 1 << 30; +// 2^31 is a smi boundary on x64. +var two_31 = 2 * two_30; + +if (%IsValidSmi(two_31)) { + // Deopt on two_31 on x64. + assertEquals(two_31, mul2(-two_31, -1)); assertUnoptimized(mul2); -})(); +} else { + // Deopt on two_30 on ia32. + assertEquals(two_30, mul2(-two_30, -1)); + assertUnoptimized(mul2); +} diff --git a/implementation-contributed/v8/test262/test262.status b/implementation-contributed/v8/test262/test262.status index 6871d7ad68..28d8f77195 100644 --- a/implementation-contributed/v8/test262/test262.status +++ b/implementation-contributed/v8/test262/test262.status @@ -674,10 +674,6 @@ ############################ INVALID TESTS ############################# - # https://github.com/tc39/test262/pull/1816#issuecomment-426799415 - # https://github.com/tc39/test262/pull/1818 - 'language/reserved-words/unreserved-words': [PASS, FAIL], - # Test makes unjustified assumptions about the number of calls to SortCompare. # Test262 Bug: https://bugs.ecmascript.org/show_bug.cgi?id=596 'built-ins/Array/prototype/sort/bug_596_1': [PASS, FAIL_OK], @@ -715,60 +711,18 @@ # https://bugs.chromium.org/p/v8/issues/detail?id=7187 'built-ins/Function/prototype/toString/line-terminator-normalisation-CR': [SKIP], - 'language/expressions/class/fields-after-same-line-static-async-gen-static-private-methods-with-fields': [FAIL], - 'language/expressions/class/fields-after-same-line-static-async-method-static-private-methods-with-fields': [FAIL], - 'language/expressions/class/fields-new-sc-line-gen-static-private-methods-with-fields': [FAIL], 'language/expressions/class/fields-private-derived-cls-direct-eval-err-contains-supercall': [FAIL], 'language/expressions/class/fields-private-derived-cls-direct-eval-err-contains-supercall-1': [FAIL], 'language/expressions/class/fields-private-derived-cls-direct-eval-err-contains-supercall-2': [FAIL], - 'language/expressions/class/fields-private-derived-cls-direct-eval-err-contains-superproperty-1': [FAIL], - 'language/expressions/class/fields-private-derived-cls-direct-eval-err-contains-superproperty-2': [FAIL], 'language/expressions/class/fields-private-derived-cls-indirect-eval-err-contains-supercall': [FAIL], 'language/expressions/class/fields-private-derived-cls-indirect-eval-err-contains-supercall-1': [FAIL], 'language/expressions/class/fields-private-derived-cls-indirect-eval-err-contains-supercall-2': [FAIL], - 'language/expressions/class/fields-private-derived-cls-indirect-eval-err-contains-superproperty-1': [FAIL], - 'language/expressions/class/fields-private-derived-cls-indirect-eval-err-contains-superproperty-2': [FAIL], - 'language/expressions/class/fields-same-line-async-gen-static-private-methods-with-fields': [FAIL], - 'language/expressions/class/fields-same-line-async-method-static-private-methods-with-fields': [FAIL], - 'language/expressions/class/fields-same-line-gen-static-private-methods-with-fields': [FAIL], - 'language/statements/class/fields-after-same-line-static-async-gen-static-private-methods-with-fields': [FAIL], - 'language/statements/class/fields-after-same-line-static-async-method-static-private-methods-with-fields': [FAIL], - 'language/statements/class/fields-new-sc-line-gen-static-private-methods-with-fields': [FAIL], 'language/statements/class/fields-private-derived-cls-direct-eval-err-contains-supercall': [FAIL], 'language/statements/class/fields-private-derived-cls-direct-eval-err-contains-supercall-1': [FAIL], 'language/statements/class/fields-private-derived-cls-direct-eval-err-contains-supercall-2': [FAIL], - 'language/statements/class/fields-private-derived-cls-direct-eval-err-contains-superproperty-1': [FAIL], - 'language/statements/class/fields-private-derived-cls-direct-eval-err-contains-superproperty-2': [FAIL], 'language/statements/class/fields-private-derived-cls-indirect-eval-err-contains-supercall': [FAIL], 'language/statements/class/fields-private-derived-cls-indirect-eval-err-contains-supercall-1': [FAIL], 'language/statements/class/fields-private-derived-cls-indirect-eval-err-contains-supercall-2': [FAIL], - 'language/statements/class/fields-private-derived-cls-indirect-eval-err-contains-superproperty-1': [FAIL], - 'language/statements/class/fields-private-derived-cls-indirect-eval-err-contains-superproperty-2': [FAIL], - 'language/statements/class/fields-same-line-async-gen-static-private-methods-with-fields': [FAIL], - 'language/statements/class/fields-same-line-async-method-static-private-methods-with-fields': [FAIL], - 'language/statements/class/fields-same-line-gen-static-private-methods-with-fields': [FAIL], - - # https://github.com/tc39/test262/issues/1817 - 'language/expressions/class/dstr-private-gen-meth-dflt-ary-init-iter-close': [FAIL], - 'language/expressions/class/dstr-private-gen-meth-dflt-ary-init-iter-no-close': [FAIL], - 'language/expressions/class/dstr-private-gen-meth-dflt-ary-ptrn-rest-id-exhausted': [FAIL], - 'language/expressions/class/dstr-private-gen-meth-static-dflt-ary-init-iter-close': [FAIL], - 'language/expressions/class/dstr-private-gen-meth-static-dflt-ary-init-iter-no-close': [FAIL], - 'language/expressions/class/dstr-private-gen-meth-static-dflt-ary-ptrn-rest-id': [FAIL], - 'language/expressions/class/dstr-private-gen-meth-static-dflt-ary-ptrn-rest-id-exhausted': [FAIL], - 'language/expressions/class/dstr-private-gen-meth-static-dflt-obj-ptrn-rest-getter': [FAIL], - 'language/expressions/class/dstr-private-gen-meth-static-dflt-obj-ptrn-rest-skip-non-enumerable': [FAIL], - 'language/expressions/class/dstr-private-gen-meth-static-dflt-obj-ptrn-rest-val-obj': [FAIL], - 'language/statements/class/dstr-private-gen-meth-dflt-ary-init-iter-close': [FAIL], - 'language/statements/class/dstr-private-gen-meth-dflt-ary-init-iter-no-close': [FAIL], - 'language/statements/class/dstr-private-gen-meth-dflt-ary-ptrn-rest-id-exhausted': [FAIL], - 'language/statements/class/dstr-private-gen-meth-static-dflt-ary-init-iter-close': [FAIL], - 'language/statements/class/dstr-private-gen-meth-static-dflt-ary-init-iter-no-close': [FAIL], - 'language/statements/class/dstr-private-gen-meth-static-dflt-ary-ptrn-rest-id': [FAIL], - 'language/statements/class/dstr-private-gen-meth-static-dflt-ary-ptrn-rest-id-exhausted': [FAIL], - 'language/statements/class/dstr-private-gen-meth-static-dflt-obj-ptrn-rest-getter': [FAIL], - 'language/statements/class/dstr-private-gen-meth-static-dflt-obj-ptrn-rest-skip-non-enumerable': [FAIL], - 'language/statements/class/dstr-private-gen-meth-static-dflt-obj-ptrn-rest-val-obj': [FAIL], ############################ SLOW TESTS ############################# @@ -841,6 +795,59 @@ # BUG(v8:4653): Test262 tests which rely on quit() are not compatible with # asan's --omit-quit flag. 'built-ins/Promise/prototype/then/deferred-is-resolved-value': [SKIP], + 'language/module-code/dynamic-import/eval-export-dflt-cls-anon': [SKIP], + 'language/module-code/dynamic-import/eval-export-dflt-cls-named': [SKIP], + 'language/module-code/dynamic-import/eval-export-dflt-cls-name-meth': [SKIP], + 'language/module-code/dynamic-import/eval-export-dflt-expr-cls-anon': [SKIP], + 'language/module-code/dynamic-import/eval-export-dflt-expr-cls-named': [SKIP], + 'language/module-code/dynamic-import/eval-export-dflt-expr-cls-name-meth': [SKIP], + 'language/module-code/dynamic-import/eval-export-dflt-expr-fn-anon': [SKIP], + 'language/module-code/dynamic-import/eval-export-dflt-expr-fn-named': [SKIP], + 'language/module-code/dynamic-import/eval-export-dflt-expr-gen-anon': [SKIP], + 'language/module-code/dynamic-import/eval-export-dflt-expr-gen-named': [SKIP], + 'language/module-code/dynamic-import/eval-export-dflt-expr-in': [SKIP], + 'language/module-code/dynamic-import/usage/nested-arrow-assignment-expression-eval-gtbndng-indirect-update-dflt': [SKIP], + 'language/module-code/dynamic-import/usage/nested-arrow-assignment-expression-eval-gtbndng-indirect-update': [SKIP], + 'language/module-code/dynamic-import/usage/nested-arrow-assignment-expression-returns-promise': [SKIP], + 'language/module-code/dynamic-import/usage/nested-arrow-import-then-eval-gtbndng-indirect-update-dflt': [SKIP], + 'language/module-code/dynamic-import/usage/nested-arrow-import-then-eval-gtbndng-indirect-update': [SKIP], + 'language/module-code/dynamic-import/usage/nested-arrow-import-then-returns-promise': [SKIP], + 'language/module-code/dynamic-import/usage/nested-async-function-await-eval-gtbndng-indirect-update-dflt': [SKIP], + 'language/module-code/dynamic-import/usage/nested-async-function-await-eval-gtbndng-indirect-update': [SKIP], + 'language/module-code/dynamic-import/usage/nested-async-function-await-returns-promise': [SKIP], + 'language/module-code/dynamic-import/usage/nested-async-function-eval-gtbndng-indirect-update-dflt': [SKIP], + 'language/module-code/dynamic-import/usage/nested-async-function-eval-gtbndng-indirect-update': [SKIP], + 'language/module-code/dynamic-import/usage/nested-async-function-return-await-eval-gtbndng-indirect-update-dflt': [SKIP], + 'language/module-code/dynamic-import/usage/nested-async-function-return-await-eval-gtbndng-indirect-update': [SKIP], + 'language/module-code/dynamic-import/usage/nested-async-function-return-await-returns-promise': [SKIP], + 'language/module-code/dynamic-import/usage/nested-async-function-returns-promise': [SKIP], + 'language/module-code/dynamic-import/usage/nested-block-import-then-eval-gtbndng-indirect-update-dflt': [SKIP], + 'language/module-code/dynamic-import/usage/nested-block-import-then-eval-gtbndng-indirect-update': [SKIP], + 'language/module-code/dynamic-import/usage/nested-block-import-then-returns-promise': [SKIP], + 'language/module-code/dynamic-import/usage/nested-do-while-eval-gtbndng-indirect-update-dflt': [SKIP], + 'language/module-code/dynamic-import/usage/nested-do-while-eval-gtbndng-indirect-update': [SKIP], + 'language/module-code/dynamic-import/usage/nested-do-while-returns-promise': [SKIP], + 'language/module-code/dynamic-import/usage/nested-else-import-then-eval-gtbndng-indirect-update-dflt': [SKIP], + 'language/module-code/dynamic-import/usage/nested-else-import-then-eval-gtbndng-indirect-update': [SKIP], + 'language/module-code/dynamic-import/usage/nested-else-import-then-returns-promise': [SKIP], + 'language/module-code/dynamic-import/usage/nested-function-import-then-eval-gtbndng-indirect-update-dflt': [SKIP], + 'language/module-code/dynamic-import/usage/nested-function-import-then-eval-gtbndng-indirect-update': [SKIP], + 'language/module-code/dynamic-import/usage/nested-function-import-then-returns-promise': [SKIP], + 'language/module-code/dynamic-import/usage/nested-if-braceless-eval-gtbndng-indirect-update-dflt': [SKIP], + 'language/module-code/dynamic-import/usage/nested-if-braceless-eval-gtbndng-indirect-update': [SKIP], + 'language/module-code/dynamic-import/usage/nested-if-braceless-returns-promise': [SKIP], + 'language/module-code/dynamic-import/usage/nested-if-import-then-eval-gtbndng-indirect-update-dflt': [SKIP], + 'language/module-code/dynamic-import/usage/nested-if-import-then-eval-gtbndng-indirect-update': [SKIP], + 'language/module-code/dynamic-import/usage/nested-if-import-then-returns-promise': [SKIP], + 'language/module-code/dynamic-import/usage/nested-while-import-then-eval-gtbndng-indirect-update-dflt': [SKIP], + 'language/module-code/dynamic-import/usage/nested-while-import-then-eval-gtbndng-indirect-update': [SKIP], + 'language/module-code/dynamic-import/usage/nested-while-import-then-returns-promise': [SKIP], + 'language/module-code/dynamic-import/usage/syntax-nested-block-labeled-eval-gtbndng-indirect-update-dflt': [SKIP], + 'language/module-code/dynamic-import/usage/syntax-nested-block-labeled-eval-gtbndng-indirect-update': [SKIP], + 'language/module-code/dynamic-import/usage/syntax-nested-block-labeled-returns-promise': [SKIP], + 'language/module-code/dynamic-import/usage/top-level-import-then-eval-gtbndng-indirect-update-dflt': [SKIP], + 'language/module-code/dynamic-import/usage/top-level-import-then-eval-gtbndng-indirect-update': [SKIP], + 'language/module-code/dynamic-import/usage/top-level-import-then-returns-promise': [SKIP], }], # asan == True ['asan == True or msan == True or tsan == True', {