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

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

Issue 8393033: Fix type tests involving an implicit closure of a non-parameterized class (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years, 1 month 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/code_generator_ia32.h ('k') | runtime/vm/object.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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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/globals.h" // Needed here to get TARGET_ARCH_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/code_generator.h" 8 #include "vm/code_generator.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
11 #include "vm/ast_printer.h" 11 #include "vm/ast_printer.h"
12 #include "vm/class_finalizer.h"
12 #include "vm/dart_entry.h" 13 #include "vm/dart_entry.h"
13 #include "vm/ic_data.h" 14 #include "vm/ic_data.h"
14 #include "vm/longjump.h" 15 #include "vm/longjump.h"
15 #include "vm/object.h" 16 #include "vm/object.h"
16 #include "vm/object_store.h" 17 #include "vm/object_store.h"
17 #include "vm/parser.h" 18 #include "vm/parser.h"
18 #include "vm/resolver.h" 19 #include "vm/resolver.h"
19 #include "vm/stub_code.h" 20 #include "vm/stub_code.h"
20 21
21 namespace dart { 22 namespace dart {
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
861 node->receiver()->Visit(this); 862 node->receiver()->Visit(this);
862 } 863 }
863 } 864 }
864 // The function type of a closure may have type arguments. In that case, pass 865 // The function type of a closure may have type arguments. In that case, pass
865 // the type arguments of the instantiator. 866 // the type arguments of the instantiator.
866 const Class& cls = Class::Handle(function.signature_class()); 867 const Class& cls = Class::Handle(function.signature_class());
867 ASSERT(!cls.IsNull()); 868 ASSERT(!cls.IsNull());
868 const bool requires_type_arguments = cls.HasTypeArguments(); 869 const bool requires_type_arguments = cls.HasTypeArguments();
869 if (requires_type_arguments) { 870 if (requires_type_arguments) {
870 ASSERT(!function.IsImplicitStaticClosureFunction()); 871 ASSERT(!function.IsImplicitStaticClosureFunction());
871 GenerateInstantiatorTypeArguments(); 872 GenerateInstantiatorTypeArguments(node->token_index());
872 } 873 }
873 const Code& stub = Code::Handle( 874 const Code& stub = Code::Handle(
874 StubCode::GetAllocationStubForClosure(function)); 875 StubCode::GetAllocationStubForClosure(function));
875 const ExternalLabel label(function.ToCString(), stub.EntryPoint()); 876 const ExternalLabel label(function.ToCString(), stub.EntryPoint());
876 GenerateCall(node->token_index(), &label); 877 GenerateCall(node->token_index(), &label);
877 if (requires_type_arguments) { 878 if (requires_type_arguments) {
878 __ popl(ECX); // Pop type arguments. 879 __ popl(ECX); // Pop type arguments.
879 } 880 }
880 if (function.IsImplicitInstanceClosureFunction()) { 881 if (function.IsImplicitInstanceClosureFunction()) {
881 __ popl(ECX); // Pop receiver. 882 __ popl(ECX); // Pop receiver.
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
1420 __ jmp(&done, Assembler::kNearJump); 1421 __ jmp(&done, Assembler::kNearJump);
1421 __ Bind(&runtime_call); 1422 __ Bind(&runtime_call);
1422 } 1423 }
1423 } 1424 }
1424 } 1425 }
1425 const Object& result = Object::ZoneHandle(); 1426 const Object& result = Object::ZoneHandle();
1426 __ PushObject(result); // Make room for the result of the runtime call. 1427 __ PushObject(result); // Make room for the result of the runtime call.
1427 __ pushl(EAX); // Push the instance. 1428 __ pushl(EAX); // Push the instance.
1428 __ PushObject(type); // Push the type. 1429 __ PushObject(type); // Push the type.
1429 if (!type.IsInstantiated()) { 1430 if (!type.IsInstantiated()) {
1430 GenerateInstantiatorTypeArguments(); 1431 GenerateInstantiatorTypeArguments(token_index);
1431 } else { 1432 } else {
1432 __ pushl(raw_null); // Null instantiator. 1433 __ pushl(raw_null); // Null instantiator.
1433 } 1434 }
1434 GenerateCallRuntime(token_index, kInstanceofRuntimeEntry); 1435 GenerateCallRuntime(token_index, kInstanceofRuntimeEntry);
1435 // Pop the two parameters supplied to the runtime entry. The result of the 1436 // Pop the two parameters supplied to the runtime entry. The result of the
1436 // instanceof runtime call will be left as the result of the operation. 1437 // instanceof runtime call will be left as the result of the operation.
1437 __ addl(ESP, Immediate(3 * kWordSize)); 1438 __ addl(ESP, Immediate(3 * kWordSize));
1438 if (negate_result) { 1439 if (negate_result) {
1439 Label negate_done; 1440 Label negate_done;
1440 __ popl(EDX); 1441 __ popl(EDX);
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1577 } 1578 }
1578 __ Bind(&runtime_call); 1579 __ Bind(&runtime_call);
1579 const Object& result = Object::ZoneHandle(); 1580 const Object& result = Object::ZoneHandle();
1580 __ PushObject(result); // Make room for the result of the runtime call. 1581 __ PushObject(result); // Make room for the result of the runtime call.
1581 const Immediate location = 1582 const Immediate location =
1582 Immediate(reinterpret_cast<int32_t>(Smi::New(token_index))); 1583 Immediate(reinterpret_cast<int32_t>(Smi::New(token_index)));
1583 __ pushl(location); // Push the source location. 1584 __ pushl(location); // Push the source location.
1584 __ pushl(EAX); // Push the source object. 1585 __ pushl(EAX); // Push the source object.
1585 __ PushObject(dst_type); // Push the type of the destination. 1586 __ PushObject(dst_type); // Push the type of the destination.
1586 if (!dst_type.IsInstantiated()) { 1587 if (!dst_type.IsInstantiated()) {
1587 GenerateInstantiatorTypeArguments(); 1588 GenerateInstantiatorTypeArguments(token_index);
1588 } else { 1589 } else {
1589 __ pushl(raw_null); // Null instantiator. 1590 __ pushl(raw_null); // Null instantiator.
1590 } 1591 }
1591 __ PushObject(dst_name); // Push the name of the destination. 1592 __ PushObject(dst_name); // Push the name of the destination.
1592 GenerateCallRuntime(token_index, kTypeCheckRuntimeEntry); 1593 GenerateCallRuntime(token_index, kTypeCheckRuntimeEntry);
1593 // Pop the parameters supplied to the runtime entry. The result of the 1594 // Pop the parameters supplied to the runtime entry. The result of the
1594 // type check runtime call is the checked value. 1595 // type check runtime call is the checked value.
1595 __ addl(ESP, Immediate(5 * kWordSize)); 1596 __ addl(ESP, Immediate(5 * kWordSize));
1596 __ popl(EAX); 1597 __ popl(EAX);
1597 1598
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after
2159 // Restore the context. 2160 // Restore the context.
2160 __ popl(CTX); 2161 __ popl(CTX);
2161 // Result is in EAX. 2162 // Result is in EAX.
2162 if (IsResultNeeded(node)) { 2163 if (IsResultNeeded(node)) {
2163 __ pushl(EAX); 2164 __ pushl(EAX);
2164 } 2165 }
2165 } 2166 }
2166 2167
2167 2168
2168 // Pushes the type arguments of the instantiator on the stack. 2169 // Pushes the type arguments of the instantiator on the stack.
2169 void CodeGenerator::GenerateInstantiatorTypeArguments() { 2170 void CodeGenerator::GenerateInstantiatorTypeArguments(intptr_t token_index) {
2170 ASSERT(parsed_function().instantiator() != NULL); 2171 const Class& instantiator_class =
2171 parsed_function().instantiator()->Visit(this); 2172 Class::Handle(parsed_function().function().owner());
2172 if (!parsed_function().function().IsInFactoryScope()) { 2173 if (instantiator_class.NumTypeParameters() == 0) {
2173 __ popl(EAX); // Pop instantiator. 2174 // The type arguments are compile time constants.
2174 const Class& instantiator_class = 2175 TypeArguments& type_arguments = TypeArguments::ZoneHandle();
2175 Class::Handle(parsed_function().function().owner()); 2176 const Type& type = Type::Handle(
2176 // The instantiator is the receiver of the caller, which is not a factory. 2177 Type::NewParameterizedType(instantiator_class, type_arguments));
2177 // The receiver cannot be null; extract its TypeArguments object. 2178 const String& errmsg = String::Handle(
2178 // Note that in the factory case, the instantiator is the first parameter 2179 ClassFinalizer::FinalizeTypeWhileParsing(type));
2179 // of the factory, i.e. already a TypeArguments object. 2180 if (!errmsg.IsNull()) {
2180 intptr_t type_arguments_instance_field_offset = 2181 ErrorMsg(token_index, errmsg.ToCString());
2181 instantiator_class.type_arguments_instance_field_offset(); 2182 }
2182 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments); 2183 type_arguments = type.arguments();
2183 __ movl(EAX, FieldAddress(EAX, type_arguments_instance_field_offset)); 2184 __ PushObject(type_arguments);
2184 __ pushl(EAX); 2185 } else {
2186 ASSERT(parsed_function().instantiator() != NULL);
2187 parsed_function().instantiator()->Visit(this);
2188 if (!parsed_function().function().IsInFactoryScope()) {
2189 __ popl(EAX); // Pop instantiator.
2190 // The instantiator is the receiver of the caller, which is not a factory.
2191 // The receiver cannot be null; extract its TypeArguments object.
2192 // Note that in the factory case, the instantiator is the first parameter
2193 // of the factory, i.e. already a TypeArguments object.
2194 intptr_t type_arguments_instance_field_offset =
2195 instantiator_class.type_arguments_instance_field_offset();
2196 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments);
2197 __ movl(EAX, FieldAddress(EAX, type_arguments_instance_field_offset));
2198 __ pushl(EAX);
2199 }
2185 } 2200 }
2186 } 2201 }
2187 2202
2188 2203
2189 // Pushes the type arguments on the stack in preparation of a constructor or 2204 // Pushes the type arguments on the stack in preparation of a constructor or
2190 // factory call. 2205 // factory call.
2191 // For a factory call, instantiates (possibly requiring an additional run time 2206 // For a factory call, instantiates (possibly requiring an additional run time
2192 // call) and pushes the type argument vector that will be passed as implicit 2207 // call) and pushes the type argument vector that will be passed as implicit
2193 // first parameter to the factory. 2208 // first parameter to the factory.
2194 // For a constructor call allocating an object of a parameterized class, pushes 2209 // For a constructor call allocating an object of a parameterized class, pushes
(...skipping 14 matching lines...) Expand all
2209 // A factory requires the type arguments as first parameter. 2224 // A factory requires the type arguments as first parameter.
2210 __ PushObject(node->type_arguments()); 2225 __ PushObject(node->type_arguments());
2211 if (!node->constructor().IsFactory()) { 2226 if (!node->constructor().IsFactory()) {
2212 // The allocator additionally requires the instantiator type arguments. 2227 // The allocator additionally requires the instantiator type arguments.
2213 __ pushl(raw_null); // Null instantiator. 2228 __ pushl(raw_null); // Null instantiator.
2214 } 2229 }
2215 } 2230 }
2216 } else { 2231 } else {
2217 // The type arguments are uninstantiated. 2232 // The type arguments are uninstantiated.
2218 ASSERT(node->constructor().IsFactory() || requires_type_arguments); 2233 ASSERT(node->constructor().IsFactory() || requires_type_arguments);
2219 GenerateInstantiatorTypeArguments(); 2234 GenerateInstantiatorTypeArguments(node->token_index());
2220 __ popl(EAX); // Pop instantiator. 2235 __ popl(EAX); // Pop instantiator.
2221 // EAX is the instantiator TypeArguments object (or null). 2236 // EAX is the instantiator TypeArguments object (or null).
2222 // If EAX is null, no need to instantiate the type arguments, use null, and 2237 // If EAX is null, no need to instantiate the type arguments, use null, and
2223 // allocate an object of a raw type. 2238 // allocate an object of a raw type.
2224 Label type_arguments_instantiated, type_arguments_uninstantiated; 2239 Label type_arguments_instantiated, type_arguments_uninstantiated;
2225 __ cmpl(EAX, raw_null); 2240 __ cmpl(EAX, raw_null);
2226 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 2241 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
2227 2242
2228 // Instantiate non-null type arguments. 2243 // Instantiate non-null type arguments.
2229 if (node->type_arguments().IsUninstantiatedIdentity()) { 2244 if (node->type_arguments().IsUninstantiatedIdentity()) {
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
2626 const Class& cls = Class::Handle(parsed_function_.function().owner()); 2641 const Class& cls = Class::Handle(parsed_function_.function().owner());
2627 const Script& script = Script::Handle(cls.script()); 2642 const Script& script = Script::Handle(cls.script());
2628 Parser::ReportMsg(script, token_index, "Error", error_msg, format, args); 2643 Parser::ReportMsg(script, token_index, "Error", error_msg, format, args);
2629 Isolate::Current()->long_jump_base()->Jump(1, error_msg); 2644 Isolate::Current()->long_jump_base()->Jump(1, error_msg);
2630 UNREACHABLE(); 2645 UNREACHABLE();
2631 } 2646 }
2632 2647
2633 } // namespace dart 2648 } // namespace dart
2634 2649
2635 #endif // defined TARGET_ARCH_IA32 2650 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/code_generator_ia32.h ('k') | runtime/vm/object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698