| Index: test/mjsunit/es6/tail-call-megatest.js
|
| diff --git a/test/mjsunit/es6/tail-call-megatest.js b/test/mjsunit/es6/tail-call-megatest.js
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f85773eb476b7ba400315f19f608fa2f558c5d64
|
| --- /dev/null
|
| +++ b/test/mjsunit/es6/tail-call-megatest.js
|
| @@ -0,0 +1,175 @@
|
| +// Copyright 2016 the V8 project authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +// Flags: --allow-natives-syntax --harmony-tailcalls --no-turbo-inlining
|
| +
|
| +"use strict";
|
| +
|
| +Error.prepareStackTrace = (error,stack) => {
|
| + error.strace = stack;
|
| + return error.message + "\n at " + stack.join("\n at ");
|
| +}
|
| +
|
| +
|
| +function CheckStackTrace(expected) {
|
| + var e = new Error();
|
| + e.stack; // prepare stack trace
|
| + var stack = e.strace;
|
| + assertEquals("CheckStackTrace", stack[0].getFunctionName());
|
| + for (var i = 0; i < expected.length; i++) {
|
| + assertEquals(expected[i].name, stack[i + 1].getFunctionName());
|
| + }
|
| +}
|
| +%NeverOptimizeFunction(CheckStackTrace);
|
| +
|
| +
|
| +function CheckArguments(expected, args) {
|
| + args = Array.prototype.slice.call(args);
|
| + assertEquals(expected, args);
|
| +}
|
| +%NeverOptimizeFunction(CheckArguments);
|
| +
|
| +
|
| +var CAN_INLINE_COMMENT = "// Let it be inlined.";
|
| +var DONT_INLINE_COMMENT = (function() {
|
| + var line = "// Don't inline. Don't inline. Don't inline. Don't inline.";
|
| + for (var i = 0; i < 4; i++) {
|
| + line += "\n " + line;
|
| + }
|
| + return line;
|
| +})();
|
| +
|
| +
|
| +function ident_source(source, ident) {
|
| + ident = " ".repeat(ident);
|
| + return ident + source.replace(/\n/gi, "\n" + ident);
|
| +}
|
| +
|
| +
|
| +function run_tests() {
|
| +
|
| + function f_template_normal(f_inlinable, f_args) {
|
| + var f_comment = f_inlinable ? CAN_INLINE_COMMENT : DONT_INLINE_COMMENT;
|
| + var lines = [
|
| + `function f(a) {`,
|
| + ` ${f_comment}`,
|
| + ` assertEquals(undefined, this);`,
|
| + ` CheckArguments([${f_args}], arguments);`,
|
| + ` CheckStackTrace([f, test]);`,
|
| + ` %DeoptimizeNow();`,
|
| + ` CheckArguments([${f_args}], arguments);`,
|
| + ` CheckStackTrace([f, test]);`,
|
| + ` return 42;`,
|
| + `}`,
|
| + ];
|
| + return lines.join("\n");
|
| + }
|
| +
|
| + function f_template_bound(f_inlinable, f_args) {
|
| + var f_comment = f_inlinable ? CAN_INLINE_COMMENT : DONT_INLINE_COMMENT;
|
| + var lines = [
|
| + `function ff(a) {`,
|
| + ` ${f_comment}`,
|
| + ` assertEquals(153, this.a);`,
|
| + ` CheckArguments([${f_args}], arguments);`,
|
| + ` CheckStackTrace([ff, test]);`,
|
| + ` %DeoptimizeNow();`,
|
| + ` CheckArguments([${f_args}], arguments);`,
|
| + ` CheckStackTrace([ff, test]);`,
|
| + ` return 42;`,
|
| + `}`,
|
| + `var f = ff.bind({a: 153});`,
|
| + ];
|
| + return lines.join("\n");
|
| + }
|
| +
|
| + function f_template_proxy(f_inlinable, f_args) {
|
| + var f_comment = f_inlinable ? CAN_INLINE_COMMENT : DONT_INLINE_COMMENT;
|
| + var lines = [
|
| + `function ff(a) {`,
|
| + ` ${f_comment}`,
|
| + ` assertEquals(undefined, this);`,
|
| + ` CheckArguments([${f_args}], arguments);`,
|
| + ` CheckStackTrace([f, test]);`,
|
| + ` %DeoptimizeNow();`,
|
| + ` CheckArguments([${f_args}], arguments);`,
|
| + ` CheckStackTrace([f, test]);`,
|
| + ` return 42;`,
|
| + `}`,
|
| + `var f = new Proxy(ff, {});`,
|
| + ];
|
| + return lines.join("\n");
|
| + }
|
| +
|
| + function g_template(g_inlinable, f_args, g_args) {
|
| + var g_comment = g_inlinable ? CAN_INLINE_COMMENT : DONT_INLINE_COMMENT;
|
| + var lines = [
|
| + `function g(a) {`,
|
| + ` ${g_comment}`,
|
| + ` CheckArguments([${g_args}], arguments);`,
|
| + ` return f(${f_args});`,
|
| + `}`,
|
| + ];
|
| + return lines.join("\n");
|
| + }
|
| +
|
| + function test_template(f_source, g_source, g_args,
|
| + f_inlinable, g_inlinable) {
|
| + f_source = ident_source(f_source, 2);
|
| + g_source = ident_source(g_source, 2);
|
| +
|
| + var lines = [
|
| + `(function() {`,
|
| + f_source,
|
| + g_source,
|
| + ` function test() {`,
|
| + ` assertEquals(42, g(${g_args}));`,
|
| + ` }`,
|
| + ` ${f_inlinable ? "%SetForceInlineFlag(f)" : ""};`,
|
| + ` ${g_inlinable ? "%SetForceInlineFlag(g)" : ""};`,
|
| + ``,
|
| + ` test();`,
|
| + ` %OptimizeFunctionOnNextCall(test);`,
|
| + ` try { %OptimizeFunctionOnNextCall(f); } catch(e) {}`,
|
| + ` try { %OptimizeFunctionOnNextCall(ff); } catch(e) {}`,
|
| + ` %OptimizeFunctionOnNextCall(g);`,
|
| + ` test();`,
|
| + `})();`,
|
| + ``,
|
| + ];
|
| + var source = lines.join("\n");
|
| + return source;
|
| + }
|
| +
|
| + // TODO(v8:4698), TODO(ishell): support all commented cases.
|
| + var f_args_variants = ["", "1", "1, 2"];
|
| + var g_args_variants = [/*"",*/ "10", /*"10, 20"*/];
|
| + var f_inlinable_variants = [/*true,*/ false];
|
| + var g_inlinable_variants = [true, false];
|
| + var f_variants = [
|
| + f_template_normal,
|
| + f_template_bound,
|
| + f_template_proxy
|
| + ];
|
| +
|
| + f_variants.forEach((f_template) => {
|
| + f_args_variants.forEach((f_args) => {
|
| + g_args_variants.forEach((g_args) => {
|
| + f_inlinable_variants.forEach((f_inlinable) => {
|
| + g_inlinable_variants.forEach((g_inlinable) => {
|
| + var f_source = f_template(f_inlinable, f_args);
|
| + var g_source = g_template(g_inlinable, f_args, g_args);
|
| + var source = test_template(f_source, g_source, g_args,
|
| + f_inlinable, g_inlinable);
|
| + print("====================");
|
| + print(source);
|
| + eval(source);
|
| + });
|
| + });
|
| + });
|
| + });
|
| + });
|
| +}
|
| +
|
| +run_tests();
|
|
|