OLD | NEW |
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 831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
842 // Type nodes are handled specially by the code generator. | 842 // Type nodes are handled specially by the code generator. |
843 UNREACHABLE(); | 843 UNREACHABLE(); |
844 } | 844 } |
845 | 845 |
846 | 846 |
847 void CodeGenerator::VisitClosureNode(ClosureNode* node) { | 847 void CodeGenerator::VisitClosureNode(ClosureNode* node) { |
848 const int current_context_level = state()->context_level(); | 848 const int current_context_level = state()->context_level(); |
849 const ContextScope& context_scope = ContextScope::ZoneHandle( | 849 const ContextScope& context_scope = ContextScope::ZoneHandle( |
850 node->scope()->PreserveOuterScope(current_context_level)); | 850 node->scope()->PreserveOuterScope(current_context_level)); |
851 const Function& function = node->function(); | 851 const Function& function = node->function(); |
| 852 ASSERT(function.IsClosureFunction() && !function.IsImplicitClosureFunction()); |
852 ASSERT(!function.HasCode()); | 853 ASSERT(!function.HasCode()); |
853 ASSERT(function.context_scope() == ContextScope::null()); | 854 ASSERT(function.context_scope() == ContextScope::null()); |
854 function.set_context_scope(context_scope); | 855 function.set_context_scope(context_scope); |
855 const Code& stub = Code::Handle( | 856 const Code& stub = Code::Handle( |
856 StubCode::GetAllocationStubForClosure(function)); | 857 StubCode::GetAllocationStubForClosure(function)); |
857 const ExternalLabel label(function.ToCString(), stub.EntryPoint()); | 858 const ExternalLabel label(function.ToCString(), stub.EntryPoint()); |
858 GenerateCall(node->token_index(), &label); | 859 GenerateCall(node->token_index(), &label); |
859 if (IsResultNeeded(node)) { | 860 if (IsResultNeeded(node)) { |
860 __ pushl(EAX); | 861 __ pushl(EAX); |
861 } | 862 } |
862 } | 863 } |
863 | 864 |
864 | 865 |
865 void CodeGenerator::VisitStaticImplicitClosureNode( | 866 void CodeGenerator::VisitStaticImplicitClosureNode( |
866 StaticImplicitClosureNode* node) { | 867 StaticImplicitClosureNode* node) { |
867 const Function& function = node->function(); | 868 const Function& function = node->function(); |
| 869 ASSERT(function.IsImplicitClosureFunction()); |
| 870 ASSERT(function.is_static()); |
868 ASSERT(function.context_scope() != ContextScope::null()); | 871 ASSERT(function.context_scope() != ContextScope::null()); |
869 const Code& stub = Code::Handle( | 872 const Code& stub = Code::Handle( |
870 StubCode::GetAllocationStubForStaticImplicitClosure(function)); | 873 StubCode::GetAllocationStubForClosure(function)); |
871 const ExternalLabel label(function.ToCString(), stub.EntryPoint()); | 874 const ExternalLabel label(function.ToCString(), stub.EntryPoint()); |
872 GenerateCall(node->token_index(), &label); | 875 GenerateCall(node->token_index(), &label); |
873 if (IsResultNeeded(node)) { | 876 if (IsResultNeeded(node)) { |
874 __ pushl(EAX); | 877 __ pushl(EAX); |
875 } | 878 } |
876 } | 879 } |
877 | 880 |
878 | 881 |
879 void CodeGenerator::VisitImplicitClosureNode(ImplicitClosureNode* node) { | 882 void CodeGenerator::VisitImplicitClosureNode(ImplicitClosureNode* node) { |
880 const Function& function = node->function(); | 883 const Function& function = node->function(); |
| 884 ASSERT(function.IsImplicitClosureFunction()); |
| 885 ASSERT(!function.is_static()); |
881 ASSERT(function.context_scope() != ContextScope::null()); | 886 ASSERT(function.context_scope() != ContextScope::null()); |
882 const Immediate raw_null = | |
883 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
884 Label null_receiver; | |
885 node->receiver()->Visit(this); | 887 node->receiver()->Visit(this); |
886 __ popl(EAX); // Get receiver. | 888 const Code& stub = Code::Handle( |
887 const Object& result = Object::ZoneHandle(); | 889 StubCode::GetAllocationStubForClosure(function)); |
888 __ PushObject(result); // Make room for the result of the runtime call. | 890 const ExternalLabel label(function.ToCString(), stub.EntryPoint()); |
889 __ PushObject(function); // Push the type. | 891 GenerateCall(node->token_index(), &label); |
890 __ pushl(EAX); // Push the receiver. | 892 __ popl(ECX); // Pop receiver. |
891 GenerateCallRuntime(node->token_index(), | |
892 kAllocateImplicitClosureRuntimeEntry); | |
893 // Pop the parameters supplied to the runtime entry. The result of the | |
894 // type check runtime call is the checked value. | |
895 __ addl(ESP, Immediate(2 * kWordSize)); | |
896 __ popl(EAX); // Allocated closure. | |
897 if (IsResultNeeded(node)) { | 893 if (IsResultNeeded(node)) { |
898 __ pushl(EAX); | 894 __ pushl(EAX); |
899 } | 895 } |
900 } | 896 } |
901 | 897 |
902 | 898 |
903 void CodeGenerator::VisitPrimaryNode(PrimaryNode* node) { | 899 void CodeGenerator::VisitPrimaryNode(PrimaryNode* node) { |
904 // PrimaryNodes are temporary during parsing. | 900 // PrimaryNodes are temporary during parsing. |
905 ErrorMsg(node->token_index(), | 901 ErrorMsg(node->token_index(), |
906 "Unexpected primary node: %s", node->primary().ToCString()); | 902 "Unexpected primary node: %s", node->primary().ToCString()); |
(...skipping 1755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2662 const Class& cls = Class::Handle(parsed_function_.function().owner()); | 2658 const Class& cls = Class::Handle(parsed_function_.function().owner()); |
2663 const Script& script = Script::Handle(cls.script()); | 2659 const Script& script = Script::Handle(cls.script()); |
2664 Parser::ReportMsg(script, token_index, "Error", error_msg, format, args); | 2660 Parser::ReportMsg(script, token_index, "Error", error_msg, format, args); |
2665 Isolate::Current()->long_jump_base()->Jump(1, error_msg); | 2661 Isolate::Current()->long_jump_base()->Jump(1, error_msg); |
2666 UNREACHABLE(); | 2662 UNREACHABLE(); |
2667 } | 2663 } |
2668 | 2664 |
2669 } // namespace dart | 2665 } // namespace dart |
2670 | 2666 |
2671 #endif // defined TARGET_ARCH_IA32 | 2667 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |