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/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
9 | 9 |
10 #include "lib/error.h" | 10 #include "lib/error.h" |
(...skipping 759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
770 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); | 770 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); |
771 } | 771 } |
772 | 772 |
773 __ Bind(&wrong_num_arguments); | 773 __ Bind(&wrong_num_arguments); |
774 if (StackSize() != 0) { | 774 if (StackSize() != 0) { |
775 // We need to unwind the space we reserved for locals and copied parameters. | 775 // We need to unwind the space we reserved for locals and copied parameters. |
776 // The NoSuchMethodFunction stub does not expect to see that area on the | 776 // The NoSuchMethodFunction stub does not expect to see that area on the |
777 // stack. | 777 // stack. |
778 __ addl(ESP, Immediate(StackSize() * kWordSize)); | 778 __ addl(ESP, Immediate(StackSize() * kWordSize)); |
779 } | 779 } |
780 // The calls immediately below have empty stackmaps because we have just | 780 // The call below has an empty stackmap because we have just |
781 // dropped the spill slots. | 781 // dropped the spill slots. |
782 BitmapBuilder* empty_stack_bitmap = new BitmapBuilder(); | 782 BitmapBuilder* empty_stack_bitmap = new BitmapBuilder(); |
783 if (function.IsClosureFunction()) { | 783 |
784 // TODO(regis): Call NoSuchMethod with "call" as name of original function. | 784 // Invoke noSuchMethod function passing the original name of the function. |
785 // We do not use GenerateCallRuntime because of the non-standard (empty) | 785 // If the function is a closure function, use "call" as the original name. |
786 // stackmap used here. | 786 const String& name = String::Handle( |
787 __ CallRuntime(kClosureArgumentMismatchRuntimeEntry); | 787 function.IsClosureFunction() ? Symbols::Call() : function.name()); |
788 AddCurrentDescriptor(PcDescriptors::kOther, | 788 const int kNumArgsChecked = 1; |
789 Isolate::kNoDeoptId, | 789 const ICData& ic_data = ICData::ZoneHandle( |
790 0); // No token position. | 790 ICData::New(function, name, Isolate::kNoDeoptId, kNumArgsChecked)); |
791 } else { | 791 __ LoadObject(ECX, ic_data); |
792 // Invoke noSuchMethod function. | 792 // EBP - 4 : PC marker, allows easy identification of RawInstruction obj. |
793 const int kNumArgsChecked = 1; | 793 // EBP : points to previous frame pointer. |
794 ICData& ic_data = ICData::ZoneHandle(); | 794 // EBP + 4 : points to return address. |
795 ic_data = ICData::New(function, | 795 // EBP + 8 : address of last argument (arg n-1). |
796 String::Handle(function.name()), | 796 // ESP + 8 + 4*(n-1) : address of first argument (arg 0). |
797 Isolate::kNoDeoptId, | 797 // ECX : ic-data. |
798 kNumArgsChecked); | 798 // EDX : arguments descriptor array. |
799 __ LoadObject(ECX, ic_data); | 799 __ call(&StubCode::CallNoSuchMethodFunctionLabel()); |
800 // EBP - 4 : PC marker, allows easy identification of RawInstruction obj. | |
801 // EBP : points to previous frame pointer. | |
802 // EBP + 4 : points to return address. | |
803 // EBP + 8 : address of last argument (arg n-1). | |
804 // ESP + 8 + 4*(n-1) : address of first argument (arg 0). | |
805 // ECX : ic-data. | |
806 // EDX : arguments descriptor array. | |
807 __ call(&StubCode::CallNoSuchMethodFunctionLabel()); | |
808 } | |
809 if (is_optimizing()) { | 800 if (is_optimizing()) { |
810 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), | 801 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), |
811 empty_stack_bitmap, | 802 empty_stack_bitmap, |
812 0); // No registers. | 803 0); // No registers. |
813 } | 804 } |
814 | 805 // The noSuchMethod call may return. |
815 __ LeaveFrame(); | 806 __ LeaveFrame(); |
816 __ ret(); | 807 __ ret(); |
817 | 808 |
818 __ Bind(&all_arguments_processed); | 809 __ Bind(&all_arguments_processed); |
819 // Nullify originally passed arguments only after they have been copied and | 810 // Nullify originally passed arguments only after they have been copied and |
820 // checked, otherwise noSuchMethod would not see their original values. | 811 // checked, otherwise noSuchMethod would not see their original values. |
821 // This step can be skipped in case we decide that formal parameters are | 812 // This step can be skipped in case we decide that formal parameters are |
822 // implicitly final, since garbage collecting the unmodified value is not | 813 // implicitly final, since garbage collecting the unmodified value is not |
823 // an issue anymore. | 814 // an issue anymore. |
824 | 815 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
905 #endif | 896 #endif |
906 if (check_arguments) { | 897 if (check_arguments) { |
907 __ Comment("Check argument count"); | 898 __ Comment("Check argument count"); |
908 // Check that num_fixed <= argc <= num_params. | 899 // Check that num_fixed <= argc <= num_params. |
909 Label argc_in_range; | 900 Label argc_in_range; |
910 // Total number of args is the first Smi in args descriptor array (EDX). | 901 // Total number of args is the first Smi in args descriptor array (EDX). |
911 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); | 902 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); |
912 __ cmpl(EAX, Immediate(Smi::RawValue(num_fixed_params))); | 903 __ cmpl(EAX, Immediate(Smi::RawValue(num_fixed_params))); |
913 __ j(EQUAL, &argc_in_range, Assembler::kNearJump); | 904 __ j(EQUAL, &argc_in_range, Assembler::kNearJump); |
914 if (function.IsClosureFunction()) { | 905 if (function.IsClosureFunction()) { |
915 // TODO(regis): Call NoSuchMethod with "call" as name of original | 906 if (StackSize() != 0) { |
916 // function. | 907 // We need to unwind the space we reserved for locals and copied |
917 GenerateCallRuntime(function.token_pos(), | 908 // parameters. The NoSuchMethodFunction stub does not expect to see |
918 kClosureArgumentMismatchRuntimeEntry, | 909 // that area on the stack. |
919 prologue_locs); | 910 __ addl(ESP, Immediate(StackSize() * kWordSize)); |
| 911 } |
| 912 // The call below has an empty stackmap because we have just |
| 913 // dropped the spill slots. |
| 914 BitmapBuilder* empty_stack_bitmap = new BitmapBuilder(); |
| 915 |
| 916 // Invoke noSuchMethod function passing "call" as the function name. |
| 917 const String& name = String::Handle(Symbols::Call()); |
| 918 const int kNumArgsChecked = 1; |
| 919 const ICData& ic_data = ICData::ZoneHandle( |
| 920 ICData::New(function, name, Isolate::kNoDeoptId, kNumArgsChecked)); |
| 921 __ LoadObject(ECX, ic_data); |
| 922 // EBP - 4 : PC marker, for easy identification of RawInstruction obj. |
| 923 // EBP : points to previous frame pointer. |
| 924 // EBP + 4 : points to return address. |
| 925 // EBP + 8 : address of last argument (arg n-1). |
| 926 // ESP + 8 + 4*(n-1) : address of first argument (arg 0). |
| 927 // ECX : ic-data. |
| 928 // EDX : arguments descriptor array. |
| 929 __ call(&StubCode::CallNoSuchMethodFunctionLabel()); |
| 930 if (is_optimizing()) { |
| 931 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), |
| 932 empty_stack_bitmap, |
| 933 0); // No registers. |
| 934 } |
| 935 // The noSuchMethod call may return. |
| 936 __ LeaveFrame(); |
| 937 __ ret(); |
920 } else { | 938 } else { |
921 __ Stop("Wrong number of arguments"); | 939 __ Stop("Wrong number of arguments"); |
922 } | 940 } |
923 __ Bind(&argc_in_range); | 941 __ Bind(&argc_in_range); |
924 } | 942 } |
925 // The arguments descriptor is never saved in the absence of optional | 943 // The arguments descriptor is never saved in the absence of optional |
926 // parameters, since any argument definition test would always yield true. | 944 // parameters, since any argument definition test would always yield true. |
927 ASSERT(saved_args_desc_var == NULL); | 945 ASSERT(saved_args_desc_var == NULL); |
928 } else { | 946 } else { |
929 if (saved_args_desc_var != NULL) { | 947 if (saved_args_desc_var != NULL) { |
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1399 __ popl(ECX); | 1417 __ popl(ECX); |
1400 __ popl(EAX); | 1418 __ popl(EAX); |
1401 } | 1419 } |
1402 | 1420 |
1403 | 1421 |
1404 #undef __ | 1422 #undef __ |
1405 | 1423 |
1406 } // namespace dart | 1424 } // namespace dart |
1407 | 1425 |
1408 #endif // defined TARGET_ARCH_IA32 | 1426 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |