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

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

Issue 8602004: Fix code generation issue with new factory syntax. (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/class_finalizer.cc ('k') | runtime/vm/parser.h » ('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"
(...skipping 2237 matching lines...) Expand 10 before | Expand all | Expand 10 after
2248 __ popl(CTX); 2248 __ popl(CTX);
2249 // Result is in EAX. 2249 // Result is in EAX.
2250 if (IsResultNeeded(node)) { 2250 if (IsResultNeeded(node)) {
2251 __ pushl(EAX); 2251 __ pushl(EAX);
2252 } 2252 }
2253 } 2253 }
2254 2254
2255 2255
2256 // Pushes the type arguments of the instantiator on the stack. 2256 // Pushes the type arguments of the instantiator on the stack.
2257 void CodeGenerator::GenerateInstantiatorTypeArguments(intptr_t token_index) { 2257 void CodeGenerator::GenerateInstantiatorTypeArguments(intptr_t token_index) {
2258 const Class& instantiator_class = 2258 Class& instantiator_class = Class::Handle();
2259 Class::Handle(parsed_function().function().owner()); 2259 Function& outer_function =
2260 Function::Handle(parsed_function().function().raw());
2261 while (outer_function.IsLocalFunction()) {
2262 outer_function = outer_function.parent_function();
2263 }
2264 if (outer_function.IsFactory()) {
2265 instantiator_class = outer_function.signature_class();
2266 } else {
2267 instantiator_class = outer_function.owner();
2268 }
2260 if (instantiator_class.NumTypeParameters() == 0) { 2269 if (instantiator_class.NumTypeParameters() == 0) {
2261 // The type arguments are compile time constants. 2270 // The type arguments are compile time constants.
2262 TypeArguments& type_arguments = TypeArguments::ZoneHandle(); 2271 TypeArguments& type_arguments = TypeArguments::ZoneHandle();
2272 // TODO(regis): Temporary type should be allocated in new gen heap.
2263 Type& type = Type::Handle( 2273 Type& type = Type::Handle(
2264 Type::NewParameterizedType(instantiator_class, type_arguments)); 2274 Type::NewParameterizedType(instantiator_class, type_arguments));
2265 String& errmsg = String::Handle(); 2275 String& errmsg = String::Handle();
2266 type = ClassFinalizer::FinalizeAndCanonicalizeType(type, &errmsg); 2276 type = ClassFinalizer::FinalizeAndCanonicalizeType(type, &errmsg);
2267 if (!errmsg.IsNull()) { 2277 if (!errmsg.IsNull()) {
2268 ErrorMsg(token_index, errmsg.ToCString()); 2278 ErrorMsg(token_index, errmsg.ToCString());
2269 } 2279 }
2270 type_arguments = type.arguments(); 2280 type_arguments = type.arguments();
2271 __ PushObject(type_arguments); 2281 __ PushObject(type_arguments);
2272 } else { 2282 } else {
2273 ASSERT(parsed_function().instantiator() != NULL); 2283 ASSERT(parsed_function().instantiator() != NULL);
2274 parsed_function().instantiator()->Visit(this); 2284 parsed_function().instantiator()->Visit(this);
2275 if (!parsed_function().function().IsInFactoryScope()) { 2285 if (!outer_function.IsFactory()) {
2276 __ popl(EAX); // Pop instantiator. 2286 __ popl(EAX); // Pop instantiator.
2277 // The instantiator is the receiver of the caller, which is not a factory. 2287 // The instantiator is the receiver of the caller, which is not a factory.
2278 // The receiver cannot be null; extract its TypeArguments object. 2288 // The receiver cannot be null; extract its TypeArguments object.
2279 // Note that in the factory case, the instantiator is the first parameter 2289 // Note that in the factory case, the instantiator is the first parameter
2280 // of the factory, i.e. already a TypeArguments object. 2290 // of the factory, i.e. already a TypeArguments object.
2281 intptr_t type_arguments_instance_field_offset = 2291 intptr_t type_arguments_instance_field_offset =
2282 instantiator_class.type_arguments_instance_field_offset(); 2292 instantiator_class.type_arguments_instance_field_offset();
2283 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments); 2293 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments);
2284 __ movl(EAX, FieldAddress(EAX, type_arguments_instance_field_offset)); 2294 __ movl(EAX, FieldAddress(EAX, type_arguments_instance_field_offset));
2285 __ pushl(EAX); 2295 __ pushl(EAX);
(...skipping 14 matching lines...) Expand all
2300 // parameterized class. 2310 // parameterized class.
2301 // Note that a class without proper type parameters may still be parameterized, 2311 // Note that a class without proper type parameters may still be parameterized,
2302 // e.g. class A extends Array<int>. 2312 // e.g. class A extends Array<int>.
2303 void CodeGenerator::GenerateTypeArguments(ConstructorCallNode* node, 2313 void CodeGenerator::GenerateTypeArguments(ConstructorCallNode* node,
2304 bool requires_type_arguments) { 2314 bool requires_type_arguments) {
2305 const Immediate raw_null = 2315 const Immediate raw_null =
2306 Immediate(reinterpret_cast<intptr_t>(Object::null())); 2316 Immediate(reinterpret_cast<intptr_t>(Object::null()));
2307 // Instantiate the type arguments if necessary. 2317 // Instantiate the type arguments if necessary.
2308 if (node->type_arguments().IsNull() || 2318 if (node->type_arguments().IsNull() ||
2309 node->type_arguments().IsInstantiated()) { 2319 node->type_arguments().IsInstantiated()) {
2310 if (node->constructor().IsFactory() || requires_type_arguments) { 2320 if (requires_type_arguments) {
2311 // A factory requires the type arguments as first parameter. 2321 // A factory requires the type arguments as first parameter.
2312 __ PushObject(node->type_arguments()); 2322 __ PushObject(node->type_arguments());
2313 if (!node->constructor().IsFactory()) { 2323 if (!node->constructor().IsFactory()) {
2314 // The allocator additionally requires the instantiator type arguments. 2324 // The allocator additionally requires the instantiator type arguments.
2315 __ pushl(raw_null); // Null instantiator. 2325 __ pushl(raw_null); // Null instantiator.
2316 } 2326 }
2317 } 2327 }
2318 } else { 2328 } else {
2319 // The type arguments are uninstantiated. 2329 // The type arguments are uninstantiated.
2320 ASSERT(node->constructor().IsFactory() || requires_type_arguments); 2330 ASSERT(requires_type_arguments);
2321 GenerateInstantiatorTypeArguments(node->token_index()); 2331 GenerateInstantiatorTypeArguments(node->token_index());
2322 __ popl(EAX); // Pop instantiator. 2332 __ popl(EAX); // Pop instantiator.
2323 // EAX is the instantiator TypeArguments object (or null). 2333 // EAX is the instantiator TypeArguments object (or null).
2324 // If EAX is null, no need to instantiate the type arguments, use null, and 2334 // If EAX is null, no need to instantiate the type arguments, use null, and
2325 // allocate an object of a raw type. 2335 // allocate an object of a raw type.
2326 Label type_arguments_instantiated, type_arguments_uninstantiated; 2336 Label type_arguments_instantiated, type_arguments_uninstantiated;
2327 __ cmpl(EAX, raw_null); 2337 __ cmpl(EAX, raw_null);
2328 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 2338 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
2329 2339
2330 // Instantiate non-null type arguments. 2340 // Instantiate non-null type arguments.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2366 __ Bind(&type_arguments_instantiated); 2376 __ Bind(&type_arguments_instantiated);
2367 __ pushl(EAX); // Instantiated type arguments. 2377 __ pushl(EAX); // Instantiated type arguments.
2368 __ pushl(raw_null); // Null instantiator. 2378 __ pushl(raw_null); // Null instantiator.
2369 __ Bind(&type_arguments_pushed); 2379 __ Bind(&type_arguments_pushed);
2370 } 2380 }
2371 } 2381 }
2372 } 2382 }
2373 2383
2374 2384
2375 void CodeGenerator::VisitConstructorCallNode(ConstructorCallNode* node) { 2385 void CodeGenerator::VisitConstructorCallNode(ConstructorCallNode* node) {
2376 const Class& cls = Class::ZoneHandle(node->constructor().owner());
2377 const bool requires_type_arguments = cls.HasTypeArguments();
2378 GenerateTypeArguments(node, requires_type_arguments);
2379 if (node->constructor().IsFactory()) { 2386 if (node->constructor().IsFactory()) {
2387 const bool requires_type_arguments = true; // Always first arg to factory.
2388 GenerateTypeArguments(node, requires_type_arguments);
2380 // The top of stack is an instantiated TypeArguments object (or null). 2389 // The top of stack is an instantiated TypeArguments object (or null).
2381 int num_args = node->arguments()->length() + 1; // +1 to include type args. 2390 int num_args = node->arguments()->length() + 1; // +1 to include type args.
2382 node->arguments()->Visit(this); 2391 node->arguments()->Visit(this);
2383 // Call the factory. 2392 // Call the factory.
2384 __ LoadObject(ECX, node->constructor()); 2393 __ LoadObject(ECX, node->constructor());
2385 __ LoadObject(EDX, ArgumentsDescriptor(num_args, 2394 __ LoadObject(EDX, ArgumentsDescriptor(num_args,
2386 node->arguments()->names())); 2395 node->arguments()->names()));
2387 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel()); 2396 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel());
2388 // Factory constructor returns object in EAX. 2397 // Factory constructor returns object in EAX.
2389 __ addl(ESP, Immediate(num_args * kWordSize)); 2398 __ addl(ESP, Immediate(num_args * kWordSize));
2390 if (IsResultNeeded(node)) { 2399 if (IsResultNeeded(node)) {
2391 __ pushl(EAX); 2400 __ pushl(EAX);
2392 } 2401 }
2393 return; 2402 return;
2394 } 2403 }
2395 2404
2405 const Class& cls = Class::ZoneHandle(node->constructor().owner());
2406 const bool requires_type_arguments = cls.HasTypeArguments();
2407 GenerateTypeArguments(node, requires_type_arguments);
2408
2396 // If cls is parameterized, the type arguments and the instantiator's 2409 // If cls is parameterized, the type arguments and the instantiator's
2397 // type arguments are on the stack. 2410 // type arguments are on the stack.
2398 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls)); 2411 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls));
2399 const ExternalLabel label(cls.ToCString(), stub.EntryPoint()); 2412 const ExternalLabel label(cls.ToCString(), stub.EntryPoint());
2400 GenerateCall(node->token_index(), &label); 2413 GenerateCall(node->token_index(), &label);
2401 if (requires_type_arguments) { 2414 if (requires_type_arguments) {
2402 __ popl(ECX); // Pop type arguments. 2415 __ popl(ECX); // Pop type arguments.
2403 __ popl(ECX); // Pop instantiator type arguments. 2416 __ popl(ECX); // Pop instantiator type arguments.
2404 } 2417 }
2405 2418
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
2737 const Class& cls = Class::Handle(parsed_function_.function().owner()); 2750 const Class& cls = Class::Handle(parsed_function_.function().owner());
2738 const Script& script = Script::Handle(cls.script()); 2751 const Script& script = Script::Handle(cls.script());
2739 Parser::ReportMsg(script, token_index, "Error", error_msg, format, args); 2752 Parser::ReportMsg(script, token_index, "Error", error_msg, format, args);
2740 Isolate::Current()->long_jump_base()->Jump(1, error_msg); 2753 Isolate::Current()->long_jump_base()->Jump(1, error_msg);
2741 UNREACHABLE(); 2754 UNREACHABLE();
2742 } 2755 }
2743 2756
2744 } // namespace dart 2757 } // namespace dart
2745 2758
2746 #endif // defined TARGET_ARCH_IA32 2759 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.cc ('k') | runtime/vm/parser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698