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 |