| 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 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 667 | 667 |
| 668 | 668 |
| 669 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | 669 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
| 670 Comment cmnt(masm_, "[ VariableProxy"); | 670 Comment cmnt(masm_, "[ VariableProxy"); |
| 671 EmitVariableLoad(expr->var(), context_); | 671 EmitVariableLoad(expr->var(), context_); |
| 672 } | 672 } |
| 673 | 673 |
| 674 | 674 |
| 675 void FullCodeGenerator::EmitVariableLoad(Variable* var, | 675 void FullCodeGenerator::EmitVariableLoad(Variable* var, |
| 676 Expression::Context context) { | 676 Expression::Context context) { |
| 677 Expression* rewrite = var->rewrite(); | 677 // Four cases: non-this global variables, lookup slots, all other |
| 678 if (rewrite == NULL) { | 678 // types of slots, and parameters that rewrite to explicit property |
| 679 ASSERT(var->is_global()); | 679 // accesses on the arguments object. |
| 680 Slot* slot = var->slot(); |
| 681 Property* property = var->AsProperty(); |
| 682 |
| 683 if (var->is_global() && !var->is_this()) { |
| 680 Comment cmnt(masm_, "Global variable"); | 684 Comment cmnt(masm_, "Global variable"); |
| 681 // Use inline caching. Variable name is passed in r2 and the global | 685 // Use inline caching. Variable name is passed in r2 and the global |
| 682 // object on the stack. | 686 // object on the stack. |
| 683 __ ldr(ip, CodeGenerator::GlobalObject()); | 687 __ ldr(ip, CodeGenerator::GlobalObject()); |
| 684 __ push(ip); | 688 __ push(ip); |
| 685 __ mov(r2, Operand(var->name())); | 689 __ mov(r2, Operand(var->name())); |
| 686 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 690 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| 687 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 691 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 688 DropAndApply(1, context, r0); | 692 DropAndApply(1, context, r0); |
| 689 } else if (rewrite->AsSlot() != NULL) { | 693 |
| 690 Slot* slot = rewrite->AsSlot(); | 694 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
| 691 if (FLAG_debug_code) { | 695 Comment cmnt(masm_, "Lookup slot"); |
| 692 switch (slot->type()) { | 696 __ mov(r1, Operand(var->name())); |
| 693 case Slot::PARAMETER: | 697 __ stm(db_w, sp, cp.bit() | r1.bit()); // Context and name. |
| 694 case Slot::LOCAL: { | 698 __ CallRuntime(Runtime::kLoadContextSlot, 2); |
| 695 Comment cmnt(masm_, "Stack slot"); | 699 Apply(context, r0); |
| 696 break; | 700 |
| 697 } | 701 } else if (slot != NULL) { |
| 698 case Slot::CONTEXT: { | 702 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT) |
| 699 Comment cmnt(masm_, "Context slot"); | 703 ? "Context slot" |
| 700 break; | 704 : "Stack slot"); |
| 701 } | |
| 702 case Slot::LOOKUP: | |
| 703 UNIMPLEMENTED(); | |
| 704 break; | |
| 705 } | |
| 706 } | |
| 707 Apply(context, slot); | 705 Apply(context, slot); |
| 706 |
| 708 } else { | 707 } else { |
| 709 Comment cmnt(masm_, "Variable rewritten to property"); | 708 Comment cmnt(masm_, "Rewritten parameter"); |
| 710 // A variable has been rewritten into an explicit access to an object | |
| 711 // property. | |
| 712 Property* property = rewrite->AsProperty(); | |
| 713 ASSERT_NOT_NULL(property); | 709 ASSERT_NOT_NULL(property); |
| 714 | 710 // Rewritten parameter accesses are of the form "slot[literal]". |
| 715 // The only property expressions that can occur are of the form | |
| 716 // "slot[literal]". | |
| 717 | 711 |
| 718 // Assert that the object is in a slot. | 712 // Assert that the object is in a slot. |
| 719 Variable* object_var = property->obj()->AsVariableProxy()->AsVariable(); | 713 Variable* object_var = property->obj()->AsVariableProxy()->AsVariable(); |
| 720 ASSERT_NOT_NULL(object_var); | 714 ASSERT_NOT_NULL(object_var); |
| 721 Slot* object_slot = object_var->slot(); | 715 Slot* object_slot = object_var->slot(); |
| 722 ASSERT_NOT_NULL(object_slot); | 716 ASSERT_NOT_NULL(object_slot); |
| 723 | 717 |
| 724 // Load the object. | 718 // Load the object. |
| 725 Move(r2, object_slot); | 719 Move(r2, object_slot); |
| 726 | 720 |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 920 Expression::Context context) { | 914 Expression::Context context) { |
| 921 __ pop(r1); | 915 __ pop(r1); |
| 922 GenericBinaryOpStub stub(op, NO_OVERWRITE); | 916 GenericBinaryOpStub stub(op, NO_OVERWRITE); |
| 923 __ CallStub(&stub); | 917 __ CallStub(&stub); |
| 924 Apply(context, r0); | 918 Apply(context, r0); |
| 925 } | 919 } |
| 926 | 920 |
| 927 | 921 |
| 928 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 922 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
| 929 Expression::Context context) { | 923 Expression::Context context) { |
| 924 // Three main cases: global variables, lookup slots, and all other |
| 925 // types of slots. Left-hand-side parameters that rewrite to |
| 926 // explicit property accesses do not reach here. |
| 930 ASSERT(var != NULL); | 927 ASSERT(var != NULL); |
| 931 ASSERT(var->is_global() || var->slot() != NULL); | 928 ASSERT(var->is_global() || var->slot() != NULL); |
| 929 |
| 930 Slot* slot = var->slot(); |
| 932 if (var->is_global()) { | 931 if (var->is_global()) { |
| 932 ASSERT(!var->is_this()); |
| 933 // Assignment to a global variable. Use inline caching for the | 933 // Assignment to a global variable. Use inline caching for the |
| 934 // assignment. Right-hand-side value is passed in r0, variable name in | 934 // assignment. Right-hand-side value is passed in r0, variable name in |
| 935 // r2, and the global object on the stack. | 935 // r2, and the global object on the stack. |
| 936 __ mov(r2, Operand(var->name())); | 936 __ mov(r2, Operand(var->name())); |
| 937 __ ldr(ip, CodeGenerator::GlobalObject()); | 937 __ ldr(ip, CodeGenerator::GlobalObject()); |
| 938 __ push(ip); | 938 __ push(ip); |
| 939 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 939 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 940 __ Call(ic, RelocInfo::CODE_TARGET); | 940 __ Call(ic, RelocInfo::CODE_TARGET); |
| 941 // Overwrite the global object on the stack with the result if needed. | 941 // Overwrite the global object on the stack with the result if needed. |
| 942 DropAndApply(1, context, r0); | 942 DropAndApply(1, context, r0); |
| 943 | 943 |
| 944 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
| 945 __ push(result_register()); // Value. |
| 946 __ mov(r1, Operand(var->name())); |
| 947 __ stm(db_w, sp, cp.bit() | r1.bit()); // Context and name. |
| 948 __ CallRuntime(Runtime::kStoreContextSlot, 3); |
| 949 Apply(context, r0); |
| 950 |
| 944 } else if (var->slot() != NULL) { | 951 } else if (var->slot() != NULL) { |
| 945 Slot* slot = var->slot(); | 952 Slot* slot = var->slot(); |
| 946 switch (slot->type()) { | 953 switch (slot->type()) { |
| 947 case Slot::LOCAL: | 954 case Slot::LOCAL: |
| 948 case Slot::PARAMETER: | 955 case Slot::PARAMETER: |
| 949 __ str(result_register(), MemOperand(fp, SlotOffset(slot))); | 956 __ str(result_register(), MemOperand(fp, SlotOffset(slot))); |
| 950 break; | 957 break; |
| 951 | 958 |
| 952 case Slot::CONTEXT: { | 959 case Slot::CONTEXT: { |
| 953 MemOperand target = EmitSlotSearch(slot, r1); | 960 MemOperand target = EmitSlotSearch(slot, r1); |
| 954 __ str(result_register(), target); | 961 __ str(result_register(), target); |
| 955 | 962 |
| 956 // RecordWrite may destroy all its register arguments. | 963 // RecordWrite may destroy all its register arguments. |
| 957 __ mov(r3, result_register()); | 964 __ mov(r3, result_register()); |
| 958 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; | 965 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; |
| 959 | 966 |
| 960 __ mov(r2, Operand(offset)); | 967 __ mov(r2, Operand(offset)); |
| 961 __ RecordWrite(r1, r2, r3); | 968 __ RecordWrite(r1, r2, r3); |
| 962 break; | 969 break; |
| 963 } | 970 } |
| 964 | 971 |
| 965 case Slot::LOOKUP: | 972 case Slot::LOOKUP: |
| 966 UNREACHABLE(); | 973 UNREACHABLE(); |
| 967 break; | 974 break; |
| 968 } | 975 } |
| 969 Apply(context, result_register()); | 976 Apply(context, result_register()); |
| 977 |
| 970 } else { | 978 } else { |
| 971 // Variables rewritten as properties are not treated as variables in | 979 // Variables rewritten as properties are not treated as variables in |
| 972 // assignments. | 980 // assignments. |
| 973 UNREACHABLE(); | 981 UNREACHABLE(); |
| 974 } | 982 } |
| 975 } | 983 } |
| 976 | 984 |
| 977 | 985 |
| 978 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 986 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
| 979 // Assignment to a property, using a named store IC. | 987 // Assignment to a property, using a named store IC. |
| (...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1713 __ pop(result_register()); | 1721 __ pop(result_register()); |
| 1714 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); | 1722 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); |
| 1715 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 1723 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
| 1716 __ add(pc, r1, Operand(masm_->CodeObject())); | 1724 __ add(pc, r1, Operand(masm_->CodeObject())); |
| 1717 } | 1725 } |
| 1718 | 1726 |
| 1719 | 1727 |
| 1720 #undef __ | 1728 #undef __ |
| 1721 | 1729 |
| 1722 } } // namespace v8::internal | 1730 } } // namespace v8::internal |
| OLD | NEW |