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 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
780 | 780 |
781 | 781 |
782 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | 782 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
783 Comment cmnt(masm_, "[ VariableProxy"); | 783 Comment cmnt(masm_, "[ VariableProxy"); |
784 EmitVariableLoad(expr->var(), context_); | 784 EmitVariableLoad(expr->var(), context_); |
785 } | 785 } |
786 | 786 |
787 | 787 |
788 void FullCodeGenerator::EmitVariableLoad(Variable* var, | 788 void FullCodeGenerator::EmitVariableLoad(Variable* var, |
789 Expression::Context context) { | 789 Expression::Context context) { |
790 Expression* rewrite = var->rewrite(); | 790 // Four cases: non-this global variables, lookup slots, all other |
791 if (rewrite == NULL) { | 791 // types of slots, and parameters that rewrite to explicit property |
792 ASSERT(var->is_global()); | 792 // accesses on the arguments object. |
| 793 Slot* slot = var->slot(); |
| 794 Property* property = var->AsProperty(); |
| 795 |
| 796 if (var->is_global() && !var->is_this()) { |
793 Comment cmnt(masm_, "Global variable"); | 797 Comment cmnt(masm_, "Global variable"); |
794 // Use inline caching. Variable name is passed in ecx and the global | 798 // Use inline caching. Variable name is passed in ecx and the global |
795 // object on the stack. | 799 // object on the stack. |
796 __ push(CodeGenerator::GlobalObject()); | 800 __ push(CodeGenerator::GlobalObject()); |
797 __ mov(ecx, var->name()); | 801 __ mov(ecx, var->name()); |
798 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 802 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
799 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 803 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
800 // By emitting a nop we make sure that we do not have a test eax | 804 // By emitting a nop we make sure that we do not have a test eax |
801 // instruction after the call it is treated specially by the LoadIC code | 805 // instruction after the call it is treated specially by the LoadIC code |
802 // Remember that the assembler may choose to do peephole optimization | 806 // Remember that the assembler may choose to do peephole optimization |
803 // (eg, push/pop elimination). | 807 // (eg, push/pop elimination). |
804 __ nop(); | 808 __ nop(); |
805 DropAndApply(1, context, eax); | 809 DropAndApply(1, context, eax); |
806 } else if (rewrite->AsSlot() != NULL) { | 810 |
807 Slot* slot = rewrite->AsSlot(); | 811 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
808 if (FLAG_debug_code) { | 812 Comment cmnt(masm_, "Lookup slot"); |
809 switch (slot->type()) { | 813 __ push(esi); // Context. |
810 case Slot::PARAMETER: | 814 __ push(Immediate(var->name())); |
811 case Slot::LOCAL: { | 815 __ CallRuntime(Runtime::kLoadContextSlot, 2); |
812 Comment cmnt(masm_, "Stack slot"); | 816 Apply(context, eax); |
813 break; | 817 |
814 } | 818 } else if (slot != NULL) { |
815 case Slot::CONTEXT: { | 819 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT) |
816 Comment cmnt(masm_, "Context slot"); | 820 ? "Context slot" |
817 break; | 821 : "Stack slot"); |
818 } | |
819 case Slot::LOOKUP: | |
820 UNIMPLEMENTED(); | |
821 break; | |
822 } | |
823 } | |
824 Apply(context, slot); | 822 Apply(context, slot); |
| 823 |
825 } else { | 824 } else { |
826 Comment cmnt(masm_, "Variable rewritten to property"); | 825 Comment cmnt(masm_, "Rewritten parameter"); |
827 // A variable has been rewritten into an explicit access to an object | |
828 // property. | |
829 Property* property = rewrite->AsProperty(); | |
830 ASSERT_NOT_NULL(property); | 826 ASSERT_NOT_NULL(property); |
831 | 827 // Rewritten parameter accesses are of the form "slot[literal]". |
832 // The only property expressions that can occur are of the form | |
833 // "slot[literal]". | |
834 | 828 |
835 // Assert that the object is in a slot. | 829 // Assert that the object is in a slot. |
836 Variable* object_var = property->obj()->AsVariableProxy()->AsVariable(); | 830 Variable* object_var = property->obj()->AsVariableProxy()->AsVariable(); |
837 ASSERT_NOT_NULL(object_var); | 831 ASSERT_NOT_NULL(object_var); |
838 Slot* object_slot = object_var->slot(); | 832 Slot* object_slot = object_var->slot(); |
839 ASSERT_NOT_NULL(object_slot); | 833 ASSERT_NOT_NULL(object_slot); |
840 | 834 |
841 // Load the object. | 835 // Load the object. |
842 MemOperand object_loc = EmitSlotSearch(object_slot, eax); | 836 MemOperand object_loc = EmitSlotSearch(object_slot, eax); |
843 __ push(object_loc); | 837 __ push(object_loc); |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1032 GenericBinaryOpStub stub(op, | 1026 GenericBinaryOpStub stub(op, |
1033 NO_OVERWRITE, | 1027 NO_OVERWRITE, |
1034 NO_GENERIC_BINARY_FLAGS); | 1028 NO_GENERIC_BINARY_FLAGS); |
1035 __ CallStub(&stub); | 1029 __ CallStub(&stub); |
1036 Apply(context, eax); | 1030 Apply(context, eax); |
1037 } | 1031 } |
1038 | 1032 |
1039 | 1033 |
1040 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1034 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
1041 Expression::Context context) { | 1035 Expression::Context context) { |
| 1036 // Three main cases: global variables, lookup slots, and all other |
| 1037 // types of slots. Left-hand-side parameters that rewrite to |
| 1038 // explicit property accesses do not reach here. |
1042 ASSERT(var != NULL); | 1039 ASSERT(var != NULL); |
1043 ASSERT(var->is_global() || var->slot() != NULL); | 1040 ASSERT(var->is_global() || var->slot() != NULL); |
| 1041 |
| 1042 Slot* slot = var->slot(); |
1044 if (var->is_global()) { | 1043 if (var->is_global()) { |
| 1044 ASSERT(!var->is_this()); |
1045 // Assignment to a global variable. Use inline caching for the | 1045 // Assignment to a global variable. Use inline caching for the |
1046 // assignment. Right-hand-side value is passed in eax, variable name in | 1046 // assignment. Right-hand-side value is passed in eax, variable name in |
1047 // ecx, and the global object on the stack. | 1047 // ecx, and the global object on the stack. |
1048 __ mov(ecx, var->name()); | 1048 __ mov(ecx, var->name()); |
1049 __ push(CodeGenerator::GlobalObject()); | 1049 __ push(CodeGenerator::GlobalObject()); |
1050 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1050 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
1051 __ call(ic, RelocInfo::CODE_TARGET); | 1051 __ call(ic, RelocInfo::CODE_TARGET); |
1052 __ nop(); | 1052 __ nop(); |
1053 // Overwrite the receiver on the stack with the result if needed. | 1053 // Overwrite the receiver on the stack with the result if needed. |
1054 DropAndApply(1, context, eax); | 1054 DropAndApply(1, context, eax); |
1055 | 1055 |
1056 } else if (var->slot() != NULL) { | 1056 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
1057 Slot* slot = var->slot(); | 1057 __ push(result_register()); // Value. |
| 1058 __ push(esi); // Context. |
| 1059 __ push(Immediate(var->name())); |
| 1060 __ CallRuntime(Runtime::kStoreContextSlot, 3); |
| 1061 Apply(context, eax); |
| 1062 |
| 1063 } else if (slot != NULL) { |
1058 switch (slot->type()) { | 1064 switch (slot->type()) { |
1059 case Slot::LOCAL: | 1065 case Slot::LOCAL: |
1060 case Slot::PARAMETER: | 1066 case Slot::PARAMETER: |
1061 __ mov(Operand(ebp, SlotOffset(slot)), result_register()); | 1067 __ mov(Operand(ebp, SlotOffset(slot)), result_register()); |
1062 break; | 1068 break; |
1063 | 1069 |
1064 case Slot::CONTEXT: { | 1070 case Slot::CONTEXT: { |
1065 MemOperand target = EmitSlotSearch(slot, ecx); | 1071 MemOperand target = EmitSlotSearch(slot, ecx); |
1066 __ mov(target, result_register()); | 1072 __ mov(target, result_register()); |
1067 | 1073 |
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1832 __ add(Operand(edx), Immediate(masm_->CodeObject())); | 1838 __ add(Operand(edx), Immediate(masm_->CodeObject())); |
1833 __ mov(Operand(esp, 0), edx); | 1839 __ mov(Operand(esp, 0), edx); |
1834 // And return. | 1840 // And return. |
1835 __ ret(0); | 1841 __ ret(0); |
1836 } | 1842 } |
1837 | 1843 |
1838 | 1844 |
1839 #undef __ | 1845 #undef __ |
1840 | 1846 |
1841 } } // namespace v8::internal | 1847 } } // namespace v8::internal |
OLD | NEW |