OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 20 matching lines...) Expand all Loading... |
31 #include "debug.h" | 31 #include "debug.h" |
32 #include "runtime.h" | 32 #include "runtime.h" |
33 | 33 |
34 namespace v8 { | 34 namespace v8 { |
35 namespace internal { | 35 namespace internal { |
36 | 36 |
37 | 37 |
38 #define __ ACCESS_MASM(masm) | 38 #define __ ACCESS_MASM(masm) |
39 | 39 |
40 | 40 |
41 void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) { | 41 void Builtins::Generate_Adaptor(MacroAssembler* masm, |
42 // TODO(428): Don't pass the function in a static variable. | 42 CFunctionId id, |
43 __ mov(ip, Operand(ExternalReference::builtin_passed_function())); | 43 BuiltinExtraArguments extra_args) { |
44 __ str(r1, MemOperand(ip, 0)); | 44 // ----------- S t a t e ------------- |
| 45 // -- r0 : number of arguments excluding receiver |
| 46 // -- r1 : called function (only guaranteed when |
| 47 // extra_args requires it) |
| 48 // -- cp : context |
| 49 // -- sp[0] : last argument |
| 50 // -- ... |
| 51 // -- sp[4 * (argc - 1)] : first argument (argc == r0) |
| 52 // -- sp[4 * argc] : receiver |
| 53 // ----------------------------------- |
45 | 54 |
46 // The actual argument count has already been loaded into register | 55 // Insert extra arguments. |
47 // r0, but JumpToRuntime expects r0 to contain the number of | 56 int num_extra_args = 0; |
48 // arguments including the receiver. | 57 if (extra_args == NEEDS_CALLED_FUNCTION) { |
49 __ add(r0, r0, Operand(1)); | 58 num_extra_args = 1; |
| 59 __ push(r1); |
| 60 } else { |
| 61 ASSERT(extra_args == NO_EXTRA_ARGUMENTS); |
| 62 } |
| 63 |
| 64 // JumpToRuntime expects r0 to contain the number of arguments |
| 65 // including the receiver and the extra arguments. |
| 66 __ add(r0, r0, Operand(num_extra_args + 1)); |
50 __ JumpToRuntime(ExternalReference(id)); | 67 __ JumpToRuntime(ExternalReference(id)); |
51 } | 68 } |
52 | 69 |
53 | 70 |
54 // Load the built-in Array function from the current context. | 71 // Load the built-in Array function from the current context. |
55 static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) { | 72 static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) { |
56 // Load the global context. | 73 // Load the global context. |
57 | 74 |
58 __ ldr(result, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); | 75 __ ldr(result, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); |
59 __ ldr(result, | 76 __ ldr(result, |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 __ bind(&non_function_call); | 501 __ bind(&non_function_call); |
485 | 502 |
486 // Set expected number of arguments to zero (not changing r0). | 503 // Set expected number of arguments to zero (not changing r0). |
487 __ mov(r2, Operand(0)); | 504 __ mov(r2, Operand(0)); |
488 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); | 505 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); |
489 __ Jump(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), | 506 __ Jump(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), |
490 RelocInfo::CODE_TARGET); | 507 RelocInfo::CODE_TARGET); |
491 } | 508 } |
492 | 509 |
493 | 510 |
494 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { | 511 static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
| 512 bool is_api_function) { |
495 // Enter a construct frame. | 513 // Enter a construct frame. |
496 __ EnterConstructFrame(); | 514 __ EnterConstructFrame(); |
497 | 515 |
498 // Preserve the two incoming parameters on the stack. | 516 // Preserve the two incoming parameters on the stack. |
499 __ mov(r0, Operand(r0, LSL, kSmiTagSize)); | 517 __ mov(r0, Operand(r0, LSL, kSmiTagSize)); |
500 __ push(r0); // Smi-tagged arguments count. | 518 __ push(r0); // Smi-tagged arguments count. |
501 __ push(r1); // Constructor function. | 519 __ push(r1); // Constructor function. |
502 | 520 |
503 // Use r7 for holding undefined which is used in several places below. | 521 // Use r7 for holding undefined which is used in several places below. |
504 __ LoadRoot(r7, Heap::kUndefinedValueRootIndex); | 522 __ LoadRoot(r7, Heap::kUndefinedValueRootIndex); |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
720 __ bind(&loop); | 738 __ bind(&loop); |
721 __ ldr(ip, MemOperand(r2, r3, LSL, kPointerSizeLog2 - 1)); | 739 __ ldr(ip, MemOperand(r2, r3, LSL, kPointerSizeLog2 - 1)); |
722 __ push(ip); | 740 __ push(ip); |
723 __ bind(&entry); | 741 __ bind(&entry); |
724 __ sub(r3, r3, Operand(2), SetCC); | 742 __ sub(r3, r3, Operand(2), SetCC); |
725 __ b(ge, &loop); | 743 __ b(ge, &loop); |
726 | 744 |
727 // Call the function. | 745 // Call the function. |
728 // r0: number of arguments | 746 // r0: number of arguments |
729 // r1: constructor function | 747 // r1: constructor function |
730 ParameterCount actual(r0); | 748 if (is_api_function) { |
731 __ InvokeFunction(r1, actual, CALL_FUNCTION); | 749 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
| 750 Handle<Code> code = Handle<Code>( |
| 751 Builtins::builtin(Builtins::HandleApiCallConstruct)); |
| 752 ParameterCount expected(0); |
| 753 __ InvokeCode(code, expected, expected, |
| 754 RelocInfo::CODE_TARGET, CALL_FUNCTION); |
| 755 } else { |
| 756 ParameterCount actual(r0); |
| 757 __ InvokeFunction(r1, actual, CALL_FUNCTION); |
| 758 } |
732 | 759 |
733 // Pop the function from the stack. | 760 // Pop the function from the stack. |
734 // sp[0]: constructor function | 761 // sp[0]: constructor function |
735 // sp[2]: receiver | 762 // sp[2]: receiver |
736 // sp[3]: constructor function | 763 // sp[3]: constructor function |
737 // sp[4]: number of arguments (smi-tagged) | 764 // sp[4]: number of arguments (smi-tagged) |
738 __ pop(); | 765 __ pop(); |
739 | 766 |
740 // Restore context from the frame. | 767 // Restore context from the frame. |
741 // r0: result | 768 // r0: result |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
776 // sp[2]: number of arguments (smi-tagged) | 803 // sp[2]: number of arguments (smi-tagged) |
777 __ ldr(r1, MemOperand(sp, 2 * kPointerSize)); | 804 __ ldr(r1, MemOperand(sp, 2 * kPointerSize)); |
778 __ LeaveConstructFrame(); | 805 __ LeaveConstructFrame(); |
779 __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - 1)); | 806 __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - 1)); |
780 __ add(sp, sp, Operand(kPointerSize)); | 807 __ add(sp, sp, Operand(kPointerSize)); |
781 __ IncrementCounter(&Counters::constructed_objects, 1, r1, r2); | 808 __ IncrementCounter(&Counters::constructed_objects, 1, r1, r2); |
782 __ Jump(lr); | 809 __ Jump(lr); |
783 } | 810 } |
784 | 811 |
785 | 812 |
| 813 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { |
| 814 Generate_JSConstructStubHelper(masm, false); |
| 815 } |
| 816 |
| 817 |
| 818 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { |
| 819 Generate_JSConstructStubHelper(masm, true); |
| 820 } |
| 821 |
| 822 |
786 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 823 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
787 bool is_construct) { | 824 bool is_construct) { |
788 // Called from Generate_JS_Entry | 825 // Called from Generate_JS_Entry |
789 // r0: code entry | 826 // r0: code entry |
790 // r1: function | 827 // r1: function |
791 // r2: receiver | 828 // r2: receiver |
792 // r3: argc | 829 // r3: argc |
793 // r4: argv | 830 // r4: argv |
794 // r5-r7, cp may be clobbered | 831 // r5-r7, cp may be clobbered |
795 | 832 |
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1262 // Dont adapt arguments. | 1299 // Dont adapt arguments. |
1263 // ------------------------------------------- | 1300 // ------------------------------------------- |
1264 __ bind(&dont_adapt_arguments); | 1301 __ bind(&dont_adapt_arguments); |
1265 __ Jump(r3); | 1302 __ Jump(r3); |
1266 } | 1303 } |
1267 | 1304 |
1268 | 1305 |
1269 #undef __ | 1306 #undef __ |
1270 | 1307 |
1271 } } // namespace v8::internal | 1308 } } // namespace v8::internal |
OLD | NEW |