OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 | 100 |
101 ZoneList<Statement*>* body = fun->body(); | 101 ZoneList<Statement*>* body = fun->body(); |
102 | 102 |
103 // Initialize state. | 103 // Initialize state. |
104 ASSERT(scope_ == NULL); | 104 ASSERT(scope_ == NULL); |
105 scope_ = fun->scope(); | 105 scope_ = fun->scope(); |
106 ASSERT(allocator_ == NULL); | 106 ASSERT(allocator_ == NULL); |
107 RegisterAllocator register_allocator(this); | 107 RegisterAllocator register_allocator(this); |
108 allocator_ = ®ister_allocator; | 108 allocator_ = ®ister_allocator; |
109 ASSERT(frame_ == NULL); | 109 ASSERT(frame_ == NULL); |
110 frame_ = new VirtualFrame(this); | 110 frame_ = new VirtualFrame(); |
111 set_in_spilled_code(false); | 111 set_in_spilled_code(false); |
112 | 112 |
113 // Adjust for function-level loop nesting. | 113 // Adjust for function-level loop nesting. |
114 loop_nesting_ += fun->loop_nesting(); | 114 loop_nesting_ += fun->loop_nesting(); |
115 | 115 |
116 JumpTarget::set_compiling_deferred_code(false); | 116 JumpTarget::set_compiling_deferred_code(false); |
117 | 117 |
118 #ifdef DEBUG | 118 #ifdef DEBUG |
119 if (strlen(FLAG_stop_at) > 0 && | 119 if (strlen(FLAG_stop_at) > 0 && |
120 fun->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { | 120 fun->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { |
(...skipping 10 matching lines...) Expand all Loading... |
131 // Entry: | 131 // Entry: |
132 // Stack: receiver, arguments, return address. | 132 // Stack: receiver, arguments, return address. |
133 // ebp: caller's frame pointer | 133 // ebp: caller's frame pointer |
134 // esp: stack pointer | 134 // esp: stack pointer |
135 // edi: called JS function | 135 // edi: called JS function |
136 // esi: callee's context | 136 // esi: callee's context |
137 allocator_->Initialize(); | 137 allocator_->Initialize(); |
138 frame_->Enter(); | 138 frame_->Enter(); |
139 | 139 |
140 // Allocate space for locals and initialize them. | 140 // Allocate space for locals and initialize them. |
141 frame_->AllocateStackSlots(scope_->num_stack_slots()); | 141 frame_->AllocateStackSlots(); |
142 // Initialize the function return target after the locals are set | 142 // Initialize the function return target after the locals are set |
143 // up, because it needs the expected frame height from the frame. | 143 // up, because it needs the expected frame height from the frame. |
144 function_return_.set_direction(JumpTarget::BIDIRECTIONAL); | 144 function_return_.set_direction(JumpTarget::BIDIRECTIONAL); |
145 function_return_is_shadowed_ = false; | 145 function_return_is_shadowed_ = false; |
146 | 146 |
147 // Allocate the arguments object and copy the parameters into it. | 147 // Allocate the arguments object and copy the parameters into it. |
148 if (scope_->arguments() != NULL) { | 148 if (scope_->arguments() != NULL) { |
149 ASSERT(scope_->arguments_shadow() != NULL); | 149 ASSERT(scope_->arguments_shadow() != NULL); |
150 Comment cmnt(masm_, "[ Allocate arguments object"); | 150 Comment cmnt(masm_, "[ Allocate arguments object"); |
151 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); | 151 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); |
(...skipping 2492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2644 } | 2644 } |
2645 | 2645 |
2646 DecrementLoopNesting(); | 2646 DecrementLoopNesting(); |
2647 node->continue_target()->Unuse(); | 2647 node->continue_target()->Unuse(); |
2648 node->break_target()->Unuse(); | 2648 node->break_target()->Unuse(); |
2649 } | 2649 } |
2650 | 2650 |
2651 | 2651 |
2652 void CodeGenerator::VisitForInStatement(ForInStatement* node) { | 2652 void CodeGenerator::VisitForInStatement(ForInStatement* node) { |
2653 ASSERT(!in_spilled_code()); | 2653 ASSERT(!in_spilled_code()); |
2654 VirtualFrame::SpilledScope spilled_scope(this); | 2654 VirtualFrame::SpilledScope spilled_scope; |
2655 Comment cmnt(masm_, "[ ForInStatement"); | 2655 Comment cmnt(masm_, "[ ForInStatement"); |
2656 CodeForStatementPosition(node); | 2656 CodeForStatementPosition(node); |
2657 | 2657 |
2658 JumpTarget primitive; | 2658 JumpTarget primitive; |
2659 JumpTarget jsobject; | 2659 JumpTarget jsobject; |
2660 JumpTarget fixed_array; | 2660 JumpTarget fixed_array; |
2661 JumpTarget entry(JumpTarget::BIDIRECTIONAL); | 2661 JumpTarget entry(JumpTarget::BIDIRECTIONAL); |
2662 JumpTarget end_del_check; | 2662 JumpTarget end_del_check; |
2663 JumpTarget exit; | 2663 JumpTarget exit; |
2664 | 2664 |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2834 // Exit. | 2834 // Exit. |
2835 exit.Bind(); | 2835 exit.Bind(); |
2836 | 2836 |
2837 node->continue_target()->Unuse(); | 2837 node->continue_target()->Unuse(); |
2838 node->break_target()->Unuse(); | 2838 node->break_target()->Unuse(); |
2839 } | 2839 } |
2840 | 2840 |
2841 | 2841 |
2842 void CodeGenerator::VisitTryCatch(TryCatch* node) { | 2842 void CodeGenerator::VisitTryCatch(TryCatch* node) { |
2843 ASSERT(!in_spilled_code()); | 2843 ASSERT(!in_spilled_code()); |
2844 VirtualFrame::SpilledScope spilled_scope(this); | 2844 VirtualFrame::SpilledScope spilled_scope; |
2845 Comment cmnt(masm_, "[ TryCatch"); | 2845 Comment cmnt(masm_, "[ TryCatch"); |
2846 CodeForStatementPosition(node); | 2846 CodeForStatementPosition(node); |
2847 | 2847 |
2848 JumpTarget try_block; | 2848 JumpTarget try_block; |
2849 JumpTarget exit; | 2849 JumpTarget exit; |
2850 | 2850 |
2851 try_block.Call(); | 2851 try_block.Call(); |
2852 // --- Catch block --- | 2852 // --- Catch block --- |
2853 frame_->EmitPush(eax); | 2853 frame_->EmitPush(eax); |
2854 | 2854 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2973 } | 2973 } |
2974 } | 2974 } |
2975 } | 2975 } |
2976 | 2976 |
2977 exit.Bind(); | 2977 exit.Bind(); |
2978 } | 2978 } |
2979 | 2979 |
2980 | 2980 |
2981 void CodeGenerator::VisitTryFinally(TryFinally* node) { | 2981 void CodeGenerator::VisitTryFinally(TryFinally* node) { |
2982 ASSERT(!in_spilled_code()); | 2982 ASSERT(!in_spilled_code()); |
2983 VirtualFrame::SpilledScope spilled_scope(this); | 2983 VirtualFrame::SpilledScope spilled_scope; |
2984 Comment cmnt(masm_, "[ TryFinally"); | 2984 Comment cmnt(masm_, "[ TryFinally"); |
2985 CodeForStatementPosition(node); | 2985 CodeForStatementPosition(node); |
2986 | 2986 |
2987 // State: Used to keep track of reason for entering the finally | 2987 // State: Used to keep track of reason for entering the finally |
2988 // block. Should probably be extended to hold information for | 2988 // block. Should probably be extended to hold information for |
2989 // break/continue from within the try block. | 2989 // break/continue from within the try block. |
2990 enum { FALLING, THROWING, JUMPING }; | 2990 enum { FALLING, THROWING, JUMPING }; |
2991 | 2991 |
2992 JumpTarget try_block; | 2992 JumpTarget try_block; |
2993 JumpTarget finally_block; | 2993 JumpTarget finally_block; |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3308 done.Bind(&value); | 3308 done.Bind(&value); |
3309 frame_->Push(&value); | 3309 frame_->Push(&value); |
3310 | 3310 |
3311 } else if (slot->var()->mode() == Variable::CONST) { | 3311 } else if (slot->var()->mode() == Variable::CONST) { |
3312 // Const slots may contain 'the hole' value (the constant hasn't been | 3312 // Const slots may contain 'the hole' value (the constant hasn't been |
3313 // initialized yet) which needs to be converted into the 'undefined' | 3313 // initialized yet) which needs to be converted into the 'undefined' |
3314 // value. | 3314 // value. |
3315 // | 3315 // |
3316 // We currently spill the virtual frame because constants use the | 3316 // We currently spill the virtual frame because constants use the |
3317 // potentially unsafe direct-frame access of SlotOperand. | 3317 // potentially unsafe direct-frame access of SlotOperand. |
3318 VirtualFrame::SpilledScope spilled_scope(this); | 3318 VirtualFrame::SpilledScope spilled_scope; |
3319 Comment cmnt(masm_, "[ Load const"); | 3319 Comment cmnt(masm_, "[ Load const"); |
3320 JumpTarget exit; | 3320 JumpTarget exit; |
3321 __ mov(ecx, SlotOperand(slot, ecx)); | 3321 __ mov(ecx, SlotOperand(slot, ecx)); |
3322 __ cmp(ecx, Factory::the_hole_value()); | 3322 __ cmp(ecx, Factory::the_hole_value()); |
3323 exit.Branch(not_equal); | 3323 exit.Branch(not_equal); |
3324 __ mov(ecx, Factory::undefined_value()); | 3324 __ mov(ecx, Factory::undefined_value()); |
3325 exit.Bind(); | 3325 exit.Bind(); |
3326 frame_->EmitPush(ecx); | 3326 frame_->EmitPush(ecx); |
3327 | 3327 |
3328 } else if (slot->type() == Slot::PARAMETER) { | 3328 } else if (slot->type() == Slot::PARAMETER) { |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3458 JumpTarget exit; | 3458 JumpTarget exit; |
3459 if (init_state == CONST_INIT) { | 3459 if (init_state == CONST_INIT) { |
3460 ASSERT(slot->var()->mode() == Variable::CONST); | 3460 ASSERT(slot->var()->mode() == Variable::CONST); |
3461 // Only the first const initialization must be executed (the slot | 3461 // Only the first const initialization must be executed (the slot |
3462 // still contains 'the hole' value). When the assignment is executed, | 3462 // still contains 'the hole' value). When the assignment is executed, |
3463 // the code is identical to a normal store (see below). | 3463 // the code is identical to a normal store (see below). |
3464 // | 3464 // |
3465 // We spill the frame in the code below because the direct-frame | 3465 // We spill the frame in the code below because the direct-frame |
3466 // access of SlotOperand is potentially unsafe with an unspilled | 3466 // access of SlotOperand is potentially unsafe with an unspilled |
3467 // frame. | 3467 // frame. |
3468 VirtualFrame::SpilledScope spilled_scope(this); | 3468 VirtualFrame::SpilledScope spilled_scope; |
3469 Comment cmnt(masm_, "[ Init const"); | 3469 Comment cmnt(masm_, "[ Init const"); |
3470 __ mov(ecx, SlotOperand(slot, ecx)); | 3470 __ mov(ecx, SlotOperand(slot, ecx)); |
3471 __ cmp(ecx, Factory::the_hole_value()); | 3471 __ cmp(ecx, Factory::the_hole_value()); |
3472 exit.Branch(not_equal); | 3472 exit.Branch(not_equal); |
3473 } | 3473 } |
3474 | 3474 |
3475 // We must execute the store. Storing a variable must keep the (new) | 3475 // We must execute the store. Storing a variable must keep the (new) |
3476 // value on the stack. This is necessary for compiling assignment | 3476 // value on the stack. This is necessary for compiling assignment |
3477 // expressions. | 3477 // expressions. |
3478 // | 3478 // |
(...skipping 3789 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7268 | 7268 |
7269 // Slow-case: Go through the JavaScript implementation. | 7269 // Slow-case: Go through the JavaScript implementation. |
7270 __ bind(&slow); | 7270 __ bind(&slow); |
7271 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 7271 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
7272 } | 7272 } |
7273 | 7273 |
7274 | 7274 |
7275 #undef __ | 7275 #undef __ |
7276 | 7276 |
7277 } } // namespace v8::internal | 7277 } } // namespace v8::internal |
OLD | NEW |