| 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 822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 833 } | 833 } |
| 834 } | 834 } |
| 835 | 835 |
| 836 | 836 |
| 837 void CodeGenerator::VisitTypeNode(TypeNode* node) { | 837 void CodeGenerator::VisitTypeNode(TypeNode* node) { |
| 838 // Type nodes are handled specially by the code generator. | 838 // Type nodes are handled specially by the code generator. |
| 839 UNREACHABLE(); | 839 UNREACHABLE(); |
| 840 } | 840 } |
| 841 | 841 |
| 842 | 842 |
| 843 // TODO(regis): Consider merging all 3 closure node flavors into a single one. | |
| 844 void CodeGenerator::VisitClosureNode(ClosureNode* node) { | 843 void CodeGenerator::VisitClosureNode(ClosureNode* node) { |
| 845 const int current_context_level = state()->context_level(); | |
| 846 const ContextScope& context_scope = ContextScope::ZoneHandle( | |
| 847 node->scope()->PreserveOuterScope(current_context_level)); | |
| 848 const Function& function = node->function(); | 844 const Function& function = node->function(); |
| 849 ASSERT(function.IsNonImplicitClosureFunction()); | 845 if (function.IsNonImplicitClosureFunction()) { |
| 850 ASSERT(!function.HasCode()); | 846 const int current_context_level = state()->context_level(); |
| 851 ASSERT(function.context_scope() == ContextScope::null()); | 847 const ContextScope& context_scope = ContextScope::ZoneHandle( |
| 852 function.set_context_scope(context_scope); | 848 node->scope()->PreserveOuterScope(current_context_level)); |
| 849 ASSERT(!function.HasCode()); |
| 850 ASSERT(function.context_scope() == ContextScope::null()); |
| 851 function.set_context_scope(context_scope); |
| 852 } else { |
| 853 ASSERT(function.context_scope() != ContextScope::null()); |
| 854 if (function.IsImplicitInstanceClosureFunction()) { |
| 855 node->receiver()->Visit(this); |
| 856 } |
| 857 } |
| 853 // The function type of a closure may be parameterized. In that case, pass | 858 // The function type of a closure may be parameterized. In that case, pass |
| 854 // the type arguments of the instantiator. | 859 // the type arguments of the instantiator. |
| 855 const Class& cls = Class::Handle(function.signature_class()); | 860 const Class& cls = Class::Handle(function.signature_class()); |
| 856 ASSERT(!cls.IsNull()); | 861 ASSERT(!cls.IsNull()); |
| 857 const bool is_cls_parameterized = cls.IsParameterized(); | 862 const bool is_cls_parameterized = cls.IsParameterized(); |
| 858 if (is_cls_parameterized) { | 863 if (is_cls_parameterized) { |
| 864 ASSERT(!function.IsImplicitStaticClosureFunction()); |
| 859 GenerateInstantiatorTypeArguments(); | 865 GenerateInstantiatorTypeArguments(); |
| 860 } | 866 } |
| 861 const Code& stub = Code::Handle( | 867 const Code& stub = Code::Handle( |
| 862 StubCode::GetAllocationStubForClosure(function)); | 868 StubCode::GetAllocationStubForClosure(function)); |
| 863 const ExternalLabel label(function.ToCString(), stub.EntryPoint()); | 869 const ExternalLabel label(function.ToCString(), stub.EntryPoint()); |
| 864 GenerateCall(node->token_index(), &label); | 870 GenerateCall(node->token_index(), &label); |
| 865 if (is_cls_parameterized) { | 871 if (is_cls_parameterized) { |
| 866 __ popl(ECX); // Pop type arguments. | 872 __ popl(ECX); // Pop type arguments. |
| 867 } | 873 } |
| 868 if (IsResultNeeded(node)) { | 874 if (function.IsImplicitInstanceClosureFunction()) { |
| 869 __ pushl(EAX); | 875 __ popl(ECX); // Pop receiver. |
| 870 } | 876 } |
| 871 } | |
| 872 | |
| 873 | |
| 874 void CodeGenerator::VisitImplicitStaticClosureNode( | |
| 875 ImplicitStaticClosureNode* node) { | |
| 876 const Function& function = node->function(); | |
| 877 ASSERT(function.IsImplicitStaticClosureFunction()); | |
| 878 ASSERT(function.context_scope() != ContextScope::null()); | |
| 879 const Code& stub = Code::Handle( | |
| 880 StubCode::GetAllocationStubForClosure(function)); | |
| 881 const ExternalLabel label(function.ToCString(), stub.EntryPoint()); | |
| 882 GenerateCall(node->token_index(), &label); | |
| 883 if (IsResultNeeded(node)) { | |
| 884 __ pushl(EAX); | |
| 885 } | |
| 886 } | |
| 887 | |
| 888 | |
| 889 void CodeGenerator::VisitImplicitInstanceClosureNode( | |
| 890 ImplicitInstanceClosureNode* node) { | |
| 891 const Function& function = node->function(); | |
| 892 ASSERT(function.IsImplicitInstanceClosureFunction()); | |
| 893 ASSERT(function.context_scope() != ContextScope::null()); | |
| 894 node->receiver()->Visit(this); | |
| 895 // The function type of a closure may be parameterized. In that case, pass | |
| 896 // the type arguments of the instantiator. | |
| 897 const Class& cls = Class::Handle(function.signature_class()); | |
| 898 ASSERT(!cls.IsNull()); | |
| 899 const bool is_cls_parameterized = cls.IsParameterized(); | |
| 900 if (is_cls_parameterized) { | |
| 901 GenerateInstantiatorTypeArguments(); | |
| 902 } | |
| 903 const Code& stub = Code::Handle( | |
| 904 StubCode::GetAllocationStubForClosure(function)); | |
| 905 const ExternalLabel label(function.ToCString(), stub.EntryPoint()); | |
| 906 GenerateCall(node->token_index(), &label); | |
| 907 if (is_cls_parameterized) { | |
| 908 __ popl(ECX); // Pop type arguments. | |
| 909 } | |
| 910 __ popl(ECX); // Pop receiver. | |
| 911 if (IsResultNeeded(node)) { | 877 if (IsResultNeeded(node)) { |
| 912 __ pushl(EAX); | 878 __ pushl(EAX); |
| 913 } | 879 } |
| 914 } | 880 } |
| 915 | 881 |
| 916 | 882 |
| 917 void CodeGenerator::VisitPrimaryNode(PrimaryNode* node) { | 883 void CodeGenerator::VisitPrimaryNode(PrimaryNode* node) { |
| 918 // PrimaryNodes are temporary during parsing. | 884 // PrimaryNodes are temporary during parsing. |
| 919 ErrorMsg(node->token_index(), | 885 ErrorMsg(node->token_index(), |
| 920 "Unexpected primary node: %s", node->primary().ToCString()); | 886 "Unexpected primary node: %s", node->primary().ToCString()); |
| (...skipping 1734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2655 const Class& cls = Class::Handle(parsed_function_.function().owner()); | 2621 const Class& cls = Class::Handle(parsed_function_.function().owner()); |
| 2656 const Script& script = Script::Handle(cls.script()); | 2622 const Script& script = Script::Handle(cls.script()); |
| 2657 Parser::ReportMsg(script, token_index, "Error", error_msg, format, args); | 2623 Parser::ReportMsg(script, token_index, "Error", error_msg, format, args); |
| 2658 Isolate::Current()->long_jump_base()->Jump(1, error_msg); | 2624 Isolate::Current()->long_jump_base()->Jump(1, error_msg); |
| 2659 UNREACHABLE(); | 2625 UNREACHABLE(); |
| 2660 } | 2626 } |
| 2661 | 2627 |
| 2662 } // namespace dart | 2628 } // namespace dart |
| 2663 | 2629 |
| 2664 #endif // defined TARGET_ARCH_IA32 | 2630 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |