// 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); } %PrepareFunctionForOptimization(foo); 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); } %PrepareFunctionForOptimization(foo); 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); } %PrepareFunctionForOptimization(foo); 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); } %PrepareFunctionForOptimization(foo); 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); } %PrepareFunctionForOptimization(foo); 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); } %PrepareFunctionForOptimization(foo); 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); } %PrepareFunctionForOptimization(foo); 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); } %PrepareFunctionForOptimization(foo); 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); } %PrepareFunctionForOptimization(foo); 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); } %PrepareFunctionForOptimization(foo); 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); } %PrepareFunctionForOptimization(foo); 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); } %PrepareFunctionForOptimization(foo); 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); } %PrepareFunctionForOptimization(foo); 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); } %PrepareFunctionForOptimization(foo); 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); } %PrepareFunctionForOptimization(foo); 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); } %PrepareFunctionForOptimization(foo); 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); } %PrepareFunctionForOptimization(foo); 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); } %PrepareFunctionForOptimization(foo); 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); } %PrepareFunctionForOptimization(foo); 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); } %PrepareFunctionForOptimization(foo); 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); } %PrepareFunctionForOptimization(foo); 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); } %PrepareFunctionForOptimization(foo); 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]; } %PrepareFunctionForOptimization(foo); 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]; } %PrepareFunctionForOptimization(foo); 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; }); } %PrepareFunctionForOptimization(foo); 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; }); } %PrepareFunctionForOptimization(foo); 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; }); } %PrepareFunctionForOptimization(foo); 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")); })();