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

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

Issue 9460012: StepOver, StepInto, StepOut (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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) 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 774 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 kTraceFunctionExitRuntimeEntry); 785 kTraceFunctionExitRuntimeEntry);
786 __ popl(EAX); // Remove argument. 786 __ popl(EAX); // Remove argument.
787 __ popl(EAX); // Restore result. 787 __ popl(EAX); // Restore result.
788 } 788 }
789 __ LeaveFrame(); 789 __ LeaveFrame();
790 __ ret(); 790 __ ret();
791 // Add a NOP to make return code pattern 5 bytes long for patching 791 // Add a NOP to make return code pattern 5 bytes long for patching
792 // in breakpoints during debugging. 792 // in breakpoints during debugging.
793 __ nop(1); 793 __ nop(1);
794 AddCurrentDescriptor(PcDescriptors::kReturn, 794 AddCurrentDescriptor(PcDescriptors::kReturn,
795 AstNode::kNoId, 795 node->id(),
796 node->token_index()); 796 node->token_index());
797 797
798 #ifdef DEBUG 798 #ifdef DEBUG
799 __ Bind(&wrong_stack); 799 __ Bind(&wrong_stack);
800 __ Stop("Exit stack size does not match the entry stack size."); 800 __ Stop("Exit stack size does not match the entry stack size.");
801 #endif // DEBUG. 801 #endif // DEBUG.
802 } 802 }
803 803
804 804
805 void CodeGenerator::VisitReturnNode(ReturnNode* node) { 805 void CodeGenerator::VisitReturnNode(ReturnNode* node) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 const Class& cls = Class::Handle(function.signature_class()); 893 const Class& cls = Class::Handle(function.signature_class());
894 ASSERT(!cls.IsNull()); 894 ASSERT(!cls.IsNull());
895 const bool requires_type_arguments = cls.HasTypeArguments(); 895 const bool requires_type_arguments = cls.HasTypeArguments();
896 if (requires_type_arguments) { 896 if (requires_type_arguments) {
897 ASSERT(!function.IsImplicitStaticClosureFunction()); 897 ASSERT(!function.IsImplicitStaticClosureFunction());
898 GenerateInstantiatorTypeArguments(node->token_index()); 898 GenerateInstantiatorTypeArguments(node->token_index());
899 } 899 }
900 const Code& stub = Code::Handle( 900 const Code& stub = Code::Handle(
901 StubCode::GetAllocationStubForClosure(function)); 901 StubCode::GetAllocationStubForClosure(function));
902 const ExternalLabel label(function.ToCString(), stub.EntryPoint()); 902 const ExternalLabel label(function.ToCString(), stub.EntryPoint());
903 GenerateCall(node->token_index(), &label); 903 GenerateCall(node->token_index(), &label, PcDescriptors::kOther);
904 if (requires_type_arguments) { 904 if (requires_type_arguments) {
905 __ popl(ECX); // Pop type arguments. 905 __ popl(ECX); // Pop type arguments.
906 } 906 }
907 if (function.IsImplicitInstanceClosureFunction()) { 907 if (function.IsImplicitInstanceClosureFunction()) {
908 __ popl(ECX); // Pop receiver. 908 __ popl(ECX); // Pop receiver.
909 } 909 }
910 if (IsResultNeeded(node)) { 910 if (IsResultNeeded(node)) {
911 __ pushl(EAX); 911 __ pushl(EAX);
912 } 912 }
913 } 913 }
(...skipping 21 matching lines...) Expand all
935 CodeGeneratorState codegen_state(this); 935 CodeGeneratorState codegen_state(this);
936 LocalScope* scope = node_sequence->scope(); 936 LocalScope* scope = node_sequence->scope();
937 const intptr_t num_context_variables = 937 const intptr_t num_context_variables =
938 (scope != NULL) ? scope->num_context_variables() : 0; 938 (scope != NULL) ? scope->num_context_variables() : 0;
939 if (num_context_variables > 0) { 939 if (num_context_variables > 0) {
940 // The loop local scope declares variables that are captured. 940 // The loop local scope declares variables that are captured.
941 // Allocate and chain a new context. 941 // Allocate and chain a new context.
942 __ movl(EDX, Immediate(num_context_variables)); 942 __ movl(EDX, Immediate(num_context_variables));
943 const ExternalLabel label("alloc_context", 943 const ExternalLabel label("alloc_context",
944 StubCode::AllocateContextEntryPoint()); 944 StubCode::AllocateContextEntryPoint());
945 GenerateCall(node_sequence->token_index(), &label); 945 GenerateCall(node_sequence->token_index(), &label, PcDescriptors::kOther);
946 946
947 // Chain the new context in EAX to its parent in CTX. 947 // Chain the new context in EAX to its parent in CTX.
948 __ StoreIntoObject(EAX, FieldAddress(EAX, Context::parent_offset()), CTX); 948 __ StoreIntoObject(EAX, FieldAddress(EAX, Context::parent_offset()), CTX);
949 // Set new context as current context. 949 // Set new context as current context.
950 __ movl(CTX, EAX); 950 __ movl(CTX, EAX);
951 state()->set_context_level(scope->context_level()); 951 state()->set_context_level(scope->context_level());
952 952
953 // If this node_sequence is the body of the function being compiled, copy 953 // If this node_sequence is the body of the function being compiled, copy
954 // the captured parameters from the frame into the context. 954 // the captured parameters from the frame into the context.
955 if (node_sequence == parsed_function_.node_sequence()) { 955 if (node_sequence == parsed_function_.node_sequence()) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 element->Visit(this); 1012 element->Visit(this);
1013 } 1013 }
1014 1014
1015 // Allocate the array. 1015 // Allocate the array.
1016 // EDX : Array length as Smi. 1016 // EDX : Array length as Smi.
1017 // ECX : element type for the array. 1017 // ECX : element type for the array.
1018 __ movl(EDX, Immediate(Smi::RawValue(node->length()))); 1018 __ movl(EDX, Immediate(Smi::RawValue(node->length())));
1019 const AbstractTypeArguments& element_type = node->type_arguments(); 1019 const AbstractTypeArguments& element_type = node->type_arguments();
1020 ASSERT(element_type.IsNull() || element_type.IsInstantiated()); 1020 ASSERT(element_type.IsNull() || element_type.IsInstantiated());
1021 __ LoadObject(ECX, element_type); 1021 __ LoadObject(ECX, element_type);
1022 GenerateCall(node->token_index(), &StubCode::AllocateArrayLabel()); 1022 GenerateCall(node->token_index(),
1023 &StubCode::AllocateArrayLabel(),
1024 PcDescriptors::kOther);
1023 1025
1024 // Pop the element values from the stack into the array. 1026 // Pop the element values from the stack into the array.
1025 __ leal(ECX, FieldAddress(EAX, Array::data_offset())); 1027 __ leal(ECX, FieldAddress(EAX, Array::data_offset()));
1026 for (int i = node->length() - 1; i >= 0; i--) { 1028 for (int i = node->length() - 1; i >= 0; i--) {
1027 __ popl(Address(ECX, i * kWordSize)); 1029 __ popl(Address(ECX, i * kWordSize));
1028 } 1030 }
1029 1031
1030 if (IsResultNeeded(node)) { 1032 if (IsResultNeeded(node)) {
1031 __ pushl(EAX); 1033 __ pushl(EAX);
1032 } 1034 }
(...skipping 1184 matching lines...) Expand 10 before | Expand all | Expand 10 after
2217 } 2219 }
2218 2220
2219 // Could not concatenate at compile time, generate a call to 2221 // Could not concatenate at compile time, generate a call to
2220 // interpolation function. 2222 // interpolation function.
2221 ArgumentListNode* interpol_arg = new ArgumentListNode(node->token_index()); 2223 ArgumentListNode* interpol_arg = new ArgumentListNode(node->token_index());
2222 interpol_arg->Add(node->values()); 2224 interpol_arg->Add(node->values());
2223 node->values()->Visit(this); 2225 node->values()->Visit(this);
2224 __ LoadObject(ECX, interpol_func); 2226 __ LoadObject(ECX, interpol_func);
2225 __ LoadObject(EDX, ArgumentsDescriptor(interpol_arg->length(), 2227 __ LoadObject(EDX, ArgumentsDescriptor(interpol_arg->length(),
2226 interpol_arg->names())); 2228 interpol_arg->names()));
2227 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel()); 2229 GenerateCall(node->token_index(),
2230 &StubCode::CallStaticFunctionLabel(),
2231 PcDescriptors::kFuncCall);
2228 __ addl(ESP, Immediate(interpol_arg->length() * kWordSize)); 2232 __ addl(ESP, Immediate(interpol_arg->length() * kWordSize));
2229 // Result is in EAX. 2233 // Result is in EAX.
2230 if (IsResultNeeded(node)) { 2234 if (IsResultNeeded(node)) {
2231 __ pushl(EAX); 2235 __ pushl(EAX);
2232 } 2236 }
2233 } 2237 }
2234 2238
2235 2239
2236 void CodeGenerator::VisitInstanceCallNode(InstanceCallNode* node) { 2240 void CodeGenerator::VisitInstanceCallNode(InstanceCallNode* node) {
2237 const int number_of_arguments = node->arguments()->length() + 1; 2241 const int number_of_arguments = node->arguments()->length() + 1;
(...skipping 16 matching lines...) Expand all
2254 __ pushl(EAX); 2258 __ pushl(EAX);
2255 } 2259 }
2256 } 2260 }
2257 2261
2258 2262
2259 void CodeGenerator::VisitStaticCallNode(StaticCallNode* node) { 2263 void CodeGenerator::VisitStaticCallNode(StaticCallNode* node) {
2260 node->arguments()->Visit(this); 2264 node->arguments()->Visit(this);
2261 __ LoadObject(ECX, node->function()); 2265 __ LoadObject(ECX, node->function());
2262 __ LoadObject(EDX, ArgumentsDescriptor(node->arguments()->length(), 2266 __ LoadObject(EDX, ArgumentsDescriptor(node->arguments()->length(),
2263 node->arguments()->names())); 2267 node->arguments()->names()));
2264 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel()); 2268 GenerateCall(node->token_index(),
2269 &StubCode::CallStaticFunctionLabel(),
2270 PcDescriptors::kFuncCall);
2265 __ addl(ESP, Immediate(node->arguments()->length() * kWordSize)); 2271 __ addl(ESP, Immediate(node->arguments()->length() * kWordSize));
2266 // Result is in EAX. 2272 // Result is in EAX.
2267 if (IsResultNeeded(node)) { 2273 if (IsResultNeeded(node)) {
2268 __ pushl(EAX); 2274 __ pushl(EAX);
2269 } 2275 }
2270 } 2276 }
2271 2277
2272 2278
2273 void CodeGenerator::VisitClosureCallNode(ClosureCallNode* node) { 2279 void CodeGenerator::VisitClosureCallNode(ClosureCallNode* node) {
2274 // The spec states that the closure is evaluated before the arguments. 2280 // The spec states that the closure is evaluated before the arguments.
2275 // Preserve the current context, since it will be overridden by the closure 2281 // Preserve the current context, since it will be overridden by the closure
2276 // context during the call. 2282 // context during the call.
2277 __ pushl(CTX); 2283 __ pushl(CTX);
2278 // Compute the closure object and pass it as first argument to the stub. 2284 // Compute the closure object and pass it as first argument to the stub.
2279 node->closure()->Visit(this); 2285 node->closure()->Visit(this);
2280 // Now compute the arguments to the call. 2286 // Now compute the arguments to the call.
2281 node->arguments()->Visit(this); 2287 node->arguments()->Visit(this);
2282 // Set up the number of arguments (excluding the closure) to the ClosureCall 2288 // Set up the number of arguments (excluding the closure) to the ClosureCall
2283 // stub which will setup the closure context and jump to the entrypoint of the 2289 // stub which will setup the closure context and jump to the entrypoint of the
2284 // closure function (the function will be compiled if it has not already been 2290 // closure function (the function will be compiled if it has not already been
2285 // compiled). 2291 // compiled).
2286 // NOTE: The stub accesses the closure before the parameter list. 2292 // NOTE: The stub accesses the closure before the parameter list.
2287 __ LoadObject(EDX, ArgumentsDescriptor(node->arguments()->length(), 2293 __ LoadObject(EDX, ArgumentsDescriptor(node->arguments()->length(),
2288 node->arguments()->names())); 2294 node->arguments()->names()));
2289 GenerateCall(node->token_index(), &StubCode::CallClosureFunctionLabel()); 2295 GenerateCall(node->token_index(),
2296 &StubCode::CallClosureFunctionLabel(),
2297 PcDescriptors::kOther);
2290 __ addl(ESP, Immediate((node->arguments()->length() + 1) * kWordSize)); 2298 __ addl(ESP, Immediate((node->arguments()->length() + 1) * kWordSize));
2291 // Restore the context. 2299 // Restore the context.
2292 __ popl(CTX); 2300 __ popl(CTX);
2293 // Result is in EAX. 2301 // Result is in EAX.
2294 if (IsResultNeeded(node)) { 2302 if (IsResultNeeded(node)) {
2295 __ pushl(EAX); 2303 __ pushl(EAX);
2296 } 2304 }
2297 } 2305 }
2298 2306
2299 2307
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
2424 const bool requires_type_arguments = true; // Always first arg to factory. 2432 const bool requires_type_arguments = true; // Always first arg to factory.
2425 GenerateTypeArguments(node, requires_type_arguments); 2433 GenerateTypeArguments(node, requires_type_arguments);
2426 // The top of stack is an instantiated AbstractTypeArguments object 2434 // The top of stack is an instantiated AbstractTypeArguments object
2427 // (or null). 2435 // (or null).
2428 int num_args = node->arguments()->length() + 1; // +1 to include type args. 2436 int num_args = node->arguments()->length() + 1; // +1 to include type args.
2429 node->arguments()->Visit(this); 2437 node->arguments()->Visit(this);
2430 // Call the factory. 2438 // Call the factory.
2431 __ LoadObject(ECX, node->constructor()); 2439 __ LoadObject(ECX, node->constructor());
2432 __ LoadObject(EDX, ArgumentsDescriptor(num_args, 2440 __ LoadObject(EDX, ArgumentsDescriptor(num_args,
2433 node->arguments()->names())); 2441 node->arguments()->names()));
2434 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel()); 2442 GenerateCall(node->token_index(),
2443 &StubCode::CallStaticFunctionLabel(),
2444 PcDescriptors::kFuncCall);
2435 // Factory constructor returns object in EAX. 2445 // Factory constructor returns object in EAX.
2436 __ addl(ESP, Immediate(num_args * kWordSize)); 2446 __ addl(ESP, Immediate(num_args * kWordSize));
2437 if (IsResultNeeded(node)) { 2447 if (IsResultNeeded(node)) {
2438 __ pushl(EAX); 2448 __ pushl(EAX);
2439 } 2449 }
2440 return; 2450 return;
2441 } 2451 }
2442 2452
2443 const Class& cls = Class::ZoneHandle(node->constructor().owner()); 2453 const Class& cls = Class::ZoneHandle(node->constructor().owner());
2444 const bool requires_type_arguments = cls.HasTypeArguments(); 2454 const bool requires_type_arguments = cls.HasTypeArguments();
2445 GenerateTypeArguments(node, requires_type_arguments); 2455 GenerateTypeArguments(node, requires_type_arguments);
2446 2456
2447 // If cls is parameterized, the type arguments and the instantiator's 2457 // If cls is parameterized, the type arguments and the instantiator's
2448 // type arguments are on the stack. 2458 // type arguments are on the stack.
2449 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls)); 2459 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls));
2450 const ExternalLabel label(cls.ToCString(), stub.EntryPoint()); 2460 const ExternalLabel label(cls.ToCString(), stub.EntryPoint());
2451 GenerateCall(node->token_index(), &label); 2461 GenerateCall(node->token_index(), &label, PcDescriptors::kOther);
2452 if (requires_type_arguments) { 2462 if (requires_type_arguments) {
2453 __ popl(ECX); // Pop type arguments. 2463 __ popl(ECX); // Pop type arguments.
2454 __ popl(ECX); // Pop instantiator type arguments. 2464 __ popl(ECX); // Pop instantiator type arguments.
2455 } 2465 }
2456 2466
2457 if (IsResultNeeded(node)) { 2467 if (IsResultNeeded(node)) {
2458 __ pushl(EAX); // Set up return value from allocate. 2468 __ pushl(EAX); // Set up return value from allocate.
2459 } 2469 }
2460 2470
2461 // First argument(this) for constructor call which follows. 2471 // First argument(this) for constructor call which follows.
2462 __ pushl(EAX); 2472 __ pushl(EAX);
2463 // Second argument is the implicit construction phase parameter. 2473 // Second argument is the implicit construction phase parameter.
2464 // Run both the constructor initializer list and the constructor body. 2474 // Run both the constructor initializer list and the constructor body.
2465 __ PushObject(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))); 2475 __ PushObject(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)));
2466 2476
2467 2477
2468 // Now setup rest of the arguments for the constructor call. 2478 // Now setup rest of the arguments for the constructor call.
2469 node->arguments()->Visit(this); 2479 node->arguments()->Visit(this);
2470 2480
2471 // Call the constructor. 2481 // Call the constructor.
2472 // +2 to include implicit receiver and phase arguments. 2482 // +2 to include implicit receiver and phase arguments.
2473 int num_args = node->arguments()->length() + 2; 2483 int num_args = node->arguments()->length() + 2;
2474 __ LoadObject(ECX, node->constructor()); 2484 __ LoadObject(ECX, node->constructor());
2475 __ LoadObject(EDX, ArgumentsDescriptor(num_args, node->arguments()->names())); 2485 __ LoadObject(EDX, ArgumentsDescriptor(num_args, node->arguments()->names()));
2476 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel()); 2486 GenerateCall(node->token_index(),
2487 &StubCode::CallStaticFunctionLabel(),
2488 PcDescriptors::kFuncCall);
2477 // Constructors do not return any value. 2489 // Constructors do not return any value.
2478 2490
2479 // Pop out all the other arguments on the stack. 2491 // Pop out all the other arguments on the stack.
2480 __ addl(ESP, Immediate(num_args * kWordSize)); 2492 __ addl(ESP, Immediate(num_args * kWordSize));
2481 } 2493 }
2482 2494
2483 2495
2484 // Expects receiver on stack, returns result in EAX.. 2496 // Expects receiver on stack, returns result in EAX..
2485 void CodeGenerator::GenerateInstanceGetterCall(intptr_t node_id, 2497 void CodeGenerator::GenerateInstanceGetterCall(intptr_t node_id,
2486 intptr_t token_index, 2498 intptr_t token_index,
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
2560 const Function& function = 2572 const Function& function =
2561 Function::ZoneHandle(field_class.LookupStaticFunction(getter_name)); 2573 Function::ZoneHandle(field_class.LookupStaticFunction(getter_name));
2562 if (function.IsNull()) { 2574 if (function.IsNull()) {
2563 ErrorMsg(token_index, "Static getter does not exist: %s", 2575 ErrorMsg(token_index, "Static getter does not exist: %s",
2564 getter_name.ToCString()); 2576 getter_name.ToCString());
2565 } 2577 }
2566 __ LoadObject(ECX, function); 2578 __ LoadObject(ECX, function);
2567 const int kNumberOfArguments = 0; 2579 const int kNumberOfArguments = 0;
2568 const Array& kNoArgumentNames = Array::Handle(); 2580 const Array& kNoArgumentNames = Array::Handle();
2569 __ LoadObject(EDX, ArgumentsDescriptor(kNumberOfArguments, kNoArgumentNames)); 2581 __ LoadObject(EDX, ArgumentsDescriptor(kNumberOfArguments, kNoArgumentNames));
2570 GenerateCall(token_index, &StubCode::CallStaticFunctionLabel()); 2582 GenerateCall(token_index,
2583 &StubCode::CallStaticFunctionLabel(),
2584 PcDescriptors::kFuncCall);
2571 // No arguments were pushed, hence nothing to pop. 2585 // No arguments were pushed, hence nothing to pop.
2572 } 2586 }
2573 2587
2574 2588
2575 // Call to static getter. 2589 // Call to static getter.
2576 void CodeGenerator::VisitStaticGetterNode(StaticGetterNode* node) { 2590 void CodeGenerator::VisitStaticGetterNode(StaticGetterNode* node) {
2577 GenerateStaticGetterCall(node->token_index(), 2591 GenerateStaticGetterCall(node->token_index(),
2578 node->cls(), 2592 node->cls(),
2579 node->field_name()); 2593 node->field_name());
2580 // Result is in EAX. 2594 // Result is in EAX.
2581 if (IsResultNeeded(node)) { 2595 if (IsResultNeeded(node)) {
2582 __ pushl(EAX); 2596 __ pushl(EAX);
2583 } 2597 }
2584 } 2598 }
2585 2599
2586 2600
2587 // Expects value on stack. 2601 // Expects value on stack.
2588 void CodeGenerator::GenerateStaticSetterCall(intptr_t token_index, 2602 void CodeGenerator::GenerateStaticSetterCall(intptr_t token_index,
2589 const Class& field_class, 2603 const Class& field_class,
2590 const String& field_name) { 2604 const String& field_name) {
2591 const String& setter_name = String::Handle(Field::SetterName(field_name)); 2605 const String& setter_name = String::Handle(Field::SetterName(field_name));
2592 const Function& function = 2606 const Function& function =
2593 Function::ZoneHandle(field_class.LookupStaticFunction(setter_name)); 2607 Function::ZoneHandle(field_class.LookupStaticFunction(setter_name));
2594 __ LoadObject(ECX, function); 2608 __ LoadObject(ECX, function);
2595 const int kNumberOfArguments = 1; // value. 2609 const int kNumberOfArguments = 1; // value.
2596 const Array& kNoArgumentNames = Array::Handle(); 2610 const Array& kNoArgumentNames = Array::Handle();
2597 __ LoadObject(EDX, ArgumentsDescriptor(kNumberOfArguments, kNoArgumentNames)); 2611 __ LoadObject(EDX, ArgumentsDescriptor(kNumberOfArguments, kNoArgumentNames));
2598 GenerateCall(token_index, &StubCode::CallStaticFunctionLabel()); 2612 GenerateCall(token_index,
2613 &StubCode::CallStaticFunctionLabel(),
2614 PcDescriptors::kFuncCall);
2599 __ addl(ESP, Immediate(kNumberOfArguments * kWordSize)); 2615 __ addl(ESP, Immediate(kNumberOfArguments * kWordSize));
2600 } 2616 }
2601 2617
2602 2618
2603 // The call to static setter implements assignment to a static field. 2619 // The call to static setter implements assignment to a static field.
2604 // The result of the assignment is the value being stored. 2620 // The result of the assignment is the value being stored.
2605 void CodeGenerator::VisitStaticSetterNode(StaticSetterNode* node) { 2621 void CodeGenerator::VisitStaticSetterNode(StaticSetterNode* node) {
2606 node->value()->Visit(this); 2622 node->value()->Visit(this);
2607 if (IsResultNeeded(node)) { 2623 if (IsResultNeeded(node)) {
2608 // Preserve the original value when returning from setter. 2624 // Preserve the original value when returning from setter.
(...skipping 12 matching lines...) Expand all
2621 // Push the result place holder initialized to NULL. 2637 // Push the result place holder initialized to NULL.
2622 __ PushObject(Object::ZoneHandle()); 2638 __ PushObject(Object::ZoneHandle());
2623 // Pass a pointer to the first argument in EAX. 2639 // Pass a pointer to the first argument in EAX.
2624 if (!node->has_optional_parameters()) { 2640 if (!node->has_optional_parameters()) {
2625 __ leal(EAX, Address(EBP, (1 + node->argument_count()) * kWordSize)); 2641 __ leal(EAX, Address(EBP, (1 + node->argument_count()) * kWordSize));
2626 } else { 2642 } else {
2627 __ leal(EAX, Address(EBP, -1 * kWordSize)); 2643 __ leal(EAX, Address(EBP, -1 * kWordSize));
2628 } 2644 }
2629 __ movl(ECX, Immediate(reinterpret_cast<uword>(node->native_c_function()))); 2645 __ movl(ECX, Immediate(reinterpret_cast<uword>(node->native_c_function())));
2630 __ movl(EDX, Immediate(node->argument_count())); 2646 __ movl(EDX, Immediate(node->argument_count()));
2631 GenerateCall(node->token_index(), &StubCode::CallNativeCFunctionLabel()); 2647 GenerateCall(node->token_index(),
2648 &StubCode::CallNativeCFunctionLabel(),
2649 PcDescriptors::kOther);
2632 // Result is on the stack. 2650 // Result is on the stack.
2633 if (!IsResultNeeded(node)) { 2651 if (!IsResultNeeded(node)) {
2634 __ popl(EAX); 2652 __ popl(EAX);
2635 } 2653 }
2636 } 2654 }
2637 2655
2638 2656
2639 void CodeGenerator::VisitCatchClauseNode(CatchClauseNode* node) { 2657 void CodeGenerator::VisitCatchClauseNode(CatchClauseNode* node) {
2640 // NOTE: The implicit variables ':saved_context', ':exception_var' 2658 // NOTE: The implicit variables ':saved_context', ':exception_var'
2641 // and ':stacktrace_var' can never be captured variables. 2659 // and ':stacktrace_var' can never be captured variables.
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
2747 GenerateLoadVariable(CTX, node->context_var()); 2765 GenerateLoadVariable(CTX, node->context_var());
2748 node->finally_block()->Visit(this); 2766 node->finally_block()->Visit(this);
2749 2767
2750 if (try_index >= 0) { 2768 if (try_index >= 0) {
2751 state()->set_try_index(try_index); 2769 state()->set_try_index(try_index);
2752 } 2770 }
2753 } 2771 }
2754 2772
2755 2773
2756 void CodeGenerator::GenerateCall(intptr_t token_index, 2774 void CodeGenerator::GenerateCall(intptr_t token_index,
2757 const ExternalLabel* ext_label) { 2775 const ExternalLabel* ext_label,
2776 PcDescriptors::Kind desc_kind) {
2758 __ call(ext_label); 2777 __ call(ext_label);
2759 AddCurrentDescriptor(PcDescriptors::kOther, AstNode::kNoId, token_index); 2778 AddCurrentDescriptor(desc_kind, AstNode::kNoId, token_index);
2760 } 2779 }
2761 2780
2762 2781
2763 void CodeGenerator::GenerateCallRuntime(intptr_t node_id, 2782 void CodeGenerator::GenerateCallRuntime(intptr_t node_id,
2764 intptr_t token_index, 2783 intptr_t token_index,
2765 const RuntimeEntry& entry) { 2784 const RuntimeEntry& entry) {
2766 __ CallRuntimeFromDart(entry); 2785 __ CallRuntimeFromDart(entry);
2767 AddCurrentDescriptor(PcDescriptors::kOther, node_id, token_index); 2786 AddCurrentDescriptor(PcDescriptors::kOther, node_id, token_index);
2768 } 2787 }
2769 2788
(...skipping 25 matching lines...) Expand all
2795 const Error& error = Error::Handle( 2814 const Error& error = Error::Handle(
2796 Parser::FormatError(script, token_index, "Error", format, args)); 2815 Parser::FormatError(script, token_index, "Error", format, args));
2797 va_end(args); 2816 va_end(args);
2798 Isolate::Current()->long_jump_base()->Jump(1, error); 2817 Isolate::Current()->long_jump_base()->Jump(1, error);
2799 UNREACHABLE(); 2818 UNREACHABLE();
2800 } 2819 }
2801 2820
2802 } // namespace dart 2821 } // namespace dart
2803 2822
2804 #endif // defined TARGET_ARCH_IA32 2823 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698