| 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 // TODO(v8:4698), TODO(ishell): support these cases. |
| 7 // Flags: --no-turbo --nostress-opt |
| 6 | 8 |
| 7 | 9 |
| 8 Error.prepareStackTrace = (error,stack) => { | 10 Error.prepareStackTrace = (error,stack) => { |
| 9 error.strace = stack; | 11 error.strace = stack; |
| 10 return error.message + "\n at " + stack.join("\n at "); | 12 return error.message + "\n at " + stack.join("\n at "); |
| 11 } | 13 } |
| 12 | 14 |
| 13 | 15 |
| 14 function CheckStackTrace(expected) { | 16 function checkStackTrace(expected) { |
| 15 var e = new Error(); | 17 var e = new Error(); |
| 16 e.stack; // prepare stack trace | 18 e.stack; // prepare stack trace |
| 17 var stack = e.strace; | 19 var stack = e.strace; |
| 18 assertEquals("CheckStackTrace", stack[0].getFunctionName()); | 20 assertEquals("checkStackTrace", stack[0].getFunctionName()); |
| 19 for (var i = 0; i < expected.length; i++) { | 21 for (var i = 0; i < expected.length; i++) { |
| 20 assertEquals(expected[i].name, stack[i + 1].getFunctionName()); | 22 assertEquals(expected[i].name, stack[i + 1].getFunctionName()); |
| 21 } | 23 } |
| 22 } | 24 } |
| 23 %NeverOptimizeFunction(CheckStackTrace); | |
| 24 | |
| 25 | |
| 26 function CheckArguments(expected, args) { | |
| 27 args = Array.prototype.slice.call(args); | |
| 28 assertEquals(expected, args); | |
| 29 } | |
| 30 %NeverOptimizeFunction(CheckArguments); | |
| 31 | 25 |
| 32 | 26 |
| 33 var CAN_INLINE_COMMENT = "// Let it be inlined."; | 27 var CAN_INLINE_COMMENT = "// Let it be inlined."; |
| 34 var DONT_INLINE_COMMENT = (function() { | 28 var DONT_INLINE_COMMENT = (function() { |
| 35 var line = "// Don't inline. Don't inline. Don't inline. Don't inline."; | 29 var line = "// Don't inline. Don't inline. Don't inline. Don't inline."; |
| 36 for (var i = 0; i < 4; i++) { | 30 for (var i = 0; i < 4; i++) { |
| 37 line += "\n " + line; | 31 line += "\n " + line; |
| 38 } | 32 } |
| 39 return line; | 33 return line; |
| 40 })(); | 34 })(); |
| 41 | 35 |
| 42 | 36 |
| 43 function ident_source(source, ident) { | 37 function ident_source(source, ident) { |
| 44 ident = " ".repeat(ident); | 38 ident = " ".repeat(ident); |
| 45 return ident + source.replace(/\n/gi, "\n" + ident); | 39 return ident + source.replace(/\n/gi, "\n" + ident); |
| 46 } | 40 } |
| 47 | 41 |
| 48 var global = Function('return this')(); | |
| 49 var the_receiver = {receiver: 1}; | |
| 50 | 42 |
| 51 function run_tests() { | 43 function run_tests() { |
| 52 function inlinable_comment(inlinable) { | 44 function inlinable_comment(inlinable) { |
| 53 return inlinable ? CAN_INLINE_COMMENT : DONT_INLINE_COMMENT; | 45 return inlinable ? CAN_INLINE_COMMENT : DONT_INLINE_COMMENT; |
| 54 } | 46 } |
| 55 | 47 |
| 48 // Check arguments manually to avoid bailing out with reason "bad value |
| 49 // context for arguments value". |
| 50 function check_arguments_template(expected_name) { |
| 51 var lines = [ |
| 52 ` assertEquals_(${expected_name}.length, arguments.length);`, |
| 53 ` for (var i = 0; i < ${expected_name}.length; i++) {`, |
| 54 ` assertEquals_(${expected_name}[i], arguments[i]);`, |
| 55 ` }`, |
| 56 ]; |
| 57 return lines.join("\n"); |
| 58 } |
| 59 var check_arguments = check_arguments_template("expected_args"); |
| 60 |
| 56 var f_cfg_sloppy = { | 61 var f_cfg_sloppy = { |
| 57 func_name: 'f', | 62 func_name: 'f', |
| 58 source_template: function(cfg) { | 63 source_template: function(cfg) { |
| 59 var receiver = cfg.f_receiver != undefined ? cfg.f_receiver | 64 var receiver = cfg.f_receiver != undefined ? cfg.f_receiver |
| 60 : "global"; | 65 : "global"; |
| 66 var do_checks = [ |
| 67 ` assertEquals_(${receiver}, this);`, |
| 68 ` assertEquals_(undefined, new.target);`, |
| 69 check_arguments, |
| 70 ` checkStackTrace_([f, test]);`, |
| 71 ].join("\n"); |
| 72 |
| 61 var lines = [ | 73 var lines = [ |
| 62 `function f(a) {`, | 74 `function f(a) {`, |
| 63 ` ${inlinable_comment(cfg.f_inlinable)}`, | 75 ` ${inlinable_comment(cfg.f_inlinable)}`, |
| 64 ` assertEquals(${receiver}, this);`, | 76 ` var expected_args = [${cfg.f_args}];`, |
| 65 ` CheckArguments([${cfg.f_args}], arguments);`, | 77 do_checks, |
| 66 ` CheckStackTrace([f, test]);`, | |
| 67 ` %DeoptimizeNow();`, | 78 ` %DeoptimizeNow();`, |
| 68 ` CheckArguments([${cfg.f_args}], arguments);`, | 79 do_checks, |
| 69 ` CheckStackTrace([f, test]);`, | |
| 70 ` return 42;`, | 80 ` return 42;`, |
| 71 `}`, | 81 `}`, |
| 72 ]; | 82 ]; |
| 73 return lines.join("\n"); | 83 return lines.join("\n"); |
| 74 }, | 84 }, |
| 75 }; | 85 }; |
| 76 | 86 |
| 77 var f_cfg_strict = { | 87 var f_cfg_strict = { |
| 78 func_name: 'f', | 88 func_name: 'f', |
| 79 source_template: function(cfg) { | 89 source_template: function(cfg) { |
| 80 var receiver = cfg.f_receiver != undefined ? cfg.f_receiver | 90 var receiver = cfg.f_receiver != undefined ? cfg.f_receiver |
| 81 : "undefined"; | 91 : "undefined"; |
| 92 var do_checks = [ |
| 93 ` assertEquals_(${receiver}, this);`, |
| 94 ` assertEquals_(undefined, new.target);`, |
| 95 check_arguments, |
| 96 ` checkStackTrace_([f, test]);`, |
| 97 ].join("\n"); |
| 98 |
| 82 var lines = [ | 99 var lines = [ |
| 83 `function f(a) {`, | 100 `function f(a) {`, |
| 84 ` "use strict";`, | 101 ` "use strict";`, |
| 85 ` ${inlinable_comment(cfg.f_inlinable)}`, | 102 ` ${inlinable_comment(cfg.f_inlinable)}`, |
| 86 ` assertEquals(${receiver}, this);`, | 103 ` var expected_args = [${cfg.f_args}];`, |
| 87 ` CheckArguments([${cfg.f_args}], arguments);`, | 104 do_checks, |
| 88 ` CheckStackTrace([f, test]);`, | |
| 89 ` %DeoptimizeNow();`, | 105 ` %DeoptimizeNow();`, |
| 90 ` CheckArguments([${cfg.f_args}], arguments);`, | 106 do_checks, |
| 91 ` CheckStackTrace([f, test]);`, | |
| 92 ` return 42;`, | 107 ` return 42;`, |
| 93 `}`, | 108 `}`, |
| 94 ]; | 109 ]; |
| 95 return lines.join("\n"); | 110 return lines.join("\n"); |
| 96 }, | 111 }, |
| 97 }; | 112 }; |
| 98 | 113 |
| 99 var f_cfg_possibly_eval = { | 114 var f_cfg_possibly_eval = { |
| 100 func_name: 'eval', | 115 func_name: 'eval', |
| 101 source_template: function(cfg) { | 116 source_template: function(cfg) { |
| 102 var receiver = cfg.f_receiver != undefined ? cfg.f_receiver | 117 var receiver = cfg.f_receiver != undefined ? cfg.f_receiver |
| 103 : "global"; | 118 : "global"; |
| 119 var do_checks = [ |
| 120 ` assertEquals_(${receiver}, this);`, |
| 121 ` assertEquals_(undefined, new.target);`, |
| 122 check_arguments, |
| 123 ` checkStackTrace_([f, test]);`, |
| 124 ].join("\n"); |
| 125 |
| 104 var lines = [ | 126 var lines = [ |
| 105 `function f(a) {`, | 127 `function f(a) {`, |
| 106 ` ${inlinable_comment(cfg.f_inlinable)}`, | 128 ` ${inlinable_comment(cfg.f_inlinable)}`, |
| 107 ` assertEquals(${receiver}, this);`, | 129 ` var expected_args = [${cfg.f_args}];`, |
| 108 ` CheckArguments([${cfg.f_args}], arguments);`, | 130 do_checks, |
| 109 ` CheckStackTrace([f, test]);`, | |
| 110 ` %DeoptimizeNow();`, | 131 ` %DeoptimizeNow();`, |
| 111 ` CheckArguments([${cfg.f_args}], arguments);`, | 132 do_checks, |
| 112 ` CheckStackTrace([f, test]);`, | |
| 113 ` return 42;`, | 133 ` return 42;`, |
| 114 `}`, | 134 `}`, |
| 115 `var eval = f;`, | 135 `var eval = f;`, |
| 116 ]; | 136 ]; |
| 117 return lines.join("\n"); | 137 return lines.join("\n"); |
| 118 }, | 138 }, |
| 119 }; | 139 }; |
| 120 | 140 |
| 121 var f_cfg_bound = { | 141 var f_cfg_bound = { |
| 122 func_name: 'bound', | 142 func_name: 'bound', |
| 123 source_template: function(cfg) { | 143 source_template: function(cfg) { |
| 144 var do_checks = [ |
| 145 ` assertEquals_(receiver, this);`, |
| 146 ` assertEquals_(undefined, new.target);`, |
| 147 check_arguments, |
| 148 ` checkStackTrace_([f, test]);`, |
| 149 ].join("\n"); |
| 150 |
| 124 var lines = [ | 151 var lines = [ |
| 125 `function f(a) {`, | 152 `function f(a) {`, |
| 126 ` "use strict";`, | 153 ` "use strict";`, |
| 127 ` ${inlinable_comment(cfg.f_inlinable)}`, | 154 ` ${inlinable_comment(cfg.f_inlinable)}`, |
| 128 ` assertEquals(receiver, this);`, | 155 ` var expected_args = [${cfg.f_args}];`, |
| 129 ` CheckArguments([${cfg.f_args}], arguments);`, | 156 do_checks, |
| 130 ` CheckStackTrace([f, test]);`, | |
| 131 ` %DeoptimizeNow();`, | 157 ` %DeoptimizeNow();`, |
| 132 ` CheckArguments([${cfg.f_args}], arguments);`, | 158 do_checks, |
| 133 ` CheckStackTrace([f, test]);`, | |
| 134 ` return 42;`, | 159 ` return 42;`, |
| 135 `}`, | 160 `}`, |
| 136 `var receiver = {a: 153};`, | 161 `var receiver = {a: 153};`, |
| 137 `var bound = f.bind(receiver);`, | 162 `var bound = f.bind(receiver);`, |
| 138 ]; | 163 ]; |
| 139 return lines.join("\n"); | 164 return lines.join("\n"); |
| 140 }, | 165 }, |
| 141 }; | 166 }; |
| 142 | 167 |
| 143 var f_cfg_proxy = { | 168 var f_cfg_proxy = { |
| 144 func_name: 'p', | 169 func_name: 'p', |
| 145 source_template: function(cfg) { | 170 source_template: function(cfg) { |
| 146 var receiver = cfg.f_receiver != undefined ? cfg.f_receiver | 171 var receiver = cfg.f_receiver != undefined ? cfg.f_receiver |
| 147 : "global"; | 172 : "global"; |
| 173 var do_checks = [ |
| 174 ` assertEquals_(${receiver}, this);`, |
| 175 ` assertEquals_(undefined, new.target);`, |
| 176 check_arguments, |
| 177 ` checkStackTrace_([f, test]);`, |
| 178 ].join("\n"); |
| 179 |
| 148 var lines = [ | 180 var lines = [ |
| 149 `function f(a) {`, | 181 `function f(a) {`, |
| 150 ` ${inlinable_comment(cfg.f_inlinable)}`, | 182 ` ${inlinable_comment(cfg.f_inlinable)}`, |
| 151 ` assertEquals(${receiver}, this);`, | 183 ` var expected_args = [${cfg.f_args}];`, |
| 152 ` CheckArguments([${cfg.f_args}], arguments);`, | 184 do_checks, |
| 153 ` CheckStackTrace([f, test]);`, | |
| 154 ` %DeoptimizeNow();`, | 185 ` %DeoptimizeNow();`, |
| 155 ` CheckArguments([${cfg.f_args}], arguments);`, | 186 do_checks, |
| 156 ` CheckStackTrace([f, test]);`, | |
| 157 ` return 42;`, | 187 ` return 42;`, |
| 158 `}`, | 188 `}`, |
| 159 `var p = new Proxy(f, {});`, | 189 `var p = new Proxy(f, {});`, |
| 160 ]; | 190 ]; |
| 161 return lines.join("\n"); | 191 return lines.join("\n"); |
| 162 }, | 192 }, |
| 163 }; | 193 }; |
| 164 | 194 |
| 165 var g_cfg_normal = { | 195 var g_cfg_normal = { |
| 166 receiver: undefined, | 196 receiver: undefined, |
| 167 source_template: function(cfg) { | 197 source_template: function(cfg) { |
| 168 var lines = [ | 198 var lines = [ |
| 169 `function g(a) {`, | 199 `function g(a) {`, |
| 170 ` "use strict";`, | 200 ` "use strict";`, |
| 171 ` ${inlinable_comment(cfg.g_inlinable)}`, | 201 ` ${inlinable_comment(cfg.g_inlinable)}`, |
| 172 ` CheckArguments([${cfg.g_args}], arguments);`, | 202 ` var expected_args = [${cfg.g_args}];`, |
| 203 check_arguments, |
| 173 ` return ${cfg.f_name}(${cfg.f_args});`, | 204 ` return ${cfg.f_name}(${cfg.f_args});`, |
| 174 `}`, | 205 `}`, |
| 175 ]; | 206 ]; |
| 176 return lines.join("\n"); | 207 return lines.join("\n"); |
| 177 }, | 208 }, |
| 178 }; | 209 }; |
| 179 | 210 |
| 180 | 211 |
| 181 var g_cfg_function_apply = { | 212 var g_cfg_function_apply = { |
| 182 receiver: "the_receiver", | 213 receiver: "the_receiver", |
| 183 source_template: function(cfg) { | 214 source_template: function(cfg) { |
| 184 var lines = [ | 215 var lines = [ |
| 185 `function g(a) {`, | 216 `function g(a) {`, |
| 186 ` "use strict";`, | 217 ` "use strict";`, |
| 187 ` ${inlinable_comment(cfg.g_inlinable)}`, | 218 ` ${inlinable_comment(cfg.g_inlinable)}`, |
| 188 ` CheckArguments([${cfg.g_args}], arguments);`, | 219 ` var expected_args = [${cfg.g_args}];`, |
| 220 check_arguments, |
| 189 ` return ${cfg.f_name}.apply(the_receiver, [${cfg.f_args}]);`, | 221 ` return ${cfg.f_name}.apply(the_receiver, [${cfg.f_args}]);`, |
| 190 `}`, | 222 `}`, |
| 191 ]; | 223 ]; |
| 192 return lines.join("\n"); | 224 return lines.join("\n"); |
| 193 }, | 225 }, |
| 194 }; | 226 }; |
| 195 | 227 |
| 196 | 228 |
| 229 var g_cfg_function_apply_arguments_object = { |
| 230 receiver: "the_receiver", |
| 231 source_template: function(cfg) { |
| 232 cfg.f_args = cfg.g_args; |
| 233 var lines = [ |
| 234 `function g(a) {`, |
| 235 ` "use strict";`, |
| 236 ` ${inlinable_comment(cfg.g_inlinable)}`, |
| 237 ` var expected_args = [${cfg.g_args}];`, |
| 238 check_arguments, |
| 239 ` return ${cfg.f_name}.apply(the_receiver, arguments);`, |
| 240 `}`, |
| 241 ]; |
| 242 return lines.join("\n"); |
| 243 }, |
| 244 }; |
| 245 |
| 246 |
| 197 var g_cfg_function_call = { | 247 var g_cfg_function_call = { |
| 198 receiver: "the_receiver", | 248 receiver: "the_receiver", |
| 199 source_template: function(cfg) { | 249 source_template: function(cfg) { |
| 200 var f_args = "the_receiver"; | 250 var f_args = "the_receiver"; |
| 201 if (cfg.f_args !== "") f_args += ", "; | 251 if (cfg.f_args !== "") f_args += ", "; |
| 202 f_args += cfg.f_args; | 252 f_args += cfg.f_args; |
| 203 | 253 |
| 204 var lines = [ | 254 var lines = [ |
| 205 `function g(a) {`, | 255 `function g(a) {`, |
| 206 ` "use strict";`, | 256 ` "use strict";`, |
| 207 ` ${inlinable_comment(cfg.g_inlinable)}`, | 257 ` ${inlinable_comment(cfg.g_inlinable)}`, |
| 208 ` CheckArguments([${cfg.g_args}], arguments);`, | 258 ` var expected_args = [${cfg.g_args}];`, |
| 259 check_arguments, |
| 209 ` return ${cfg.f_name}.call(${f_args});`, | 260 ` return ${cfg.f_name}.call(${f_args});`, |
| 210 `}`, | 261 `}`, |
| 211 ]; | 262 ]; |
| 212 return lines.join("\n"); | 263 return lines.join("\n"); |
| 213 }, | 264 }, |
| 214 }; | 265 }; |
| 215 | 266 |
| 216 | 267 |
| 217 function test_template(cfg) { | 268 function test_template(cfg) { |
| 269 // Note: g_source_template modifies cfg.f_args in some cases. |
| 270 var g_source = cfg.g_source_template(cfg); |
| 271 g_source = ident_source(g_source, 2); |
| 272 |
| 218 var f_source = cfg.f_source_template(cfg); | 273 var f_source = cfg.f_source_template(cfg); |
| 219 var g_source = cfg.g_source_template(cfg); | |
| 220 f_source = ident_source(f_source, 2); | 274 f_source = ident_source(f_source, 2); |
| 221 g_source = ident_source(g_source, 2); | |
| 222 | 275 |
| 223 var lines = [ | 276 var lines = [ |
| 224 `(function() {`, | 277 `(function() {`, |
| 278 ` // Avoid bailing out because of "Reference to a variable which requires
dynamic lookup".`, |
| 279 ` var assertEquals_ = assertEquals;`, |
| 280 ` var checkStackTrace_ = checkStackTrace;`, |
| 281 ` var undefined = void 0;`, |
| 282 ` var global = Function('return this')();`, |
| 283 ` var the_receiver = {receiver: 1};`, |
| 284 ``, |
| 285 ` // Don't inline helper functions`, |
| 286 ` %NeverOptimizeFunction(assertEquals);`, |
| 287 ` %NeverOptimizeFunction(checkStackTrace);`, |
| 288 ``, |
| 225 f_source, | 289 f_source, |
| 226 g_source, | 290 g_source, |
| 227 ` function test() {`, | 291 ` function test() {`, |
| 228 ` "use strict";`, | 292 ` "use strict";`, |
| 229 ` assertEquals(42, g(${cfg.g_args}));`, | 293 ` assertEquals_(42, g(${cfg.g_args}));`, |
| 230 ` }`, | 294 ` }`, |
| 231 ` ${cfg.f_inlinable ? "%SetForceInlineFlag(f)" : ""};`, | 295 ` ${cfg.f_inlinable ? "%SetForceInlineFlag(f)" : ""};`, |
| 232 ` ${cfg.g_inlinable ? "%SetForceInlineFlag(g)" : ""};`, | 296 ` ${cfg.g_inlinable ? "%SetForceInlineFlag(g)" : ""};`, |
| 233 ``, | 297 ` ${"test();".repeat(cfg.test_warmup_count)}`, |
| 234 ` test();`, | |
| 235 ` %OptimizeFunctionOnNextCall(test);`, | 298 ` %OptimizeFunctionOnNextCall(test);`, |
| 236 ` %OptimizeFunctionOnNextCall(f);`, | 299 ` %OptimizeFunctionOnNextCall(f);`, |
| 237 ` %OptimizeFunctionOnNextCall(g);`, | 300 ` %OptimizeFunctionOnNextCall(g);`, |
| 238 ` test();`, | 301 ` test();`, |
| 239 `})();`, | 302 `})();`, |
| 240 ``, | 303 ``, |
| 241 ]; | 304 ]; |
| 242 var source = lines.join("\n"); | 305 var source = lines.join("\n"); |
| 243 return source; | 306 return source; |
| 244 } | 307 } |
| 245 | 308 |
| 246 // TODO(v8:4698), TODO(ishell): support all commented cases. | 309 // TODO(v8:4698), TODO(ishell): support all commented cases. |
| 247 var f_args_variants = ["", "1", "1, 2"]; | 310 var f_args_variants = ["", "1", "1, 2"]; |
| 248 var g_args_variants = [/*"",*/ "10", /*"10, 20"*/]; | 311 var g_args_variants = ["", "10", "10, 20"]; |
| 249 var f_inlinable_variants = [/*true,*/ false]; | 312 var f_inlinable_variants = [/*true,*/ false]; |
| 250 var g_inlinable_variants = [true, false]; | 313 var g_inlinable_variants = [/*true,*/ false]; |
| 251 var f_variants = [ | 314 var f_variants = [ |
| 252 f_cfg_sloppy, | 315 f_cfg_sloppy, |
| 253 f_cfg_strict, | 316 f_cfg_strict, |
| 254 f_cfg_bound, | 317 f_cfg_bound, |
| 255 f_cfg_proxy, | 318 f_cfg_proxy, |
| 256 f_cfg_possibly_eval, | 319 f_cfg_possibly_eval, |
| 257 ]; | 320 ]; |
| 258 var g_variants = [ | 321 var g_variants = [ |
| 259 g_cfg_normal, | 322 g_cfg_normal, |
| 260 g_cfg_function_call, | 323 g_cfg_function_call, |
| 261 g_cfg_function_apply, | 324 g_cfg_function_apply, |
| 325 g_cfg_function_apply_arguments_object, |
| 262 ]; | 326 ]; |
| 327 var test_warmup_counts = [0, 1, 2]; |
| 263 | 328 |
| 264 f_variants.forEach((f_cfg) => { | 329 f_variants.forEach((f_cfg) => { |
| 265 g_variants.forEach((g_cfg) => { | 330 g_variants.forEach((g_cfg) => { |
| 266 f_args_variants.forEach((f_args) => { | 331 f_args_variants.forEach((f_args) => { |
| 267 g_args_variants.forEach((g_args) => { | 332 g_args_variants.forEach((g_args) => { |
| 268 f_inlinable_variants.forEach((f_inlinable) => { | 333 f_inlinable_variants.forEach((f_inlinable) => { |
| 269 g_inlinable_variants.forEach((g_inlinable) => { | 334 g_inlinable_variants.forEach((g_inlinable) => { |
| 270 var cfg = { | 335 test_warmup_counts.forEach((test_warmup_count) => { |
| 271 f_source_template: f_cfg.source_template, | 336 var cfg = { |
| 272 f_inlinable, | 337 f_source_template: f_cfg.source_template, |
| 273 f_args, | 338 f_inlinable, |
| 274 f_name: f_cfg.func_name, | 339 f_args, |
| 275 f_receiver: g_cfg.receiver, | 340 f_name: f_cfg.func_name, |
| 276 g_source_template: g_cfg.source_template, | 341 f_receiver: g_cfg.receiver, |
| 277 g_inlinable, | 342 g_source_template: g_cfg.source_template, |
| 278 g_args, | 343 g_inlinable, |
| 279 }; | 344 g_args, |
| 280 var source = test_template(cfg); | 345 test_warmup_count, |
| 281 print("===================="); | 346 }; |
| 282 print(source); | 347 var source = test_template(cfg); |
| 283 eval(source); | 348 print("===================="); |
| 349 print(source); |
| 350 eval(source); |
| 351 }); |
| 284 }); | 352 }); |
| 285 }); | 353 }); |
| 286 }); | 354 }); |
| 287 }); | 355 }); |
| 288 }); | 356 }); |
| 289 }); | 357 }); |
| 290 } | 358 } |
| 291 | 359 |
| 292 run_tests(); | 360 run_tests(); |
| OLD | NEW |