| 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 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 Address::Absolute(Isolate::Current()->stack_limit_address())); | 750 Address::Absolute(Isolate::Current()->stack_limit_address())); |
| 751 Label no_stack_overflow; | 751 Label no_stack_overflow; |
| 752 __ j(ABOVE, &no_stack_overflow); | 752 __ j(ABOVE, &no_stack_overflow); |
| 753 GenerateCallRuntime(AstNode::kNoId, | 753 GenerateCallRuntime(AstNode::kNoId, |
| 754 0, | 754 0, |
| 755 kStackOverflowRuntimeEntry); | 755 kStackOverflowRuntimeEntry); |
| 756 __ Bind(&no_stack_overflow); | 756 __ Bind(&no_stack_overflow); |
| 757 } | 757 } |
| 758 | 758 |
| 759 | 759 |
| 760 void CodeGenerator::GenerateReturnEpilog() { | 760 void CodeGenerator::GenerateReturnEpilog(ReturnNode* node) { |
| 761 // Unchain the context(s) up to context level 0. | 761 // Unchain the context(s) up to context level 0. |
| 762 int context_level = state()->context_level(); | 762 int context_level = state()->context_level(); |
| 763 ASSERT(context_level >= 0); | 763 ASSERT(context_level >= 0); |
| 764 while (context_level-- > 0) { | 764 while (context_level-- > 0) { |
| 765 __ movl(CTX, FieldAddress(CTX, Context::parent_offset())); | 765 __ movl(CTX, FieldAddress(CTX, Context::parent_offset())); |
| 766 } | 766 } |
| 767 #ifdef DEBUG | 767 #ifdef DEBUG |
| 768 // Check that the entry stack size matches the exit stack size. | 768 // Check that the entry stack size matches the exit stack size. |
| 769 __ movl(EDX, EBP); | 769 __ movl(EDX, EBP); |
| 770 __ subl(EDX, ESP); | 770 __ subl(EDX, ESP); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 781 __ LoadObject(EBX, function); | 781 __ LoadObject(EBX, function); |
| 782 __ pushl(EBX); | 782 __ pushl(EBX); |
| 783 GenerateCallRuntime(AstNode::kNoId, | 783 GenerateCallRuntime(AstNode::kNoId, |
| 784 0, | 784 0, |
| 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 |
| 792 // in breakpoints during debugging. |
| 793 __ nop(1); |
| 794 AddCurrentDescriptor(PcDescriptors::kReturn, |
| 795 AstNode::kNoId, |
| 796 node->token_index()); |
| 791 | 797 |
| 792 #ifdef DEBUG | 798 #ifdef DEBUG |
| 793 __ Bind(&wrong_stack); | 799 __ Bind(&wrong_stack); |
| 794 __ Stop("Exit stack size does not match the entry stack size."); | 800 __ Stop("Exit stack size does not match the entry stack size."); |
| 795 #endif // DEBUG. | 801 #endif // DEBUG. |
| 796 } | 802 } |
| 797 | 803 |
| 798 | 804 |
| 799 void CodeGenerator::VisitReturnNode(ReturnNode* node) { | 805 void CodeGenerator::VisitReturnNode(ReturnNode* node) { |
| 800 ASSERT(!IsResultNeeded(node)); | 806 ASSERT(!IsResultNeeded(node)); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 830 // Implicit getters do not need a type check at return. | 836 // Implicit getters do not need a type check at return. |
| 831 if ((kind != RawFunction::kImplicitGetter) && | 837 if ((kind != RawFunction::kImplicitGetter) && |
| 832 (kind != RawFunction::kConstImplicitGetter)) { | 838 (kind != RawFunction::kConstImplicitGetter)) { |
| 833 GenerateAssertAssignable( | 839 GenerateAssertAssignable( |
| 834 node->id(), | 840 node->id(), |
| 835 node->value()->token_index(), | 841 node->value()->token_index(), |
| 836 AbstractType::ZoneHandle(parsed_function().function().result_type()), | 842 AbstractType::ZoneHandle(parsed_function().function().result_type()), |
| 837 String::ZoneHandle(String::NewSymbol("function result"))); | 843 String::ZoneHandle(String::NewSymbol("function result"))); |
| 838 } | 844 } |
| 839 } | 845 } |
| 840 GenerateReturnEpilog(); | 846 GenerateReturnEpilog(node); |
| 841 } | 847 } |
| 842 | 848 |
| 843 | 849 |
| 844 void CodeGenerator::VisitLiteralNode(LiteralNode* node) { | 850 void CodeGenerator::VisitLiteralNode(LiteralNode* node) { |
| 845 if (!IsResultNeeded(node)) return; | 851 if (!IsResultNeeded(node)) return; |
| 846 __ PushObject(node->literal()); | 852 __ PushObject(node->literal()); |
| 847 } | 853 } |
| 848 | 854 |
| 849 | 855 |
| 850 void CodeGenerator::VisitTypeNode(TypeNode* node) { | 856 void CodeGenerator::VisitTypeNode(TypeNode* node) { |
| (...skipping 1938 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2789 const Error& error = Error::Handle( | 2795 const Error& error = Error::Handle( |
| 2790 Parser::FormatError(script, token_index, "Error", format, args)); | 2796 Parser::FormatError(script, token_index, "Error", format, args)); |
| 2791 va_end(args); | 2797 va_end(args); |
| 2792 Isolate::Current()->long_jump_base()->Jump(1, error); | 2798 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2793 UNREACHABLE(); | 2799 UNREACHABLE(); |
| 2794 } | 2800 } |
| 2795 | 2801 |
| 2796 } // namespace dart | 2802 } // namespace dart |
| 2797 | 2803 |
| 2798 #endif // defined TARGET_ARCH_IA32 | 2804 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |