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

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

Powered by Google App Engine
This is Rietveld 408576698