Version 2.15.0-117.0.dev
Merge commit '790d0b601cba52e826c53108a787a0a52d29a02b' into 'dev'
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index c93f71d..c5f54b2 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -15340,7 +15340,7 @@
// #### Description
//
// The analyzer produces this diagnostic when a null-aware operator (`?.`,
- // `?..`, `?[`, `?..[`, or `...?`) is used on a target that's known to be
+ // `?..`, `?[`, `?..[`, or `...?`) is used on a receiver that's known to be
// non-nullable.
//
// #### Example
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index 3b82cae..e13b744 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -6761,7 +6761,7 @@
#### Description
The analyzer produces this diagnostic when a null-aware operator (`?.`,
-`?..`, `?[`, `?..[`, or `...?`) is used on a target that's known to be
+`?..`, `?[`, `?..[`, or `...?`) is used on a receiver that's known to be
non-nullable.
#### Example
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index c254a6c..90b5822 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -937,7 +937,7 @@
/// If none is found, [defaultTarget] is returned.
ObjectAccessTarget _findDirectExtensionTypeMember(
ExtensionType receiverType, Name name, int fileOffset,
- {required ObjectAccessTarget defaultTarget}) {
+ {required ObjectAccessTarget defaultTarget, required bool isSetter}) {
Member? targetMember;
Member? targetTearoff;
ProcedureKind? targetKind;
@@ -946,27 +946,37 @@
if (descriptor.name == name) {
switch (descriptor.kind) {
case ExtensionMemberKind.Method:
- targetMember = descriptor.member.asMember;
- targetTearoff ??= targetMember;
- targetKind = ProcedureKind.Method;
+ if (!isSetter) {
+ targetMember = descriptor.member.asMember;
+ targetTearoff ??= targetMember;
+ targetKind = ProcedureKind.Method;
+ }
break;
case ExtensionMemberKind.TearOff:
- targetTearoff = descriptor.member.asMember;
+ if (!isSetter) {
+ targetTearoff = descriptor.member.asMember;
+ }
break;
case ExtensionMemberKind.Getter:
- targetMember = descriptor.member.asMember;
- targetTearoff = null;
- targetKind = ProcedureKind.Getter;
+ if (!isSetter) {
+ targetMember = descriptor.member.asMember;
+ targetTearoff = null;
+ targetKind = ProcedureKind.Getter;
+ }
break;
case ExtensionMemberKind.Setter:
- targetMember = descriptor.member.asMember;
- targetTearoff = null;
- targetKind = ProcedureKind.Setter;
+ if (isSetter) {
+ targetMember = descriptor.member.asMember;
+ targetTearoff = null;
+ targetKind = ProcedureKind.Setter;
+ }
break;
case ExtensionMemberKind.Operator:
- targetMember = descriptor.member.asMember;
- targetTearoff = null;
- targetKind = ProcedureKind.Operator;
+ if (!isSetter) {
+ targetMember = descriptor.member.asMember;
+ targetTearoff = null;
+ targetKind = ProcedureKind.Operator;
+ }
break;
default:
unhandled("${descriptor.kind}", "_findDirectExtensionMember",
@@ -1233,7 +1243,7 @@
} else if (library.enableExtensionTypesInLibrary &&
receiverBound is ExtensionType) {
target = _findDirectExtensionTypeMember(receiverBound, name, fileOffset,
- defaultTarget: const ObjectAccessTarget.missing());
+ isSetter: setter, defaultTarget: const ObjectAccessTarget.missing());
if (target.kind == ObjectAccessTargetKind.missing) {
target = _findShownExtensionTypeMember(receiverBound, name, fileOffset,
isSetter: setter,
diff --git a/pkg/front_end/testcases/extension_types/access_setter_as_getter.dart b/pkg/front_end/testcases/extension_types/access_setter_as_getter.dart
new file mode 100644
index 0000000..2b50a93
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/access_setter_as_getter.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2021, 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.
+
+class A {}
+
+extension E on A {
+ void set foo(int value) {}
+ int get bar => 42;
+}
+
+test(E e) {
+ e.foo = 42; // Ok.
+ e.bar; // Ok.
+
+ e.foo; // Error.
+ e.bar = 42; // Error.
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extension_types/access_setter_as_getter.dart.strong.expect b/pkg/front_end/testcases/extension_types/access_setter_as_getter.dart.strong.expect
new file mode 100644
index 0000000..cd89df1
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/access_setter_as_getter.dart.strong.expect
@@ -0,0 +1,42 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_types/access_setter_as_getter.dart:16:5: Error: The getter 'foo' isn't defined for the extension 'E'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'foo'.
+// e.foo; // Error.
+// ^^^
+//
+// pkg/front_end/testcases/extension_types/access_setter_as_getter.dart:17:5: Error: The setter 'bar' isn't defined for the extension 'E'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'bar'.
+// e.bar = 42; // Error.
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+}
+extension E on self::A {
+ get bar = self::E|get#bar;
+ set foo = self::E|set#foo;
+}
+static method E|set#foo(lowered final self::A #this, core::int value) → void {}
+static method E|get#bar(lowered final self::A #this) → core::int
+ return 42;
+static method test(self::E e) → dynamic {
+ self::E|set#foo(e, 42);
+ self::E|get#bar(e);
+ invalid-expression "pkg/front_end/testcases/extension_types/access_setter_as_getter.dart:16:5: Error: The getter 'foo' isn't defined for the extension 'E'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'foo'.
+ e.foo; // Error.
+ ^^^" in e{<unresolved>}.foo;
+ invalid-expression "pkg/front_end/testcases/extension_types/access_setter_as_getter.dart:17:5: Error: The setter 'bar' isn't defined for the extension 'E'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'bar'.
+ e.bar = 42; // Error.
+ ^^^" in e{<unresolved>}.bar = 42;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extension_types/access_setter_as_getter.dart.textual_outline.expect b/pkg/front_end/testcases/extension_types/access_setter_as_getter.dart.textual_outline.expect
new file mode 100644
index 0000000..d7b5f21
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/access_setter_as_getter.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A {}
+
+extension E on A {
+ void set foo(int value) {}
+ int get bar => 42;
+}
+
+test(E e) {}
+main() {}
diff --git a/pkg/front_end/testcases/extension_types/access_setter_as_getter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extension_types/access_setter_as_getter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7a2c265
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/access_setter_as_getter.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A {}
+
+extension E on A {
+ int get bar => 42;
+ void set foo(int value) {}
+}
+
+main() {}
+test(E e) {}
diff --git a/pkg/front_end/testcases/extension_types/access_setter_as_getter.dart.weak.expect b/pkg/front_end/testcases/extension_types/access_setter_as_getter.dart.weak.expect
new file mode 100644
index 0000000..cd89df1
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/access_setter_as_getter.dart.weak.expect
@@ -0,0 +1,42 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_types/access_setter_as_getter.dart:16:5: Error: The getter 'foo' isn't defined for the extension 'E'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'foo'.
+// e.foo; // Error.
+// ^^^
+//
+// pkg/front_end/testcases/extension_types/access_setter_as_getter.dart:17:5: Error: The setter 'bar' isn't defined for the extension 'E'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'bar'.
+// e.bar = 42; // Error.
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+}
+extension E on self::A {
+ get bar = self::E|get#bar;
+ set foo = self::E|set#foo;
+}
+static method E|set#foo(lowered final self::A #this, core::int value) → void {}
+static method E|get#bar(lowered final self::A #this) → core::int
+ return 42;
+static method test(self::E e) → dynamic {
+ self::E|set#foo(e, 42);
+ self::E|get#bar(e);
+ invalid-expression "pkg/front_end/testcases/extension_types/access_setter_as_getter.dart:16:5: Error: The getter 'foo' isn't defined for the extension 'E'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'foo'.
+ e.foo; // Error.
+ ^^^" in e{<unresolved>}.foo;
+ invalid-expression "pkg/front_end/testcases/extension_types/access_setter_as_getter.dart:17:5: Error: The setter 'bar' isn't defined for the extension 'E'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'bar'.
+ e.bar = 42; // Error.
+ ^^^" in e{<unresolved>}.bar = 42;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extension_types/access_setter_as_getter.dart.weak.outline.expect b/pkg/front_end/testcases/extension_types/access_setter_as_getter.dart.weak.outline.expect
new file mode 100644
index 0000000..b1f1b7a
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/access_setter_as_getter.dart.weak.outline.expect
@@ -0,0 +1,20 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ ;
+}
+extension E on self::A {
+ get bar = self::E|get#bar;
+ set foo = self::E|set#foo;
+}
+static method E|set#foo(lowered final self::A #this, core::int value) → void
+ ;
+static method E|get#bar(lowered final self::A #this) → core::int
+ ;
+static method test(self::E e) → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/outline.status b/pkg/front_end/testcases/outline.status
index a88beba..4158e04 100644
--- a/pkg/front_end/testcases/outline.status
+++ b/pkg/front_end/testcases/outline.status
@@ -4,6 +4,7 @@
const_functions/const_functions_const_factory: VerificationError
constructor_tearoffs/lowering/invalid_redirect: VerificationError
+extension_types/access_setter_as_getter: ExpectationFileMismatchSerialized # Expected.
extension_types/extension_on_nullable: ExpectationFileMismatchSerialized # Expected.
extension_types/show_and_run_ceil: ExpectationFileMismatchSerialized # Expected.
extension_types/simple: ExpectationFileMismatchSerialized
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 90cc78d..1646398 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -10,6 +10,7 @@
constructor_tearoffs/call_instantiation: TypeCheckError
constructor_tearoffs/lowering/invalid_redirect: VerificationError
+extension_types/access_setter_as_getter: ExpectationFileMismatchSerialized # Expected.
extension_types/extension_on_nullable: ExpectationFileMismatchSerialized # Expected.
extension_types/issue45775: ExpectationFileMismatchSerialized # Expected.
extension_types/show_and_run_ceil: ExpectationFileMismatchSerialized # Expected.
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index c226f31..3187786 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -8,6 +8,7 @@
constructor_tearoffs/call_instantiation: TypeCheckError
constructor_tearoffs/lowering/invalid_redirect: VerificationError
+extension_types/access_setter_as_getter: ExpectationFileMismatchSerialized # Expected.
extension_types/extension_on_nullable: ExpectationFileMismatchSerialized # Expected.
extension_types/issue45775: ExpectationFileMismatchSerialized # Expected.
extension_types/show_and_run_ceil: ExpectationFileMismatchSerialized # Expected.
diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status
index 84e72b9..a018083 100644
--- a/pkg/front_end/testcases/weak.status
+++ b/pkg/front_end/testcases/weak.status
@@ -13,6 +13,7 @@
constructor_tearoffs/call_instantiation: TypeCheckError
constructor_tearoffs/lowering/invalid_redirect: VerificationError
+extension_types/access_setter_as_getter: ExpectationFileMismatchSerialized # Expected.
extension_types/extension_on_nullable: ExpectationFileMismatchSerialized # Expected.
extension_types/issue45775: ExpectationFileMismatchSerialized # Expected.
extension_types/show_and_run_ceil: ExpectationFileMismatchSerialized # Expected.
diff --git a/pkg/kernel/lib/transformations/async.dart b/pkg/kernel/lib/transformations/async.dart
index 621d51e..acca81a 100644
--- a/pkg/kernel/lib/transformations/async.dart
+++ b/pkg/kernel/lib/transformations/async.dart
@@ -529,19 +529,7 @@
final R = continuationRewriter;
var shouldName = seenAwait;
var type = expr.getStaticType(_staticTypeContext);
- Expression result = new VariableGet(asyncResult);
- if (type is! DynamicType) {
- int fileOffset = expr.operand.fileOffset;
- if (fileOffset == TreeNode.noOffset) {
- fileOffset = expr.fileOffset;
- }
- assert(fileOffset != TreeNode.noOffset);
- result = new StaticInvocation(
- continuationRewriter.helper.unsafeCast,
- new Arguments(<Expression>[result], types: <DartType>[type])
- ..fileOffset = fileOffset)
- ..fileOffset = fileOffset;
- }
+ Expression result = unsafeCastVariableGet(asyncResult, type);
// The statements are in reverse order, so name the result first if
// necessary and then add the two other statements in reverse.
diff --git a/runtime/observatory/tests/service/breakpoint_on_simple_conditions_test.dart b/runtime/observatory/tests/service/breakpoint_on_simple_conditions_test.dart
new file mode 100644
index 0000000..c8ab6c3
--- /dev/null
+++ b/runtime/observatory/tests/service/breakpoint_on_simple_conditions_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2021, 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 'test_helper.dart';
+import 'service_test_common.dart';
+
+const int LINE_A = 15;
+const int LINE_B = 20;
+const int LINE_C = 24;
+const int LINE_D = 28;
+
+testMain() {
+ bool foo = false;
+ if (foo) { // LINE_A
+ print('1');
+ }
+
+ const bar = false;
+ if (bar) { // LINE_B
+ print('2');
+ }
+
+ while (foo) { // LINE_C
+ print('3');
+ }
+
+ while (bar) { // LINE_D
+ print('4');
+ }
+}
+
+var tests = <IsolateTest>[
+ hasPausedAtStart,
+ setBreakpointAtLine(LINE_A),
+ setBreakpointAtLine(LINE_B),
+ setBreakpointAtLine(LINE_C),
+ setBreakpointAtLine(LINE_D),
+ resumeIsolate,
+ hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE_A),
+ resumeIsolate,
+ hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE_B),
+ resumeIsolate,
+ hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE_C),
+ resumeIsolate,
+ hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE_D),
+ resumeIsolate,
+];
+
+main(args) => runIsolateTests(args, tests,
+ testeeConcurrent: testMain, pause_on_start: true);
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index fae5fd0..e5f8df6 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -61,6 +61,7 @@
breakpoint_on_if_null_2_test: SkipByDesign # Debugger is disabled in AOT mode.
breakpoint_on_if_null_3_test: SkipByDesign # Debugger is disabled in AOT mode.
breakpoint_on_if_null_4_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_on_simple_conditions_test: SkipByDesign # Debugger is disabled in AOT mode.
breakpoint_partfile_test: SkipByDesign # Debugger is disabled in AOT mode.
breakpoint_two_args_checked_test: SkipByDesign # Debugger is disabled in AOT mode.
breakpoints_with_mixin_test: SkipByDesign # Debugger is disabled in AOT mode.
diff --git a/runtime/observatory_2/tests/service_2/breakpoint_on_simple_conditions_test.dart b/runtime/observatory_2/tests/service_2/breakpoint_on_simple_conditions_test.dart
new file mode 100644
index 0000000..c8ab6c3
--- /dev/null
+++ b/runtime/observatory_2/tests/service_2/breakpoint_on_simple_conditions_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2021, 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 'test_helper.dart';
+import 'service_test_common.dart';
+
+const int LINE_A = 15;
+const int LINE_B = 20;
+const int LINE_C = 24;
+const int LINE_D = 28;
+
+testMain() {
+ bool foo = false;
+ if (foo) { // LINE_A
+ print('1');
+ }
+
+ const bar = false;
+ if (bar) { // LINE_B
+ print('2');
+ }
+
+ while (foo) { // LINE_C
+ print('3');
+ }
+
+ while (bar) { // LINE_D
+ print('4');
+ }
+}
+
+var tests = <IsolateTest>[
+ hasPausedAtStart,
+ setBreakpointAtLine(LINE_A),
+ setBreakpointAtLine(LINE_B),
+ setBreakpointAtLine(LINE_C),
+ setBreakpointAtLine(LINE_D),
+ resumeIsolate,
+ hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE_A),
+ resumeIsolate,
+ hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE_B),
+ resumeIsolate,
+ hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE_C),
+ resumeIsolate,
+ hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE_D),
+ resumeIsolate,
+];
+
+main(args) => runIsolateTests(args, tests,
+ testeeConcurrent: testMain, pause_on_start: true);
diff --git a/runtime/observatory_2/tests/service_2/service_2_kernel.status b/runtime/observatory_2/tests/service_2/service_2_kernel.status
index 98dd984..5138ddd 100644
--- a/runtime/observatory_2/tests/service_2/service_2_kernel.status
+++ b/runtime/observatory_2/tests/service_2/service_2_kernel.status
@@ -61,6 +61,7 @@
breakpoint_on_if_null_2_test: SkipByDesign # Debugger is disabled in AOT mode.
breakpoint_on_if_null_3_test: SkipByDesign # Debugger is disabled in AOT mode.
breakpoint_on_if_null_4_test: SkipByDesign # Debugger is disabled in AOT mode.
+breakpoint_on_simple_conditions_test: SkipByDesign # Debugger is disabled in AOT mode.
breakpoint_partfile_test: SkipByDesign # Debugger is disabled in AOT mode.
breakpoint_two_args_checked_test: SkipByDesign # Debugger is disabled in AOT mode.
breakpoints_with_mixin_test: SkipByDesign # Debugger is disabled in AOT mode.
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 03d5a27..d74fc3d 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -1928,6 +1928,9 @@
ASSERT(instructions.current->previous() != nullptr);
instructions.current = instructions.current->previous();
} else {
+ if (NeedsDebugStepCheck(stack(), position)) {
+ instructions = DebugStepCheck(position) + instructions;
+ }
instructions += CheckBoolean(position);
instructions += Constant(Bool::True());
Value* right_value = Pop();
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 442248a..7406e5a 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -834,7 +834,8 @@
String* name_to_modify,
bool symbolize,
bool obfuscate) {
- if (name_to_modify->Length() >= 1 && name_to_modify->CharAt(0) == '_') {
+ if (name_to_modify->Length() >= 1 && name_to_modify->CharAt(0) == '_' &&
+ !library.IsNull()) {
*name_to_modify = library.PrivateName(*name_to_modify);
if (obfuscate && IG->obfuscate()) {
const String& library_key = String::Handle(library.private_key());
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index fb7e37c..7e0034b 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -2315,8 +2315,12 @@
msg.value.as_string = const_cast<char*>(message);
arr_values[0] = &msg;
Dart_CObject stack;
- stack.type = Dart_CObject_kString;
- stack.value.as_string = const_cast<char*>(stacktrace);
+ if (stacktrace == NULL) {
+ stack.type = Dart_CObject_kNull;
+ } else {
+ stack.type = Dart_CObject_kString;
+ stack.value.as_string = const_cast<char*>(stacktrace);
+ }
arr_values[1] = &stack;
SendPort& listener = SendPort::Handle(current_zone());
diff --git a/runtime/vm/longjump.h b/runtime/vm/longjump.h
index c551584..60f514b 100644
--- a/runtime/vm/longjump.h
+++ b/runtime/vm/longjump.h
@@ -16,11 +16,9 @@
class LongJumpScope : public StackResource {
public:
- LongJumpScope()
- : StackResource(ThreadState::Current()),
- top_(nullptr),
- base_(thread()->long_jump_base()) {
- thread()->set_long_jump_base(this);
+ explicit LongJumpScope(ThreadState* thread = ThreadState::Current())
+ : StackResource(thread), top_(nullptr), base_(thread->long_jump_base()) {
+ thread->set_long_jump_base(this);
}
~LongJumpScope() {
diff --git a/runtime/vm/message_snapshot.cc b/runtime/vm/message_snapshot.cc
index e7cc76e..ac2eef3 100644
--- a/runtime/vm/message_snapshot.cc
+++ b/runtime/vm/message_snapshot.cc
@@ -3162,6 +3162,7 @@
cid = kDoubleCid;
break;
case Dart_CObject_kString: {
+ RELEASE_ASSERT(object->value.as_string != NULL);
const uint8_t* utf8_str =
reinterpret_cast<const uint8_t*>(object->value.as_string);
intptr_t utf8_len = strlen(object->value.as_string);
@@ -3744,7 +3745,7 @@
volatile bool has_exception = false;
{
- LongJumpScope jump;
+ LongJumpScope jump(thread);
if (setjmp(*jump.Set()) == 0) {
serializer.Serialize(obj);
} else {
@@ -3819,8 +3820,13 @@
return ReadObjectGraphCopyMessage(thread, message->persistent_handle());
} else {
RELEASE_ASSERT(message->IsSnapshot());
- MessageDeserializer deserializer(thread, message);
- return deserializer.Deserialize();
+ LongJumpScope jump(thread);
+ if (setjmp(*jump.Set()) == 0) {
+ MessageDeserializer deserializer(thread, message);
+ return deserializer.Deserialize();
+ } else {
+ return thread->StealStickyError();
+ }
}
}
diff --git a/tools/VERSION b/tools/VERSION
index 7671f3f..90c741d 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 15
PATCH 0
-PRERELEASE 116
+PRERELEASE 117
PRERELEASE_PATCH 0
\ No newline at end of file