OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |