From 4dc81d37886f49512eb60dafe13b794af5ffeb29 Mon Sep 17 00:00:00 2001 From: Mike Pennisi Date: Mon, 1 Feb 2016 12:10:33 -0500 Subject: [PATCH] Add tests for tail-call optimization ECMAScript 2015 introduced tail call optimization for function calls occuring in a number of positions in the grammar. Assert expected behavior by triggering a large (but configurable) number of recursive function calls in these positions. Compliant runtimes will execute such programs without error; non-compliant runtimes are expected to fail these tests by throwing an error or crashing when system resources are exhausted. --- harness/tco-helper.js | 4 +++ .../expressions/call/tco-call-args.js | 20 +++++++++++++++ .../expressions/call/tco-member-args.js | 19 ++++++++++++++ test/language/expressions/comma/tco-final.js | 19 ++++++++++++++ .../expressions/conditional/tco-cond.js | 19 ++++++++++++++ .../expressions/conditional/tco-pos.js | 19 ++++++++++++++ .../expressions/logical-and/tco-right.js | 19 ++++++++++++++ .../expressions/logical-or/tco-right.js | 19 ++++++++++++++ .../expressions/tagged-template/tco-call.js | 25 +++++++++++++++++++ .../expressions/tagged-template/tco-member.js | 22 ++++++++++++++++ test/language/expressions/tco-pos.js | 19 ++++++++++++++ .../statements/block/tco-stmt-list.js | 19 ++++++++++++++ test/language/statements/block/tco-stmt.js | 19 ++++++++++++++ test/language/statements/do-while/tco-body.js | 21 ++++++++++++++++ .../language/statements/for/tco-const-body.js | 21 ++++++++++++++++ test/language/statements/for/tco-let-body.js | 21 ++++++++++++++++ test/language/statements/for/tco-lhs-body.js | 22 ++++++++++++++++ test/language/statements/for/tco-var-body.js | 21 ++++++++++++++++ test/language/statements/if/tco-else-body.js | 19 ++++++++++++++ test/language/statements/if/tco-if-body.js | 19 ++++++++++++++ test/language/statements/labeled/tco.js | 19 ++++++++++++++ test/language/statements/return/tco.js | 19 ++++++++++++++ .../statements/switch/tco-case-body-dflt.js | 19 ++++++++++++++ .../statements/switch/tco-case-body.js | 19 ++++++++++++++ .../statements/switch/tco-dftl-body.js | 19 ++++++++++++++ .../statements/try/tco-catch-finally.js | 21 ++++++++++++++++ test/language/statements/try/tco-catch.js | 23 +++++++++++++++++ test/language/statements/try/tco-finally.js | 21 ++++++++++++++++ test/language/statements/while/tco-body.js | 21 ++++++++++++++++ 29 files changed, 567 insertions(+) create mode 100644 harness/tco-helper.js create mode 100644 test/language/expressions/call/tco-call-args.js create mode 100644 test/language/expressions/call/tco-member-args.js create mode 100644 test/language/expressions/comma/tco-final.js create mode 100644 test/language/expressions/conditional/tco-cond.js create mode 100644 test/language/expressions/conditional/tco-pos.js create mode 100644 test/language/expressions/logical-and/tco-right.js create mode 100644 test/language/expressions/logical-or/tco-right.js create mode 100644 test/language/expressions/tagged-template/tco-call.js create mode 100644 test/language/expressions/tagged-template/tco-member.js create mode 100644 test/language/expressions/tco-pos.js create mode 100644 test/language/statements/block/tco-stmt-list.js create mode 100644 test/language/statements/block/tco-stmt.js create mode 100644 test/language/statements/do-while/tco-body.js create mode 100644 test/language/statements/for/tco-const-body.js create mode 100644 test/language/statements/for/tco-let-body.js create mode 100644 test/language/statements/for/tco-lhs-body.js create mode 100644 test/language/statements/for/tco-var-body.js create mode 100644 test/language/statements/if/tco-else-body.js create mode 100644 test/language/statements/if/tco-if-body.js create mode 100644 test/language/statements/labeled/tco.js create mode 100644 test/language/statements/return/tco.js create mode 100644 test/language/statements/switch/tco-case-body-dflt.js create mode 100644 test/language/statements/switch/tco-case-body.js create mode 100644 test/language/statements/switch/tco-dftl-body.js create mode 100644 test/language/statements/try/tco-catch-finally.js create mode 100644 test/language/statements/try/tco-catch.js create mode 100644 test/language/statements/try/tco-finally.js create mode 100644 test/language/statements/while/tco-body.js diff --git a/harness/tco-helper.js b/harness/tco-helper.js new file mode 100644 index 0000000000..5e9bee2257 --- /dev/null +++ b/harness/tco-helper.js @@ -0,0 +1,4 @@ +// This defines the number of consecutive recursive function calls that must be +// made in order to prove that stack frames are properly destroyed according to +// ES2015 tail call optimization semantics. +var $MAX_ITERATIONS = 100000; diff --git a/test/language/expressions/call/tco-call-args.js b/test/language/expressions/call/tco-call-args.js new file mode 100644 index 0000000000..586c06ddac --- /dev/null +++ b/test/language/expressions/call/tco-call-args.js @@ -0,0 +1,20 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Expression is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + function getF() { return f; } + return getF()(n - 1); +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/expressions/call/tco-member-args.js b/test/language/expressions/call/tco-member-args.js new file mode 100644 index 0000000000..4db0c9d180 --- /dev/null +++ b/test/language/expressions/call/tco-member-args.js @@ -0,0 +1,19 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Expression is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + return f(n - 1); +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/expressions/comma/tco-final.js b/test/language/expressions/comma/tco-final.js new file mode 100644 index 0000000000..a47bebbe2b --- /dev/null +++ b/test/language/expressions/comma/tco-final.js @@ -0,0 +1,19 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Expression is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + return 0, f(n - 1); +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/expressions/conditional/tco-cond.js b/test/language/expressions/conditional/tco-cond.js new file mode 100644 index 0000000000..910746f002 --- /dev/null +++ b/test/language/expressions/conditional/tco-cond.js @@ -0,0 +1,19 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Expression is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + return true ? f(n - 1) : 0; +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/expressions/conditional/tco-pos.js b/test/language/expressions/conditional/tco-pos.js new file mode 100644 index 0000000000..55cd30016a --- /dev/null +++ b/test/language/expressions/conditional/tco-pos.js @@ -0,0 +1,19 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Expression is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + return false ? 0 : f(n - 1); +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/expressions/logical-and/tco-right.js b/test/language/expressions/logical-and/tco-right.js new file mode 100644 index 0000000000..f4c34e71b8 --- /dev/null +++ b/test/language/expressions/logical-and/tco-right.js @@ -0,0 +1,19 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Expression is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + return true && f(n - 1); +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/expressions/logical-or/tco-right.js b/test/language/expressions/logical-or/tco-right.js new file mode 100644 index 0000000000..035218ffe3 --- /dev/null +++ b/test/language/expressions/logical-or/tco-right.js @@ -0,0 +1,19 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Expression is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + return false || f(n - 1); +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/expressions/tagged-template/tco-call.js b/test/language/expressions/tagged-template/tco-call.js new file mode 100644 index 0000000000..bcd50bcbf8 --- /dev/null +++ b/test/language/expressions/tagged-template/tco-call.js @@ -0,0 +1,25 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Expression is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +(function() { + var finished = false; + function getF() { + return f; + } + function f(_, n) { + if (n === 0) { + finished = true; + return; + } + return getF()`${n-1}`; + } + f(null, $MAX_ITERATIONS); + return finished; +}()); diff --git a/test/language/expressions/tagged-template/tco-member.js b/test/language/expressions/tagged-template/tco-member.js new file mode 100644 index 0000000000..c1148b9ff7 --- /dev/null +++ b/test/language/expressions/tagged-template/tco-member.js @@ -0,0 +1,22 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Expression is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +(function() { + var finished = false; + function f(_, n) { + if (n === 0) { + finished = true; + return; + } + return f`${n-1}`; + } + f(null, $MAX_ITERATIONS); + return finished; +}()); diff --git a/test/language/expressions/tco-pos.js b/test/language/expressions/tco-pos.js new file mode 100644 index 0000000000..652c1b54bc --- /dev/null +++ b/test/language/expressions/tco-pos.js @@ -0,0 +1,19 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Expression is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + return (f(n - 1)); +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/statements/block/tco-stmt-list.js b/test/language/statements/block/tco-stmt-list.js new file mode 100644 index 0000000000..f60ac5fb0a --- /dev/null +++ b/test/language/statements/block/tco-stmt-list.js @@ -0,0 +1,19 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Statement within statement is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + { void 0; return f(n - 1); } +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/statements/block/tco-stmt.js b/test/language/statements/block/tco-stmt.js new file mode 100644 index 0000000000..2bfdbdd1e2 --- /dev/null +++ b/test/language/statements/block/tco-stmt.js @@ -0,0 +1,19 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Statement within statement is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + { return f(n - 1); } +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/statements/do-while/tco-body.js b/test/language/statements/do-while/tco-body.js new file mode 100644 index 0000000000..5de287bb97 --- /dev/null +++ b/test/language/statements/do-while/tco-body.js @@ -0,0 +1,21 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Statement within statement is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + do { + return f(n - 1); + } while (false) +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/statements/for/tco-const-body.js b/test/language/statements/for/tco-const-body.js new file mode 100644 index 0000000000..d9c2c8427e --- /dev/null +++ b/test/language/statements/for/tco-const-body.js @@ -0,0 +1,21 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Statement within statement is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + for (const x = 0; ;) { + return f(n - 1); + } +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/statements/for/tco-let-body.js b/test/language/statements/for/tco-let-body.js new file mode 100644 index 0000000000..fb4dd5e5d1 --- /dev/null +++ b/test/language/statements/for/tco-let-body.js @@ -0,0 +1,21 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Statement within statement is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + for (let x = 0; ;) { + return f(n - 1); + } +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/statements/for/tco-lhs-body.js b/test/language/statements/for/tco-lhs-body.js new file mode 100644 index 0000000000..f6e04dc74a --- /dev/null +++ b/test/language/statements/for/tco-lhs-body.js @@ -0,0 +1,22 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Statement within statement is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + var x; + for (x = 0; x < 1; ++x) { + return f(n - 1); + } +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/statements/for/tco-var-body.js b/test/language/statements/for/tco-var-body.js new file mode 100644 index 0000000000..836b38ac92 --- /dev/null +++ b/test/language/statements/for/tco-var-body.js @@ -0,0 +1,21 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Statement within statement is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + for (var x = 0; ;) { + return f(n - 1); + } +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/statements/if/tco-else-body.js b/test/language/statements/if/tco-else-body.js new file mode 100644 index 0000000000..52472eed49 --- /dev/null +++ b/test/language/statements/if/tco-else-body.js @@ -0,0 +1,19 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Statement within statement is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + if (false) { } else { return f(n - 1); } +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/statements/if/tco-if-body.js b/test/language/statements/if/tco-if-body.js new file mode 100644 index 0000000000..07178b1fa2 --- /dev/null +++ b/test/language/statements/if/tco-if-body.js @@ -0,0 +1,19 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Statement within statement is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + if (true) { return f(n - 1); } +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/statements/labeled/tco.js b/test/language/statements/labeled/tco.js new file mode 100644 index 0000000000..2935d4c044 --- /dev/null +++ b/test/language/statements/labeled/tco.js @@ -0,0 +1,19 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Statement within statement is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + test262: return f(n - 1); +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/statements/return/tco.js b/test/language/statements/return/tco.js new file mode 100644 index 0000000000..89aa0670f8 --- /dev/null +++ b/test/language/statements/return/tco.js @@ -0,0 +1,19 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Expression within statement is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + return f(n - 1); +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/statements/switch/tco-case-body-dflt.js b/test/language/statements/switch/tco-case-body-dflt.js new file mode 100644 index 0000000000..e4edf2f663 --- /dev/null +++ b/test/language/statements/switch/tco-case-body-dflt.js @@ -0,0 +1,19 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Statement within statement is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + switch(0) { case 0: return f(n - 1); default: } +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/statements/switch/tco-case-body.js b/test/language/statements/switch/tco-case-body.js new file mode 100644 index 0000000000..834bb49ee4 --- /dev/null +++ b/test/language/statements/switch/tco-case-body.js @@ -0,0 +1,19 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Statement within statement is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + switch(0) { case 0: return f(n - 1); } +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/statements/switch/tco-dftl-body.js b/test/language/statements/switch/tco-dftl-body.js new file mode 100644 index 0000000000..edeec48ea9 --- /dev/null +++ b/test/language/statements/switch/tco-dftl-body.js @@ -0,0 +1,19 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Statement within statement is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + switch(0) { default: return f(n - 1); } +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/statements/try/tco-catch-finally.js b/test/language/statements/try/tco-catch-finally.js new file mode 100644 index 0000000000..74117563f1 --- /dev/null +++ b/test/language/statements/try/tco-catch-finally.js @@ -0,0 +1,21 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Statement within statement is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + try { } catch (err) { } finally { + return f(n - 1); + } +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/statements/try/tco-catch.js b/test/language/statements/try/tco-catch.js new file mode 100644 index 0000000000..e653703a9b --- /dev/null +++ b/test/language/statements/try/tco-catch.js @@ -0,0 +1,23 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Statement within statement is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + try { + throw null; + } catch (err) { + return f(n - 1); + } +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/statements/try/tco-finally.js b/test/language/statements/try/tco-finally.js new file mode 100644 index 0000000000..95ded7f3ca --- /dev/null +++ b/test/language/statements/try/tco-finally.js @@ -0,0 +1,21 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Statement within statement is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + try { } finally { + return f(n - 1); + } +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1); diff --git a/test/language/statements/while/tco-body.js b/test/language/statements/while/tco-body.js new file mode 100644 index 0000000000..c2d882bd4c --- /dev/null +++ b/test/language/statements/while/tco-body.js @@ -0,0 +1,21 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Statement within statement is a candidate for tail-call optimization. +id: static-semantics-hasproductionintailposition +flags: [onlyStrict] +features: [tail-call-optimization] +includes: [tco-helper.js] +---*/ + +var callCount = 0; +(function f(n) { + if (n === 0) { + callCount += 1 + return; + } + while (true) { + return f(n - 1); + } +}($MAX_ITERATIONS)); +assert.sameValue(callCount, 1);