OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Flags: --allow-natives-syntax --harmony-tailcalls --no-turbo-inlining | 5 // Flags: --allow-natives-syntax --harmony-tailcalls --no-turbo-inlining |
6 | 6 |
7 "use strict"; | |
8 | 7 |
9 Error.prepareStackTrace = (error,stack) => { | 8 Error.prepareStackTrace = (error,stack) => { |
10 error.strace = stack; | 9 error.strace = stack; |
11 return error.message + "\n at " + stack.join("\n at "); | 10 return error.message + "\n at " + stack.join("\n at "); |
12 } | 11 } |
13 | 12 |
14 | 13 |
15 function CheckStackTrace(expected) { | 14 function CheckStackTrace(expected) { |
16 var e = new Error(); | 15 var e = new Error(); |
17 e.stack; // prepare stack trace | 16 e.stack; // prepare stack trace |
(...skipping 21 matching lines...) Expand all Loading... |
39 } | 38 } |
40 return line; | 39 return line; |
41 })(); | 40 })(); |
42 | 41 |
43 | 42 |
44 function ident_source(source, ident) { | 43 function ident_source(source, ident) { |
45 ident = " ".repeat(ident); | 44 ident = " ".repeat(ident); |
46 return ident + source.replace(/\n/gi, "\n" + ident); | 45 return ident + source.replace(/\n/gi, "\n" + ident); |
47 } | 46 } |
48 | 47 |
| 48 var global = Function('return this')(); |
| 49 var the_receiver = {receiver: 1}; |
49 | 50 |
50 function run_tests() { | 51 function run_tests() { |
51 | 52 function inlinable_comment(inlinable) { |
52 function f_template_normal(f_inlinable, f_args) { | 53 return inlinable ? CAN_INLINE_COMMENT : DONT_INLINE_COMMENT; |
53 var f_comment = f_inlinable ? CAN_INLINE_COMMENT : DONT_INLINE_COMMENT; | |
54 var lines = [ | |
55 `function f(a) {`, | |
56 ` ${f_comment}`, | |
57 ` assertEquals(undefined, this);`, | |
58 ` CheckArguments([${f_args}], arguments);`, | |
59 ` CheckStackTrace([f, test]);`, | |
60 ` %DeoptimizeNow();`, | |
61 ` CheckArguments([${f_args}], arguments);`, | |
62 ` CheckStackTrace([f, test]);`, | |
63 ` return 42;`, | |
64 `}`, | |
65 ]; | |
66 return lines.join("\n"); | |
67 } | 54 } |
68 | 55 |
69 function f_template_bound(f_inlinable, f_args) { | 56 var f_cfg_sloppy = { |
70 var f_comment = f_inlinable ? CAN_INLINE_COMMENT : DONT_INLINE_COMMENT; | 57 func_name: 'f', |
71 var lines = [ | 58 source_template: function(cfg) { |
72 `function ff(a) {`, | 59 var receiver = cfg.f_receiver != undefined ? cfg.f_receiver |
73 ` ${f_comment}`, | 60 : "global"; |
74 ` assertEquals(153, this.a);`, | 61 var lines = [ |
75 ` CheckArguments([${f_args}], arguments);`, | 62 `function f(a) {`, |
76 ` CheckStackTrace([ff, test]);`, | 63 ` ${inlinable_comment(cfg.f_inlinable)}`, |
77 ` %DeoptimizeNow();`, | 64 ` assertEquals(${receiver}, this);`, |
78 ` CheckArguments([${f_args}], arguments);`, | 65 ` CheckArguments([${cfg.f_args}], arguments);`, |
79 ` CheckStackTrace([ff, test]);`, | 66 ` CheckStackTrace([f, test]);`, |
80 ` return 42;`, | 67 ` %DeoptimizeNow();`, |
81 `}`, | 68 ` CheckArguments([${cfg.f_args}], arguments);`, |
82 `var f = ff.bind({a: 153});`, | 69 ` CheckStackTrace([f, test]);`, |
83 ]; | 70 ` return 42;`, |
84 return lines.join("\n"); | 71 `}`, |
85 } | 72 ]; |
| 73 return lines.join("\n"); |
| 74 }, |
| 75 }; |
86 | 76 |
87 function f_template_proxy(f_inlinable, f_args) { | 77 var f_cfg_strict = { |
88 var f_comment = f_inlinable ? CAN_INLINE_COMMENT : DONT_INLINE_COMMENT; | 78 func_name: 'f', |
89 var lines = [ | 79 source_template: function(cfg) { |
90 `function ff(a) {`, | 80 var receiver = cfg.f_receiver != undefined ? cfg.f_receiver |
91 ` ${f_comment}`, | 81 : "undefined"; |
92 ` assertEquals(undefined, this);`, | 82 var lines = [ |
93 ` CheckArguments([${f_args}], arguments);`, | 83 `function f(a) {`, |
94 ` CheckStackTrace([f, test]);`, | 84 ` "use strict";`, |
95 ` %DeoptimizeNow();`, | 85 ` ${inlinable_comment(cfg.f_inlinable)}`, |
96 ` CheckArguments([${f_args}], arguments);`, | 86 ` assertEquals(${receiver}, this);`, |
97 ` CheckStackTrace([f, test]);`, | 87 ` CheckArguments([${cfg.f_args}], arguments);`, |
98 ` return 42;`, | 88 ` CheckStackTrace([f, test]);`, |
99 `}`, | 89 ` %DeoptimizeNow();`, |
100 `var f = new Proxy(ff, {});`, | 90 ` CheckArguments([${cfg.f_args}], arguments);`, |
101 ]; | 91 ` CheckStackTrace([f, test]);`, |
102 return lines.join("\n"); | 92 ` return 42;`, |
103 } | 93 `}`, |
| 94 ]; |
| 95 return lines.join("\n"); |
| 96 }, |
| 97 }; |
104 | 98 |
105 function g_template(g_inlinable, f_args, g_args) { | 99 var f_cfg_possibly_eval = { |
106 var g_comment = g_inlinable ? CAN_INLINE_COMMENT : DONT_INLINE_COMMENT; | 100 func_name: 'eval', |
107 var lines = [ | 101 source_template: function(cfg) { |
108 `function g(a) {`, | 102 var receiver = cfg.f_receiver != undefined ? cfg.f_receiver |
109 ` ${g_comment}`, | 103 : "global"; |
110 ` CheckArguments([${g_args}], arguments);`, | 104 var lines = [ |
111 ` return f(${f_args});`, | 105 `function f(a) {`, |
112 `}`, | 106 ` ${inlinable_comment(cfg.f_inlinable)}`, |
113 ]; | 107 ` assertEquals(${receiver}, this);`, |
114 return lines.join("\n"); | 108 ` CheckArguments([${cfg.f_args}], arguments);`, |
115 } | 109 ` CheckStackTrace([f, test]);`, |
| 110 ` %DeoptimizeNow();`, |
| 111 ` CheckArguments([${cfg.f_args}], arguments);`, |
| 112 ` CheckStackTrace([f, test]);`, |
| 113 ` return 42;`, |
| 114 `}`, |
| 115 `var eval = f;`, |
| 116 ]; |
| 117 return lines.join("\n"); |
| 118 }, |
| 119 }; |
116 | 120 |
117 function test_template(f_source, g_source, g_args, | 121 var f_cfg_bound = { |
118 f_inlinable, g_inlinable) { | 122 func_name: 'bound', |
| 123 source_template: function(cfg) { |
| 124 var lines = [ |
| 125 `function f(a) {`, |
| 126 ` "use strict";`, |
| 127 ` ${inlinable_comment(cfg.f_inlinable)}`, |
| 128 ` assertEquals(receiver, this);`, |
| 129 ` CheckArguments([${cfg.f_args}], arguments);`, |
| 130 ` CheckStackTrace([f, test]);`, |
| 131 ` %DeoptimizeNow();`, |
| 132 ` CheckArguments([${cfg.f_args}], arguments);`, |
| 133 ` CheckStackTrace([f, test]);`, |
| 134 ` return 42;`, |
| 135 `}`, |
| 136 `var receiver = {a: 153};`, |
| 137 `var bound = f.bind(receiver);`, |
| 138 ]; |
| 139 return lines.join("\n"); |
| 140 }, |
| 141 }; |
| 142 |
| 143 var f_cfg_proxy = { |
| 144 func_name: 'p', |
| 145 source_template: function(cfg) { |
| 146 var receiver = cfg.f_receiver != undefined ? cfg.f_receiver |
| 147 : "global"; |
| 148 var lines = [ |
| 149 `function f(a) {`, |
| 150 ` ${inlinable_comment(cfg.f_inlinable)}`, |
| 151 ` assertEquals(${receiver}, this);`, |
| 152 ` CheckArguments([${cfg.f_args}], arguments);`, |
| 153 ` CheckStackTrace([f, test]);`, |
| 154 ` %DeoptimizeNow();`, |
| 155 ` CheckArguments([${cfg.f_args}], arguments);`, |
| 156 ` CheckStackTrace([f, test]);`, |
| 157 ` return 42;`, |
| 158 `}`, |
| 159 `var p = new Proxy(f, {});`, |
| 160 ]; |
| 161 return lines.join("\n"); |
| 162 }, |
| 163 }; |
| 164 |
| 165 var g_cfg_normal = { |
| 166 receiver: undefined, |
| 167 source_template: function(cfg) { |
| 168 var lines = [ |
| 169 `function g(a) {`, |
| 170 ` "use strict";`, |
| 171 ` ${inlinable_comment(cfg.g_inlinable)}`, |
| 172 ` CheckArguments([${cfg.g_args}], arguments);`, |
| 173 ` return ${cfg.f_name}(${cfg.f_args});`, |
| 174 `}`, |
| 175 ]; |
| 176 return lines.join("\n"); |
| 177 }, |
| 178 }; |
| 179 |
| 180 |
| 181 var g_cfg_function_apply = { |
| 182 receiver: "the_receiver", |
| 183 source_template: function(cfg) { |
| 184 var lines = [ |
| 185 `function g(a) {`, |
| 186 ` "use strict";`, |
| 187 ` ${inlinable_comment(cfg.g_inlinable)}`, |
| 188 ` CheckArguments([${cfg.g_args}], arguments);`, |
| 189 ` return ${cfg.f_name}.apply(the_receiver, [${cfg.f_args}]);`, |
| 190 `}`, |
| 191 ]; |
| 192 return lines.join("\n"); |
| 193 }, |
| 194 }; |
| 195 |
| 196 |
| 197 var g_cfg_function_call = { |
| 198 receiver: "the_receiver", |
| 199 source_template: function(cfg) { |
| 200 var f_args = "the_receiver"; |
| 201 if (cfg.f_args !== "") f_args += ", "; |
| 202 f_args += cfg.f_args; |
| 203 |
| 204 var lines = [ |
| 205 `function g(a) {`, |
| 206 ` "use strict";`, |
| 207 ` ${inlinable_comment(cfg.g_inlinable)}`, |
| 208 ` CheckArguments([${cfg.g_args}], arguments);`, |
| 209 ` return ${cfg.f_name}.call(${f_args});`, |
| 210 `}`, |
| 211 ]; |
| 212 return lines.join("\n"); |
| 213 }, |
| 214 }; |
| 215 |
| 216 |
| 217 function test_template(cfg) { |
| 218 var f_source = cfg.f_source_template(cfg); |
| 219 var g_source = cfg.g_source_template(cfg); |
119 f_source = ident_source(f_source, 2); | 220 f_source = ident_source(f_source, 2); |
120 g_source = ident_source(g_source, 2); | 221 g_source = ident_source(g_source, 2); |
121 | 222 |
122 var lines = [ | 223 var lines = [ |
123 `(function() {`, | 224 `(function() {`, |
124 f_source, | 225 f_source, |
125 g_source, | 226 g_source, |
126 ` function test() {`, | 227 ` function test() {`, |
127 ` assertEquals(42, g(${g_args}));`, | 228 ` "use strict";`, |
| 229 ` assertEquals(42, g(${cfg.g_args}));`, |
128 ` }`, | 230 ` }`, |
129 ` ${f_inlinable ? "%SetForceInlineFlag(f)" : ""};`, | 231 ` ${cfg.f_inlinable ? "%SetForceInlineFlag(f)" : ""};`, |
130 ` ${g_inlinable ? "%SetForceInlineFlag(g)" : ""};`, | 232 ` ${cfg.g_inlinable ? "%SetForceInlineFlag(g)" : ""};`, |
131 ``, | 233 ``, |
132 ` test();`, | 234 ` test();`, |
133 ` %OptimizeFunctionOnNextCall(test);`, | 235 ` %OptimizeFunctionOnNextCall(test);`, |
134 ` try { %OptimizeFunctionOnNextCall(f); } catch(e) {}`, | 236 ` %OptimizeFunctionOnNextCall(f);`, |
135 ` try { %OptimizeFunctionOnNextCall(ff); } catch(e) {}`, | |
136 ` %OptimizeFunctionOnNextCall(g);`, | 237 ` %OptimizeFunctionOnNextCall(g);`, |
137 ` test();`, | 238 ` test();`, |
138 `})();`, | 239 `})();`, |
139 ``, | 240 ``, |
140 ]; | 241 ]; |
141 var source = lines.join("\n"); | 242 var source = lines.join("\n"); |
142 return source; | 243 return source; |
143 } | 244 } |
144 | 245 |
145 // TODO(v8:4698), TODO(ishell): support all commented cases. | 246 // TODO(v8:4698), TODO(ishell): support all commented cases. |
146 var f_args_variants = ["", "1", "1, 2"]; | 247 var f_args_variants = ["", "1", "1, 2"]; |
147 var g_args_variants = [/*"",*/ "10", /*"10, 20"*/]; | 248 var g_args_variants = [/*"",*/ "10", /*"10, 20"*/]; |
148 var f_inlinable_variants = [/*true,*/ false]; | 249 var f_inlinable_variants = [/*true,*/ false]; |
149 var g_inlinable_variants = [true, false]; | 250 var g_inlinable_variants = [true, false]; |
150 var f_variants = [ | 251 var f_variants = [ |
151 f_template_normal, | 252 f_cfg_sloppy, |
152 f_template_bound, | 253 f_cfg_strict, |
153 f_template_proxy | 254 f_cfg_bound, |
| 255 f_cfg_proxy, |
| 256 f_cfg_possibly_eval, |
| 257 ]; |
| 258 var g_variants = [ |
| 259 g_cfg_normal, |
| 260 g_cfg_function_call, |
| 261 g_cfg_function_apply, |
154 ]; | 262 ]; |
155 | 263 |
156 f_variants.forEach((f_template) => { | 264 f_variants.forEach((f_cfg) => { |
157 f_args_variants.forEach((f_args) => { | 265 g_variants.forEach((g_cfg) => { |
158 g_args_variants.forEach((g_args) => { | 266 f_args_variants.forEach((f_args) => { |
159 f_inlinable_variants.forEach((f_inlinable) => { | 267 g_args_variants.forEach((g_args) => { |
160 g_inlinable_variants.forEach((g_inlinable) => { | 268 f_inlinable_variants.forEach((f_inlinable) => { |
161 var f_source = f_template(f_inlinable, f_args); | 269 g_inlinable_variants.forEach((g_inlinable) => { |
162 var g_source = g_template(g_inlinable, f_args, g_args); | 270 var cfg = { |
163 var source = test_template(f_source, g_source, g_args, | 271 f_source_template: f_cfg.source_template, |
164 f_inlinable, g_inlinable); | 272 f_inlinable, |
165 print("===================="); | 273 f_args, |
166 print(source); | 274 f_name: f_cfg.func_name, |
167 eval(source); | 275 f_receiver: g_cfg.receiver, |
| 276 g_source_template: g_cfg.source_template, |
| 277 g_inlinable, |
| 278 g_args, |
| 279 }; |
| 280 var source = test_template(cfg); |
| 281 print("===================="); |
| 282 print(source); |
| 283 eval(source); |
| 284 }); |
168 }); | 285 }); |
169 }); | 286 }); |
170 }); | 287 }); |
171 }); | 288 }); |
172 }); | 289 }); |
173 } | 290 } |
174 | 291 |
175 run_tests(); | 292 run_tests(); |
OLD | NEW |