7b53e209c5
Summary: 1. Previously, in 'BuildGraphOfConvertedClosureFunction', the VM was unable to correctly forward parameters to converted closure functions when they were captured in the converted function's body. This could happen when, for example, a closure was introduced into it by async conversion. Now, this is fixed by an approach that mirrors the technique in 'BuildGraphOfFunction'. 2. Previously, local variables declared inside loop bodies were being saved in the loop's enclosing context, so closures within the loop would see new values initialized to the variable in subsequent iterations. Now, this is fixed by creating nested contexts for all loops, regardless of whether the loop variables are captured. 3. Previously, arity checks were not being performed on converted closures, so they could be called with too few or too many arguments. In the former case, the missing arguments would be filled in with garbage on the stack. Now, the assembly generation in 'CompileGraph' inserts argument count checks for converted closures as well as regular closures. Test Plan: Introduced new tests in the closure conversion suite to test each bug: 1. syncstart.dart 2. loop2.dart, blocks.dart, updated for_in_closure.dart 3. arity.dart With these changes, closure conversion passes all co19 tests in non-checked mode, except those that are not passed without it: python tools/test.py -m release -c dartk --vm-options "--reify --reify_generic_functions" co19 BUG= R=dmitryas@google.com Review-Url: https://codereview.chromium.org/3000333002 .
25 lines
662 B
Dart
25 lines
662 B
Dart
// Copyright (c) 2017, 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.
|
|
//
|
|
// This tests that the wrapper function around converted closures in the VM
|
|
// doesn't break when the context parameter is captured (since async
|
|
// transformations introduces an additional closure here).
|
|
|
|
range(int high) {
|
|
iter(int low) sync* {
|
|
while (high-- > low) yield high;
|
|
}
|
|
|
|
return iter;
|
|
}
|
|
|
|
main() {
|
|
var sum = 0;
|
|
for (var x in range(10)(2)) sum += x;
|
|
|
|
if (sum != 44) {
|
|
throw new Exception("Incorrect output.");
|
|
}
|
|
}
|