| 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 |