| Index: runtime/vm/code_generator_ia32.cc
|
| ===================================================================
|
| --- runtime/vm/code_generator_ia32.cc (revision 770)
|
| +++ runtime/vm/code_generator_ia32.cc (working copy)
|
| @@ -9,6 +9,7 @@
|
|
|
| #include "lib/error.h"
|
| #include "vm/ast_printer.h"
|
| +#include "vm/class_finalizer.h"
|
| #include "vm/dart_entry.h"
|
| #include "vm/ic_data.h"
|
| #include "vm/longjump.h"
|
| @@ -868,7 +869,7 @@
|
| const bool requires_type_arguments = cls.HasTypeArguments();
|
| if (requires_type_arguments) {
|
| ASSERT(!function.IsImplicitStaticClosureFunction());
|
| - GenerateInstantiatorTypeArguments();
|
| + GenerateInstantiatorTypeArguments(node->token_index());
|
| }
|
| const Code& stub = Code::Handle(
|
| StubCode::GetAllocationStubForClosure(function));
|
| @@ -1427,7 +1428,7 @@
|
| __ pushl(EAX); // Push the instance.
|
| __ PushObject(type); // Push the type.
|
| if (!type.IsInstantiated()) {
|
| - GenerateInstantiatorTypeArguments();
|
| + GenerateInstantiatorTypeArguments(token_index);
|
| } else {
|
| __ pushl(raw_null); // Null instantiator.
|
| }
|
| @@ -1584,7 +1585,7 @@
|
| __ pushl(EAX); // Push the source object.
|
| __ PushObject(dst_type); // Push the type of the destination.
|
| if (!dst_type.IsInstantiated()) {
|
| - GenerateInstantiatorTypeArguments();
|
| + GenerateInstantiatorTypeArguments(token_index);
|
| } else {
|
| __ pushl(raw_null); // Null instantiator.
|
| }
|
| @@ -2166,22 +2167,36 @@
|
|
|
|
|
| // 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);
|
| +void CodeGenerator::GenerateInstantiatorTypeArguments(intptr_t token_index) {
|
| + const Class& instantiator_class =
|
| + Class::Handle(parsed_function().function().owner());
|
| + if (instantiator_class.NumTypeParameters() == 0) {
|
| + // The type arguments are compile time constants.
|
| + TypeArguments& type_arguments = TypeArguments::ZoneHandle();
|
| + const Type& type = Type::Handle(
|
| + Type::NewParameterizedType(instantiator_class, type_arguments));
|
| + const String& errmsg = String::Handle(
|
| + ClassFinalizer::FinalizeTypeWhileParsing(type));
|
| + if (!errmsg.IsNull()) {
|
| + ErrorMsg(token_index, errmsg.ToCString());
|
| + }
|
| + type_arguments = type.arguments();
|
| + __ PushObject(type_arguments);
|
| + } else {
|
| + ASSERT(parsed_function().instantiator() != NULL);
|
| + parsed_function().instantiator()->Visit(this);
|
| + if (!parsed_function().function().IsInFactoryScope()) {
|
| + __ popl(EAX); // Pop instantiator.
|
| + // 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);
|
| + }
|
| }
|
| }
|
|
|
| @@ -2216,7 +2231,7 @@
|
| } else {
|
| // The type arguments are uninstantiated.
|
| ASSERT(node->constructor().IsFactory() || requires_type_arguments);
|
| - GenerateInstantiatorTypeArguments();
|
| + GenerateInstantiatorTypeArguments(node->token_index());
|
| __ popl(EAX); // Pop instantiator.
|
| // EAX is the instantiator TypeArguments object (or null).
|
| // If EAX is null, no need to instantiate the type arguments, use null, and
|
|
|