| // Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'package:expect/expect.dart'; |
| |
| dynamic function = 'function'; |
| dynamic growable = 'growable'; |
| dynamic length = 'length'; |
| |
| // Use top level dynamic variables so this call is not lowered. This function |
| // and the callers (test1, test2) are not inlined to prevent store-forwarding of |
| // the top-level variables. |
| @pragma('dart2js:noInline') |
| List<T> general<T>() => List<T>.generate(length, function, growable: growable); |
| |
| void main() { |
| function = (int i) => i; |
| growable = true; |
| length = 5; |
| |
| test1(); |
| |
| int k = 0; |
| function = (int u) => seq3(u += 10, k += 100, () => u += k + 100000); |
| growable = false; |
| length = 5; |
| |
| test2(); |
| } |
| |
| @pragma('dart2js:noInline') |
| void test1() { |
| // Simple test. |
| final r1 = List<num>.generate(5, (i) => i, growable: true); |
| final r2 = general<num>(); |
| |
| Expect.equals('[0, 1, 2, 3, 4]', '$r1'); |
| Expect.equals('[0, 1, 2, 3, 4]', '$r2'); |
| } |
| |
| // A sequence of two operations in expression form, returning the last value. |
| T seq2<T>(dynamic a, T b) => b; |
| T seq3<T>(dynamic a, dynamic b, T c) => c; |
| |
| @pragma('dart2js:noInline') |
| void test2() { |
| // Test with a complex environment. |
| int c = 0; |
| final r1 = List<int Function()>.generate( |
| 5, |
| (i) => seq3(i += 10, c += 100, () => i += c + 100000), |
| growable: false, |
| ); |
| final r2 = general<int Function()>(); |
| |
| final e12 = r1[2]; |
| final e22 = r2[2]; |
| |
| final s123 = [e12(), e12(), e12()]; |
| final s223 = [e22(), e22(), e22()]; |
| |
| // 'i' is bound to the loop variable (2 for element at [2]). |
| // 'i' is incremented by 10, so the low digits are '12' |
| // 'c' is shared by all closures, and has been incremented to 500 at end of |
| // construction, so each call increments 'i' by 100500. |
| Expect.equals('[100512, 201012, 301512]', '$s123'); |
| Expect.equals('[100512, 201012, 301512]', '$s123'); |
| } |