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

Unified Diff: runtime/vm/code_generator_ia32.cc

Issue 8271008: Set type argument vector at run time in instantiated closure objects. (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
Index: runtime/vm/code_generator_ia32.cc
===================================================================
--- runtime/vm/code_generator_ia32.cc (revision 403)
+++ runtime/vm/code_generator_ia32.cc (working copy)
@@ -854,10 +854,21 @@
ASSERT(!function.HasCode());
ASSERT(function.context_scope() == ContextScope::null());
function.set_context_scope(context_scope);
+ // The function type of a closure may be parameterized. In that case, pass
+ // the type arguments of the instantiator.
+ const Class& cls = Class::Handle(function.signature_class());
+ ASSERT(!cls.IsNull());
+ const bool is_cls_parameterized = cls.IsParameterized();
+ if (is_cls_parameterized) {
+ GenerateInstantiatorTypeArguments();
+ }
const Code& stub = Code::Handle(
StubCode::GetAllocationStubForClosure(function));
const ExternalLabel label(function.ToCString(), stub.EntryPoint());
GenerateCall(node->token_index(), &label);
+ if (is_cls_parameterized) {
+ __ popl(ECX); // Pop type arguments.
+ }
if (IsResultNeeded(node)) {
__ pushl(EAX);
}
@@ -885,10 +896,21 @@
ASSERT(function.IsImplicitInstanceClosureFunction());
ASSERT(function.context_scope() != ContextScope::null());
node->receiver()->Visit(this);
+ // The function type of a closure may be parameterized. In that case, pass
+ // the type arguments of the instantiator.
+ const Class& cls = Class::Handle(function.signature_class());
+ ASSERT(!cls.IsNull());
+ const bool is_cls_parameterized = cls.IsParameterized();
+ if (is_cls_parameterized) {
+ GenerateInstantiatorTypeArguments();
+ }
const Code& stub = Code::Handle(
StubCode::GetAllocationStubForClosure(function));
const ExternalLabel label(function.ToCString(), stub.EntryPoint());
GenerateCall(node->token_index(), &label);
+ if (is_cls_parameterized) {
+ __ popl(ECX); // Pop type arguments.
+ }
__ popl(ECX); // Pop receiver.
siva 2011/10/13 20:52:21 The code for VisitClosureNode and VisitImplicitIns
regis 2011/10/13 21:33:46 I tried to factorize the visiting code of all 3 cl
if (IsResultNeeded(node)) {
__ pushl(EAX);
@@ -1436,22 +1458,7 @@
__ pushl(EAX); // Push the instance.
__ PushObject(type); // Push the type.
if (!type.IsInstantiated()) {
- ASSERT(parsed_function().instantiator() != NULL);
- parsed_function().instantiator()->Visit(this); // Instantiator on stack.
- if (!parsed_function().function().IsInFactoryScope()) {
- __ popl(EAX); // Pop instantiator.
- const Class& instantiator_class =
- Class::Handle(parsed_function().function().owner());
- // The instantiator is the receiver of the caller, which is not a factory.
- // The receiver cannot be null; extract its TypeArguments object.
- // Note that in the factory case, the instantiator is the first parameter
- // of the factory, i.e. already a TypeArguments object.
- intptr_t type_arguments_instance_field_offset =
- instantiator_class.type_arguments_instance_field_offset();
- ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments);
- __ movl(EAX, FieldAddress(EAX, type_arguments_instance_field_offset));
- __ pushl(EAX); // Push instantiator.
- }
+ GenerateInstantiatorTypeArguments();
} else {
__ PushObject(TypeArguments::ZoneHandle()); // Null instantiator.
}
@@ -1608,22 +1615,7 @@
__ pushl(EAX); // Push the source object.
__ PushObject(dst_type); // Push the type of the destination.
if (!dst_type.IsInstantiated()) {
- ASSERT(parsed_function().instantiator() != NULL);
- parsed_function().instantiator()->Visit(this); // Instantiator on stack.
- if (!parsed_function().function().IsInFactoryScope()) {
- __ popl(EAX); // Pop instantiator.
- const Class& instantiator_class =
- Class::Handle(parsed_function().function().owner());
- // The instantiator is the receiver of the caller, which is not a factory.
- // The receiver cannot be null; extract its TypeArguments object.
- // Note that in the factory case, the instantiator is the first parameter
- // of the factory, i.e. already a TypeArguments object.
- intptr_t type_arguments_instance_field_offset =
- instantiator_class.type_arguments_instance_field_offset();
- ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments);
- __ movl(EAX, FieldAddress(EAX, type_arguments_instance_field_offset));
- __ pushl(EAX); // Push instantiator.
- }
+ GenerateInstantiatorTypeArguments();
} else {
__ PushObject(TypeArguments::ZoneHandle()); // Null instantiator.
}
@@ -2205,6 +2197,27 @@
}
+// Pushes the type arguments of the instantiator on the stack.
+void CodeGenerator::GenerateInstantiatorTypeArguments() {
+ ASSERT(parsed_function().instantiator() != NULL);
+ parsed_function().instantiator()->Visit(this);
+ if (!parsed_function().function().IsInFactoryScope()) {
+ __ popl(EAX); // Pop instantiator.
+ const Class& instantiator_class =
+ Class::Handle(parsed_function().function().owner());
+ // The instantiator is the receiver of the caller, which is not a factory.
+ // The receiver cannot be null; extract its TypeArguments object.
+ // Note that in the factory case, the instantiator is the first parameter
+ // of the factory, i.e. already a TypeArguments object.
+ intptr_t type_arguments_instance_field_offset =
+ instantiator_class.type_arguments_instance_field_offset();
+ ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments);
+ __ movl(EAX, FieldAddress(EAX, type_arguments_instance_field_offset));
+ __ pushl(EAX);
+ }
+}
+
+
// Pushes the type arguments on the stack in preparation of a constructor or
// factory call.
// For a factory call, instantiates (possibly requiring an additional run time
@@ -2232,22 +2245,9 @@
}
} else {
// The type arguments are uninstantiated.
- ASSERT(parsed_function().instantiator() != NULL);
ASSERT(node->constructor().IsFactory() || is_cls_parameterized);
- parsed_function().instantiator()->Visit(this);
- __ popl(EAX); // Pop instantiator.
- if (!parsed_function().function().IsInFactoryScope()) {
- const Class& instantiator_class =
- Class::Handle(parsed_function().function().owner());
- // The instantiator is the receiver of the caller, which is not a factory.
- // The receiver cannot be null; extract its TypeArguments object.
- // Note that in the factory case, the instantiator is the first parameter
- // of the factory, i.e. already a TypeArguments object.
- intptr_t type_arguments_instance_field_offset =
- instantiator_class.type_arguments_instance_field_offset();
- ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments);
- __ movl(EAX, FieldAddress(EAX, type_arguments_instance_field_offset));
- }
+ GenerateInstantiatorTypeArguments();
+ __ popl(EAX);
siva 2011/10/13 20:52:21 // Pop instantiator.
regis 2011/10/13 21:33:46 Done.
// EAX is the instantiator TypeArguments object (or null).
// If EAX is null, no need to instantiate the type arguments, use null, and
// allocate an object of a raw type.

Powered by Google App Engine
This is Rietveld 408576698