| //@ 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; |
| } |
| } |
| } |
| } |
| } |
| } |