OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 // Load this again, if it's used by the local context below. | 118 // Load this again, if it's used by the local context below. |
119 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 119 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
120 } else { | 120 } else { |
121 __ mov(r3, r1); | 121 __ mov(r3, r1); |
122 } | 122 } |
123 // Receiver is just before the parameters on the caller's stack. | 123 // Receiver is just before the parameters on the caller's stack. |
124 int offset = scope()->num_parameters() * kPointerSize; | 124 int offset = scope()->num_parameters() * kPointerSize; |
125 __ add(r2, fp, | 125 __ add(r2, fp, |
126 Operand(StandardFrameConstants::kCallerSPOffset + offset)); | 126 Operand(StandardFrameConstants::kCallerSPOffset + offset)); |
127 __ mov(r1, Operand(Smi::FromInt(scope()->num_parameters()))); | 127 __ mov(r1, Operand(Smi::FromInt(scope()->num_parameters()))); |
128 __ stm(db_w, sp, r3.bit() | r2.bit() | r1.bit()); | 128 __ Push(r3, r2, r1); |
129 | 129 |
130 // Arguments to ArgumentsAccessStub: | 130 // Arguments to ArgumentsAccessStub: |
131 // function, receiver address, parameter count. | 131 // function, receiver address, parameter count. |
132 // The stub will rewrite receiever and parameter count if the previous | 132 // The stub will rewrite receiever and parameter count if the previous |
133 // stack frame was an arguments adapter frame. | 133 // stack frame was an arguments adapter frame. |
134 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); | 134 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); |
135 __ CallStub(&stub); | 135 __ CallStub(&stub); |
136 // Duplicate the value; move-to-slot operation might clobber registers. | 136 // Duplicate the value; move-to-slot operation might clobber registers. |
137 __ mov(r3, r0); | 137 __ mov(r3, r0); |
138 Move(arguments->slot(), r0, r1, r2); | 138 Move(arguments->slot(), r0, r1, r2); |
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 // Four cases: non-this global variables, lookup slots, all other | 689 // Four cases: non-this global variables, lookup slots, all other |
690 // types of slots, and parameters that rewrite to explicit property | 690 // types of slots, and parameters that rewrite to explicit property |
691 // accesses on the arguments object. | 691 // accesses on the arguments object. |
692 Slot* slot = var->slot(); | 692 Slot* slot = var->slot(); |
693 Property* property = var->AsProperty(); | 693 Property* property = var->AsProperty(); |
694 | 694 |
695 if (var->is_global() && !var->is_this()) { | 695 if (var->is_global() && !var->is_this()) { |
696 Comment cmnt(masm_, "Global variable"); | 696 Comment cmnt(masm_, "Global variable"); |
697 // Use inline caching. Variable name is passed in r2 and the global | 697 // Use inline caching. Variable name is passed in r2 and the global |
698 // object on the stack. | 698 // object on the stack. |
699 __ ldr(ip, CodeGenerator::GlobalObject()); | 699 __ ldr(r0, CodeGenerator::GlobalObject()); |
700 __ push(ip); | 700 __ push(r0); |
701 __ mov(r2, Operand(var->name())); | 701 __ mov(r2, Operand(var->name())); |
702 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 702 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
703 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 703 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
704 DropAndApply(1, context, r0); | 704 DropAndApply(1, context, r0); |
705 | 705 |
706 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { | 706 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
707 Comment cmnt(masm_, "Lookup slot"); | 707 Comment cmnt(masm_, "Lookup slot"); |
708 __ mov(r1, Operand(var->name())); | 708 __ mov(r1, Operand(var->name())); |
709 __ stm(db_w, sp, cp.bit() | r1.bit()); // Context and name. | 709 __ stm(db_w, sp, cp.bit() | r1.bit()); // Context and name. |
710 __ CallRuntime(Runtime::kLoadContextSlot, 2); | 710 __ CallRuntime(Runtime::kLoadContextSlot, 2); |
(...skipping 21 matching lines...) Expand all Loading... |
732 | 732 |
733 // Assert that the key is a smi. | 733 // Assert that the key is a smi. |
734 Literal* key_literal = property->key()->AsLiteral(); | 734 Literal* key_literal = property->key()->AsLiteral(); |
735 ASSERT_NOT_NULL(key_literal); | 735 ASSERT_NOT_NULL(key_literal); |
736 ASSERT(key_literal->handle()->IsSmi()); | 736 ASSERT(key_literal->handle()->IsSmi()); |
737 | 737 |
738 // Load the key. | 738 // Load the key. |
739 __ mov(r1, Operand(key_literal->handle())); | 739 __ mov(r1, Operand(key_literal->handle())); |
740 | 740 |
741 // Push both as arguments to ic. | 741 // Push both as arguments to ic. |
742 __ stm(db_w, sp, r2.bit() | r1.bit()); | 742 __ Push(r2, r1); |
743 | 743 |
744 // Do a keyed property load. | 744 // Do a keyed property load. |
745 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 745 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
746 __ Call(ic, RelocInfo::CODE_TARGET); | 746 __ Call(ic, RelocInfo::CODE_TARGET); |
747 | 747 |
748 // Drop key and object left on the stack by IC, and push the result. | 748 // Drop key and object left on the stack by IC, and push the result. |
749 DropAndApply(2, context, r0); | 749 DropAndApply(2, context, r0); |
750 } | 750 } |
751 } | 751 } |
752 | 752 |
(...skipping 11 matching lines...) Expand all Loading... |
764 __ ldr(r4, FieldMemOperand(r0, JSFunction::kLiteralsOffset)); | 764 __ ldr(r4, FieldMemOperand(r0, JSFunction::kLiteralsOffset)); |
765 int literal_offset = | 765 int literal_offset = |
766 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; | 766 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; |
767 __ ldr(r0, FieldMemOperand(r4, literal_offset)); | 767 __ ldr(r0, FieldMemOperand(r4, literal_offset)); |
768 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 768 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
769 __ cmp(r0, ip); | 769 __ cmp(r0, ip); |
770 __ b(ne, &done); | 770 __ b(ne, &done); |
771 __ mov(r3, Operand(Smi::FromInt(expr->literal_index()))); | 771 __ mov(r3, Operand(Smi::FromInt(expr->literal_index()))); |
772 __ mov(r2, Operand(expr->pattern())); | 772 __ mov(r2, Operand(expr->pattern())); |
773 __ mov(r1, Operand(expr->flags())); | 773 __ mov(r1, Operand(expr->flags())); |
774 __ stm(db_w, sp, r4.bit() | r3.bit() | r2.bit() | r1.bit()); | 774 __ Push(r4, r3, r2, r1); |
775 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); | 775 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); |
776 __ bind(&done); | 776 __ bind(&done); |
777 Apply(context_, r0); | 777 Apply(context_, r0); |
778 } | 778 } |
779 | 779 |
780 | 780 |
781 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { | 781 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
782 Comment cmnt(masm_, "[ ObjectLiteral"); | 782 Comment cmnt(masm_, "[ ObjectLiteral"); |
783 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 783 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
784 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); | 784 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); |
785 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); | 785 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); |
786 __ mov(r1, Operand(expr->constant_properties())); | 786 __ mov(r1, Operand(expr->constant_properties())); |
787 __ mov(r0, Operand(Smi::FromInt(expr->fast_elements() ? 1 : 0))); | 787 __ mov(r0, Operand(Smi::FromInt(expr->fast_elements() ? 1 : 0))); |
788 __ stm(db_w, sp, r3.bit() | r2.bit() | r1.bit() | r0.bit()); | 788 __ Push(r3, r2, r1, r0); |
789 if (expr->depth() > 1) { | 789 if (expr->depth() > 1) { |
790 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); | 790 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); |
791 } else { | 791 } else { |
792 __ CallRuntime(Runtime::kCreateObjectLiteralShallow, 4); | 792 __ CallRuntime(Runtime::kCreateObjectLiteralShallow, 4); |
793 } | 793 } |
794 | 794 |
795 // If result_saved is true the result is on top of the stack. If | 795 // If result_saved is true the result is on top of the stack. If |
796 // result_saved is false the result is in r0. | 796 // result_saved is false the result is in r0. |
797 bool result_saved = false; | 797 bool result_saved = false; |
798 | 798 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
853 } | 853 } |
854 } | 854 } |
855 | 855 |
856 | 856 |
857 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 857 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
858 Comment cmnt(masm_, "[ ArrayLiteral"); | 858 Comment cmnt(masm_, "[ ArrayLiteral"); |
859 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 859 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
860 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); | 860 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); |
861 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); | 861 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); |
862 __ mov(r1, Operand(expr->constant_elements())); | 862 __ mov(r1, Operand(expr->constant_elements())); |
863 __ stm(db_w, sp, r3.bit() | r2.bit() | r1.bit()); | 863 __ Push(r3, r2, r1); |
864 if (expr->depth() > 1) { | 864 if (expr->depth() > 1) { |
865 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); | 865 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); |
866 } else { | 866 } else { |
867 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); | 867 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); |
868 } | 868 } |
869 | 869 |
870 bool result_saved = false; // Is the result saved to the stack? | 870 bool result_saved = false; // Is the result saved to the stack? |
871 | 871 |
872 // Emit code to evaluate all the non-constant subexpressions and to store | 872 // Emit code to evaluate all the non-constant subexpressions and to store |
873 // them into the newly cloned array. | 873 // them into the newly cloned array. |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
990 EmitKeyedPropertyAssignment(expr); | 990 EmitKeyedPropertyAssignment(expr); |
991 break; | 991 break; |
992 } | 992 } |
993 } | 993 } |
994 | 994 |
995 | 995 |
996 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 996 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
997 SetSourcePosition(prop->position()); | 997 SetSourcePosition(prop->position()); |
998 Literal* key = prop->key()->AsLiteral(); | 998 Literal* key = prop->key()->AsLiteral(); |
999 __ mov(r2, Operand(key->handle())); | 999 __ mov(r2, Operand(key->handle())); |
| 1000 __ ldr(r0, MemOperand(sp, 0)); |
1000 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1001 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
1001 __ Call(ic, RelocInfo::CODE_TARGET); | 1002 __ Call(ic, RelocInfo::CODE_TARGET); |
1002 } | 1003 } |
1003 | 1004 |
1004 | 1005 |
1005 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1006 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
1006 SetSourcePosition(prop->position()); | 1007 SetSourcePosition(prop->position()); |
1007 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1008 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
1008 __ Call(ic, RelocInfo::CODE_TARGET); | 1009 __ Call(ic, RelocInfo::CODE_TARGET); |
1009 } | 1010 } |
(...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1853 __ pop(result_register()); | 1854 __ pop(result_register()); |
1854 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); | 1855 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); |
1855 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 1856 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
1856 __ add(pc, r1, Operand(masm_->CodeObject())); | 1857 __ add(pc, r1, Operand(masm_->CodeObject())); |
1857 } | 1858 } |
1858 | 1859 |
1859 | 1860 |
1860 #undef __ | 1861 #undef __ |
1861 | 1862 |
1862 } } // namespace v8::internal | 1863 } } // namespace v8::internal |
OLD | NEW |