| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 729 opt_param_position[i + 1] = opt_param_position[i]; | 729 opt_param_position[i + 1] = opt_param_position[i]; |
| 730 } | 730 } |
| 731 opt_param[i + 1] = parameter; | 731 opt_param[i + 1] = parameter; |
| 732 opt_param_position[i + 1] = pos; | 732 opt_param_position[i + 1] = pos; |
| 733 } | 733 } |
| 734 // Generate code handling each optional parameter in alphabetical order. | 734 // Generate code handling each optional parameter in alphabetical order. |
| 735 __ movl(EBX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 735 __ movl(EBX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
| 736 __ movl(ECX, | 736 __ movl(ECX, |
| 737 FieldAddress(EDX, ArgumentsDescriptor::positional_count_offset())); | 737 FieldAddress(EDX, ArgumentsDescriptor::positional_count_offset())); |
| 738 __ SmiUntag(ECX); | 738 __ SmiUntag(ECX); |
| 739 // Let EBX point to the first passed argument, i.e. to fp[1 + argc - 0]. | 739 // Let EBX point to the first passed argument, i.e. to |
| 740 __ leal(EBX, Address(EBP, EBX, TIMES_2, kWordSize)); // EBX is Smi. | 740 // fp[kLastParamSlotIndex + num_args - 1 - 0]; num_args (EBX) is Smi. |
| 741 __ leal(EBX, |
| 742 Address(EBP, EBX, TIMES_2, (kLastParamSlotIndex - 1) * kWordSize)); |
| 741 // Let EDI point to the entry of the first named argument. | 743 // Let EDI point to the entry of the first named argument. |
| 742 __ leal(EDI, | 744 __ leal(EDI, |
| 743 FieldAddress(EDX, ArgumentsDescriptor::first_named_entry_offset())); | 745 FieldAddress(EDX, ArgumentsDescriptor::first_named_entry_offset())); |
| 744 for (int i = 0; i < num_opt_named_params; i++) { | 746 for (int i = 0; i < num_opt_named_params; i++) { |
| 745 Label load_default_value, assign_optional_parameter, next_parameter; | 747 Label load_default_value, assign_optional_parameter; |
| 746 const int param_pos = opt_param_position[i]; | 748 const int param_pos = opt_param_position[i]; |
| 747 // Check if this named parameter was passed in. | 749 // Check if this named parameter was passed in. |
| 748 // Load EAX with the name of the argument. | 750 // Load EAX with the name of the argument. |
| 749 __ movl(EAX, Address(EDI, ArgumentsDescriptor::name_offset())); | 751 __ movl(EAX, Address(EDI, ArgumentsDescriptor::name_offset())); |
| 750 ASSERT(opt_param[i]->name().IsSymbol()); | 752 ASSERT(opt_param[i]->name().IsSymbol()); |
| 751 __ CompareObject(EAX, opt_param[i]->name()); | 753 __ CompareObject(EAX, opt_param[i]->name()); |
| 752 __ j(NOT_EQUAL, &load_default_value, Assembler::kNearJump); | 754 __ j(NOT_EQUAL, &load_default_value, Assembler::kNearJump); |
| 753 // Load EAX with passed-in argument at provided arg_pos, i.e. at | 755 // Load EAX with passed-in argument at provided arg_pos, i.e. at |
| 754 // fp[1 + argc - arg_pos]. | 756 // fp[kLastParamSlotIndex + num_args - 1 - arg_pos]. |
| 755 __ movl(EAX, Address(EDI, ArgumentsDescriptor::position_offset())); | 757 __ movl(EAX, Address(EDI, ArgumentsDescriptor::position_offset())); |
| 756 // EAX is arg_pos as Smi. | 758 // EAX is arg_pos as Smi. |
| 757 // Point to next named entry. | 759 // Point to next named entry. |
| 758 __ addl(EDI, Immediate(ArgumentsDescriptor::named_entry_size())); | 760 __ addl(EDI, Immediate(ArgumentsDescriptor::named_entry_size())); |
| 759 __ negl(EAX); | 761 __ negl(EAX); |
| 760 Address argument_addr(EBX, EAX, TIMES_2, 0); // EAX is a negative Smi. | 762 Address argument_addr(EBX, EAX, TIMES_2, 0); // EAX is a negative Smi. |
| 761 __ movl(EAX, argument_addr); | 763 __ movl(EAX, argument_addr); |
| 762 __ jmp(&assign_optional_parameter, Assembler::kNearJump); | 764 __ jmp(&assign_optional_parameter, Assembler::kNearJump); |
| 763 __ Bind(&load_default_value); | 765 __ Bind(&load_default_value); |
| 764 // Load EAX with default argument. | 766 // Load EAX with default argument. |
| 765 const Object& value = Object::ZoneHandle( | 767 const Object& value = Object::ZoneHandle( |
| 766 parsed_function().default_parameter_values().At( | 768 parsed_function().default_parameter_values().At( |
| 767 param_pos - num_fixed_params)); | 769 param_pos - num_fixed_params)); |
| 768 __ LoadObject(EAX, value); | 770 __ LoadObject(EAX, value); |
| 769 __ Bind(&assign_optional_parameter); | 771 __ Bind(&assign_optional_parameter); |
| 770 // Assign EAX to fp[kFirstLocalSlotIndex - param_pos]. | 772 // Assign EAX to fp[kFirstLocalSlotIndex - param_pos]. |
| 771 // We do not use the final allocation index of the variable here, i.e. | 773 // We do not use the final allocation index of the variable here, i.e. |
| 772 // scope->VariableAt(i)->index(), because captured variables still need | 774 // scope->VariableAt(i)->index(), because captured variables still need |
| 773 // to be copied to the context that is not yet allocated. | 775 // to be copied to the context that is not yet allocated. |
| 774 const intptr_t computed_param_pos = kFirstLocalSlotIndex - param_pos; | 776 const intptr_t computed_param_pos = kFirstLocalSlotIndex - param_pos; |
| 775 const Address param_addr(EBP, (computed_param_pos * kWordSize)); | 777 const Address param_addr(EBP, computed_param_pos * kWordSize); |
| 776 __ movl(param_addr, EAX); | 778 __ movl(param_addr, EAX); |
| 777 __ Bind(&next_parameter); | |
| 778 } | 779 } |
| 779 delete[] opt_param; | 780 delete[] opt_param; |
| 780 delete[] opt_param_position; | 781 delete[] opt_param_position; |
| 781 // Check that EDI now points to the null terminator in the array descriptor. | 782 // Check that EDI now points to the null terminator in the array descriptor. |
| 782 __ cmpl(Address(EDI, 0), raw_null); | 783 __ cmpl(Address(EDI, 0), raw_null); |
| 783 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); | 784 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); |
| 784 } else { | 785 } else { |
| 785 ASSERT(num_opt_pos_params > 0); | 786 ASSERT(num_opt_pos_params > 0); |
| 786 __ movl(ECX, | 787 __ movl(ECX, |
| 787 FieldAddress(EDX, ArgumentsDescriptor::positional_count_offset())); | 788 FieldAddress(EDX, ArgumentsDescriptor::positional_count_offset())); |
| 788 __ SmiUntag(ECX); | 789 __ SmiUntag(ECX); |
| 789 for (int i = 0; i < num_opt_pos_params; i++) { | 790 for (int i = 0; i < num_opt_pos_params; i++) { |
| 790 Label next_parameter; | 791 Label next_parameter; |
| 791 // Handle this optional positonal parameter only if k or fewer positional | 792 // Handle this optional positional parameter only if k or fewer positional |
| 792 // arguments have been passed, where k is param_pos, the position of this | 793 // arguments have been passed, where k is param_pos, the position of this |
| 793 // optional parameter in the formal parameter list. | 794 // optional parameter in the formal parameter list. |
| 794 const int param_pos = num_fixed_params + i; | 795 const int param_pos = num_fixed_params + i; |
| 795 __ cmpl(ECX, Immediate(param_pos)); | 796 __ cmpl(ECX, Immediate(param_pos)); |
| 796 __ j(GREATER, &next_parameter, Assembler::kNearJump); | 797 __ j(GREATER, &next_parameter, Assembler::kNearJump); |
| 797 // Load RAX with default argument. | 798 // Load EAX with default argument. |
| 798 const Object& value = Object::ZoneHandle( | 799 const Object& value = Object::ZoneHandle( |
| 799 parsed_function().default_parameter_values().At(i)); | 800 parsed_function().default_parameter_values().At(i)); |
| 800 __ LoadObject(EAX, value); | 801 __ LoadObject(EAX, value); |
| 801 // Assign EAX to fp[kFirstLocalSlotIndex - param_pos]. | 802 // Assign EAX to fp[kFirstLocalSlotIndex - param_pos]. |
| 802 // We do not use the final allocation index of the variable here, i.e. | 803 // We do not use the final allocation index of the variable here, i.e. |
| 803 // scope->VariableAt(i)->index(), because captured variables still need | 804 // scope->VariableAt(i)->index(), because captured variables still need |
| 804 // to be copied to the context that is not yet allocated. | 805 // to be copied to the context that is not yet allocated. |
| 805 const intptr_t computed_param_pos = kFirstLocalSlotIndex - param_pos; | 806 const intptr_t computed_param_pos = kFirstLocalSlotIndex - param_pos; |
| 806 const Address param_addr(EBP, (computed_param_pos * kWordSize)); | 807 const Address param_addr(EBP, computed_param_pos * kWordSize); |
| 807 __ movl(param_addr, EAX); | 808 __ movl(param_addr, EAX); |
| 808 __ Bind(&next_parameter); | 809 __ Bind(&next_parameter); |
| 809 } | 810 } |
| 810 __ movl(EBX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 811 __ movl(EBX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
| 811 __ SmiUntag(EBX); | 812 __ SmiUntag(EBX); |
| 812 // Check that ECX equals EBX, i.e. no named arguments passed. | 813 // Check that ECX equals EBX, i.e. no named arguments passed. |
| 813 __ cmpl(ECX, EBX); | 814 __ cmpl(ECX, EBX); |
| 814 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); | 815 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); |
| 815 } | 816 } |
| 816 | 817 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 855 // checked, otherwise noSuchMethod would not see their original values. | 856 // checked, otherwise noSuchMethod would not see their original values. |
| 856 // This step can be skipped in case we decide that formal parameters are | 857 // This step can be skipped in case we decide that formal parameters are |
| 857 // implicitly final, since garbage collecting the unmodified value is not | 858 // implicitly final, since garbage collecting the unmodified value is not |
| 858 // an issue anymore. | 859 // an issue anymore. |
| 859 | 860 |
| 860 // EDX : arguments descriptor array. | 861 // EDX : arguments descriptor array. |
| 861 __ movl(ECX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 862 __ movl(ECX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
| 862 __ SmiUntag(ECX); | 863 __ SmiUntag(ECX); |
| 863 Label null_args_loop, null_args_loop_condition; | 864 Label null_args_loop, null_args_loop_condition; |
| 864 __ jmp(&null_args_loop_condition, Assembler::kNearJump); | 865 __ jmp(&null_args_loop_condition, Assembler::kNearJump); |
| 865 const Address original_argument_addr(EBP, ECX, TIMES_4, 2 * kWordSize); | 866 const Address original_argument_addr( |
| 867 EBP, ECX, TIMES_4, kLastParamSlotIndex * kWordSize); |
| 866 __ Bind(&null_args_loop); | 868 __ Bind(&null_args_loop); |
| 867 __ movl(original_argument_addr, raw_null); | 869 __ movl(original_argument_addr, raw_null); |
| 868 __ Bind(&null_args_loop_condition); | 870 __ Bind(&null_args_loop_condition); |
| 869 __ decl(ECX); | 871 __ decl(ECX); |
| 870 __ j(POSITIVE, &null_args_loop, Assembler::kNearJump); | 872 __ j(POSITIVE, &null_args_loop, Assembler::kNearJump); |
| 871 } | 873 } |
| 872 | 874 |
| 873 | 875 |
| 874 void FlowGraphCompiler::GenerateInlinedGetter(intptr_t offset) { | 876 void FlowGraphCompiler::GenerateInlinedGetter(intptr_t offset) { |
| 875 // TOS: return address. | 877 // TOS: return address. |
| (...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1715 __ popl(ECX); | 1717 __ popl(ECX); |
| 1716 __ popl(EAX); | 1718 __ popl(EAX); |
| 1717 } | 1719 } |
| 1718 | 1720 |
| 1719 | 1721 |
| 1720 #undef __ | 1722 #undef __ |
| 1721 | 1723 |
| 1722 } // namespace dart | 1724 } // namespace dart |
| 1723 | 1725 |
| 1724 #endif // defined TARGET_ARCH_IA32 | 1726 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |