mirror of
				https://github.com/tc39/test262.git
				synced 2025-10-31 03:34:08 +01:00 
			
		
		
		
	sourceRevisionAtLastExport: 33f2fb0e53d135f0ee17cfccd9d993eb2a6f47de targetRevisionAtLastExport: 31340cbd9add103f586d501b0c3354b7b182abc0
		
			
				
	
	
		
			380 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			380 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // Copyright 2017 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: --preparser-scope-analysis --enable-slow-asserts
 | |
| 
 | |
| (function TestBasicSkipping() {
 | |
|   var result = 0;
 | |
| 
 | |
|   function lazy(ctxt_alloc_param) {
 | |
|     var ctxt_alloc_var = 10;
 | |
|     function skip_me() {
 | |
|       result = ctxt_alloc_param + ctxt_alloc_var;
 | |
|     }
 | |
|     return skip_me;
 | |
|   }
 | |
|   // Test that parameters and variables of the outer function get context
 | |
|   // allocated even if we skip the inner function.
 | |
|   lazy(9)();
 | |
|   assertEquals(19, result);
 | |
| })();
 | |
| 
 | |
| (function TestSkippingFunctionWithEval() {
 | |
|   var result = 0;
 | |
| 
 | |
|   function lazy(ctxt_alloc_param) {
 | |
|     var ctxt_alloc_var = 10;
 | |
|     function skip_me() {
 | |
|       eval('result = ctxt_alloc_param + ctxt_alloc_var');
 | |
|     }
 | |
|     return skip_me;
 | |
|   }
 | |
|   // Test that parameters and variables of the outer function get context
 | |
|   // allocated even if we skip the inner function.
 | |
|   lazy(9)();
 | |
|   assertEquals(19, result);
 | |
| })();
 | |
| 
 | |
| (function TestCtxtAllocatingNonSimpleParams1() {
 | |
|   var result = 0;
 | |
| 
 | |
|   function lazy([other_param1, ctxt_alloc_param, other_param2]) {
 | |
|     function skip_me() {
 | |
|       result = ctxt_alloc_param;
 | |
|     }
 | |
|     return skip_me;
 | |
|   }
 | |
|   // Test that parameters and variables of the outer function get context
 | |
|   // allocated even if we skip the inner function.
 | |
|   lazy([30, 29, 28])();
 | |
|   assertEquals(29, result);
 | |
| })();
 | |
| 
 | |
| (function TestCtxtAllocatingNonSimpleParams2() {
 | |
|   var result = 0;
 | |
| 
 | |
|   function lazy({a: other_param1, b: ctxt_alloc_param, c: other_param2}) {
 | |
|     function skip_me() {
 | |
|       result = ctxt_alloc_param;
 | |
|     }
 | |
|     return skip_me;
 | |
|   }
 | |
|   // Test that parameters and variables of the outer function get context
 | |
|   // allocated even if we skip the inner function.
 | |
|   lazy({a: 31, b: 32, c: 33})();
 | |
|   assertEquals(32, result);
 | |
| })();
 | |
| 
 | |
| (function TestCtxtAllocatingNonSimpleParams3() {
 | |
|   var result = 0;
 | |
| 
 | |
|   function lazy(...ctxt_alloc_param) {
 | |
|     function skip_me() {
 | |
|       result = ctxt_alloc_param;
 | |
|     }
 | |
|     return skip_me;
 | |
|   }
 | |
|   // Test that parameters and variables of the outer function get context
 | |
|   // allocated even if we skip the inner function.
 | |
|   lazy(34, 35)();
 | |
|   assertEquals([34, 35], result);
 | |
| })();
 | |
| 
 | |
| // Skippable top level functions.
 | |
| var result = 0;
 | |
| function lazy_top_level(ctxt_alloc_param) {
 | |
|   let ctxt_alloc_var = 24;
 | |
|   function skip_me() {
 | |
|     result = ctxt_alloc_param + ctxt_alloc_var;
 | |
|   }
 | |
|   skip_me();
 | |
| }
 | |
| 
 | |
| lazy_top_level(10);
 | |
| assertEquals(34, result);
 | |
| 
 | |
| // Tests for using a function name in an inner function.
 | |
| var TestUsingNamedExpressionName1 = function this_is_the_name() {
 | |
|   function inner() {
 | |
|     this_is_the_name;
 | |
|   }
 | |
|   inner();
 | |
| }
 | |
| TestUsingNamedExpressionName1();
 | |
| 
 | |
| function TestUsingNamedExpressionName2() {
 | |
|   let f = function this_is_the_name() {
 | |
|     function inner() {
 | |
|       this_is_the_name;
 | |
|     }
 | |
|     inner();
 | |
|   }
 | |
|   f();
 | |
| }
 | |
| TestUsingNamedExpressionName2();
 | |
| 
 | |
| function TestSkippedFunctionInsideLoopInitializer() {
 | |
|   let saved_func;
 | |
|   for (let i = 0, f = function() { return i }; i < 1; ++i) {
 | |
|     saved_func = f;
 | |
|   }
 | |
|   assertEquals(0, saved_func());
 | |
| }
 | |
| TestSkippedFunctionInsideLoopInitializer();
 | |
| 
 | |
| (function TestSkippedFunctionWithParameters() {
 | |
|   var result = 0;
 | |
| 
 | |
|   function lazy(ctxt_alloc_param) {
 | |
|     var ctxt_alloc_var = 10;
 | |
|     function skip_me(param1, param2) {
 | |
|       result = ctxt_alloc_param + ctxt_alloc_var + param1 + param2;
 | |
|     }
 | |
|     return skip_me;
 | |
|   }
 | |
|   lazy(9)(8, 7);
 | |
|   assertEquals(34, result);
 | |
| })();
 | |
| 
 | |
| function TestSkippingDeeperLazyFunctions() {
 | |
|   let result = 0;
 | |
|   function inner_lazy(ctxt_alloc_param) {
 | |
|     let ctxt_alloc_var = 13;
 | |
|     function skip_me() {
 | |
|       result = ctxt_alloc_param + ctxt_alloc_var;
 | |
|     }
 | |
|     return skip_me;
 | |
|   }
 | |
|   let f = inner_lazy(12);
 | |
|   f();
 | |
|   assertEquals(25, result);
 | |
| }
 | |
| 
 | |
| TestSkippingDeeperLazyFunctions();
 | |
| 
 | |
| function TestEagerFunctionsBetweenLazyFunctions() {
 | |
|   let result = 0;
 | |
|   // We produce one data set for TestEagerFunctionsBetweenLazyFunctions and
 | |
|   // another one for inner. The variable data for eager belongs to the former
 | |
|   // data set.
 | |
|   let ctxt_allocated1 = 3;
 | |
|   (function eager() {
 | |
|     let ctxt_allocated2 = 4;
 | |
|     function inner() {
 | |
|       result = ctxt_allocated1 + ctxt_allocated2;
 | |
|     }
 | |
|     return inner;
 | |
|   })()();
 | |
|   assertEquals(7, result);
 | |
| }
 | |
| 
 | |
| TestEagerFunctionsBetweenLazyFunctions();
 | |
| 
 | |
| function TestEagerNotIifeFunctionsBetweenLazyFunctions() {
 | |
|   let result = 0;
 | |
|   // We produce one data set for TestEagerFunctionsBetweenLazyFunctions and
 | |
|   // another one for inner. The variable data for eager belongs to the former
 | |
|   // data set.
 | |
|   let ctxt_allocated1 = 3;
 | |
|   (function eager_not_iife() {
 | |
|     let ctxt_allocated2 = 4;
 | |
|     function inner() {
 | |
|       result = ctxt_allocated1 + ctxt_allocated2;
 | |
|     }
 | |
|     return inner;
 | |
|   }); // Function not called; not an iife.
 | |
|   // This is just a regression test. We cannot test that the context allocation
 | |
|   // was done correctly (since there's no way to call eager_not_iife), but code
 | |
|   // like this used to trigger some DCHECKs.
 | |
| }
 | |
| 
 | |
| TestEagerNotIifeFunctionsBetweenLazyFunctions();
 | |
| 
 | |
| // Regression test for functions inside a lazy arrow function. (Only top-level
 | |
| // arrow functions are lazy, so this cannot be wrapped in a function.)
 | |
| result = 0;
 | |
| let f1 = (ctxt_alloc_param) => {
 | |
|   let ctxt_alloc_var = 10;
 | |
|   function inner() {
 | |
|     result = ctxt_alloc_param + ctxt_alloc_var;
 | |
|   }
 | |
|   return inner;
 | |
| }
 | |
| f1(9)();
 | |
| assertEquals(19, result);
 | |
| 
 | |
| function TestStrictEvalInParams() {
 | |
|   "use strict";
 | |
|   var result = 0;
 | |
| 
 | |
|   function lazy(a = function() { return 2; }, b = eval('3')) {
 | |
|     function skip_me() {
 | |
|       result = a() + b;
 | |
|     }
 | |
|     return skip_me;
 | |
|   }
 | |
|   lazy()();
 | |
|   assertEquals(5, result);
 | |
| 
 | |
|   function not_skippable_either() {}
 | |
| }
 | |
| 
 | |
| TestStrictEvalInParams();
 | |
| 
 | |
| function TestSloppyEvalInFunctionWithComplexParams() {
 | |
|   var result = 0;
 | |
| 
 | |
|   function lazy1(ctxt_alloc_param = 2) {
 | |
|     var ctxt_alloc_var = 3;
 | |
|     function skip_me() {
 | |
|       result = ctxt_alloc_param + ctxt_alloc_var;
 | |
|     }
 | |
|     eval('');
 | |
|     return skip_me;
 | |
|   }
 | |
|   lazy1()();
 | |
|   assertEquals(5, result);
 | |
| 
 | |
|   function lazy2(ctxt_alloc_param = 4) {
 | |
|     var ctxt_alloc_var = 5;
 | |
|     function skip_me() {
 | |
|       eval('result = ctxt_alloc_param + ctxt_alloc_var;');
 | |
|     }
 | |
|     return skip_me;
 | |
|   }
 | |
|   lazy2()();
 | |
|   assertEquals(9, result);
 | |
| }
 | |
| 
 | |
| TestSloppyEvalInFunctionWithComplexParams();
 | |
| 
 | |
| function TestSkippableFunctionInForOfHeader() {
 | |
|   var c;
 | |
|   function inner() {
 | |
|     for (let [a, b = c = function() { return a; }] of [[10]]) {
 | |
|     }
 | |
|   }
 | |
|   inner();
 | |
|   var result = c();
 | |
|   assertEquals(10, result);
 | |
| }
 | |
| 
 | |
| TestSkippableFunctionInForOfHeader();
 | |
| 
 | |
| function TestSkippableFunctionInForOfBody() {
 | |
|   var c;
 | |
|   function inner() {
 | |
|     for (let [a, b] of [[10, 11]]) {
 | |
|       c = function f() {
 | |
|         return a + b;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   inner();
 | |
|   var result = c();
 | |
|   assertEquals(21, result);
 | |
| }
 | |
| 
 | |
| TestSkippableFunctionInForOfBody();
 | |
| 
 | |
| 
 | |
| function TestSkippableFunctionInForOfHeaderAndBody() {
 | |
|   var c1;
 | |
|   var c2;
 | |
|   function inner() {
 | |
|     for (let [a, b = c1 = function() { return a; }] of [[10]]) {
 | |
|       c2 = function f() {
 | |
|         return a + 1;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   inner();
 | |
|   var result = c1() + c2();
 | |
|   assertEquals(21, result);
 | |
| }
 | |
| 
 | |
| TestSkippableFunctionInForOfHeaderAndBody();
 | |
| 
 | |
| (function TestSkippableGeneratorInSloppyBlock() {
 | |
|   var result = 0;
 | |
| 
 | |
|   function lazy(ctxt_alloc_param) {
 | |
|     var ctxt_alloc_var = 10;
 | |
|     {
 | |
|       function *skip_me() {
 | |
|         result = ctxt_alloc_param + ctxt_alloc_var;
 | |
|         yield 3;
 | |
|       }
 | |
|       return skip_me;
 | |
|     }
 | |
|   }
 | |
|   // Test that parameters and variables of the outer function get context
 | |
|   // allocated even if we skip the inner function.
 | |
|   assertEquals(3, lazy(9)().next().value);
 | |
|   assertEquals(19, result);
 | |
| })();
 | |
| 
 | |
| (function TestRestoringDataToAsyncArrowFunctionWithNonSimpleParams_1() {
 | |
|   // Regression test for
 | |
|   // https://bugs.chromium.org/p/chromium/issues/detail?id=765532
 | |
|   function lazy() {
 | |
|     // The arrow function is not skippable, but we need to traverse its scopes
 | |
|     // and restore data to them.
 | |
|     async(a=0) => { const d = 0; }
 | |
|     function skippable() {}
 | |
|   }
 | |
|   lazy();
 | |
| })();
 | |
| 
 | |
| (function TestRestoringDataToAsyncArrowFunctionWithNonSimpleParams_2() {
 | |
|   // Regression test for
 | |
|   // https://bugs.chromium.org/p/chromium/issues/detail?id=765532
 | |
|   function lazy() {
 | |
|     // The arrow function is not skippable, but we need to traverse its scopes
 | |
|     // and restore data to them.
 | |
|     async(...a) => { const d = 0; }
 | |
|     function skippable() {}
 | |
|   }
 | |
|   lazy();
 | |
| })();
 | |
| 
 | |
| (function TestSloppyBlockFunctionShadowingCatchVariable() {
 | |
|   // Regression test for
 | |
|   // https://bugs.chromium.org/p/chromium/issues/detail?id=771474
 | |
|   function lazy() {
 | |
|     try {
 | |
|     } catch (my_var) {
 | |
|       if (false) {
 | |
|         function my_var() { }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   lazy();
 | |
| })();
 | |
| 
 | |
| 
 | |
| (function TestLazinessDecisionWithDefaultConstructors() {
 | |
|   // Regression test for
 | |
|   // https://bugs.chromium.org/p/chromium/issues/detail?id=773576
 | |
| 
 | |
|   // The problem was that Parser and PreParser treated default constructors
 | |
|   // differently, and that threw off the "next / previous function is likely
 | |
|   // called" logic.
 | |
| 
 | |
|   function lazy(p = (function() {}, class {}, function() {}, class { method1() { } })) { }
 | |
|   lazy();
 | |
| })();
 | |
| 
 | |
| (function TestOneByteTwoByteMismatch() {
 | |
|   // Regression test for
 | |
|   // https://bugs.chromium.org/p/v8/issues/detail?id=7428
 | |
| 
 | |
|   let name = 'weird_string\u2653'.slice(0, 12);
 | |
|   let o = {};
 | |
|   o[name] = null;
 | |
|   var x;
 | |
|   eval('x = function weird_string() { function skip() {} };');
 | |
|   x();
 | |
| })();
 |