Version 1.22.1
Cherry-pick 339d16fbc5d611fbbcf46235c290c615589ecc87 to stable
Cherry-pick 67a93da99eb11ada7d8267243c6824d5c67de91c to stable
Cherry-pick 031af9e89990d39ca73cfe8726ab018c038e8b7e to stable
Cherry-pick bbd687197bc96b4d7a0555d3f0cd0e1e64c2b672 to stable
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a831e65..45a5ce4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 1.22.1 - 2017-02-22
+
+Patch release, resolves two issues:
+* Dart VM crash: [Issue 28072](https://github.com/dart-lang/sdk/issues/28757)
+
+* Dart VM bug combining types, await, and deferred loading: [Issue 28678](https://github.com/dart-lang/sdk/issues/28678)
+
+
## 1.22.0 - 2017-02-14
### Language
diff --git a/runtime/vm/ast.h b/runtime/vm/ast.h
index ca75856..c99b6cb 100644
--- a/runtime/vm/ast.h
+++ b/runtime/vm/ast.h
@@ -443,8 +443,12 @@
class TypeNode : public AstNode {
public:
- TypeNode(TokenPosition token_pos, const AbstractType& type)
- : AstNode(token_pos), type_(type) {
+ TypeNode(TokenPosition token_pos,
+ const AbstractType& type,
+ bool is_deferred_reference = false)
+ : AstNode(token_pos),
+ type_(type),
+ is_deferred_reference_(is_deferred_reference) {
ASSERT(type_.IsZoneHandle());
ASSERT(!type_.IsNull());
ASSERT(type_.IsFinalized());
@@ -466,10 +470,14 @@
virtual void VisitChildren(AstNodeVisitor* visitor) const {}
+ bool is_deferred_reference() const { return is_deferred_reference_; }
+ void set_is_deferred_reference(bool value) { is_deferred_reference_ = value; }
+
DECLARE_COMMON_NODE_FUNCTIONS(TypeNode);
private:
const AbstractType& type_;
+ bool is_deferred_reference_;
DISALLOW_IMPLICIT_CONSTRUCTORS(TypeNode);
};
diff --git a/runtime/vm/ast_transformer.cc b/runtime/vm/ast_transformer.cc
index fa1028d..af1331c 100644
--- a/runtime/vm/ast_transformer.cc
+++ b/runtime/vm/ast_transformer.cc
@@ -119,7 +119,14 @@
void AwaitTransformer::VisitTypeNode(TypeNode* node) {
- result_ = new (Z) TypeNode(node->token_pos(), node->type());
+ if (node->is_deferred_reference()) {
+ // Deferred references must use a temporary even after loading
+ // happened, so that the number of await temps is the same as
+ // before the loading.
+ result_ = MakeName(node);
+ } else {
+ result_ = node;
+ }
}
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index e75d86d..9f918e0 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -11638,7 +11638,8 @@
ClassFinalizer::kCanonicalize);
// Type may be malbounded, but not malformed.
ASSERT(!type.IsMalformed());
- array = new (Z) TypeNode(primary_pos, type);
+ array = new (Z) TypeNode(primary_pos, type,
+ primary_node->is_deferred_reference());
} else if (primary_node->primary().IsTypeParameter()) {
array = LoadTypeParameter(primary_node);
} else {
@@ -11733,7 +11734,8 @@
ClassFinalizer::kCanonicalize);
// Type may be malbounded, but not malformed.
ASSERT(!type.IsMalformed());
- selector = new (Z) TypeNode(primary_pos, type);
+ selector = new (Z) TypeNode(primary_pos, type,
+ primary_node->is_deferred_reference());
} else {
UNREACHABLE(); // Internal parser error.
}
@@ -11760,7 +11762,8 @@
ClassFinalizer::kCanonicalize);
// Type may be malbounded, but not malformed.
ASSERT(!type.IsMalformed());
- left = new (Z) TypeNode(primary_pos, type);
+ left = new (Z) TypeNode(primary_pos, type,
+ primary_node->is_deferred_reference());
} else if (primary_node->primary().IsTypeParameter()) {
left = LoadTypeParameter(primary_node);
} else if (primary_node->IsSuper()) {
@@ -12652,7 +12655,8 @@
if ((resolved == NULL) || (resolved_func_level < type_param_func_level)) {
// The identifier is a function type parameter, possibly shadowing
// 'resolved'.
- if (type_param_func_level < FunctionLevel()) {
+ if ((FunctionLevel() > 0) &&
+ (type_param_func_level < FunctionLevel())) {
// Make sure that the function instantiator is captured.
CaptureFunctionInstantiator();
}
@@ -12719,7 +12723,8 @@
ClassFinalizer::kCanonicalize);
// Type may be malbounded, but not malformed.
ASSERT(!type.IsMalformed());
- resolved = new (Z) TypeNode(primary_pos, type);
+ resolved =
+ new (Z) TypeNode(primary_pos, type, primary->is_deferred_reference());
}
}
return resolved;
@@ -14007,7 +14012,8 @@
(primary_func_level < type_param_func_level)) {
// The identifier is a function type parameter, possibly shadowing
// already resolved 'primary'.
- if (type_param_func_level < FunctionLevel()) {
+ if ((FunctionLevel() > 0) &&
+ (type_param_func_level < FunctionLevel())) {
// Make sure that the function instantiator is captured.
CaptureFunctionInstantiator();
}
diff --git a/tests/language/deferred_regression_28678_lib.dart b/tests/language/deferred_regression_28678_lib.dart
new file mode 100644
index 0000000..f36c206
--- /dev/null
+++ b/tests/language/deferred_regression_28678_lib.dart
@@ -0,0 +1,7 @@
+// 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.
+
+var v;
+
+class Clazz { }
diff --git a/tests/language/deferred_regression_28678_test.dart b/tests/language/deferred_regression_28678_test.dart
new file mode 100644
index 0000000..5051e72
--- /dev/null
+++ b/tests/language/deferred_regression_28678_test.dart
@@ -0,0 +1,28 @@
+// 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.
+
+// Test that await after deferred loading works as expected.
+
+import 'dart:async';
+import "package:expect/expect.dart";
+import 'deferred_regression_28678_lib.dart' deferred as lib;
+
+class A {
+ m() => "here";
+}
+
+f(a, b) => new Future.microtask(() {});
+
+class R {
+ Future test_deferred() async {
+ var a = new A();
+ await lib.loadLibrary();
+ await f(lib.Clazz, lib.v);
+ Expect.equals("here", a.m());
+ }
+}
+
+main() async {
+ await new R().test_deferred();
+}
diff --git a/tests/language/language.status b/tests/language/language.status
index 717b3d4..5c7703f 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -272,6 +272,7 @@
deferred_optimized_test: Crash # Requires deferred libraries
deferred_redirecting_factory_test: Crash # Requires deferred libraries
deferred_regression_22995_test: Crash # Requires deferred libraries
+deferred_regression_28678_test: Crash # Requires deferred libraries
deferred_shadow_load_library_test: Crash # Requires deferred libraries
deferred_shared_and_unshared_classes_test: Crash # Requires deferred libraries
deferred_static_seperate_test: Crash # Requires deferred libraries
diff --git a/tests/language/language_kernel.status b/tests/language/language_kernel.status
index c53b287..fc6bb7c 100644
--- a/tests/language/language_kernel.status
+++ b/tests/language/language_kernel.status
@@ -222,7 +222,7 @@
# dartk: precompilation failures
[ $compiler == dartkp && $runtime == dart_precompiled ]
-if_null_assignment_static_test/35: Crash # Dartk Issue 28302
+deferred_regression_28678_test: RuntimeError # Issue 28335
# dartk: precompilation failures (debug)
[ $compiler == dartkp && $runtime == dart_precompiled && $mode == debug ]
diff --git a/tools/VERSION b/tools/VERSION
index 9b5dcb4..fceaa52 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -26,6 +26,6 @@
CHANNEL stable
MAJOR 1
MINOR 22
-PATCH 0
+PATCH 1
PRERELEASE 0
PRERELEASE_PATCH 0