mirror of https://github.com/tc39/test262.git
166 lines
5.0 KiB
JavaScript
166 lines
5.0 KiB
JavaScript
//@ skip if $architecture == "x86"
|
|
|
|
var createBuiltin = $vm.createBuiltin;
|
|
|
|
// This is pretty bad but I need a private name.
|
|
var putFuncToPrivateName = createBuiltin(`(function (func) { @arrayIteratorIsDone = func })`)
|
|
putFuncToPrivateName(function (a,b) { return b; })
|
|
|
|
function createTailCallForwardingFuncWith(body, thisValue) {
|
|
return createBuiltin(`(function (a) {
|
|
"use strict";
|
|
|
|
${body}
|
|
|
|
return @tailCallForwardArguments(@arrayIteratorIsDone, ${thisValue});
|
|
})`);
|
|
}
|
|
|
|
var foo = createTailCallForwardingFuncWith("", "@undefined");
|
|
|
|
function baz() {
|
|
return foo.call(true, 7);
|
|
}
|
|
noInline(baz);
|
|
|
|
|
|
|
|
var fooNoInline = createTailCallForwardingFuncWith("", "@undefined");
|
|
noInline(foo);
|
|
|
|
for (let i = 0; i < 100000; i++) {
|
|
if (baz.call() !== undefined)
|
|
throw new Error(i);
|
|
if (fooNoInline.call(undefined, 3) !== undefined)
|
|
throw new Error(i);
|
|
}
|
|
|
|
putFuncToPrivateName(function () { "use strict"; return { thisValue: this, argumentsValue: arguments}; });
|
|
var foo2 = createTailCallForwardingFuncWith("", "this");
|
|
var fooNI2 = createTailCallForwardingFuncWith("", "this");
|
|
noInline(fooNI2);
|
|
|
|
function baz2() {
|
|
return foo2.call(true, 7);
|
|
}
|
|
noInline(baz2);
|
|
|
|
for (let i = 0; i < 100000; i++) {
|
|
let result = foo2.call(true, 7);
|
|
if (result.thisValue !== true || result.argumentsValue.length !== 1 || result.argumentsValue[0] !== 7)
|
|
throw new Error(i);
|
|
result = baz2.call();
|
|
if (result.thisValue !== true || result.argumentsValue.length !== 1 || result.argumentsValue[0] !== 7)
|
|
throw new Error(i);
|
|
result = fooNI2.call(true, 7);
|
|
if (result.thisValue !== true || result.argumentsValue.length !== 1 || result.argumentsValue[0] !== 7)
|
|
throw new Error(i);
|
|
}
|
|
|
|
putFuncToPrivateName(function () { "use strict"; return this; });
|
|
var foo3 = createTailCallForwardingFuncWith("", "{ thisValue: this, otherValue: 'hello'} ");
|
|
var fooNI3 = createTailCallForwardingFuncWith("", "{ thisValue: this, otherValue: 'hello'} ");
|
|
noInline(fooNI3);
|
|
function baz3() {
|
|
return foo3.call(true, 7);
|
|
}
|
|
noInline(baz3);
|
|
|
|
for (let i = 0; i < 100000; i++) {
|
|
let result = foo3.call(true, 7);
|
|
if (result.thisValue !== true)
|
|
throw new Error(i);
|
|
result = baz3.call();
|
|
if (result.thisValue !== true)
|
|
throw new Error(i);
|
|
result = fooNI3.call(true, 7);
|
|
if (result.thisValue !== true)
|
|
throw new Error(i);
|
|
}
|
|
|
|
|
|
putFuncToPrivateName(function () { "use strict"; return this; });
|
|
let bodyText = `
|
|
for (let i = 0; i < 100; i++) {
|
|
if (a + i === 100)
|
|
return a;
|
|
}
|
|
`;
|
|
var foo4 = createTailCallForwardingFuncWith(bodyText, "{ thisValue: this, otherValue: 'hello'} ");
|
|
var fooNI4 = createTailCallForwardingFuncWith(bodyText, "{ thisValue: this, otherValue: 'hello'} ");
|
|
noInline(fooNI4);
|
|
function baz4() {
|
|
return foo4.call(true, 0);
|
|
}
|
|
noInline(baz4);
|
|
|
|
for (let i = 0; i < 100000; i++) {
|
|
let result = foo4.call(true, 0);
|
|
if (result.thisValue !== true || result.otherValue !== "hello")
|
|
throw new Error(i);
|
|
result = baz4.call();
|
|
if (result.thisValue !== true || result.otherValue !== "hello")
|
|
throw new Error(i);
|
|
result = fooNI4.call(true, 0);
|
|
if (result.thisValue !== true || result.otherValue !== "hello")
|
|
throw new Error(i);
|
|
result = fooNI4.call(true, 1);
|
|
if (result !== 1)
|
|
throw new Error(i);
|
|
result = fooNI4.call(true, "");
|
|
if (result.thisValue !== true || result.otherValue !== "hello")
|
|
throw new Error(i);
|
|
}
|
|
|
|
var testFunc = function () { "use strict"; return this; }
|
|
noInline(testFunc);
|
|
putFuncToPrivateName(testFunc);
|
|
|
|
var foo5 = createTailCallForwardingFuncWith(bodyText, "{ thisValue: this, otherValue: 'hello'} ");
|
|
var fooNI5 = createTailCallForwardingFuncWith(bodyText, "{ thisValue: this, otherValue: 'hello'} ");
|
|
noInline(fooNI5);
|
|
function baz5() {
|
|
return foo5.call(true, 0);
|
|
}
|
|
noInline(baz5);
|
|
|
|
for (let i = 0; i < 100000; i++) {
|
|
let result = foo5.call(true, 0);
|
|
if (result.thisValue !== true || result.otherValue !== "hello")
|
|
throw new Error(i);
|
|
result = baz5.call();
|
|
if (result.thisValue !== true || result.otherValue !== "hello")
|
|
throw new Error(i);
|
|
result = fooNI5.call(true, 0);
|
|
if (result.thisValue !== true || result.otherValue !== "hello")
|
|
throw new Error(i);
|
|
result = fooNI5.call(true, 1);
|
|
if (result !== 1)
|
|
throw new Error(i);
|
|
result = fooNI5.call(true, "");
|
|
if (result.thisValue !== true || result.otherValue !== "hello")
|
|
throw new Error(i);
|
|
}
|
|
|
|
putFuncToPrivateName(function() { return arguments; });
|
|
var foo6 = createTailCallForwardingFuncWith(bodyText, "{ thisValue: this, otherValue: 'hello'} ");
|
|
function baz6() {
|
|
"use strict"
|
|
return foo6.apply(this, arguments);
|
|
}
|
|
noInline(baz6);
|
|
|
|
function arrayEq(a, b) {
|
|
if (a.length !== b.length)
|
|
throw new Error();
|
|
for (let i = 0; i < a.length; i++) {
|
|
if (a[i] !== b[i])
|
|
throw new Error();
|
|
}
|
|
}
|
|
let args = ["a", {}, [], Symbol(), 1, 1.234, undefined, null];
|
|
for (let i = 0; i < 100000; i++) {
|
|
let result = baz6.apply(undefined, args);
|
|
arrayEq(result, args);
|
|
}
|