Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(109)

Unified Diff: runtime/vm/object.cc

Issue 8289027: Set type argument vector at compile time in type of closure parameters; this (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/object.cc
===================================================================
--- runtime/vm/object.cc (revision 478)
+++ runtime/vm/object.cc (working copy)
@@ -696,6 +696,39 @@
}
+RawType* Class::SignatureType() const {
+ // Return the cached signature type if any.
+ if (raw_ptr()->signature_type_ != Type::null()) {
+ return raw_ptr()->signature_type_;
+ }
+ ASSERT(IsSignatureClass());
+ TypeArguments& signature_type_arguments = TypeArguments::Handle();
+ const intptr_t num_type_params = NumTypeParameters();
+ // If the signature class extends a parameterized class, the type arguments of
+ // the super class will be prepended to the type argument vector during type
+ // finalization. We only need to provide the type parameters of the signature
+ // class here.
+ if (num_type_params > 0) {
+ const Array& type_params = Array::Handle(type_parameters());
+ signature_type_arguments = TypeArguments::NewTypeArray(num_type_params);
+ String& type_param_name = String::Handle();
+ Type& type_param = Type::Handle();
+ for (int i = 0; i < num_type_params; i++) {
+ type_param_name ^= type_params.At(i);
+ type_param = Type::NewTypeParameter(i, type_param_name);
+ signature_type_arguments.SetTypeAt(i, type_param);
+ }
+ }
+ const ParameterizedType& signature_type = ParameterizedType::Handle(
+ ParameterizedType::New(*this, signature_type_arguments));
+
+ // Cache and return the still unfinalized signature type.
+ ASSERT(!signature_type.IsFinalized());
+ set_signature_type(signature_type);
+ return signature_type.raw();
+}
+
+
template <class FakeObject>
RawClass* Class::New() {
Class& class_class = Class::Handle(Object::class_class());
@@ -766,6 +799,11 @@
}
+void Class::set_signature_type(const Type& value) const {
+ StorePointer(&raw_ptr()->signature_type_, value.raw());
+}
+
+
void Class::set_class_state(int8_t state) const {
ASSERT(state == RawClass::kAllocated ||
state == RawClass::kPreFinalized ||
@@ -802,7 +840,8 @@
intptr_t Class::NumTypeArguments() const {
intptr_t num_type_args = NumTypeParameters();
const Class& superclass = Class::Handle(SuperClass());
- if (!superclass.IsNull()) {
+ // Object is its own super class during bootstrap.
+ if (!superclass.IsNull() && (superclass.raw() != raw())) {
num_type_args += superclass.NumTypeArguments();
}
return num_type_args;
@@ -977,19 +1016,21 @@
intptr_t token_index) {
ASSERT(!signature_function.IsNull());
Type& super_type = Type::Handle(Type::ObjectType());
+ const Class& owner_class = Class::Handle(signature_function.owner());
+ ASSERT(!owner_class.IsNull());
Array& type_parameters = Array::Handle();
TypeArray& type_parameter_extends = TypeArray::Handle();
if (!signature_function.is_static()) {
- const Class& owner_class = Class::Handle(signature_function.owner());
- ASSERT(!owner_class.IsNull());
- ASSERT(!owner_class.is_interface());
- if (owner_class.IsParameterized()) {
+ if (owner_class.IsParameterized() &&
+ !signature_function.HasInstantiatedSignature()) {
// Share the function owner super class as the super class of the
// signature class, so that the type argument vector of the closure at
// run time matches the type argument vector of the closure instantiator.
type_parameters = owner_class.type_parameters();
type_parameter_extends = owner_class.type_parameter_extends();
- super_type = owner_class.super_type();
+ if (!owner_class.is_interface()) {
+ super_type = owner_class.super_type();
+ }
}
}
Class& result = Class::Handle(New<Closure>(name, script));
@@ -1586,6 +1627,13 @@
}
+bool Type::IsBeingFinalized() const {
+ // Type is an abstract class.
+ UNREACHABLE();
+ return false;
+}
+
+
RawType* Type::InstantiateFrom(
const TypeArguments& instantiator_type_arguments,
intptr_t offset) const {
@@ -1606,12 +1654,23 @@
class_name = cls.Name();
num_type_params = cls.NumTypeParameters(); // Do not print the full vector.
if (num_type_params > num_args) {
- ASSERT(!IsFinalized());
+ ASSERT(num_args == 0); // Type is raw.
// We fill up with "var".
first_type_param_index = 0;
} else {
first_type_param_index = num_args - num_type_params;
}
+ if (cls.IsSignatureClass()) {
+ const Function& signature_function = Function::Handle(
+ cls.signature_function());
+ // We may be reporting an error about an illformed function type. In that
+ // case, avoid instantiating the signature, since it may lead to cycles.
+ if (IsBeingFinalized()) {
+ return class_name.raw();
+ }
+ return signature_function.InstantiatedSignatureFrom(
+ args, first_type_param_index);
+ }
} else {
const UnresolvedClass& type = UnresolvedClass::Handle(unresolved_class());
class_name = type.Name();
@@ -1645,7 +1704,7 @@
ASSERT(s == num_strings);
type_name = String::ConcatAll(strings);
}
- // The name is only used for naming function types and for debugging purposes.
+ // The name is only used for type checking and debugging purposes.
// Unless profiling data shows otherwise, it is not worth caching the name in
// the type.
return String::NewSymbol(type_name);
@@ -1842,7 +1901,7 @@
void ParameterizedType::set_is_being_finalized() const {
- ASSERT(!IsFinalized() && !is_being_finalized());
+ ASSERT(!IsFinalized() && !IsBeingFinalized());
set_type_state(RawParameterizedType::kBeingFinalized);
}
@@ -1901,8 +1960,11 @@
type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments,
offset);
}
+ const Class& cls = Class::Handle(type_class());
ParameterizedType& instantiated_type = ParameterizedType::Handle(
- ParameterizedType::New(Object::Handle(type_class()), type_arguments));
+ ParameterizedType::New(cls, type_arguments));
+ ASSERT(type_arguments.IsNull() ||
+ (type_arguments.Length() == cls.NumTypeArguments()));
instantiated_type.set_is_finalized();
return instantiated_type.raw();
}
@@ -2910,21 +2972,21 @@
}
-// Build a string of the form '<T>(A, [b: B, c: C]) => R)' representing the
-// signature of the given function.
-RawString* Function::Signature() const {
+RawString* Function::BuildSignature(bool instantiate,
+ const TypeArguments& instantiator,
+ intptr_t offset) const {
GrowableArray<const String*> pieces;
- const String& kSpaceExtendsSpace =
- String::Handle(String::NewSymbol(" extends "));
const String& kCommaSpace = String::Handle(String::NewSymbol(", "));
const String& kColonSpace = String::Handle(String::NewSymbol(": "));
- const String& kLAngleBracket = String::Handle(String::NewSymbol("<"));
- const String& kRAngleBracket = String::Handle(String::NewSymbol(">"));
const String& kLParen = String::Handle(String::NewSymbol("("));
const String& kRParen = String::Handle(String::NewSymbol(") => "));
const String& kLBracket = String::Handle(String::NewSymbol("["));
const String& kRBracket = String::Handle(String::NewSymbol("]"));
- if (!is_static()) {
+ if (!instantiate && !is_static()) {
+ const String& kSpaceExtendsSpace =
+ String::Handle(String::NewSymbol(" extends "));
+ const String& kLAngleBracket = String::Handle(String::NewSymbol("<"));
+ const String& kRAngleBracket = String::Handle(String::NewSymbol(">"));
const Class& function_class = Class::Handle(owner());
ASSERT(!function_class.IsNull());
const Array& type_parameters = Array::Handle(
@@ -2960,6 +3022,9 @@
for (intptr_t i = 0; i < num_fixed_params; i++) {
param_type = ParameterTypeAt(i);
ASSERT(!param_type.IsNull());
+ if (instantiate && !param_type.IsInstantiated()) {
+ param_type = param_type.InstantiateFrom(instantiator, offset);
+ }
pieces.Add(&String::ZoneHandle(param_type.Name()));
if (i != (num_params - 1)) {
pieces.Add(&kCommaSpace);
@@ -2971,6 +3036,9 @@
pieces.Add(&String::ZoneHandle(ParameterNameAt(i)));
pieces.Add(&kColonSpace);
param_type = ParameterTypeAt(i);
+ if (instantiate && !param_type.IsInstantiated()) {
+ param_type = param_type.InstantiateFrom(instantiator, offset);
+ }
ASSERT(!param_type.IsNull());
pieces.Add(&String::ZoneHandle(param_type.Name()));
if (i != (num_params - 1)) {
@@ -2980,13 +3048,32 @@
pieces.Add(&kRBracket);
}
pieces.Add(&kRParen);
- const Type& res_type = Type::Handle(result_type());
+ Type& res_type = Type::Handle(result_type());
+ if (instantiate && !res_type.IsInstantiated()) {
+ res_type = res_type.InstantiateFrom(instantiator, offset);
+ }
pieces.Add(&String::Handle(res_type.Name()));
const Array& strings = Array::Handle(NewArray<const String>(pieces));
return String::NewSymbol(String::Handle(String::ConcatAll(strings)));
}
+bool Function::HasInstantiatedSignature() const {
+ Type& type = Type::Handle(result_type());
+ if (!type.IsInstantiated()) {
+ return false;
+ }
+ const intptr_t num_parameters = NumberOfParameters();
+ for (intptr_t i = 0; i < num_parameters; i++) {
+ type = ParameterTypeAt(i);
+ if (!type.IsInstantiated()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
const char* Function::ToCString() const {
const char* f0 = is_static() ? " static" : "";
const char* f1 = NULL;
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698