Skip to content

Commit b4ab28f

Browse files
alexmarkovcommit-bot@chromium.org
authored andcommitted
[vm/bytecode] Do not declare receiver variable in closures
While 'this' variable (receiver) is in scope in closures inside instance methods, closures do not take it as a parameter and they shouldn't declare a local variable for receiver unless it's captured. Fixes #38743 Fixes #39285 Change-Id: Ic5c735fd50457a5fb39acb3ec3590964e4dddba3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/124825 Reviewed-by: Régis Crelier <regis@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
1 parent cd6dbad commit b4ab28f

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

pkg/vm/lib/bytecode/gen_bytecode.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1964,7 +1964,8 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
19641964
asm.localVariableTable
19651965
.recordContextVariable(asm.offset, locals.contextVarIndexInFrame);
19661966
}
1967-
if (locals.hasReceiver) {
1967+
if (locals.hasReceiver &&
1968+
(!isClosure || locals.isCaptured(locals.receiverVar))) {
19681969
_declareLocalVariable(locals.receiverVar, function.fileOffset);
19691970
}
19701971
for (var v in function.positionalParameters) {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// VMOptions=--stacktrace_every=1 --deterministic --optimization-counter-threshold=6 --optimization-filter=baz
6+
7+
// Regression test for https://github.com/dart-lang/sdk/issues/38743.
8+
// Verifies that VM doesn't crash when collecting debugger stack traces in
9+
// closures inside instance methods.
10+
11+
class A {
12+
foo(unusedArg0) {
13+
baz() {
14+
for (int i = 0; i < 3; ++i) {
15+
print('[$i] $unusedArg0');
16+
}
17+
}
18+
19+
baz();
20+
}
21+
}
22+
23+
main() {
24+
A().foo(null);
25+
}

0 commit comments

Comments
 (0)