blob: 183f09847f43b6c6a2bde98c27d66f7ca13067eb [file] [log] [blame]
//@ skip if $architecture == "x86"
var createBuiltin = $vm.createBuiltin;
var iterationCount = 100000;
// This is pretty bad but I need a private name.
var putFuncToPrivateName = createBuiltin(`(function (func) { @generatorThis = func })`)
putFuncToPrivateName(function (a,b) { return b; })
function createTailCallForwardingFuncWith(body, thisValue) {
return createBuiltin(`(function (a) {
"use strict";
${body}
return @tailCallForwardArguments(@generatorThis, ${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 < iterationCount; 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 < iterationCount; 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 < iterationCount; 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);
}