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 21 matching lines...) Expand all Loading... | |
32 // #include "macro-assembler.h" | 32 // #include "macro-assembler.h" |
33 #include "codegen-inl.h" | 33 #include "codegen-inl.h" |
34 #include "register-allocator-inl.h" | 34 #include "register-allocator-inl.h" |
35 | 35 |
36 // TEST | 36 // TEST |
37 #include "compiler.h" | 37 #include "compiler.h" |
38 | 38 |
39 namespace v8 { | 39 namespace v8 { |
40 namespace internal { | 40 namespace internal { |
41 | 41 |
42 #define __ ACCESS_MASM(masm_) | |
43 | |
42 // ------------------------------------------------------------------------- | 44 // ------------------------------------------------------------------------- |
43 // Platform-specific DeferredCode functions. | 45 // Platform-specific DeferredCode functions. |
44 | 46 |
45 void DeferredCode::SaveRegisters() { UNIMPLEMENTED(); } | 47 void DeferredCode::SaveRegisters() { |
48 for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) { | |
49 int action = registers_[i]; | |
50 if (action == kPush) { | |
51 __ push(RegisterAllocator::ToRegister(i)); | |
52 } else if (action != kIgnore && (action & kSyncedFlag) == 0) { | |
53 __ movq(Operand(rbp, action), RegisterAllocator::ToRegister(i)); | |
54 } | |
55 } | |
56 } | |
46 | 57 |
47 void DeferredCode::RestoreRegisters() { UNIMPLEMENTED(); } | 58 void DeferredCode::RestoreRegisters() { |
59 // Restore registers in reverse order due to the stack. | |
60 for (int i = RegisterAllocator::kNumRegisters - 1; i >= 0; i--) { | |
61 int action = registers_[i]; | |
62 if (action == kPush) { | |
63 __ pop(RegisterAllocator::ToRegister(i)); | |
64 } else if (action != kIgnore) { | |
65 action &= ~kSyncedFlag; | |
66 __ movq(RegisterAllocator::ToRegister(i), Operand(rbp, action)); | |
67 } | |
68 } | |
69 } | |
70 | |
71 #undef __ | |
48 | 72 |
49 // ------------------------------------------------------------------------- | 73 // ------------------------------------------------------------------------- |
50 // CodeGenState implementation. | 74 // CodeGenState implementation. |
51 | 75 |
52 CodeGenState::CodeGenState(CodeGenerator* owner) | 76 CodeGenState::CodeGenState(CodeGenerator* owner) |
53 : owner_(owner), | 77 : owner_(owner), |
54 typeof_state_(NOT_INSIDE_TYPEOF), | 78 typeof_state_(NOT_INSIDE_TYPEOF), |
55 destination_(NULL), | 79 destination_(NULL), |
56 previous_(NULL) { | 80 previous_(NULL) { |
57 owner_->set_state(this); | 81 owner_->set_state(this); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
105 // Compile a function from a string, and run it. | 129 // Compile a function from a string, and run it. |
106 | 130 |
107 // Set flags appropriately for this stage of implementation. | 131 // Set flags appropriately for this stage of implementation. |
108 // TODO(X64): Make ic and lazy compilation work, and stop disabling them. | 132 // TODO(X64): Make ic and lazy compilation work, and stop disabling them. |
109 // These settings stick - remove them when we don't want them anymore. | 133 // These settings stick - remove them when we don't want them anymore. |
110 #ifdef DEBUG | 134 #ifdef DEBUG |
111 FLAG_print_builtin_source = true; | 135 FLAG_print_builtin_source = true; |
112 FLAG_print_builtin_ast = true; | 136 FLAG_print_builtin_ast = true; |
113 #endif | 137 #endif |
114 FLAG_use_ic = false; | 138 FLAG_use_ic = false; |
115 FLAG_lazy = false; | |
116 | 139 |
117 Handle<JSFunction> test_function = Compiler::Compile( | 140 Handle<JSFunction> test_function = Compiler::Compile( |
118 Factory::NewStringFromAscii(CStrVector( | 141 Factory::NewStringFromAscii(CStrVector( |
119 "// Put all code in anonymous function to avoid global scope.\n" | 142 "// Put all code in anonymous function to avoid global scope.\n" |
120 "(function(){" | 143 "(function(){" |
121 " function test_if_then_else(x, y, z){" | 144 " function test_if_then_else(x, y, z){" |
122 " if (x) {" | 145 " if (x) {" |
123 " x = y;" | 146 " x = y;" |
124 " } else {" | 147 " } else {" |
125 " x = z;" | 148 " x = z;" |
126 " }" | 149 " }" |
127 " return x;" | 150 " return x;" |
128 " }" | 151 " }" |
129 " function test_local_variables(x, y){" | 152 " function test_local_variables(x, y){" |
130 " var w; y = x; x = w; w = y; y = x; return w;" | 153 " var w; y = x; x = w; w = y; y = x; return w;" |
131 " };" | 154 " };" |
132 " test_local_variables(2,3);" | 155 " test_local_variables(2,3);" |
133 " function test_nesting_calls(x, y, zee){return zee;};" | 156 " function test_nesting_calls(x, y, zee){return zee;};" |
134 " test_local_variables(" | 157 " test_local_variables(" |
135 " test_nesting_calls(test_local_variables(1,3), 42, 47)," | 158 " test_nesting_calls(test_local_variables(1,3), 42, 47)," |
136 " test_local_variables(-25.3, 2));" | 159 " test_local_variables(-25.3, 2));" |
160 " var x_value = 42;" | |
161 " var o = { x: x_value };" | |
William Hesse
2009/06/22 10:31:35
Why isn't this hitting the unimplemented
case Ob
Mads Ager (chromium)
2009/06/22 10:51:05
It is, accidentally uploaded this instead of just
| |
137 " return test_if_then_else(1, 47, 39);" | 162 " return test_if_then_else(1, 47, 39);" |
138 "})()")), | 163 "})()")), |
139 Factory::NewStringFromAscii(CStrVector("CodeGeneratorTestScript")), | 164 Factory::NewStringFromAscii(CStrVector("CodeGeneratorTestScript")), |
140 0, | 165 0, |
141 0, | 166 0, |
142 NULL, | 167 NULL, |
143 NULL); | 168 NULL); |
144 | 169 |
145 Code* code_object = test_function->code(); // Local for debugging ease. | 170 Code* code_object = test_function->code(); // Local for debugging ease. |
146 USE(code_object); | 171 USE(code_object); |
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
670 void CodeGenerator::VisitLiteral(Literal* node) { | 695 void CodeGenerator::VisitLiteral(Literal* node) { |
671 Comment cmnt(masm_, "[ Literal"); | 696 Comment cmnt(masm_, "[ Literal"); |
672 frame_->Push(node->handle()); | 697 frame_->Push(node->handle()); |
673 } | 698 } |
674 | 699 |
675 | 700 |
676 void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* a) { | 701 void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* a) { |
677 UNIMPLEMENTED(); | 702 UNIMPLEMENTED(); |
678 } | 703 } |
679 | 704 |
680 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* a) { | 705 |
681 UNIMPLEMENTED(); | 706 // Materialize the object literal 'node' in the literals array |
707 // 'literals' of the function. Leave the object boilerplate in | |
708 // 'boilerplate'. | |
709 class DeferredObjectLiteral: public DeferredCode { | |
710 public: | |
711 DeferredObjectLiteral(Register boilerplate, | |
712 Register literals, | |
713 ObjectLiteral* node) | |
714 : boilerplate_(boilerplate), literals_(literals), node_(node) { | |
715 set_comment("[ DeferredObjectLiteral"); | |
716 } | |
717 | |
718 void Generate(); | |
719 | |
720 private: | |
721 Register boilerplate_; | |
722 Register literals_; | |
723 ObjectLiteral* node_; | |
724 }; | |
725 | |
726 | |
727 void DeferredObjectLiteral::Generate() { | |
728 // Since the entry is undefined we call the runtime system to | |
729 // compute the literal. | |
730 // Literal array (0). | |
731 __ push(literals_); | |
732 // Literal index (1). | |
733 __ push(Immediate(Smi::FromInt(node_->literal_index()))); | |
734 // Constant properties (2). | |
735 __ movq(kScratchRegister, | |
736 node_->constant_properties(), | |
737 RelocInfo::EMBEDDED_OBJECT); | |
738 __ push(kScratchRegister); | |
739 __ CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3); | |
740 if (!boilerplate_.is(rax)) __ movq(boilerplate_, rax); | |
741 } | |
742 | |
743 | |
744 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { | |
745 Comment cmnt(masm_, "[ ObjectLiteral"); | |
746 | |
747 // Retrieve the literals array and check the allocated entry. Begin | |
748 // with a writable copy of the function of this activation in a | |
749 // register. | |
750 frame_->PushFunction(); | |
751 Result literals = frame_->Pop(); | |
752 literals.ToRegister(); | |
753 frame_->Spill(literals.reg()); | |
754 | |
755 // Load the literals array of the function. | |
756 __ movq(literals.reg(), | |
757 FieldOperand(literals.reg(), JSFunction::kLiteralsOffset)); | |
758 | |
759 // Load the literal at the ast saved index. | |
760 Result boilerplate = allocator_->Allocate(); | |
761 ASSERT(boilerplate.is_valid()); | |
762 int literal_offset = | |
763 FixedArray::kHeaderSize + node->literal_index() * kPointerSize; | |
764 __ movq(boilerplate.reg(), FieldOperand(literals.reg(), literal_offset)); | |
765 | |
766 // Check whether we need to materialize the object literal boilerplate. | |
767 // If so, jump to the deferred code passing the literals array. | |
768 DeferredObjectLiteral* deferred = | |
769 new DeferredObjectLiteral(boilerplate.reg(), literals.reg(), node); | |
770 __ movq(kScratchRegister, | |
771 Factory::undefined_value(), | |
772 RelocInfo::EMBEDDED_OBJECT); | |
773 __ cmpq(boilerplate.reg(), kScratchRegister); | |
774 deferred->Branch(equal); | |
775 deferred->BindExit(); | |
776 literals.Unuse(); | |
777 | |
778 // Push the boilerplate object. | |
779 frame_->Push(&boilerplate); | |
780 // Clone the boilerplate object. | |
781 Runtime::FunctionId clone_function_id = Runtime::kCloneLiteralBoilerplate; | |
782 if (node->depth() == 1) { | |
783 clone_function_id = Runtime::kCloneShallowLiteralBoilerplate; | |
784 } | |
785 Result clone = frame_->CallRuntime(clone_function_id, 1); | |
786 // Push the newly cloned literal object as the result. | |
787 frame_->Push(&clone); | |
788 | |
789 for (int i = 0; i < node->properties()->length(); i++) { | |
790 ObjectLiteral::Property* property = node->properties()->at(i); | |
791 switch (property->kind()) { | |
792 case ObjectLiteral::Property::CONSTANT: | |
793 break; | |
794 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | |
795 if (CompileTimeValue::IsCompileTimeValue(property->value())) break; | |
796 // else fall through. | |
797 case ObjectLiteral::Property::COMPUTED: { | |
798 // TODO(X64): Implement setting of computed values in object literals. | |
799 UNIMPLEMENTED(); | |
800 } | |
801 case ObjectLiteral::Property::PROTOTYPE: { | |
802 // Duplicate the object as an argument to the runtime call. | |
803 frame_->Dup(); | |
804 Load(property->key()); | |
805 Load(property->value()); | |
806 Result ignored = frame_->CallRuntime(Runtime::kSetProperty, 3); | |
807 // Ignore the result. | |
808 break; | |
809 } | |
810 case ObjectLiteral::Property::SETTER: { | |
811 // Duplicate the object as an argument to the runtime call. | |
812 frame_->Dup(); | |
813 Load(property->key()); | |
814 frame_->Push(Smi::FromInt(1)); | |
815 Load(property->value()); | |
816 Result ignored = frame_->CallRuntime(Runtime::kDefineAccessor, 4); | |
817 // Ignore the result. | |
818 break; | |
819 } | |
820 case ObjectLiteral::Property::GETTER: { | |
821 // Duplicate the object as an argument to the runtime call. | |
822 frame_->Dup(); | |
823 Load(property->key()); | |
824 frame_->Push(Smi::FromInt(0)); | |
825 Load(property->value()); | |
826 Result ignored = frame_->CallRuntime(Runtime::kDefineAccessor, 4); | |
827 // Ignore the result. | |
828 break; | |
829 } | |
830 default: UNREACHABLE(); | |
831 } | |
832 } | |
682 } | 833 } |
683 | 834 |
684 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* a) { | 835 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* a) { |
685 UNIMPLEMENTED(); | 836 UNIMPLEMENTED(); |
686 } | 837 } |
687 | 838 |
688 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* a) { | 839 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* a) { |
689 UNIMPLEMENTED(); | 840 UNIMPLEMENTED(); |
690 } | 841 } |
691 | 842 |
(...skipping 1863 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2555 __ addq(rsp, Immediate(2 * kPointerSize)); // remove markers | 2706 __ addq(rsp, Immediate(2 * kPointerSize)); // remove markers |
2556 | 2707 |
2557 // Restore frame pointer and return. | 2708 // Restore frame pointer and return. |
2558 __ pop(rbp); | 2709 __ pop(rbp); |
2559 __ ret(0); | 2710 __ ret(0); |
2560 } | 2711 } |
2561 | 2712 |
2562 #undef __ | 2713 #undef __ |
2563 | 2714 |
2564 } } // namespace v8::internal | 2715 } } // namespace v8::internal |
OLD | NEW |