blob: 2857b04638e8d8f5dddab52404871f36eb04080e [file] [log] [blame]
//@ runFTLNoCJIT
// Tests accessing an element in arguments before and after having a bad time.
// This test should not crash.
let verbose = false;
var utilities = 'function shouldEqual(testId, actual, expected) {' + '\n' +
' if (actual != expected)' + '\n' +
' throw testId + ": ERROR: expect " + expected + ", actual " + actual;' + '\n' +
'}' + '\n';
var haveABadTime = 'Object.defineProperty(Object.prototype, 20, { get() { return 20; } });' + '\n';
var directArgumentsDecl = ' var args = arguments;' + '\n';
var scopedArgumentsDecl = ' var args = arguments;' + '\n' +
' function closure() { return x; }' + '\n';
var clonedArgumentsDecl = ' "use strict";' + '\n' +
' var args = arguments;' + '\n';
function testFunction(argsDecl, insertElementAction, indexToReturn) {
var script = 'function test(x) {' + '\n' +
argsDecl +
insertElementAction +
' return args[' + indexToReturn + '];' + '\n' +
'}' + '\n' +
'noInline(test);' + '\n';
return script;
}
function warmupFunction(tierWarmupCount, testArgs) {
var script = 'function warmup() {' + '\n' +
' for (var i = 0; i < ' + tierWarmupCount + '; i++) {' + '\n' +
' test(' + testArgs + ');' + '\n' +
' }' + '\n' +
'}' + '\n';
return script;
}
let argumentsDecls = {
direct: directArgumentsDecl,
scoped: scopedArgumentsDecl,
cloned: clonedArgumentsDecl
};
let indicesToReturn = {
inBounds: 0,
outOfBoundsInsertedElement: 10,
outOfBoundsInPrototype: 20
};
let tierWarmupCounts = {
llint: 1,
baseline: 50,
dfg: 1000,
ftl: 10000
};
let testArgsList = {
noArgs: {
args: '',
result: {
inBounds: { beforeBadTime: 'undefined', afterBadTime: 'undefined', },
outOfBoundsInsertedElement: { beforeBadTime: '10', afterBadTime: '10', },
outOfBoundsInPrototype: { beforeBadTime: 'undefined', afterBadTime: '20', },
}
},
someArgs: {
args: '1, 2, 3',
result: {
inBounds: { beforeBadTime: '1', afterBadTime: '1', },
outOfBoundsInsertedElement: { beforeBadTime: '10', afterBadTime: '10', },
outOfBoundsInPrototype: { beforeBadTime: 'undefined', afterBadTime: '20', },
}
}
};
let insertElementActions = {
insertElement: ' args[10] = 10;' + '\n',
dontInsertElement: ''
};
for (let argsDeclIndex in argumentsDecls) {
let argsDecl = argumentsDecls[argsDeclIndex];
for (let indexToReturnIndex in indicesToReturn) {
let indexToReturn = indicesToReturn[indexToReturnIndex];
for (let insertElementActionIndex in insertElementActions) {
let insertElementAction = insertElementActions[insertElementActionIndex];
for (let tierWarmupCountIndex in tierWarmupCounts) {
let tierWarmupCount = tierWarmupCounts[tierWarmupCountIndex];
for (let testArgsIndex in testArgsList) {
let testArgs = testArgsList[testArgsIndex].args;
let expectedResult = testArgsList[testArgsIndex].result[indexToReturnIndex];
if (indexToReturnIndex == 'outOfBoundsInsertedElement'
&& insertElementActionIndex == 'dontInsertElement')
expectedResult = 'undefined';
let testName =
argsDeclIndex + '-' +
indexToReturnIndex + '-' +
insertElementActionIndex + '-' +
tierWarmupCountIndex + '-' +
testArgsIndex;
let script = utilities +
testFunction(argsDecl, insertElementAction, indexToReturn) +
warmupFunction(tierWarmupCount, testArgs) +
'warmup()' + '\n' +
'shouldEqual(10000, test(' + testArgs + '), ' + expectedResult['beforeBadTime'] + ');' + '\n';
haveABadTime +
'shouldEqual(20000, test(' + testArgs + '), ' + expectedResult['afterBadTime'] + ');' + '\n';
if (verbose) {
print('Running test configuration: ' + testName);
print(
'Test script: ====================================================\n' +
script +
'=== END script ==================================================');
}
try {
runString(script);
} catch (e) {
print('FAILED test configuration: ' + testName);
print('FAILED test script:\n' + script);
throw e;
}
}
}
}
}
}