Skip to content

Commit 384a595

Browse files
aamcommit-bot@chromium.org
authored andcommitted
Recognize synthetic catch-clause and unhandled exceptions.
Bug: flutter/flutter#16741 Change-Id: I619c2eb0662cfdd16cc865ae5eae9c7d19bc55c4 Reviewed-on: https://dart-review.googlesource.com/52984 Commit-Queue: Alexander Aprelev <[email protected]> Reviewed-by: Alexander Markov <[email protected]> Reviewed-by: Jens Johansen <[email protected]>
1 parent c448d35 commit 384a595

File tree

13 files changed

+53
-37
lines changed

13 files changed

+53
-37
lines changed

pkg/kernel/binary.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,8 +1050,8 @@ type ReturnStatement extends Statement {
10501050
type TryCatch extends Statement {
10511051
Byte tag = 75;
10521052
Statement body;
1053-
// 1 if any catch needs a stacktrace (have a stacktrace variable).
1054-
Byte anyCatchNeedsStackTrace;
1053+
// "any catch needs a stacktrace" means it has a stacktrace variable.
1054+
Byte flags (anyCatchNeedsStackTrace, isSynthesized);
10551055
List<Catch> catches;
10561056
}
10571057

pkg/kernel/lib/ast.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4174,8 +4174,9 @@ class ReturnStatement extends Statement {
41744174
class TryCatch extends Statement {
41754175
Statement body;
41764176
List<Catch> catches;
4177+
bool isSynthetic;
41774178

4178-
TryCatch(this.body, this.catches) {
4179+
TryCatch(this.body, this.catches, {this.isSynthetic: false}) {
41794180
body?.parent = this;
41804181
setParents(catches, this);
41814182
}

pkg/kernel/lib/binary/ast_from_binary.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1549,8 +1549,8 @@ class BinaryBuilder {
15491549
return new ReturnStatement(readExpressionOption())..fileOffset = offset;
15501550
case Tag.TryCatch:
15511551
Statement body = readStatement();
1552-
readByte(); // whether any catch needs a stacktrace.
1553-
return new TryCatch(body, readCatchList());
1552+
int flags = readByte();
1553+
return new TryCatch(body, readCatchList(), isSynthetic: flags & 2 == 2);
15541554
case Tag.TryFinally:
15551555
return new TryFinally(readStatement(), readStatement());
15561556
case Tag.YieldStatement:

pkg/kernel/lib/binary/ast_to_binary.dart

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,17 +1544,16 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
15441544
writeOptionalNode(node.expression);
15451545
}
15461546

1547+
int _encodeTryCatchFlags(bool needsStackTrace, bool isSynthetic) {
1548+
return (needsStackTrace ? 1 : 0) | (isSynthetic ? 2 : 0);
1549+
}
1550+
15471551
@override
15481552
void visitTryCatch(TryCatch node) {
15491553
writeByte(Tag.TryCatch);
15501554
writeNode(node.body);
1551-
if (node.catches.any((Catch c) => c.stackTrace != null)) {
1552-
// at least one catch needs the stack trace.
1553-
writeByte(1);
1554-
} else {
1555-
// no catch needs the stack trace.
1556-
writeByte(0);
1557-
}
1555+
bool needsStackTrace = node.catches.any((Catch c) => c.stackTrace != null);
1556+
writeByte(_encodeTryCatchFlags(needsStackTrace, node.isSynthetic));
15581557
writeNodeList(node.catches);
15591558
}
15601559

pkg/kernel/lib/binary/tag.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ class Tag {
135135
/// Internal version of kernel binary format.
136136
/// Bump it when making incompatible changes in kernel binaries.
137137
/// Keep in sync with runtime/vm/kernel_binary.h.
138-
static const int BinaryFormatVersion = 4;
138+
static const int BinaryFormatVersion = 5;
139139
}
140140

141141
abstract class ConstantTag {

pkg/kernel/lib/clone.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,8 @@ class CloneVisitor implements TreeVisitor {
372372
}
373373

374374
visitTryCatch(TryCatch node) {
375-
return new TryCatch(clone(node.body), node.catches.map(clone).toList());
375+
return new TryCatch(clone(node.body), node.catches.map(clone).toList(),
376+
isSynthetic: node.isSynthetic);
376377
}
377378

378379
visitCatch(Catch node) {

pkg/kernel/lib/transformations/continuation.dart

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -355,14 +355,18 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase {
355355
var exceptionVariable = new VariableDeclaration(":exception");
356356
var stackTraceVariable = new VariableDeclaration(":stack_trace");
357357

358-
return new TryCatch(buildReturn(labeledBody), <Catch>[
359-
new Catch(
360-
exceptionVariable,
361-
new Block(<Statement>[
362-
buildCatchBody(exceptionVariable, stackTraceVariable)
363-
]),
364-
stackTrace: stackTraceVariable)
365-
]);
358+
return new TryCatch(
359+
buildReturn(labeledBody),
360+
<Catch>[
361+
new Catch(
362+
exceptionVariable,
363+
new Block(<Statement>[
364+
buildCatchBody(exceptionVariable, stackTraceVariable)
365+
]),
366+
stackTrace: stackTraceVariable)
367+
],
368+
isSynthetic: true,
369+
);
366370
}
367371

368372
Statement buildCatchBody(

runtime/observatory/tests/service/service_kernel.status

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ evaluate_activation_in_method_class_test: RuntimeError
1616
evaluate_activation_test/instance: RuntimeError
1717
evaluate_activation_test/scope: RuntimeError
1818
evaluate_in_sync_star_activation_test: RuntimeError
19-
pause_on_unhandled_async_exceptions2_test: RuntimeError # --pause-isolates-on-unhandled-exceptions doesn't currently work. Issue #29056
2019
pause_on_unhandled_async_exceptions_test: RuntimeError # --pause-isolates-on-unhandled-exceptions doesn't currently work. Issue #29056
2120
step_through_arithmetic_test: RuntimeError # probably constant evaluator pre-evaluating e.g. 1+2
2221
unused_changes_in_last_reload_test: RuntimeError

runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1807,7 +1807,7 @@ void StreamingScopeBuilder::VisitStatement() {
18071807
++depth_.catch_;
18081808
AddCatchVariables();
18091809

1810-
builder_->ReadBool(); // read any_catch_needs_stack_trace.
1810+
builder_->ReadByte(); // read flags
18111811
intptr_t catch_count =
18121812
builder_->ReadListLength(); // read number of catches.
18131813
for (intptr_t i = 0; i < catch_count; ++i) {
@@ -4355,7 +4355,7 @@ void KernelFingerprintHelper::CalculateStatementFingerprint() {
43554355
}
43564356
case kTryCatch: {
43574357
CalculateStatementFingerprint(); // read body.
4358-
BuildHash(ReadBool()); // read any_catch_needs_stack_trace.
4358+
BuildHash(ReadByte()); // read flags
43594359
intptr_t catch_count = ReadListLength(); // read number of catches.
43604360
for (intptr_t i = 0; i < catch_count; ++i) {
43614361
ReadPosition(); // read position.
@@ -6603,7 +6603,7 @@ void KernelReaderHelper::SkipStatement() {
66036603
}
66046604
case kTryCatch: {
66056605
SkipStatement(); // read body.
6606-
ReadBool(); // read any_catch_needs_stack_trace.
6606+
ReadByte(); // read flags
66076607
intptr_t catch_count = ReadListLength(); // read number of catches.
66086608
for (intptr_t i = 0; i < catch_count; ++i) {
66096609
ReadPosition(); // read position.
@@ -7163,9 +7163,10 @@ Fragment StreamingFlowGraphBuilder::BranchIfNull(
71637163

71647164
Fragment StreamingFlowGraphBuilder::CatchBlockEntry(const Array& handler_types,
71657165
intptr_t handler_index,
7166-
bool needs_stacktrace) {
7166+
bool needs_stacktrace,
7167+
bool is_synthesized) {
71677168
return flow_graph_builder_->CatchBlockEntry(handler_types, handler_index,
7168-
needs_stacktrace);
7169+
needs_stacktrace, is_synthesized);
71697170
}
71707171

71717172
Fragment StreamingFlowGraphBuilder::TryCatch(int try_handler_index) {
@@ -9851,14 +9852,21 @@ Fragment StreamingFlowGraphBuilder::BuildTryCatch() {
98519852
}
98529853
try_depth_dec();
98539854

9854-
bool needs_stacktrace = ReadBool(); // read any_catch_needs_stack_trace
9855+
const int kNeedsStracktraceBit = 1 << 0;
9856+
const int kIsSyntheticBit = 1 << 1;
9857+
9858+
uint8_t flags = ReadByte();
9859+
bool needs_stacktrace =
9860+
(flags & kNeedsStracktraceBit) == kNeedsStracktraceBit;
9861+
bool is_synthetic = (flags & kIsSyntheticBit) == kIsSyntheticBit;
98559862

98569863
catch_depth_inc();
98579864
intptr_t catch_count = ReadListLength(); // read number of catches.
98589865
const Array& handler_types =
98599866
Array::ZoneHandle(Z, Array::New(catch_count, Heap::kOld));
9860-
Fragment catch_body =
9861-
CatchBlockEntry(handler_types, try_handler_index, needs_stacktrace);
9867+
9868+
Fragment catch_body = CatchBlockEntry(handler_types, try_handler_index,
9869+
needs_stacktrace, is_synthetic);
98629870
// Fill in the body of the catch.
98639871
for (intptr_t i = 0; i < catch_count; ++i) {
98649872
intptr_t catch_offset = ReaderOffset(); // Catch has no tag.
@@ -10029,7 +10037,8 @@ Fragment StreamingFlowGraphBuilder::BuildTryFinally() {
1002910037
handler_types.SetAt(0, Object::dynamic_type());
1003010038
// Note: rethrow will actually force mark the handler as needing a stacktrace.
1003110039
Fragment finally_body = CatchBlockEntry(handler_types, try_handler_index,
10032-
/* needs_stacktrace = */ false);
10040+
/* needs_stacktrace = */ false,
10041+
/* is_synthesized = */ true);
1003310042
SetOffset(finalizer_offset);
1003410043
finally_body += BuildStatement(); // read finalizer
1003510044
if (finally_body.is_open()) {

runtime/vm/compiler/frontend/kernel_binary_flowgraph.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1421,7 +1421,8 @@ class StreamingFlowGraphBuilder : public KernelReaderHelper {
14211421
bool negate = false);
14221422
Fragment CatchBlockEntry(const Array& handler_types,
14231423
intptr_t handler_index,
1424-
bool needs_stacktrace);
1424+
bool needs_stacktrace,
1425+
bool is_synthesized);
14251426
Fragment TryCatch(int try_handler_index);
14261427
Fragment Drop();
14271428

runtime/vm/compiler/frontend/kernel_to_il.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,14 +1176,15 @@ Fragment BaseFlowGraphBuilder::BranchIfStrictEqual(
11761176

11771177
Fragment FlowGraphBuilder::CatchBlockEntry(const Array& handler_types,
11781178
intptr_t handler_index,
1179-
bool needs_stacktrace) {
1179+
bool needs_stacktrace,
1180+
bool is_synthesized) {
11801181
ASSERT(CurrentException()->is_captured() ==
11811182
CurrentStackTrace()->is_captured());
11821183
const bool should_restore_closure_context =
11831184
CurrentException()->is_captured() || CurrentCatchContext()->is_captured();
11841185
CatchBlockEntryInstr* entry = new (Z) CatchBlockEntryInstr(
11851186
TokenPosition::kNoSource, // Token position of catch block.
1186-
false, // Not an artifact of compilation.
1187+
is_synthesized, // whether catch block was synthesized by FE compiler
11871188
AllocateBlockId(), CurrentTryIndex(), graph_entry_, handler_types,
11881189
handler_index, *CurrentException(), *CurrentStackTrace(),
11891190
needs_stacktrace, GetNextDeoptId(), should_restore_closure_context);

runtime/vm/compiler/frontend/kernel_to_il.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,8 @@ class FlowGraphBuilder : public BaseFlowGraphBuilder {
731731
Fragment BooleanNegate();
732732
Fragment CatchBlockEntry(const Array& handler_types,
733733
intptr_t handler_index,
734-
bool needs_stacktrace);
734+
bool needs_stacktrace,
735+
bool is_synthesized);
735736
Fragment TryCatch(int try_handler_index);
736737
Fragment CheckStackOverflowInPrologue(TokenPosition position);
737738
Fragment CheckStackOverflow(TokenPosition position);

runtime/vm/kernel_binary.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace kernel {
1919
// Keep in sync with package:kernel/lib/binary/tag.dart.
2020

2121
static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
22-
static const uint32_t kBinaryFormatVersion = 4;
22+
static const uint32_t kBinaryFormatVersion = 5;
2323

2424
// Keep in sync with package:kernel/lib/binary/tag.dart
2525
#define KERNEL_TAG_LIST(V) \

0 commit comments

Comments
 (0)