Chromium Code Reviews| 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 |