v8/test/mjsunit/baseline/test-baseline.js
Toon Verwaest 863a2d6c24 [interpreter] Remove unused interpreter intrinsics
This also removes intrinsics that were just used in tests. It keeps
InlineIncBlockCounter for now because it's a less straightforward.

Change-Id: I77e55d7a746294892d0fd7ab577ebf8eb42f1f08
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2953195
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75217}
2021-06-17 13:43:41 +00:00

329 lines
8.7 KiB
JavaScript

// Copyright 2020 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 --super-ic --sparkplug --no-always-sparkplug
function run(f, ...args) {
try { f(...args); } catch (e) {}
%CompileBaseline(f);
return f(...args);
}
function construct(f, ...args) {
try { new f(...args); } catch (e) {}
%CompileBaseline(f);
return new f(...args);
}
// Constants
assertEquals(run(()=>undefined), undefined);
assertEquals(run(()=>null), null);
assertEquals(run(()=>true), true);
assertEquals(run(()=>false), false);
assertEquals(run(()=>"bla"), "bla");
assertEquals(run(()=>42), 42);
assertEquals(run(()=>0), 0);
// Variables
assertEquals(run(()=>{let a = 42; return a}), 42);
assertEquals(run(()=>{let a = 42; let b = 32; return a}), 42);
// Arguments
assertEquals(run((a)=>a, 42), 42);
assertEquals(run((a,b)=>b, 1, 42), 42);
assertEquals(run((a,b,c)=>c, 1, 2, 42), 42);
// Property load
assertEquals(run((o)=>o.a, {a:42}), 42);
assertEquals(run((o, k)=>o[k], {a:42}, "a"), 42);
// Property store
assertEquals(run((o)=>{o.a=42; return o}, {}).a, 42);
assertEquals(run((o, k)=>{o[k]=42; return o}, {}, "a").a, 42);
// Global load/store
global_x = 45;
assertEquals(run(()=>global_x), 45);
run(()=>{ global_x = 49 })
assertEquals(global_x, 49);
// Context load
(function () {
let x = 42;
assertEquals(run(()=>{return x;}), 42);
})();
(function () {
let x = 4;
x = 42;
assertEquals(run(()=>{return x;}), 42);
})();
// Context store
(function () {
let x = 4;
run(()=>{x = 42;});
assertEquals(x, 42);
})();
// Super
// var o = {__proto__:{a:42}, m() { return super.a }};
// assertEquals(run(o.m), 42);
// Control flow
assertEquals(run((x)=>{ if(x) return 5; return 10;}), 10);
assertEquals(run(()=>{ var x = 0; for(var i = 1; i; i=0) x=10; return x;}), 10);
assertEquals(run(()=>{ var x = 0; for(var i = 0; i < 10; i+=1) x+=1; return x;}), 10);
assertEquals(run(()=>{ var x = 0; for(var i = 0; i < 10; ++i) x+=1; return x;}), 10);
// Typeof
function testTypeOf(o, t) {
let types = ['number', 'string', 'symbol', 'boolean', 'bigint', 'undefined',
'function', 'object'];
assertEquals(t, eval('run(()=>typeof ' + o + ')'),
`(()=>typeof ${o})() == ${t}`);
assertTrue(eval('run(()=>typeof ' + o + ' == "' + t + '")'),
`typeof ${o} == ${t}`);
var other_types = types.filter((x) => x !== t);
for (var other of other_types) {
assertFalse(eval('run(()=>typeof ' + o + ' == "' + other + '")'),
`typeof ${o} != ${other}`);
}
}
testTypeOf('undefined', 'undefined');
testTypeOf('null', 'object');
testTypeOf('true', 'boolean');
testTypeOf('false', 'boolean');
testTypeOf('42.42', 'number');
testTypeOf('42', 'number');
testTypeOf('42n', 'bigint');
testTypeOf('"42"', 'string');
testTypeOf('Symbol(42)', 'symbol');
testTypeOf('{}', 'object');
testTypeOf('[]', 'object');
testTypeOf('new Proxy({}, {})', 'object');
testTypeOf('new Proxy([], {})', 'object');
testTypeOf('(_ => 42)', 'function');
testTypeOf('function() {}', 'function');
testTypeOf('function*() {}', 'function');
testTypeOf('async function() {}', 'function');
testTypeOf('async function*() {}', 'function');
testTypeOf('new Proxy(_ => 42, {})', 'function');
testTypeOf('class {}', 'function');
testTypeOf('Object', 'function');
// Binop
assertEquals(run((a,b)=>{return a+b}, 41, 1), 42);
assertEquals(run((a,b)=>{return a*b}, 21, 2), 42);
assertEquals(run((a)=>{return a+3}, 39), 42);
assertEquals(run((a,b)=>{return a&b}, 0x23, 0x7), 0x3);
assertEquals(run((a)=>{return a&0x7}, 0x23), 0x3);
assertEquals(run((a,b)=>{return a|b}, 0x23, 0x7), 0x27);
assertEquals(run((a)=>{return a|0x7}, 0x23), 0x27);
assertEquals(run((a,b)=>{return a^b}, 0x23, 0x7), 0x24);
assertEquals(run((a)=>{return a^0x7}, 0x23), 0x24);
// Unop
assertEquals(run((x)=>{return x++}, 41), 41);
assertEquals(run((x)=>{return ++x}, 41), 42);
assertEquals(run((x)=>{return x--}, 41), 41);
assertEquals(run((x)=>{return --x}, 41), 40);
assertEquals(run((x)=>{return !x}, 41), false);
assertEquals(run((x)=>{return ~x}, 41), ~41);
// Calls
function f0() { return 42; }
function f1(x) { return x; }
function f2(x, y) { return x + y; }
function f3(x, y, z) { return y + z; }
assertEquals(run(()=>{return f0()}), 42);
assertEquals(run(()=>{return f1(42)}), 42);
assertEquals(run(()=>{return f2(41, 1)}), 42);
assertEquals(run(()=>{return f3(1, 2, 40)}), 42);
// Mapped Arguments
function mapped_args() {
return [arguments.length, ...arguments];
}
function mapped_args_dup(a,a) {
return [arguments.length, ...arguments];
}
assertEquals(run(mapped_args, 1, 2, 3), [3,1,2,3]);
assertEquals(run(mapped_args_dup, 1, 2, 3), [3,1,2,3]);
// Unmapped Arguments
function unmapped_args() {
"use strict";
return [arguments.length, ...arguments];
}
assertEquals(run(unmapped_args, 1, 2, 3), [3,1,2,3]);
// Rest Arguments
function rest_args(...rest) {
return [rest.length, ...rest];
}
assertEquals(run(rest_args, 1, 2, 3), [3,1,2,3]);
// Property call
let obj = {
f0: () => { return 42; },
f1: (x) => { return x; },
f2: (x, y) => { return x + y; },
f3: (x, y, z) => { return y + z; }
}
assertEquals(run(()=>{return obj.f0()}), 42);
assertEquals(run(()=>{return obj.f1(42)}), 42);
assertEquals(run(()=>{return obj.f2(41, 1)}), 42);
assertEquals(run(()=>{return obj.f3(1, 2, 40)}), 42);
// Call with spread
let ns = [2, 40];
assertEquals(run(()=>{return f3("x", ...ns)}), 42);
// Construct
function C(a, b, c) { this.x = 39 + b + c; }
assertEquals(run(()=>{return (new C("a", 1, 2)).x}), 42);
assertEquals(run(()=>{return (new C("a", ...ns)).x}), 81);
// Construct Array
assertEquals(run(()=>{return new Array(1, 2, 39);}).reduce((a,x)=>a+x), 42);
// Call Runtime
assertMatches(run(() => { return %NewRegExpWithBacktrackLimit("ax", "", 50); }), "ax");
run(() => { %CompileBaseline(()=>{}); });
// CallRuntimeForPair
assertEquals(run(()=>{with (f0) return f0();}), 42);
// Closure
assertEquals(run((o)=>{if (true) {let x = o; return ()=>x}}, 42)(), 42);
assertEquals(run((o)=>{return ()=>o}, 42)(), 42);
// Object / Array Literals
assertEquals(run((o)=>{return {a:42}}), {a:42});
assertEquals(run((o)=>{return [42]}), [42]);
assertEquals(run((o)=>{return []}), []);
assertEquals(run((o)=>{return {}}), {});
assertEquals(run((o)=>{return {...o}}, {a:42}), {a:42});
assertEquals(run((o)=>{return /42/}), /42/);
assertEquals(run((o)=>{return [...o]}, [1,2,3,4]), [1,2,3,4]);
// Construct
// Throw if the super() isn't a constructor
class T extends Object { constructor() { super() } }
T.__proto__ = null;
assertThrows(()=>construct(T));
run((o)=>{ try { } finally { } });
// SwitchOnSmiNoFeeback
run((o) => {
var x = 0;
var y = 0;
while (true) {
try {
x++;
if (x == 2) continue;
if (x == 5) break;
} finally {
y++;
}
}
return x + y;
}, 10);
// GetIterator
assertEquals(run((o)=>{
let sum = 0; for (x of [1, 2]) {sum += x;} return sum;}), 3);
// ForIn
assertEquals(run((o)=>{ let sum = 0; for (let k in o) { sum += o[k] }; return sum }, {a:41,b:1}), 42);
// In
assertTrue(run((o, k)=>{return k in o}, {a:1}, "a"));
assertFalse(run((o, k)=>{return k in o}, {a:1}, "b"));
class D {}
assertTrue(run((o, c)=>{return o instanceof c}, new D(), D));
assertTrue(run((o, c)=>{return o instanceof c}, new D(), Object));
assertFalse(run((o, c)=>{return o instanceof c}, new D(), RegExp));
// CreateArrayFromIterable
assertEquals(run((a)=>{return [...a]}, [1,2,3]), [1,2,3]);
// Generator
let gen = run(function*() {
yield 1;
yield 2;
yield 3;
});
let i = 1;
for (let val of gen) {
assertEquals(i++, val);
}
assertEquals(4, i);
// Generator with a lot of locals
let gen_func_with_a_lot_of_locals = eval(`(function*() {
${ Array(32*1024).fill().map((x,i)=>`let local_${i};`).join("\n") }
yield 1;
yield 2;
yield 3;
})`);
i = 1;
for (let val of run(gen_func_with_a_lot_of_locals)) {
assertEquals(i++, val);
}
assertEquals(4, i);
// Async await
run(async function() {
await 1;
await 1;
await 1;
return 42;
}).then(x=>assertEquals(42, x));
// Try-catch
assertEquals(run((x)=>{
if (x) {
try {
if (x) throw x;
return 45;
} catch (e) {
return e;
}
}
}, 42), 42);
// Tier-up via InterpreterEntryTrampoline
(function() {
function factory() {
return function(a) {
return a;
};
}
let f1 = factory();
let f2 = factory();
%NeverOptimizeFunction(f1);
%NeverOptimizeFunction(f2);
assertEquals(f1(0), 0);
assertEquals(f2(0), 0);
assertTrue(isInterpreted(f1))
assertFalse(isBaseline(f1));
assertTrue(isInterpreted(f2))
assertFalse(isBaseline(f2));
%CompileBaseline(f1);
assertEquals(f1(0), 0);
assertTrue(isBaseline(f1));
assertFalse(isBaseline(f2));
assertEquals(f2(0), 0);
assertTrue(isBaseline(f1));
assertTrue(isBaseline(f2));
})();