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

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

Issue 9484002: 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
« no previous file with comments | « runtime/vm/code_generator_ia32.h ('k') | runtime/vm/code_generator_x64.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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 707 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 kTraceFunctionExitRuntimeEntry); 718 kTraceFunctionExitRuntimeEntry);
719 __ popl(EAX); // Remove argument. 719 __ popl(EAX); // Remove argument.
720 __ popl(EAX); // Restore result. 720 __ popl(EAX); // Restore result.
721 } 721 }
722 __ LeaveFrame(); 722 __ LeaveFrame();
723 __ ret(); 723 __ ret();
724 // Add a NOP to make return code pattern 5 bytes long for patching 724 // Add a NOP to make return code pattern 5 bytes long for patching
725 // in breakpoints during debugging. 725 // in breakpoints during debugging.
726 __ nop(1); 726 __ nop(1);
727 AddCurrentDescriptor(PcDescriptors::kReturn, 727 AddCurrentDescriptor(PcDescriptors::kReturn,
728 AstNode::kNoId, 728 node->id(),
729 node->token_index()); 729 node->token_index());
730 730
731 #ifdef DEBUG 731 #ifdef DEBUG
732 __ Bind(&wrong_stack); 732 __ Bind(&wrong_stack);
733 __ Stop("Exit stack size does not match the entry stack size."); 733 __ Stop("Exit stack size does not match the entry stack size.");
734 #endif // DEBUG. 734 #endif // DEBUG.
735 } 735 }
736 736
737 737
738 void CodeGenerator::VisitReturnNode(ReturnNode* node) { 738 void CodeGenerator::VisitReturnNode(ReturnNode* node) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 const Class& cls = Class::Handle(function.signature_class()); 826 const Class& cls = Class::Handle(function.signature_class());
827 ASSERT(!cls.IsNull()); 827 ASSERT(!cls.IsNull());
828 const bool requires_type_arguments = cls.HasTypeArguments(); 828 const bool requires_type_arguments = cls.HasTypeArguments();
829 if (requires_type_arguments) { 829 if (requires_type_arguments) {
830 ASSERT(!function.IsImplicitStaticClosureFunction()); 830 ASSERT(!function.IsImplicitStaticClosureFunction());
831 GenerateInstantiatorTypeArguments(node->token_index()); 831 GenerateInstantiatorTypeArguments(node->token_index());
832 } 832 }
833 const Code& stub = Code::Handle( 833 const Code& stub = Code::Handle(
834 StubCode::GetAllocationStubForClosure(function)); 834 StubCode::GetAllocationStubForClosure(function));
835 const ExternalLabel label(function.ToCString(), stub.EntryPoint()); 835 const ExternalLabel label(function.ToCString(), stub.EntryPoint());
836 GenerateCall(node->token_index(), &label); 836 GenerateCall(node->token_index(), &label, PcDescriptors::kOther);
837 if (requires_type_arguments) { 837 if (requires_type_arguments) {
838 __ popl(ECX); // Pop type arguments. 838 __ popl(ECX); // Pop type arguments.
839 } 839 }
840 if (function.IsImplicitInstanceClosureFunction()) { 840 if (function.IsImplicitInstanceClosureFunction()) {
841 __ popl(ECX); // Pop receiver. 841 __ popl(ECX); // Pop receiver.
842 } 842 }
843 if (IsResultNeeded(node)) { 843 if (IsResultNeeded(node)) {
844 __ pushl(EAX); 844 __ pushl(EAX);
845 } 845 }
846 } 846 }
(...skipping 20 matching lines...) Expand all
867 CodeGeneratorState codegen_state(this); 867 CodeGeneratorState codegen_state(this);
868 LocalScope* scope = node_sequence->scope(); 868 LocalScope* scope = node_sequence->scope();
869 const intptr_t num_context_variables = 869 const intptr_t num_context_variables =
870 (scope != NULL) ? scope->num_context_variables() : 0; 870 (scope != NULL) ? scope->num_context_variables() : 0;
871 if (num_context_variables > 0) { 871 if (num_context_variables > 0) {
872 // The loop local scope declares variables that are captured. 872 // The loop local scope declares variables that are captured.
873 // Allocate and chain a new context. 873 // Allocate and chain a new context.
874 __ movl(EDX, Immediate(num_context_variables)); 874 __ movl(EDX, Immediate(num_context_variables));
875 const ExternalLabel label("alloc_context", 875 const ExternalLabel label("alloc_context",
876 StubCode::AllocateContextEntryPoint()); 876 StubCode::AllocateContextEntryPoint());
877 GenerateCall(node_sequence->token_index(), &label); 877 GenerateCall(node_sequence->token_index(), &label, PcDescriptors::kOther);
878 878
879 // Chain the new context in EAX to its parent in CTX. 879 // Chain the new context in EAX to its parent in CTX.
880 __ StoreIntoObject(EAX, FieldAddress(EAX, Context::parent_offset()), CTX); 880 __ StoreIntoObject(EAX, FieldAddress(EAX, Context::parent_offset()), CTX);
881 // Set new context as current context. 881 // Set new context as current context.
882 __ movl(CTX, EAX); 882 __ movl(CTX, EAX);
883 state()->set_context_level(scope->context_level()); 883 state()->set_context_level(scope->context_level());
884 884
885 // If this node_sequence is the body of the function being compiled, copy 885 // If this node_sequence is the body of the function being compiled, copy
886 // the captured parameters from the frame into the context. 886 // the captured parameters from the frame into the context.
887 if (node_sequence == parsed_function_.node_sequence()) { 887 if (node_sequence == parsed_function_.node_sequence()) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 element->Visit(this); 946 element->Visit(this);
947 } 947 }
948 948
949 // Allocate the array. 949 // Allocate the array.
950 // EDX : Array length as Smi. 950 // EDX : Array length as Smi.
951 // ECX : element type for the array. 951 // ECX : element type for the array.
952 __ movl(EDX, Immediate(Smi::RawValue(node->length()))); 952 __ movl(EDX, Immediate(Smi::RawValue(node->length())));
953 const AbstractTypeArguments& element_type = node->type_arguments(); 953 const AbstractTypeArguments& element_type = node->type_arguments();
954 ASSERT(element_type.IsNull() || element_type.IsInstantiated()); 954 ASSERT(element_type.IsNull() || element_type.IsInstantiated());
955 __ LoadObject(ECX, element_type); 955 __ LoadObject(ECX, element_type);
956 GenerateCall(node->token_index(), &StubCode::AllocateArrayLabel()); 956 GenerateCall(node->token_index(),
957 &StubCode::AllocateArrayLabel(),
958 PcDescriptors::kOther);
957 959
958 // Pop the element values from the stack into the array. 960 // Pop the element values from the stack into the array.
959 __ leal(ECX, FieldAddress(EAX, Array::data_offset())); 961 __ leal(ECX, FieldAddress(EAX, Array::data_offset()));
960 for (int i = node->length() - 1; i >= 0; i--) { 962 for (int i = node->length() - 1; i >= 0; i--) {
961 __ popl(Address(ECX, i * kWordSize)); 963 __ popl(Address(ECX, i * kWordSize));
962 } 964 }
963 965
964 if (IsResultNeeded(node)) { 966 if (IsResultNeeded(node)) {
965 __ pushl(EAX); 967 __ pushl(EAX);
966 } 968 }
(...skipping 1174 matching lines...) Expand 10 before | Expand all | Expand 10 after
2141 } 2143 }
2142 2144
2143 // Could not concatenate at compile time, generate a call to 2145 // Could not concatenate at compile time, generate a call to
2144 // interpolation function. 2146 // interpolation function.
2145 ArgumentListNode* interpol_arg = new ArgumentListNode(node->token_index()); 2147 ArgumentListNode* interpol_arg = new ArgumentListNode(node->token_index());
2146 interpol_arg->Add(node->values()); 2148 interpol_arg->Add(node->values());
2147 node->values()->Visit(this); 2149 node->values()->Visit(this);
2148 __ LoadObject(ECX, interpol_func); 2150 __ LoadObject(ECX, interpol_func);
2149 __ LoadObject(EDX, ArgumentsDescriptor(interpol_arg->length(), 2151 __ LoadObject(EDX, ArgumentsDescriptor(interpol_arg->length(),
2150 interpol_arg->names())); 2152 interpol_arg->names()));
2151 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel()); 2153 GenerateCall(node->token_index(),
2154 &StubCode::CallStaticFunctionLabel(),
2155 PcDescriptors::kFuncCall);
2152 __ addl(ESP, Immediate(interpol_arg->length() * kWordSize)); 2156 __ addl(ESP, Immediate(interpol_arg->length() * kWordSize));
2153 // Result is in EAX. 2157 // Result is in EAX.
2154 if (IsResultNeeded(node)) { 2158 if (IsResultNeeded(node)) {
2155 __ pushl(EAX); 2159 __ pushl(EAX);
2156 } 2160 }
2157 } 2161 }
2158 2162
2159 2163
2160 void CodeGenerator::VisitInstanceCallNode(InstanceCallNode* node) { 2164 void CodeGenerator::VisitInstanceCallNode(InstanceCallNode* node) {
2161 const int number_of_arguments = node->arguments()->length() + 1; 2165 const int number_of_arguments = node->arguments()->length() + 1;
(...skipping 16 matching lines...) Expand all
2178 __ pushl(EAX); 2182 __ pushl(EAX);
2179 } 2183 }
2180 } 2184 }
2181 2185
2182 2186
2183 void CodeGenerator::VisitStaticCallNode(StaticCallNode* node) { 2187 void CodeGenerator::VisitStaticCallNode(StaticCallNode* node) {
2184 node->arguments()->Visit(this); 2188 node->arguments()->Visit(this);
2185 __ LoadObject(ECX, node->function()); 2189 __ LoadObject(ECX, node->function());
2186 __ LoadObject(EDX, ArgumentsDescriptor(node->arguments()->length(), 2190 __ LoadObject(EDX, ArgumentsDescriptor(node->arguments()->length(),
2187 node->arguments()->names())); 2191 node->arguments()->names()));
2188 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel()); 2192 GenerateCall(node->token_index(),
2193 &StubCode::CallStaticFunctionLabel(),
2194 PcDescriptors::kFuncCall);
2189 __ addl(ESP, Immediate(node->arguments()->length() * kWordSize)); 2195 __ addl(ESP, Immediate(node->arguments()->length() * kWordSize));
2190 // Result is in EAX. 2196 // Result is in EAX.
2191 if (IsResultNeeded(node)) { 2197 if (IsResultNeeded(node)) {
2192 __ pushl(EAX); 2198 __ pushl(EAX);
2193 } 2199 }
2194 } 2200 }
2195 2201
2196 2202
2197 void CodeGenerator::VisitClosureCallNode(ClosureCallNode* node) { 2203 void CodeGenerator::VisitClosureCallNode(ClosureCallNode* node) {
2198 // The spec states that the closure is evaluated before the arguments. 2204 // The spec states that the closure is evaluated before the arguments.
2199 // Preserve the current context, since it will be overridden by the closure 2205 // Preserve the current context, since it will be overridden by the closure
2200 // context during the call. 2206 // context during the call.
2201 __ pushl(CTX); 2207 __ pushl(CTX);
2202 // Compute the closure object and pass it as first argument to the stub. 2208 // Compute the closure object and pass it as first argument to the stub.
2203 node->closure()->Visit(this); 2209 node->closure()->Visit(this);
2204 // Now compute the arguments to the call. 2210 // Now compute the arguments to the call.
2205 node->arguments()->Visit(this); 2211 node->arguments()->Visit(this);
2206 // Set up the number of arguments (excluding the closure) to the ClosureCall 2212 // Set up the number of arguments (excluding the closure) to the ClosureCall
2207 // stub which will setup the closure context and jump to the entrypoint of the 2213 // stub which will setup the closure context and jump to the entrypoint of the
2208 // closure function (the function will be compiled if it has not already been 2214 // closure function (the function will be compiled if it has not already been
2209 // compiled). 2215 // compiled).
2210 // NOTE: The stub accesses the closure before the parameter list. 2216 // NOTE: The stub accesses the closure before the parameter list.
2211 __ LoadObject(EDX, ArgumentsDescriptor(node->arguments()->length(), 2217 __ LoadObject(EDX, ArgumentsDescriptor(node->arguments()->length(),
2212 node->arguments()->names())); 2218 node->arguments()->names()));
2213 GenerateCall(node->token_index(), &StubCode::CallClosureFunctionLabel()); 2219 GenerateCall(node->token_index(),
2220 &StubCode::CallClosureFunctionLabel(),
2221 PcDescriptors::kOther);
2214 __ addl(ESP, Immediate((node->arguments()->length() + 1) * kWordSize)); 2222 __ addl(ESP, Immediate((node->arguments()->length() + 1) * kWordSize));
2215 // Restore the context. 2223 // Restore the context.
2216 __ popl(CTX); 2224 __ popl(CTX);
2217 // Result is in EAX. 2225 // Result is in EAX.
2218 if (IsResultNeeded(node)) { 2226 if (IsResultNeeded(node)) {
2219 __ pushl(EAX); 2227 __ pushl(EAX);
2220 } 2228 }
2221 } 2229 }
2222 2230
2223 2231
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
2348 const bool requires_type_arguments = true; // Always first arg to factory. 2356 const bool requires_type_arguments = true; // Always first arg to factory.
2349 GenerateTypeArguments(node, requires_type_arguments); 2357 GenerateTypeArguments(node, requires_type_arguments);
2350 // The top of stack is an instantiated AbstractTypeArguments object 2358 // The top of stack is an instantiated AbstractTypeArguments object
2351 // (or null). 2359 // (or null).
2352 int num_args = node->arguments()->length() + 1; // +1 to include type args. 2360 int num_args = node->arguments()->length() + 1; // +1 to include type args.
2353 node->arguments()->Visit(this); 2361 node->arguments()->Visit(this);
2354 // Call the factory. 2362 // Call the factory.
2355 __ LoadObject(ECX, node->constructor()); 2363 __ LoadObject(ECX, node->constructor());
2356 __ LoadObject(EDX, ArgumentsDescriptor(num_args, 2364 __ LoadObject(EDX, ArgumentsDescriptor(num_args,
2357 node->arguments()->names())); 2365 node->arguments()->names()));
2358 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel()); 2366 GenerateCall(node->token_index(),
2367 &StubCode::CallStaticFunctionLabel(),
2368 PcDescriptors::kFuncCall);
2359 // Factory constructor returns object in EAX. 2369 // Factory constructor returns object in EAX.
2360 __ addl(ESP, Immediate(num_args * kWordSize)); 2370 __ addl(ESP, Immediate(num_args * kWordSize));
2361 if (IsResultNeeded(node)) { 2371 if (IsResultNeeded(node)) {
2362 __ pushl(EAX); 2372 __ pushl(EAX);
2363 } 2373 }
2364 return; 2374 return;
2365 } 2375 }
2366 2376
2367 const Class& cls = Class::ZoneHandle(node->constructor().owner()); 2377 const Class& cls = Class::ZoneHandle(node->constructor().owner());
2368 const bool requires_type_arguments = cls.HasTypeArguments(); 2378 const bool requires_type_arguments = cls.HasTypeArguments();
2369 GenerateTypeArguments(node, requires_type_arguments); 2379 GenerateTypeArguments(node, requires_type_arguments);
2370 2380
2371 // If cls is parameterized, the type arguments and the instantiator's 2381 // If cls is parameterized, the type arguments and the instantiator's
2372 // type arguments are on the stack. 2382 // type arguments are on the stack.
2373 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls)); 2383 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls));
2374 const ExternalLabel label(cls.ToCString(), stub.EntryPoint()); 2384 const ExternalLabel label(cls.ToCString(), stub.EntryPoint());
2375 GenerateCall(node->token_index(), &label); 2385 GenerateCall(node->token_index(), &label, PcDescriptors::kOther);
2376 if (requires_type_arguments) { 2386 if (requires_type_arguments) {
2377 __ popl(ECX); // Pop type arguments. 2387 __ popl(ECX); // Pop type arguments.
2378 __ popl(ECX); // Pop instantiator type arguments. 2388 __ popl(ECX); // Pop instantiator type arguments.
2379 } 2389 }
2380 2390
2381 if (IsResultNeeded(node)) { 2391 if (IsResultNeeded(node)) {
2382 __ pushl(EAX); // Set up return value from allocate. 2392 __ pushl(EAX); // Set up return value from allocate.
2383 } 2393 }
2384 2394
2385 // First argument(this) for constructor call which follows. 2395 // First argument(this) for constructor call which follows.
2386 __ pushl(EAX); 2396 __ pushl(EAX);
2387 // Second argument is the implicit construction phase parameter. 2397 // Second argument is the implicit construction phase parameter.
2388 // Run both the constructor initializer list and the constructor body. 2398 // Run both the constructor initializer list and the constructor body.
2389 __ PushObject(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))); 2399 __ PushObject(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)));
2390 2400
2391 2401
2392 // Now setup rest of the arguments for the constructor call. 2402 // Now setup rest of the arguments for the constructor call.
2393 node->arguments()->Visit(this); 2403 node->arguments()->Visit(this);
2394 2404
2395 // Call the constructor. 2405 // Call the constructor.
2396 // +2 to include implicit receiver and phase arguments. 2406 // +2 to include implicit receiver and phase arguments.
2397 int num_args = node->arguments()->length() + 2; 2407 int num_args = node->arguments()->length() + 2;
2398 __ LoadObject(ECX, node->constructor()); 2408 __ LoadObject(ECX, node->constructor());
2399 __ LoadObject(EDX, ArgumentsDescriptor(num_args, node->arguments()->names())); 2409 __ LoadObject(EDX, ArgumentsDescriptor(num_args, node->arguments()->names()));
2400 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel()); 2410 GenerateCall(node->token_index(),
2411 &StubCode::CallStaticFunctionLabel(),
2412 PcDescriptors::kFuncCall);
2401 // Constructors do not return any value. 2413 // Constructors do not return any value.
2402 2414
2403 // Pop out all the other arguments on the stack. 2415 // Pop out all the other arguments on the stack.
2404 __ addl(ESP, Immediate(num_args * kWordSize)); 2416 __ addl(ESP, Immediate(num_args * kWordSize));
2405 } 2417 }
2406 2418
2407 2419
2408 // Expects receiver on stack, returns result in EAX.. 2420 // Expects receiver on stack, returns result in EAX..
2409 void CodeGenerator::GenerateInstanceGetterCall(intptr_t node_id, 2421 void CodeGenerator::GenerateInstanceGetterCall(intptr_t node_id,
2410 intptr_t token_index, 2422 intptr_t token_index,
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
2484 const Function& function = 2496 const Function& function =
2485 Function::ZoneHandle(field_class.LookupStaticFunction(getter_name)); 2497 Function::ZoneHandle(field_class.LookupStaticFunction(getter_name));
2486 if (function.IsNull()) { 2498 if (function.IsNull()) {
2487 ErrorMsg(token_index, "Static getter does not exist: %s", 2499 ErrorMsg(token_index, "Static getter does not exist: %s",
2488 getter_name.ToCString()); 2500 getter_name.ToCString());
2489 } 2501 }
2490 __ LoadObject(ECX, function); 2502 __ LoadObject(ECX, function);
2491 const int kNumberOfArguments = 0; 2503 const int kNumberOfArguments = 0;
2492 const Array& kNoArgumentNames = Array::Handle(); 2504 const Array& kNoArgumentNames = Array::Handle();
2493 __ LoadObject(EDX, ArgumentsDescriptor(kNumberOfArguments, kNoArgumentNames)); 2505 __ LoadObject(EDX, ArgumentsDescriptor(kNumberOfArguments, kNoArgumentNames));
2494 GenerateCall(token_index, &StubCode::CallStaticFunctionLabel()); 2506 GenerateCall(token_index,
2507 &StubCode::CallStaticFunctionLabel(),
2508 PcDescriptors::kFuncCall);
2495 // No arguments were pushed, hence nothing to pop. 2509 // No arguments were pushed, hence nothing to pop.
2496 } 2510 }
2497 2511
2498 2512
2499 // Call to static getter. 2513 // Call to static getter.
2500 void CodeGenerator::VisitStaticGetterNode(StaticGetterNode* node) { 2514 void CodeGenerator::VisitStaticGetterNode(StaticGetterNode* node) {
2501 GenerateStaticGetterCall(node->token_index(), 2515 GenerateStaticGetterCall(node->token_index(),
2502 node->cls(), 2516 node->cls(),
2503 node->field_name()); 2517 node->field_name());
2504 // Result is in EAX. 2518 // Result is in EAX.
2505 if (IsResultNeeded(node)) { 2519 if (IsResultNeeded(node)) {
2506 __ pushl(EAX); 2520 __ pushl(EAX);
2507 } 2521 }
2508 } 2522 }
2509 2523
2510 2524
2511 // Expects value on stack. 2525 // Expects value on stack.
2512 void CodeGenerator::GenerateStaticSetterCall(intptr_t token_index, 2526 void CodeGenerator::GenerateStaticSetterCall(intptr_t token_index,
2513 const Class& field_class, 2527 const Class& field_class,
2514 const String& field_name) { 2528 const String& field_name) {
2515 const String& setter_name = String::Handle(Field::SetterName(field_name)); 2529 const String& setter_name = String::Handle(Field::SetterName(field_name));
2516 const Function& function = 2530 const Function& function =
2517 Function::ZoneHandle(field_class.LookupStaticFunction(setter_name)); 2531 Function::ZoneHandle(field_class.LookupStaticFunction(setter_name));
2518 __ LoadObject(ECX, function); 2532 __ LoadObject(ECX, function);
2519 const int kNumberOfArguments = 1; // value. 2533 const int kNumberOfArguments = 1; // value.
2520 const Array& kNoArgumentNames = Array::Handle(); 2534 const Array& kNoArgumentNames = Array::Handle();
2521 __ LoadObject(EDX, ArgumentsDescriptor(kNumberOfArguments, kNoArgumentNames)); 2535 __ LoadObject(EDX, ArgumentsDescriptor(kNumberOfArguments, kNoArgumentNames));
2522 GenerateCall(token_index, &StubCode::CallStaticFunctionLabel()); 2536 GenerateCall(token_index,
2537 &StubCode::CallStaticFunctionLabel(),
2538 PcDescriptors::kFuncCall);
2523 __ addl(ESP, Immediate(kNumberOfArguments * kWordSize)); 2539 __ addl(ESP, Immediate(kNumberOfArguments * kWordSize));
2524 } 2540 }
2525 2541
2526 2542
2527 // The call to static setter implements assignment to a static field. 2543 // The call to static setter implements assignment to a static field.
2528 // The result of the assignment is the value being stored. 2544 // The result of the assignment is the value being stored.
2529 void CodeGenerator::VisitStaticSetterNode(StaticSetterNode* node) { 2545 void CodeGenerator::VisitStaticSetterNode(StaticSetterNode* node) {
2530 node->value()->Visit(this); 2546 node->value()->Visit(this);
2531 if (IsResultNeeded(node)) { 2547 if (IsResultNeeded(node)) {
2532 // Preserve the original value when returning from setter. 2548 // Preserve the original value when returning from setter.
(...skipping 12 matching lines...) Expand all
2545 // Push the result place holder initialized to NULL. 2561 // Push the result place holder initialized to NULL.
2546 __ PushObject(Object::ZoneHandle()); 2562 __ PushObject(Object::ZoneHandle());
2547 // Pass a pointer to the first argument in EAX. 2563 // Pass a pointer to the first argument in EAX.
2548 if (!node->has_optional_parameters()) { 2564 if (!node->has_optional_parameters()) {
2549 __ leal(EAX, Address(EBP, (1 + node->argument_count()) * kWordSize)); 2565 __ leal(EAX, Address(EBP, (1 + node->argument_count()) * kWordSize));
2550 } else { 2566 } else {
2551 __ leal(EAX, Address(EBP, -1 * kWordSize)); 2567 __ leal(EAX, Address(EBP, -1 * kWordSize));
2552 } 2568 }
2553 __ movl(ECX, Immediate(reinterpret_cast<uword>(node->native_c_function()))); 2569 __ movl(ECX, Immediate(reinterpret_cast<uword>(node->native_c_function())));
2554 __ movl(EDX, Immediate(node->argument_count())); 2570 __ movl(EDX, Immediate(node->argument_count()));
2555 GenerateCall(node->token_index(), &StubCode::CallNativeCFunctionLabel()); 2571 GenerateCall(node->token_index(),
2572 &StubCode::CallNativeCFunctionLabel(),
2573 PcDescriptors::kOther);
2556 // Result is on the stack. 2574 // Result is on the stack.
2557 if (!IsResultNeeded(node)) { 2575 if (!IsResultNeeded(node)) {
2558 __ popl(EAX); 2576 __ popl(EAX);
2559 } 2577 }
2560 } 2578 }
2561 2579
2562 2580
2563 void CodeGenerator::VisitCatchClauseNode(CatchClauseNode* node) { 2581 void CodeGenerator::VisitCatchClauseNode(CatchClauseNode* node) {
2564 // NOTE: The implicit variables ':saved_context', ':exception_var' 2582 // NOTE: The implicit variables ':saved_context', ':exception_var'
2565 // and ':stacktrace_var' can never be captured variables. 2583 // and ':stacktrace_var' can never be captured variables.
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
2671 GenerateLoadVariable(CTX, node->context_var()); 2689 GenerateLoadVariable(CTX, node->context_var());
2672 node->finally_block()->Visit(this); 2690 node->finally_block()->Visit(this);
2673 2691
2674 if (try_index >= 0) { 2692 if (try_index >= 0) {
2675 state()->set_try_index(try_index); 2693 state()->set_try_index(try_index);
2676 } 2694 }
2677 } 2695 }
2678 2696
2679 2697
2680 void CodeGenerator::GenerateCall(intptr_t token_index, 2698 void CodeGenerator::GenerateCall(intptr_t token_index,
2681 const ExternalLabel* ext_label) { 2699 const ExternalLabel* ext_label,
2700 PcDescriptors::Kind desc_kind) {
2682 __ call(ext_label); 2701 __ call(ext_label);
2683 AddCurrentDescriptor(PcDescriptors::kOther, AstNode::kNoId, token_index); 2702 AddCurrentDescriptor(desc_kind, AstNode::kNoId, token_index);
2684 } 2703 }
2685 2704
2686 2705
2687 void CodeGenerator::GenerateCallRuntime(intptr_t node_id, 2706 void CodeGenerator::GenerateCallRuntime(intptr_t node_id,
2688 intptr_t token_index, 2707 intptr_t token_index,
2689 const RuntimeEntry& entry) { 2708 const RuntimeEntry& entry) {
2690 __ CallRuntimeFromDart(entry); 2709 __ CallRuntimeFromDart(entry);
2691 AddCurrentDescriptor(PcDescriptors::kOther, node_id, token_index); 2710 AddCurrentDescriptor(PcDescriptors::kOther, node_id, token_index);
2692 } 2711 }
2693 2712
(...skipping 25 matching lines...) Expand all
2719 const Error& error = Error::Handle( 2738 const Error& error = Error::Handle(
2720 Parser::FormatError(script, token_index, "Error", format, args)); 2739 Parser::FormatError(script, token_index, "Error", format, args));
2721 va_end(args); 2740 va_end(args);
2722 Isolate::Current()->long_jump_base()->Jump(1, error); 2741 Isolate::Current()->long_jump_base()->Jump(1, error);
2723 UNREACHABLE(); 2742 UNREACHABLE();
2724 } 2743 }
2725 2744
2726 } // namespace dart 2745 } // namespace dart
2727 2746
2728 #endif // defined TARGET_ARCH_IA32 2747 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/code_generator_ia32.h ('k') | runtime/vm/code_generator_x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698