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

Side by Side Diff: runtime/vm/object.cc

Issue 12123002: Fix class patching involving type parameters: type parameters of patched classes (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/bigint_operations.h" 10 #include "vm/bigint_operations.h"
(...skipping 1425 matching lines...) Expand 10 before | Expand all | Expand 10 after
1436 // This class is a function type alias. Return the canonical signature type. 1436 // This class is a function type alias. Return the canonical signature type.
1437 const Class& canonical_class = Class::Handle(function.signature_class()); 1437 const Class& canonical_class = Class::Handle(function.signature_class());
1438 return canonical_class.SignatureType(); 1438 return canonical_class.SignatureType();
1439 } 1439 }
1440 // Return the first canonical signature type if already computed. 1440 // Return the first canonical signature type if already computed.
1441 const Array& signature_types = Array::Handle(canonical_types()); 1441 const Array& signature_types = Array::Handle(canonical_types());
1442 // The canonical_types array is initialized to the empty array. 1442 // The canonical_types array is initialized to the empty array.
1443 ASSERT(!signature_types.IsNull()); 1443 ASSERT(!signature_types.IsNull());
1444 if (signature_types.Length() > 0) { 1444 if (signature_types.Length() > 0) {
1445 // At most one signature type per signature class. 1445 // At most one signature type per signature class.
1446 ASSERT(signature_types.Length() == 1); 1446 ASSERT((signature_types.Length() == 1) ||
1447 ((signature_types.Length() == 2) &&
1448 (signature_types.At(1) == Type::null())));
1447 Type& signature_type = Type::Handle(); 1449 Type& signature_type = Type::Handle();
1448 signature_type ^= signature_types.At(0); 1450 signature_type ^= signature_types.At(0);
1449 ASSERT(!signature_type.IsNull()); 1451 ASSERT(!signature_type.IsNull());
1450 return signature_type.raw(); 1452 return signature_type.raw();
1451 } 1453 }
1452 // A signature class extends class Instance and is parameterized in the same 1454 // A signature class extends class Instance and is parameterized in the same
1453 // way as the owner class of its non-static signature function. 1455 // way as the owner class of its non-static signature function.
1454 // It is not type parameterized if its signature function is static. 1456 // It is not type parameterized if its signature function is static.
1455 // See Class::NewSignatureClass() for the setup of its type parameters. 1457 // See Class::NewSignatureClass() for the setup of its type parameters.
1456 // During type finalization, the type arguments of the super class of the 1458 // During type finalization, the type arguments of the super class of the
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
1908 RawClass* Class::New(const String& name, 1910 RawClass* Class::New(const String& name,
1909 const Script& script, 1911 const Script& script,
1910 intptr_t token_pos) { 1912 intptr_t token_pos) {
1911 Class& result = Class::Handle(New<Instance>(name, script, token_pos)); 1913 Class& result = Class::Handle(New<Instance>(name, script, token_pos));
1912 return result.raw(); 1914 return result.raw();
1913 } 1915 }
1914 1916
1915 1917
1916 RawClass* Class::NewSignatureClass(const String& name, 1918 RawClass* Class::NewSignatureClass(const String& name,
1917 const Function& signature_function, 1919 const Function& signature_function,
1918 const Script& script) { 1920 const Script& script,
1921 intptr_t token_pos) {
1922 const Class& result = Class::Handle(New<Instance>(name, script, token_pos));
1923 const Type& super_type = Type::Handle(Type::ObjectType());
1924 ASSERT(!super_type.IsNull());
1925 // Instances of a signature class can only be closures.
1926 result.set_instance_size(Closure::InstanceSize());
1927 result.set_next_field_offset(Closure::InstanceSize());
1928 result.set_super_type(super_type);
1929 result.set_type_arguments_field_offset(Closure::type_arguments_offset());
1930 // Implements interface "Function".
1931 const Type& function_type = Type::Handle(Type::Function());
1932 const Array& interfaces = Array::Handle(Array::New(1, Heap::kOld));
1933 interfaces.SetAt(0, function_type);
1934 result.set_interfaces(interfaces);
1935 if (!signature_function.IsNull()) {
1936 result.PatchSignatureFunction(signature_function);
1937 }
1938 return result.raw();
1939 }
1940
1941
1942 void Class::PatchSignatureFunction(const Function& signature_function) const {
1919 ASSERT(!signature_function.IsNull()); 1943 ASSERT(!signature_function.IsNull());
1920 const Class& owner_class = Class::Handle(signature_function.Owner()); 1944 const Class& owner_class = Class::Handle(signature_function.Owner());
1921 ASSERT(!owner_class.IsNull()); 1945 ASSERT(!owner_class.IsNull());
1922 TypeArguments& type_parameters = TypeArguments::Handle(); 1946 TypeArguments& type_parameters = TypeArguments::Handle();
1923 // A signature class extends class Instance and is parameterized in the same 1947 // A signature class extends class Instance and is parameterized in the same
1924 // way as the owner class of its non-static signature function. 1948 // way as the owner class of its non-static signature function.
1925 // It is not type parameterized if its signature function is static. 1949 // It is not type parameterized if its signature function is static.
1950 // In case of a function type alias, the function owner is the alias class
1951 // instead of the enclosing class.
1926 if (!signature_function.is_static() && 1952 if (!signature_function.is_static() &&
1927 (owner_class.NumTypeParameters() > 0) && 1953 (owner_class.NumTypeParameters() > 0) &&
1928 !signature_function.HasInstantiatedSignature()) { 1954 !signature_function.HasInstantiatedSignature()) {
1929 type_parameters = owner_class.type_parameters(); 1955 type_parameters = owner_class.type_parameters();
1930 } 1956 }
1931 const intptr_t token_pos = signature_function.token_pos(); 1957 set_signature_function(signature_function);
1932 Class& result = Class::Handle(New<Instance>(name, script, token_pos)); 1958 set_type_parameters(type_parameters);
1933 const Type& super_type = Type::Handle(Type::ObjectType()); 1959 if (owner_class.raw() == raw()) {
1934 ASSERT(!super_type.IsNull()); 1960 // This signature class is an alias, which cannot be the canonical
1935 result.set_instance_size(Closure::InstanceSize()); 1961 // signature class for this signature function.
1936 result.set_next_field_offset(Closure::InstanceSize()); 1962 ASSERT(!IsCanonicalSignatureClass());
1937 result.set_super_type(super_type); 1963 } else if (signature_function.signature_class() == Object::null()) {
1938 result.set_signature_function(signature_function); 1964 // Make this signature class the canonical signature class.
1939 result.set_type_parameters(type_parameters); 1965 signature_function.set_signature_class(*this);
1940 result.SetFields(Object::empty_array()); 1966 ASSERT(IsCanonicalSignatureClass());
1941 result.SetFunctions(Object::empty_array());
1942 result.set_type_arguments_field_offset(
1943 Closure::type_arguments_offset());
1944 // Implements interface "Function".
1945 const Type& function_type = Type::Handle(Type::Function());
1946 const Array& interfaces = Array::Handle(Array::New(1, Heap::kOld));
1947 interfaces.SetAt(0, function_type);
1948 result.set_interfaces(interfaces);
1949 // Unless the signature function already has a signature class, create a
1950 // canonical signature class by having the signature function point back to
1951 // the signature class.
1952 if (signature_function.signature_class() == Object::null()) {
1953 signature_function.set_signature_class(result);
1954 result.set_is_finalized();
1955 } else {
1956 // This new signature class is an alias.
1957 ASSERT(!result.IsCanonicalSignatureClass());
1958 // Do not yet mark it as finalized, so that the class finalizer can check it
1959 // for illegal self references.
1960 result.set_is_prefinalized();
1961 } 1967 }
1962 // Instances of a signature class can only be closures. 1968 set_is_prefinalized();
1963 ASSERT(result.instance_size() == Closure::InstanceSize());
1964 // Cache the signature type as the first canonicalized type in result.
1965 const Type& signature_type = Type::Handle(result.SignatureType());
1966 ASSERT(!signature_type.IsFinalized());
1967 const Array& new_canonical_types = Array::Handle(Array::New(1, Heap::kOld));
1968 new_canonical_types.SetAt(0, signature_type);
1969 result.set_canonical_types(new_canonical_types);
1970 return result.raw();
1971 } 1969 }
1972 1970
1973 1971
1974 RawClass* Class::NewNativeWrapper(const Library& library, 1972 RawClass* Class::NewNativeWrapper(const Library& library,
1975 const String& name, 1973 const String& name,
1976 int field_count) { 1974 int field_count) {
1977 Class& cls = Class::Handle(library.LookupClass(name)); 1975 Class& cls = Class::Handle(library.LookupClass(name));
1978 if (cls.IsNull()) { 1976 if (cls.IsNull()) {
1979 cls = New<Instance>(name, Script::Handle(), Scanner::kDummyTokenIndex); 1977 cls = New<Instance>(name, Script::Handle(), Scanner::kDummyTokenIndex);
1980 cls.SetFields(Object::empty_array()); 1978 cls.SetFields(Object::empty_array());
(...skipping 2225 matching lines...) Expand 10 before | Expand all | Expand 10 after
4206 ASSERT(!owner_class.IsNull() && (Owner() == closure_function.Owner())); 4204 ASSERT(!owner_class.IsNull() && (Owner() == closure_function.Owner()));
4207 const Library& library = Library::Handle(owner_class.library()); 4205 const Library& library = Library::Handle(owner_class.library());
4208 ASSERT(!library.IsNull()); 4206 ASSERT(!library.IsNull());
4209 const String& signature = String::Handle(closure_function.Signature()); 4207 const String& signature = String::Handle(closure_function.Signature());
4210 Class& signature_class = Class::ZoneHandle( 4208 Class& signature_class = Class::ZoneHandle(
4211 library.LookupLocalClass(signature)); 4209 library.LookupLocalClass(signature));
4212 if (signature_class.IsNull()) { 4210 if (signature_class.IsNull()) {
4213 const Script& script = Script::Handle(this->script()); 4211 const Script& script = Script::Handle(this->script());
4214 signature_class = Class::NewSignatureClass(signature, 4212 signature_class = Class::NewSignatureClass(signature,
4215 closure_function, 4213 closure_function,
4216 script); 4214 script,
4215 closure_function.token_pos());
4217 library.AddClass(signature_class); 4216 library.AddClass(signature_class);
4218 } else { 4217 } else {
4219 closure_function.set_signature_class(signature_class); 4218 closure_function.set_signature_class(signature_class);
4220 } 4219 }
4221 const Type& signature_type = Type::Handle(signature_class.SignatureType()); 4220 const Type& signature_type = Type::Handle(signature_class.SignatureType());
4222 if (!signature_type.IsFinalized()) { 4221 if (!signature_type.IsFinalized()) {
4223 ClassFinalizer::FinalizeType( 4222 ClassFinalizer::FinalizeType(
4224 signature_class, signature_type, ClassFinalizer::kCanonicalize); 4223 signature_class, signature_type, ClassFinalizer::kCanonicalize);
4225 } 4224 }
4226 ASSERT(closure_function.signature_class() == signature_class.raw()); 4225 ASSERT(closure_function.signature_class() == signature_class.raw());
4227 set_implicit_closure_function(closure_function); 4226 set_implicit_closure_function(closure_function);
4228 ASSERT(closure_function.IsImplicitClosureFunction()); 4227 ASSERT(closure_function.IsImplicitClosureFunction());
4229 return closure_function.raw(); 4228 return closure_function.raw();
4230 } 4229 }
4231 4230
4232 4231
4233 RawString* Function::BuildSignature( 4232 RawString* Function::BuildSignature(
4234 bool instantiate, 4233 bool instantiate,
4235 NameVisibility name_visibility, 4234 NameVisibility name_visibility,
4236 const AbstractTypeArguments& instantiator) const { 4235 const AbstractTypeArguments& instantiator) const {
4237 const GrowableObjectArray& pieces = 4236 const GrowableObjectArray& pieces =
4238 GrowableObjectArray::Handle(GrowableObjectArray::New()); 4237 GrowableObjectArray::Handle(GrowableObjectArray::New());
4239 String& name = String::Handle(); 4238 String& name = String::Handle();
4240 if (!instantiate && !is_static() && (name_visibility == kInternalName)) { 4239 if (!instantiate && !is_static() && (name_visibility == kInternalName)) {
4241 // Prefix the signature with its class and type parameters, if any (e.g. 4240 // Prefix the signature with its signature class and type parameters, if any
4242 // "Map<K, V>(K) => bool"). 4241 // (e.g. "Map<K, V>(K) => bool"). In case of a function type alias, the
4242 // signature class name is the alias name.
4243 // The signature of static functions cannot be type parameterized. 4243 // The signature of static functions cannot be type parameterized.
4244 const Class& function_class = Class::Handle(Owner()); 4244 const Class& function_class = Class::Handle(Owner());
4245 ASSERT(!function_class.IsNull()); 4245 ASSERT(!function_class.IsNull());
4246 const TypeArguments& type_parameters = TypeArguments::Handle( 4246 const TypeArguments& type_parameters = TypeArguments::Handle(
4247 function_class.type_parameters()); 4247 function_class.type_parameters());
4248 if (!type_parameters.IsNull()) { 4248 if (!type_parameters.IsNull()) {
4249 const String& function_class_name = String::Handle(function_class.Name()); 4249 const String& function_class_name = String::Handle(function_class.Name());
4250 pieces.Add(function_class_name); 4250 pieces.Add(function_class_name);
4251 intptr_t num_type_parameters = type_parameters.Length(); 4251 intptr_t num_type_parameters = type_parameters.Length();
4252 pieces.Add(Symbols::LAngleBracket()); 4252 pieces.Add(Symbols::LAngleBracket());
(...skipping 8530 matching lines...) Expand 10 before | Expand all | Expand 10 after
12783 } 12783 }
12784 return result.raw(); 12784 return result.raw();
12785 } 12785 }
12786 12786
12787 12787
12788 const char* WeakProperty::ToCString() const { 12788 const char* WeakProperty::ToCString() const {
12789 return "_WeakProperty"; 12789 return "_WeakProperty";
12790 } 12790 }
12791 12791
12792 } // namespace dart 12792 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698