diff --git a/implementation-contributed/javascriptcore/stress/block-scope-redeclarations.js b/implementation-contributed/javascriptcore/stress/block-scope-redeclarations.js new file mode 100644 index 0000000000..e244647d8d --- /dev/null +++ b/implementation-contributed/javascriptcore/stress/block-scope-redeclarations.js @@ -0,0 +1,39 @@ +function shouldNotThrow(script) { + eval(script); +} + +function shouldThrowSyntaxError(script) { + let error; + try { + eval(script); + } catch (e) { + error = e; + } + + if (!(error instanceof SyntaxError)) + throw new Error('Expected SyntaxError!'); +} + +shouldThrowSyntaxError('{ var x; let x; }'); +shouldThrowSyntaxError('{ { var x; } let x; }'); +shouldThrowSyntaxError('{ { { var x; } } let x; }'); +shouldThrowSyntaxError('{ let x; var x; }'); +shouldThrowSyntaxError('{ let x; { var x; } }'); +shouldThrowSyntaxError('{ let x; { { var x; } } }'); + +shouldNotThrow('{ var x; { let x; } }'); +shouldNotThrow('{ var x; { { let x; } } }'); +shouldNotThrow('{ { let x; } var x; }'); +shouldNotThrow('{ { { let x; } } var x; }'); + +shouldThrowSyntaxError('{ var x; const x = 0; }'); +shouldThrowSyntaxError('{ { var x; } const x = 0; }'); +shouldThrowSyntaxError('{ { { var x; } } const x = 0; }'); +shouldThrowSyntaxError('{ const x = 0; var x; }'); +shouldThrowSyntaxError('{ const x = 0; { var x; } }'); +shouldThrowSyntaxError('{ const x = 0; { { var x; } } }'); + +shouldNotThrow('{ var x; { const x = 0; } }'); +shouldNotThrow('{ var x; { { const x = 0; } } }'); +shouldNotThrow('{ { const x = 0; } var x; }'); +shouldNotThrow('{ { { const x = 0; } } var x; }'); diff --git a/implementation-contributed/javascriptcore/stress/for-in-invalidate-context-weird-assignments.js b/implementation-contributed/javascriptcore/stress/for-in-invalidate-context-weird-assignments.js new file mode 100644 index 0000000000..8c1a4fc93a --- /dev/null +++ b/implementation-contributed/javascriptcore/stress/for-in-invalidate-context-weird-assignments.js @@ -0,0 +1,94 @@ +function assert(b) { + if (!b) + throw new Error("Bad"); +} + +function test(f) { + noInline(f); + for (let i = 0; i < 1000; ++i) + f(); +} + +function shouldThrowSyntaxError(script) { + let error; + try { + eval(script); + } catch (e) { + error = e; + } + + if (!(error instanceof SyntaxError)) + throw new Error('Expected SyntaxError!'); +} + +test(function() { + let o = {xx: 0}; + for (let i in o) { + for (i in [0, 1, 2]) { } + assert(typeof i === "string"); + assert(o[i] === undefined); + } +}); + +test(function() { + let o = {xx: 0}; + for (let i in o) { + for ({i} of [{i: 0}]) { } + assert(typeof i === "number"); + assert(o[i] === undefined); + } +}); + +test(function() { + let o = {xx: 0}; + for (let i in o) { + ;({i} = {i: 0}); + assert(typeof i === "number"); + assert(o[i] === undefined); + } +}); + +test(function() { + let o = {xx: 0}; + for (let i in o) { + ;([i] = [0]); + assert(typeof i === "number"); + assert(o[i] === undefined); + } +}); + +test(function() { + let o = {xx: 0}; + for (let i in o) { + ;({...i} = {a:20, b:30}); + assert(typeof i === "object"); + assert(o[i] === undefined); + } +}); + +test(function() { + let o = {xx: 0}; + for (let i in o) { + eval("i = 0;"); + assert(typeof i === "number"); + assert(o[i] === undefined); + } +}); + +shouldThrowSyntaxError( + `function f() { + let o = {xx: 0}; + for (let i in o) { + for (var i of [0]) { } + } + }` +); + +shouldThrowSyntaxError( + `function f() { + let o = {xx: 0}; + for (let i in o) { + var i = 0; + } + }` +); diff --git a/implementation-contributed/javascriptcore/stress/for-in-tests.js b/implementation-contributed/javascriptcore/stress/for-in-tests.js new file mode 100644 index 0000000000..3282c5f1db --- /dev/null +++ b/implementation-contributed/javascriptcore/stress/for-in-tests.js @@ -0,0 +1,199 @@ +function shouldThrowSyntaxError(script) { + let error; + try { + eval(script); + } catch (e) { + error = e; + } + + if (!(error instanceof SyntaxError)) + throw new Error('Expected SyntaxError!'); +} + +(function() { + // Iterate over an array with normal indexed properties. + var foo = function() { + var a = [1, 2, 3, 4, 5]; + var sum = 0; + var result = ""; + for (var p in a) + result += a[p]; + return result; + }; + noInline(foo); + for (var i = 0; i < 10000; ++i) { + if (foo() !== "12345") + throw new Error("bad result"); + } + foo(null); +})(); +(function() { + // Iterate over an object with normal non-indexed properties. + var foo = function() { + var o = {}; + o.x = 1; + o.y = 2; + o.z = 3; + var result = ""; + for (var p in o) + result += o[p]; + return result; + }; + noInline(foo); + for (var i = 0; i < 10000; ++i) { + if (foo() !== "123") + throw new Error("bad result"); + } + foo(null); +})(); +(function() { + // Iterate over an object with both indexed and non-indexed properties. + var foo = function() { + var o = {}; + o.x = 1; + o.y = 2; + o.z = 3; + o[0] = 4; + o[1] = 5; + o[2] = 6; + var result = ""; + for (var p in o) + result += o[p]; + return result; + }; + noInline(foo); + for (var i = 0; i < 10000; ++i) { + if (foo() != "456123") + throw new Error("bad result"); + } + foo(null); +})(); +(function() { + // Iterate over an array with both indexed and non-indexed properties. + var foo = function() { + var a = [4, 5, 6]; + a.x = 1; + a.y = 2; + a.z = 3; + var result = ""; + for (var p in a) + result += a[p]; + return result; + }; + noInline(foo); + for (var i = 0; i < 10000; ++i) { + if (foo() !== "456123") + throw new Error("bad result"); + } + foo(null); +})(); +(function() { + var foo = function(a, b) { + for (var p in b) { + var f1 = a[p]; + var f2 = b[p]; + if (f1 === f2) + continue; + a[p] = b[p]; + } + }; + noInline(foo); + for (var i = 0; i < 10000; ++i) { + var o1 = {}; + var o2 = {}; + o2.x = 42; + o2.y = 53; + foo(o1, o2); + if (o1.x !== o2.x) + throw new Error("bad result: " + o1.x + "!==" + o2.x); + if (o1.y !== o2.y) + throw new Error("bad result: " + o1.y + "!==" + o2.y); + } +})(); + +(function() { + var foo = function(a, b) { + for (var p = b in a) {} + return p; + }; + noInline(foo); + for (var i = 0; i < 10000; ++i) { + var expected = 'expected-result'; + var result = foo({}, expected); + if (expected !== result) + throw new Error("bad result: " + result + "!==" + expected); + } + for (var i = 0; i < 10000; ++i) { + var expected = 'a'; + var result = foo({a:'abcd'}, expected); + if (expected !== result) + throw new Error("bad result: " + result + "!==" + expected); + } + for (var i = 0; i < 10000; ++i) { + var expected = 'b'; + var result = foo({a:'abcd', b: 'bcde'}, expected); + if (expected !== result) + throw new Error("bad result: " + result + "!==" + expected); + } + + for (var i = 0; i < 10000; ++i) { + var expected = 'c'; + var o = {a:'abcd', b: 'bcde'}; + o.c = 'cdef'; + var result = foo(o, expected); + if (expected !== result) + throw new Error("bad result: " + result + "!==" + expected); + } +})(); + +(function() { + var boo = function () { return 'expected-result'; }; + var foo = function(a) { + for (var p = boo() in a) {} + return p; + }; + noInline(foo); + for (var i = 0; i < 10000; ++i) { + var expected = 'expected-result'; + var result = foo({}); + if (expected !== result) + throw new Error("bad result: " + result + "!==" + expected); + } +})(); + +shouldThrowSyntaxError( + `function foo(a, b) { + { + let p = 'some-value'; + for (var p = b in a) {} + } + }` +); + +(function() { + var foo = function(a, b, c) { + for (var p = b + c in a) {} + return p; + }; + noInline(foo); + for (var i = 0; i < 10000; ++i) { + var expected = 'expected-result'; + var result = foo({}, 'expected', '-result'); + if (expected !== result) + throw new Error("bad result: " + result + "!==" + expected); + } +})(); + +shouldThrowSyntaxError( + `function foo() { + 'use strict'; + for (var i = 0 in {}) {} + }` +); + +shouldThrowSyntaxError( + `function foo() { + const i = 10; + for (var i = 0 in {}) {} + }` +); diff --git a/implementation-contributed/javascriptcore/stress/json-stringify-string-builder-overflow.js b/implementation-contributed/javascriptcore/stress/json-stringify-string-builder-overflow.js new file mode 100644 index 0000000000..240c4f3c23 --- /dev/null +++ b/implementation-contributed/javascriptcore/stress/json-stringify-string-builder-overflow.js @@ -0,0 +1,29 @@ +//@ slow! +//@ skip if $architecture != "arm64" and $architecture != "x86-64" + +var exception; +try { + var str = JSON.stringify({ + 'a1': { + 'a2': { + 'a3': { + 'a4': { + 'a5': { + 'a6': 'AAAAAAAAAA' + } + } + } + } + } + }, function (key, value) { + var val = { + 'A': true, + }; + return val; + }, 1); +} catch (e) { + exception = e; +} + +if (exception != "Error: Out of memory") + throw "FAILED"; diff --git a/implementation-contributed/javascriptcore/stress/pow-expects-update-expression-on-lhs.js b/implementation-contributed/javascriptcore/stress/pow-expects-update-expression-on-lhs.js new file mode 100644 index 0000000000..c255259f3f --- /dev/null +++ b/implementation-contributed/javascriptcore/stress/pow-expects-update-expression-on-lhs.js @@ -0,0 +1,96 @@ +function testSyntax(script) { + try { + eval(script); + } catch (error) { + if (error instanceof SyntaxError) + throw new Error("Bad error: " + String(error)); + } +} + +function testSyntaxError(script, message) { + var error = null; + try { + eval(script); + } catch (e) { + error = e; + } + if (!error) + throw new Error("Expected syntax error not thrown"); + + if (String(error) !== message) + throw new Error("Bad error: " + String(error)); +} + +{ + let tokens = [ + '-', + '+', + '~', + '!', + 'typeof', + 'void', + 'delete', + ]; + + for (let token of tokens) { + testSyntaxError(` + function pow(a, b) + { + return ${token} a ** b; + } + `, `SyntaxError: Unexpected token '**'. Ambiguous unary expression in the left hand side of the exponentiation expression; parentheses must be used to disambiguate the expression.`); + } +} + +{ + let tokens = [ + '-', + '+', + '~', + '!', + 'typeof', + 'void', + 'delete', + ]; + + for (let token of tokens) { + testSyntax(` + function pow(a, b) + { + return (${token} a) ** b; + } + `); + } +} + +{ + let tokens = [ + '++', + '--', + ]; + + for (let token of tokens) { + testSyntax(` + function pow(a, b) + { + return ${token} a ** b; + } + `); + } +} + +{ + let tokens = [ + '++', + '--', + ]; + + for (let token of tokens) { + testSyntax(` + function pow(a, b) + { + return a ${token} ** b; + } + `); + } +} diff --git a/implementation-contributed/javascriptcore/stress/property-name-enumerator-should-cache-structure-after-getting-property-names.js b/implementation-contributed/javascriptcore/stress/property-name-enumerator-should-cache-structure-after-getting-property-names.js new file mode 100644 index 0000000000..27c4192e27 --- /dev/null +++ b/implementation-contributed/javascriptcore/stress/property-name-enumerator-should-cache-structure-after-getting-property-names.js @@ -0,0 +1,11 @@ +function foo(){ + o = Error(); + for (var s in o) { + o[s]; + o = Error(); + } +} +noInline(foo); + +for(var i = 0; i < 100; i++) + foo(); diff --git a/implementation-contributed/javascriptcore/stress/string-16bit-repeat-overflow.js b/implementation-contributed/javascriptcore/stress/string-16bit-repeat-overflow.js new file mode 100644 index 0000000000..bc724fbf62 --- /dev/null +++ b/implementation-contributed/javascriptcore/stress/string-16bit-repeat-overflow.js @@ -0,0 +1,9 @@ +var exception; +try { + print('\ud000'.repeat(2**30)); +} catch (e) { + exception = e; +} + +if (exception != "Error: Out of memory") + throw "FAILED"; diff --git a/implementation-contributed/javascriptcore/stress/string-overflow-createError.js b/implementation-contributed/javascriptcore/stress/string-overflow-createError.js new file mode 100644 index 0000000000..01d95ad622 --- /dev/null +++ b/implementation-contributed/javascriptcore/stress/string-overflow-createError.js @@ -0,0 +1,11 @@ +var exception; +try { + bar = '2.3023e-320' + foo = bar.padEnd(2147483644, 1); + foo(true, 1).value; +} catch (e) { + exception = e; +} + +if (exception != "Error: Out of memory") + throw "FAILED";