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" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 __ pushl(ECX); // Element type. | 693 __ pushl(ECX); // Element type. |
694 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); | 694 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); |
695 __ popl(EAX); // Pop element type argument. | 695 __ popl(EAX); // Pop element type argument. |
696 __ popl(EDX); // Pop array length argument. | 696 __ popl(EDX); // Pop array length argument. |
697 __ popl(EAX); // Pop return value from return slot. | 697 __ popl(EAX); // Pop return value from return slot. |
698 __ LeaveFrame(); | 698 __ LeaveFrame(); |
699 __ ret(); | 699 __ ret(); |
700 } | 700 } |
701 | 701 |
702 | 702 |
703 // Input parameters: | |
704 // EDX: Arguments descriptor array. | |
705 // Note: The closure object is the first argument to the function being | |
706 // called, the stub accesses the closure from this location directly | |
707 // when trying to resolve the call. | |
708 // Uses EDI. | |
709 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) { | |
710 const Immediate& raw_null = | |
711 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
712 | |
713 // Load num_args. | |
714 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | |
715 // Load closure object in EDI. | |
716 __ movl(EDI, Address(ESP, EAX, TIMES_2, 0)); // EAX is a Smi. | |
717 | |
718 // Verify that EDI is a closure by checking its class. | |
719 Label not_closure; | |
720 __ cmpl(EDI, raw_null); | |
721 // Not a closure, but null object. | |
722 __ j(EQUAL, ¬_closure, Assembler::kNearJump); | |
723 __ testl(EDI, Immediate(kSmiTagMask)); | |
724 __ j(ZERO, ¬_closure, Assembler::kNearJump); // Not a closure, but a smi. | |
725 // Verify that the class of the object is a closure class by checking that | |
726 // class.signature_function() is not null. | |
727 __ LoadClass(EAX, EDI, ECX); | |
728 __ movl(EAX, FieldAddress(EAX, Class::signature_function_offset())); | |
729 __ cmpl(EAX, raw_null); | |
730 // Actual class is not a closure class. | |
731 __ j(EQUAL, ¬_closure, Assembler::kNearJump); | |
732 | |
733 // EAX is just the signature function. Load the actual closure function. | |
734 __ movl(EAX, FieldAddress(EDI, Closure::function_offset())); | |
735 | |
736 // Load closure context in CTX; note that CTX has already been preserved. | |
737 __ movl(CTX, FieldAddress(EDI, Closure::context_offset())); | |
738 | |
739 // EBX: Code (compiled code or lazy compile stub). | |
740 __ movl(EBX, FieldAddress(EAX, Function::code_offset())); | |
741 | |
742 // EAX: Function. | |
743 // EDX: Arguments descriptor array. | |
744 // ECX: Smi 0 (no IC data; the lazy-compile stub expects a GC-safe value). | |
745 __ xorl(ECX, ECX); | |
746 __ movl(EBX, FieldAddress(EBX, Code::instructions_offset())); | |
747 __ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | |
748 __ jmp(EBX); | |
749 | |
750 __ Bind(¬_closure); | |
751 // Call runtime to attempt to resolve and invoke a call method on a | |
752 // non-closure object, passing the non-closure object and its arguments array, | |
753 // returning here. | |
754 // If no call method exists, throw a NoSuchMethodError. | |
755 // EDI: non-closure object. | |
756 // EDX: arguments descriptor array. | |
757 | |
758 // Create a stub frame as we are pushing some objects on the stack before | |
759 // calling into the runtime. | |
760 __ EnterStubFrame(); | |
761 | |
762 __ pushl(raw_null); // Setup space on stack for result from error reporting. | |
763 __ pushl(EDX); // Arguments descriptor. | |
764 // Load smi-tagged arguments array length, including the non-closure. | |
765 __ movl(EDX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | |
766 PushArgumentsArray(assembler); | |
767 | |
768 __ CallRuntime(kInvokeNonClosureRuntimeEntry, 2); | |
769 // Remove arguments. | |
770 __ Drop(2); | |
771 __ popl(EAX); // Get result into EAX. | |
772 | |
773 // Remove the stub frame as we are about to return. | |
774 __ LeaveFrame(); | |
775 __ ret(); | |
776 } | |
777 | |
778 | |
779 // Called when invoking dart code from C++ (VM code). | 703 // Called when invoking dart code from C++ (VM code). |
780 // Input parameters: | 704 // Input parameters: |
781 // ESP : points to return address. | 705 // ESP : points to return address. |
782 // ESP + 4 : entrypoint of the dart function to call. | 706 // ESP + 4 : entrypoint of the dart function to call. |
783 // ESP + 8 : arguments descriptor array. | 707 // ESP + 8 : arguments descriptor array. |
784 // ESP + 12 : arguments array. | 708 // ESP + 12 : arguments array. |
785 // ESP + 16 : new context containing the current isolate pointer. | 709 // ESP + 16 : new context containing the current isolate pointer. |
786 // Uses EAX, EDX, ECX, EDI as temporary registers. | 710 // Uses EAX, EDX, ECX, EDI as temporary registers. |
787 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { | 711 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { |
788 const intptr_t kEntryPointOffset = 2 * kWordSize; | 712 const intptr_t kEntryPointOffset = 2 * kWordSize; |
(...skipping 1151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1940 const Register temp = ECX; | 1864 const Register temp = ECX; |
1941 __ movl(left, Address(ESP, 2 * kWordSize)); | 1865 __ movl(left, Address(ESP, 2 * kWordSize)); |
1942 __ movl(right, Address(ESP, 1 * kWordSize)); | 1866 __ movl(right, Address(ESP, 1 * kWordSize)); |
1943 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 1867 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
1944 __ ret(); | 1868 __ ret(); |
1945 } | 1869 } |
1946 | 1870 |
1947 } // namespace dart | 1871 } // namespace dart |
1948 | 1872 |
1949 #endif // defined TARGET_ARCH_IA32 | 1873 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |