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 772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
783 | 783 |
784 | 784 |
785 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | 785 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
786 Comment cmnt(masm_, "[ VariableProxy"); | 786 Comment cmnt(masm_, "[ VariableProxy"); |
787 EmitVariableLoad(expr->var(), context_); | 787 EmitVariableLoad(expr->var(), context_); |
788 } | 788 } |
789 | 789 |
790 | 790 |
791 void FullCodeGenerator::EmitVariableLoad(Variable* var, | 791 void FullCodeGenerator::EmitVariableLoad(Variable* var, |
792 Expression::Context context) { | 792 Expression::Context context) { |
793 Expression* rewrite = var->rewrite(); | 793 // Four cases: non-this global variables, lookup slots, all other |
794 if (rewrite == NULL) { | 794 // types of slots, and parameters that rewrite to explicit property |
795 ASSERT(var->is_global()); | 795 // accesses on the arguments object. |
| 796 Slot* slot = var->slot(); |
| 797 Property* property = var->AsProperty(); |
| 798 |
| 799 if (var->is_global() && !var->is_this()) { |
796 Comment cmnt(masm_, "Global variable"); | 800 Comment cmnt(masm_, "Global variable"); |
797 // Use inline caching. Variable name is passed in rcx and the global | 801 // Use inline caching. Variable name is passed in rcx and the global |
798 // object on the stack. | 802 // object on the stack. |
799 __ push(CodeGenerator::GlobalObject()); | 803 __ push(CodeGenerator::GlobalObject()); |
800 __ Move(rcx, var->name()); | 804 __ Move(rcx, var->name()); |
801 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 805 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
802 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 806 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
803 // A test rax instruction following the call is used by the IC to | 807 // A test rax instruction following the call is used by the IC to |
804 // indicate that the inobject property case was inlined. Ensure there | 808 // indicate that the inobject property case was inlined. Ensure there |
805 // is no test rax instruction here. | 809 // is no test rax instruction here. |
806 __ nop(); | 810 __ nop(); |
807 DropAndApply(1, context, rax); | 811 DropAndApply(1, context, rax); |
808 } else if (rewrite->AsSlot() != NULL) { | 812 |
809 Slot* slot = rewrite->AsSlot(); | 813 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
810 if (FLAG_debug_code) { | 814 Comment cmnt(masm_, "Lookup slot"); |
811 switch (slot->type()) { | 815 __ push(rsi); // Context. |
812 case Slot::PARAMETER: | 816 __ Push(var->name()); |
813 case Slot::LOCAL: { | 817 __ CallRuntime(Runtime::kLoadContextSlot, 2); |
814 Comment cmnt(masm_, "Stack slot"); | 818 Apply(context, rax); |
815 break; | 819 |
816 } | 820 } else if (slot != NULL) { |
817 case Slot::CONTEXT: { | 821 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT) |
818 Comment cmnt(masm_, "Context slot"); | 822 ? "Context slot" |
819 break; | 823 : "Stack slot"); |
820 } | |
821 case Slot::LOOKUP: | |
822 UNIMPLEMENTED(); | |
823 break; | |
824 } | |
825 } | |
826 Apply(context, slot); | 824 Apply(context, slot); |
| 825 |
827 } else { | 826 } else { |
828 Comment cmnt(masm_, "Variable rewritten to property"); | 827 Comment cmnt(masm_, "Rewritten parameter"); |
829 // A variable has been rewritten into an explicit access to an object | |
830 // property. | |
831 Property* property = rewrite->AsProperty(); | |
832 ASSERT_NOT_NULL(property); | 828 ASSERT_NOT_NULL(property); |
833 | 829 // Rewritten parameter accesses are of the form "slot[literal]". |
834 // The only property expressions that can occur are of the form | |
835 // "slot[literal]". | |
836 | 830 |
837 // Assert that the object is in a slot. | 831 // Assert that the object is in a slot. |
838 Variable* object_var = property->obj()->AsVariableProxy()->AsVariable(); | 832 Variable* object_var = property->obj()->AsVariableProxy()->AsVariable(); |
839 ASSERT_NOT_NULL(object_var); | 833 ASSERT_NOT_NULL(object_var); |
840 Slot* object_slot = object_var->slot(); | 834 Slot* object_slot = object_var->slot(); |
841 ASSERT_NOT_NULL(object_slot); | 835 ASSERT_NOT_NULL(object_slot); |
842 | 836 |
843 // Load the object. | 837 // Load the object. |
844 MemOperand object_loc = EmitSlotSearch(object_slot, rax); | 838 MemOperand object_loc = EmitSlotSearch(object_slot, rax); |
845 __ push(object_loc); | 839 __ push(object_loc); |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1034 GenericBinaryOpStub stub(op, | 1028 GenericBinaryOpStub stub(op, |
1035 NO_OVERWRITE, | 1029 NO_OVERWRITE, |
1036 NO_GENERIC_BINARY_FLAGS); | 1030 NO_GENERIC_BINARY_FLAGS); |
1037 __ CallStub(&stub); | 1031 __ CallStub(&stub); |
1038 Apply(context, rax); | 1032 Apply(context, rax); |
1039 } | 1033 } |
1040 | 1034 |
1041 | 1035 |
1042 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1036 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
1043 Expression::Context context) { | 1037 Expression::Context context) { |
| 1038 // Three main cases: non-this global variables, lookup slots, and |
| 1039 // all other types of slots. Left-hand-side parameters that rewrite |
| 1040 // to explicit property accesses do not reach here. |
1044 ASSERT(var != NULL); | 1041 ASSERT(var != NULL); |
1045 ASSERT(var->is_global() || var->slot() != NULL); | 1042 ASSERT(var->is_global() || var->slot() != NULL); |
| 1043 Slot* slot = var->slot(); |
1046 if (var->is_global()) { | 1044 if (var->is_global()) { |
| 1045 ASSERT(!var->is_this()); |
1047 // Assignment to a global variable. Use inline caching for the | 1046 // Assignment to a global variable. Use inline caching for the |
1048 // assignment. Right-hand-side value is passed in rax, variable name in | 1047 // assignment. Right-hand-side value is passed in rax, variable name in |
1049 // rcx, and the global object on the stack. | 1048 // rcx, and the global object on the stack. |
1050 __ Move(rcx, var->name()); | 1049 __ Move(rcx, var->name()); |
1051 __ push(CodeGenerator::GlobalObject()); | 1050 __ push(CodeGenerator::GlobalObject()); |
1052 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1051 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
1053 __ Call(ic, RelocInfo::CODE_TARGET); | 1052 __ Call(ic, RelocInfo::CODE_TARGET); |
1054 // Overwrite the global object on the stack with the result if needed. | 1053 // Overwrite the global object on the stack with the result if needed. |
1055 DropAndApply(1, context, rax); | 1054 DropAndApply(1, context, rax); |
1056 | 1055 |
| 1056 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
| 1057 __ push(result_register()); // Value. |
| 1058 __ push(rsi); // Context. |
| 1059 __ Push(var->name()); |
| 1060 __ CallRuntime(Runtime::kStoreContextSlot, 3); |
| 1061 Apply(context, rax); |
| 1062 |
1057 } else if (var->slot() != NULL) { | 1063 } else if (var->slot() != NULL) { |
1058 Slot* slot = var->slot(); | |
1059 switch (slot->type()) { | 1064 switch (slot->type()) { |
1060 case Slot::LOCAL: | 1065 case Slot::LOCAL: |
1061 case Slot::PARAMETER: | 1066 case Slot::PARAMETER: |
1062 __ movq(Operand(rbp, SlotOffset(slot)), result_register()); | 1067 __ movq(Operand(rbp, SlotOffset(slot)), result_register()); |
1063 break; | 1068 break; |
1064 | 1069 |
1065 case Slot::CONTEXT: { | 1070 case Slot::CONTEXT: { |
1066 MemOperand target = EmitSlotSearch(slot, rcx); | 1071 MemOperand target = EmitSlotSearch(slot, rcx); |
1067 __ movq(target, result_register()); | 1072 __ movq(target, result_register()); |
1068 | 1073 |
1069 // RecordWrite may destroy all its register arguments. | 1074 // RecordWrite may destroy all its register arguments. |
1070 __ movq(rdx, result_register()); | 1075 __ movq(rdx, result_register()); |
1071 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; | 1076 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; |
1072 __ RecordWrite(rcx, offset, rdx, rbx); | 1077 __ RecordWrite(rcx, offset, rdx, rbx); |
1073 break; | 1078 break; |
1074 } | 1079 } |
1075 | 1080 |
1076 case Slot::LOOKUP: | 1081 case Slot::LOOKUP: |
1077 UNREACHABLE(); | 1082 UNREACHABLE(); |
1078 break; | 1083 break; |
1079 } | 1084 } |
1080 Apply(context, result_register()); | 1085 Apply(context, result_register()); |
| 1086 |
1081 } else { | 1087 } else { |
1082 // Variables rewritten as properties are not treated as variables in | 1088 // Variables rewritten as properties are not treated as variables in |
1083 // assignments. | 1089 // assignments. |
1084 UNREACHABLE(); | 1090 UNREACHABLE(); |
1085 } | 1091 } |
1086 } | 1092 } |
1087 | 1093 |
1088 | 1094 |
1089 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 1095 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
1090 // Assignment to a property, using a named store IC. | 1096 // Assignment to a property, using a named store IC. |
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1843 __ movq(Operand(rsp, 0), rdx); | 1849 __ movq(Operand(rsp, 0), rdx); |
1844 // And return. | 1850 // And return. |
1845 __ ret(0); | 1851 __ ret(0); |
1846 } | 1852 } |
1847 | 1853 |
1848 | 1854 |
1849 #undef __ | 1855 #undef __ |
1850 | 1856 |
1851 | 1857 |
1852 } } // namespace v8::internal | 1858 } } // namespace v8::internal |
OLD | NEW |