OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/full-codegen/full-codegen.h" | 5 #include "src/full-codegen/full-codegen.h" |
6 | 6 |
7 #include "src/ast/ast-numbering.h" | 7 #include "src/ast/ast-numbering.h" |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/ast/prettyprinter.h" | 9 #include "src/ast/prettyprinter.h" |
10 #include "src/ast/scopeinfo.h" | 10 #include "src/ast/scopeinfo.h" |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 expr->values()->length() > JSArray::kInitialMaxFastElementArray; | 155 expr->values()->length() > JSArray::kInitialMaxFastElementArray; |
156 } | 156 } |
157 | 157 |
158 | 158 |
159 void FullCodeGenerator::Initialize() { | 159 void FullCodeGenerator::Initialize() { |
160 InitializeAstVisitor(info_->isolate()); | 160 InitializeAstVisitor(info_->isolate()); |
161 masm_->set_emit_debug_code(FLAG_debug_code); | 161 masm_->set_emit_debug_code(FLAG_debug_code); |
162 masm_->set_predictable_code_size(true); | 162 masm_->set_predictable_code_size(true); |
163 } | 163 } |
164 | 164 |
165 void FullCodeGenerator::PrepareForBailout(Expression* node, | 165 |
166 BailoutState state) { | 166 void FullCodeGenerator::PrepareForBailout(Expression* node, State state) { |
167 PrepareForBailoutForId(node->id(), state); | 167 PrepareForBailoutForId(node->id(), state); |
168 } | 168 } |
169 | 169 |
170 | 170 |
171 void FullCodeGenerator::CallLoadIC(TypeofMode typeof_mode, | 171 void FullCodeGenerator::CallLoadIC(TypeofMode typeof_mode, |
172 TypeFeedbackId id) { | 172 TypeFeedbackId id) { |
173 Handle<Code> ic = CodeFactory::LoadIC(isolate(), typeof_mode).code(); | 173 Handle<Code> ic = CodeFactory::LoadIC(isolate(), typeof_mode).code(); |
174 CallIC(ic, id); | 174 CallIC(ic, id); |
175 } | 175 } |
176 | 176 |
177 | 177 |
178 void FullCodeGenerator::CallStoreIC(TypeFeedbackId id) { | 178 void FullCodeGenerator::CallStoreIC(TypeFeedbackId id) { |
179 Handle<Code> ic = CodeFactory::StoreIC(isolate(), language_mode()).code(); | 179 Handle<Code> ic = CodeFactory::StoreIC(isolate(), language_mode()).code(); |
180 CallIC(ic, id); | 180 CallIC(ic, id); |
181 } | 181 } |
182 | 182 |
183 | 183 |
184 void FullCodeGenerator::RecordJSReturnSite(Call* call) { | 184 void FullCodeGenerator::RecordJSReturnSite(Call* call) { |
185 // We record the offset of the function return so we can rebuild the frame | 185 // We record the offset of the function return so we can rebuild the frame |
186 // if the function was inlined, i.e., this is the return address in the | 186 // if the function was inlined, i.e., this is the return address in the |
187 // inlined function's frame. | 187 // inlined function's frame. |
188 // | 188 // |
189 // The bailout state is ignored. We defensively set it to TOS_REGISTER, which | 189 // The state is ignored. We defensively set it to TOS_REG, which is the |
190 // is the real state of the unoptimized code at the return site. | 190 // real state of the unoptimized code at the return site. |
191 PrepareForBailoutForId(call->ReturnId(), BailoutState::TOS_REGISTER); | 191 PrepareForBailoutForId(call->ReturnId(), TOS_REG); |
192 #ifdef DEBUG | 192 #ifdef DEBUG |
193 // In debug builds, mark the return so we can verify that this function | 193 // In debug builds, mark the return so we can verify that this function |
194 // was called. | 194 // was called. |
195 DCHECK(!call->return_is_recorded_); | 195 DCHECK(!call->return_is_recorded_); |
196 call->return_is_recorded_ = true; | 196 call->return_is_recorded_ = true; |
197 #endif | 197 #endif |
198 } | 198 } |
199 | 199 |
200 void FullCodeGenerator::PrepareForBailoutForId(BailoutId id, | 200 |
201 BailoutState state) { | 201 void FullCodeGenerator::PrepareForBailoutForId(BailoutId id, State state) { |
202 // There's no need to prepare this code for bailouts from already optimized | 202 // There's no need to prepare this code for bailouts from already optimized |
203 // code or code that can't be optimized. | 203 // code or code that can't be optimized. |
204 if (!info_->HasDeoptimizationSupport()) return; | 204 if (!info_->HasDeoptimizationSupport()) return; |
205 unsigned pc_and_state = | 205 unsigned pc_and_state = |
206 BailoutStateField::encode(state) | PcField::encode(masm_->pc_offset()); | 206 StateField::encode(state) | PcField::encode(masm_->pc_offset()); |
207 DCHECK(Smi::IsValid(pc_and_state)); | 207 DCHECK(Smi::IsValid(pc_and_state)); |
208 #ifdef DEBUG | 208 #ifdef DEBUG |
209 for (int i = 0; i < bailout_entries_.length(); ++i) { | 209 for (int i = 0; i < bailout_entries_.length(); ++i) { |
210 DCHECK(bailout_entries_[i].id != id); | 210 DCHECK(bailout_entries_[i].id != id); |
211 } | 211 } |
212 #endif | 212 #endif |
213 BailoutEntry entry = { id, pc_and_state }; | 213 BailoutEntry entry = { id, pc_and_state }; |
214 bailout_entries_.Add(entry, zone()); | 214 bailout_entries_.Add(entry, zone()); |
215 } | 215 } |
216 | 216 |
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
743 Label done; | 743 Label done; |
744 | 744 |
745 if (context()->IsTest()) { | 745 if (context()->IsTest()) { |
746 Label eval_right; | 746 Label eval_right; |
747 const TestContext* test = TestContext::cast(context()); | 747 const TestContext* test = TestContext::cast(context()); |
748 if (is_logical_and) { | 748 if (is_logical_and) { |
749 VisitForControl(left, &eval_right, test->false_label(), &eval_right); | 749 VisitForControl(left, &eval_right, test->false_label(), &eval_right); |
750 } else { | 750 } else { |
751 VisitForControl(left, test->true_label(), &eval_right, &eval_right); | 751 VisitForControl(left, test->true_label(), &eval_right, &eval_right); |
752 } | 752 } |
753 PrepareForBailoutForId(right_id, BailoutState::NO_REGISTERS); | 753 PrepareForBailoutForId(right_id, NO_REGISTERS); |
754 __ bind(&eval_right); | 754 __ bind(&eval_right); |
755 | 755 |
756 } else if (context()->IsAccumulatorValue()) { | 756 } else if (context()->IsAccumulatorValue()) { |
757 VisitForAccumulatorValue(left); | 757 VisitForAccumulatorValue(left); |
758 // We want the value in the accumulator for the test, and on the stack in | 758 // We want the value in the accumulator for the test, and on the stack in |
759 // case we need it. | 759 // case we need it. |
760 __ Push(result_register()); | 760 __ Push(result_register()); |
761 Label discard, restore; | 761 Label discard, restore; |
762 if (is_logical_and) { | 762 if (is_logical_and) { |
763 DoTest(left, &discard, &restore, &restore); | 763 DoTest(left, &discard, &restore, &restore); |
764 } else { | 764 } else { |
765 DoTest(left, &restore, &discard, &restore); | 765 DoTest(left, &restore, &discard, &restore); |
766 } | 766 } |
767 __ bind(&restore); | 767 __ bind(&restore); |
768 __ Pop(result_register()); | 768 __ Pop(result_register()); |
769 __ jmp(&done); | 769 __ jmp(&done); |
770 __ bind(&discard); | 770 __ bind(&discard); |
771 __ Drop(1); | 771 __ Drop(1); |
772 PrepareForBailoutForId(right_id, BailoutState::NO_REGISTERS); | 772 PrepareForBailoutForId(right_id, NO_REGISTERS); |
773 | 773 |
774 } else if (context()->IsStackValue()) { | 774 } else if (context()->IsStackValue()) { |
775 VisitForAccumulatorValue(left); | 775 VisitForAccumulatorValue(left); |
776 // We want the value in the accumulator for the test, and on the stack in | 776 // We want the value in the accumulator for the test, and on the stack in |
777 // case we need it. | 777 // case we need it. |
778 __ Push(result_register()); | 778 __ Push(result_register()); |
779 Label discard; | 779 Label discard; |
780 if (is_logical_and) { | 780 if (is_logical_and) { |
781 DoTest(left, &discard, &done, &discard); | 781 DoTest(left, &discard, &done, &discard); |
782 } else { | 782 } else { |
783 DoTest(left, &done, &discard, &discard); | 783 DoTest(left, &done, &discard, &discard); |
784 } | 784 } |
785 __ bind(&discard); | 785 __ bind(&discard); |
786 __ Drop(1); | 786 __ Drop(1); |
787 PrepareForBailoutForId(right_id, BailoutState::NO_REGISTERS); | 787 PrepareForBailoutForId(right_id, NO_REGISTERS); |
788 | 788 |
789 } else { | 789 } else { |
790 DCHECK(context()->IsEffect()); | 790 DCHECK(context()->IsEffect()); |
791 Label eval_right; | 791 Label eval_right; |
792 if (is_logical_and) { | 792 if (is_logical_and) { |
793 VisitForControl(left, &eval_right, &done, &eval_right); | 793 VisitForControl(left, &eval_right, &done, &eval_right); |
794 } else { | 794 } else { |
795 VisitForControl(left, &done, &eval_right, &eval_right); | 795 VisitForControl(left, &done, &eval_right, &eval_right); |
796 } | 796 } |
797 PrepareForBailoutForId(right_id, BailoutState::NO_REGISTERS); | 797 PrepareForBailoutForId(right_id, NO_REGISTERS); |
798 __ bind(&eval_right); | 798 __ bind(&eval_right); |
799 } | 799 } |
800 | 800 |
801 VisitInDuplicateContext(right); | 801 VisitInDuplicateContext(right); |
802 __ bind(&done); | 802 __ bind(&done); |
803 } | 803 } |
804 | 804 |
805 | 805 |
806 void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) { | 806 void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) { |
807 Token::Value op = expr->op(); | 807 Token::Value op = expr->op(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
845 PopOperand(LoadDescriptor::ReceiverRegister()); | 845 PopOperand(LoadDescriptor::ReceiverRegister()); |
846 EmitKeyedPropertyLoad(expr); | 846 EmitKeyedPropertyLoad(expr); |
847 } else { | 847 } else { |
848 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 848 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
849 VisitForStackValue( | 849 VisitForStackValue( |
850 expr->obj()->AsSuperPropertyReference()->home_object()); | 850 expr->obj()->AsSuperPropertyReference()->home_object()); |
851 VisitForStackValue(expr->key()); | 851 VisitForStackValue(expr->key()); |
852 EmitKeyedSuperPropertyLoad(expr); | 852 EmitKeyedSuperPropertyLoad(expr); |
853 } | 853 } |
854 } | 854 } |
855 PrepareForBailoutForId(expr->LoadId(), BailoutState::TOS_REGISTER); | 855 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
856 context()->Plug(result_register()); | 856 context()->Plug(result_register()); |
857 } | 857 } |
858 | 858 |
859 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 859 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
860 VariableProxy* proxy = expr->AsVariableProxy(); | 860 VariableProxy* proxy = expr->AsVariableProxy(); |
861 DCHECK(!context()->IsEffect()); | 861 DCHECK(!context()->IsEffect()); |
862 DCHECK(!context()->IsTest()); | 862 DCHECK(!context()->IsTest()); |
863 | 863 |
864 if (proxy != NULL && (proxy->var()->IsUnallocatedOrGlobalSlot() || | 864 if (proxy != NULL && (proxy->var()->IsUnallocatedOrGlobalSlot() || |
865 proxy->var()->IsLookupSlot())) { | 865 proxy->var()->IsLookupSlot())) { |
866 EmitVariableLoad(proxy, INSIDE_TYPEOF); | 866 EmitVariableLoad(proxy, INSIDE_TYPEOF); |
867 PrepareForBailout(proxy, BailoutState::TOS_REGISTER); | 867 PrepareForBailout(proxy, TOS_REG); |
868 } else { | 868 } else { |
869 // This expression cannot throw a reference error at the top level. | 869 // This expression cannot throw a reference error at the top level. |
870 VisitInDuplicateContext(expr); | 870 VisitInDuplicateContext(expr); |
871 } | 871 } |
872 } | 872 } |
873 | 873 |
874 | 874 |
875 void FullCodeGenerator::VisitBlock(Block* stmt) { | 875 void FullCodeGenerator::VisitBlock(Block* stmt) { |
876 Comment cmnt(masm_, "[ Block"); | 876 Comment cmnt(masm_, "[ Block"); |
877 NestedBlock nested_block(this, stmt); | 877 NestedBlock nested_block(this, stmt); |
(...skipping 27 matching lines...) Expand all Loading... |
905 } | 905 } |
906 | 906 |
907 | 907 |
908 void FullCodeGenerator::VisitIfStatement(IfStatement* stmt) { | 908 void FullCodeGenerator::VisitIfStatement(IfStatement* stmt) { |
909 Comment cmnt(masm_, "[ IfStatement"); | 909 Comment cmnt(masm_, "[ IfStatement"); |
910 SetStatementPosition(stmt); | 910 SetStatementPosition(stmt); |
911 Label then_part, else_part, done; | 911 Label then_part, else_part, done; |
912 | 912 |
913 if (stmt->HasElseStatement()) { | 913 if (stmt->HasElseStatement()) { |
914 VisitForControl(stmt->condition(), &then_part, &else_part, &then_part); | 914 VisitForControl(stmt->condition(), &then_part, &else_part, &then_part); |
915 PrepareForBailoutForId(stmt->ThenId(), BailoutState::NO_REGISTERS); | 915 PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS); |
916 __ bind(&then_part); | 916 __ bind(&then_part); |
917 Visit(stmt->then_statement()); | 917 Visit(stmt->then_statement()); |
918 __ jmp(&done); | 918 __ jmp(&done); |
919 | 919 |
920 PrepareForBailoutForId(stmt->ElseId(), BailoutState::NO_REGISTERS); | 920 PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS); |
921 __ bind(&else_part); | 921 __ bind(&else_part); |
922 Visit(stmt->else_statement()); | 922 Visit(stmt->else_statement()); |
923 } else { | 923 } else { |
924 VisitForControl(stmt->condition(), &then_part, &done, &then_part); | 924 VisitForControl(stmt->condition(), &then_part, &done, &then_part); |
925 PrepareForBailoutForId(stmt->ThenId(), BailoutState::NO_REGISTERS); | 925 PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS); |
926 __ bind(&then_part); | 926 __ bind(&then_part); |
927 Visit(stmt->then_statement()); | 927 Visit(stmt->then_statement()); |
928 | 928 |
929 PrepareForBailoutForId(stmt->ElseId(), BailoutState::NO_REGISTERS); | 929 PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS); |
930 } | 930 } |
931 __ bind(&done); | 931 __ bind(&done); |
932 PrepareForBailoutForId(stmt->IfId(), BailoutState::NO_REGISTERS); | 932 PrepareForBailoutForId(stmt->IfId(), NO_REGISTERS); |
933 } | 933 } |
934 | 934 |
935 void FullCodeGenerator::EmitContinue(Statement* target) { | 935 void FullCodeGenerator::EmitContinue(Statement* target) { |
936 NestedStatement* current = nesting_stack_; | 936 NestedStatement* current = nesting_stack_; |
937 int context_length = 0; | 937 int context_length = 0; |
938 // When continuing, we clobber the unpredictable value in the accumulator | 938 // When continuing, we clobber the unpredictable value in the accumulator |
939 // with one that's safe for GC. If we hit an exit from the try block of | 939 // with one that's safe for GC. If we hit an exit from the try block of |
940 // try...finally on our way out, we will unconditionally preserve the | 940 // try...finally on our way out, we will unconditionally preserve the |
941 // accumulator on the stack. | 941 // accumulator on the stack. |
942 ClearAccumulator(); | 942 ClearAccumulator(); |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1086 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { | 1086 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { |
1087 // Stack: receiver, home_object, key. | 1087 // Stack: receiver, home_object, key. |
1088 SetExpressionPosition(prop); | 1088 SetExpressionPosition(prop); |
1089 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); | 1089 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); |
1090 } | 1090 } |
1091 | 1091 |
1092 void FullCodeGenerator::EmitPropertyKey(ObjectLiteralProperty* property, | 1092 void FullCodeGenerator::EmitPropertyKey(ObjectLiteralProperty* property, |
1093 BailoutId bailout_id) { | 1093 BailoutId bailout_id) { |
1094 VisitForStackValue(property->key()); | 1094 VisitForStackValue(property->key()); |
1095 CallRuntimeWithOperands(Runtime::kToName); | 1095 CallRuntimeWithOperands(Runtime::kToName); |
1096 PrepareForBailoutForId(bailout_id, BailoutState::NO_REGISTERS); | 1096 PrepareForBailoutForId(bailout_id, NO_REGISTERS); |
1097 PushOperand(result_register()); | 1097 PushOperand(result_register()); |
1098 } | 1098 } |
1099 | 1099 |
1100 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorSlot slot) { | 1100 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorSlot slot) { |
1101 DCHECK(!slot.IsInvalid()); | 1101 DCHECK(!slot.IsInvalid()); |
1102 __ Move(VectorStoreICTrampolineDescriptor::SlotRegister(), SmiFromSlot(slot)); | 1102 __ Move(VectorStoreICTrampolineDescriptor::SlotRegister(), SmiFromSlot(slot)); |
1103 } | 1103 } |
1104 | 1104 |
1105 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { | 1105 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { |
1106 Comment cmnt(masm_, "[ ReturnStatement"); | 1106 Comment cmnt(masm_, "[ ReturnStatement"); |
1107 SetStatementPosition(stmt); | 1107 SetStatementPosition(stmt); |
1108 Expression* expr = stmt->expression(); | 1108 Expression* expr = stmt->expression(); |
1109 VisitForAccumulatorValue(expr); | 1109 VisitForAccumulatorValue(expr); |
1110 EmitUnwindAndReturn(); | 1110 EmitUnwindAndReturn(); |
1111 } | 1111 } |
1112 | 1112 |
1113 | 1113 |
1114 void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) { | 1114 void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) { |
1115 Comment cmnt(masm_, "[ WithStatement"); | 1115 Comment cmnt(masm_, "[ WithStatement"); |
1116 SetStatementPosition(stmt); | 1116 SetStatementPosition(stmt); |
1117 | 1117 |
1118 VisitForAccumulatorValue(stmt->expression()); | 1118 VisitForAccumulatorValue(stmt->expression()); |
1119 Callable callable = CodeFactory::ToObject(isolate()); | 1119 Callable callable = CodeFactory::ToObject(isolate()); |
1120 __ Move(callable.descriptor().GetRegisterParameter(0), result_register()); | 1120 __ Move(callable.descriptor().GetRegisterParameter(0), result_register()); |
1121 __ Call(callable.code(), RelocInfo::CODE_TARGET); | 1121 __ Call(callable.code(), RelocInfo::CODE_TARGET); |
1122 PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::NO_REGISTERS); | 1122 PrepareForBailoutForId(stmt->ToObjectId(), NO_REGISTERS); |
1123 PushOperand(result_register()); | 1123 PushOperand(result_register()); |
1124 PushFunctionArgumentForContextAllocation(); | 1124 PushFunctionArgumentForContextAllocation(); |
1125 CallRuntimeWithOperands(Runtime::kPushWithContext); | 1125 CallRuntimeWithOperands(Runtime::kPushWithContext); |
1126 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); | 1126 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); |
1127 PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS); | 1127 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); |
1128 | 1128 |
1129 Scope* saved_scope = scope(); | 1129 Scope* saved_scope = scope(); |
1130 scope_ = stmt->scope(); | 1130 scope_ = stmt->scope(); |
1131 { WithOrCatch body(this); | 1131 { WithOrCatch body(this); |
1132 Visit(stmt->statement()); | 1132 Visit(stmt->statement()); |
1133 } | 1133 } |
1134 scope_ = saved_scope; | 1134 scope_ = saved_scope; |
1135 | 1135 |
1136 // Pop context. | 1136 // Pop context. |
1137 LoadContextField(context_register(), Context::PREVIOUS_INDEX); | 1137 LoadContextField(context_register(), Context::PREVIOUS_INDEX); |
(...skipping 11 matching lines...) Expand all Loading... |
1149 | 1149 |
1150 Iteration loop_statement(this, stmt); | 1150 Iteration loop_statement(this, stmt); |
1151 increment_loop_depth(); | 1151 increment_loop_depth(); |
1152 | 1152 |
1153 __ bind(&body); | 1153 __ bind(&body); |
1154 Visit(stmt->body()); | 1154 Visit(stmt->body()); |
1155 | 1155 |
1156 // Record the position of the do while condition and make sure it is | 1156 // Record the position of the do while condition and make sure it is |
1157 // possible to break on the condition. | 1157 // possible to break on the condition. |
1158 __ bind(loop_statement.continue_label()); | 1158 __ bind(loop_statement.continue_label()); |
1159 PrepareForBailoutForId(stmt->ContinueId(), BailoutState::NO_REGISTERS); | 1159 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); |
1160 | 1160 |
1161 // Here is the actual 'while' keyword. | 1161 // Here is the actual 'while' keyword. |
1162 SetExpressionAsStatementPosition(stmt->cond()); | 1162 SetExpressionAsStatementPosition(stmt->cond()); |
1163 VisitForControl(stmt->cond(), | 1163 VisitForControl(stmt->cond(), |
1164 &book_keeping, | 1164 &book_keeping, |
1165 loop_statement.break_label(), | 1165 loop_statement.break_label(), |
1166 &book_keeping); | 1166 &book_keeping); |
1167 | 1167 |
1168 // Check stack before looping. | 1168 // Check stack before looping. |
1169 PrepareForBailoutForId(stmt->BackEdgeId(), BailoutState::NO_REGISTERS); | 1169 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); |
1170 __ bind(&book_keeping); | 1170 __ bind(&book_keeping); |
1171 EmitBackEdgeBookkeeping(stmt, &body); | 1171 EmitBackEdgeBookkeeping(stmt, &body); |
1172 __ jmp(&body); | 1172 __ jmp(&body); |
1173 | 1173 |
1174 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); | 1174 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
1175 __ bind(loop_statement.break_label()); | 1175 __ bind(loop_statement.break_label()); |
1176 decrement_loop_depth(); | 1176 decrement_loop_depth(); |
1177 } | 1177 } |
1178 | 1178 |
1179 | 1179 |
1180 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { | 1180 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { |
1181 Comment cmnt(masm_, "[ WhileStatement"); | 1181 Comment cmnt(masm_, "[ WhileStatement"); |
1182 Label loop, body; | 1182 Label loop, body; |
1183 | 1183 |
1184 Iteration loop_statement(this, stmt); | 1184 Iteration loop_statement(this, stmt); |
1185 increment_loop_depth(); | 1185 increment_loop_depth(); |
1186 | 1186 |
1187 __ bind(&loop); | 1187 __ bind(&loop); |
1188 | 1188 |
1189 SetExpressionAsStatementPosition(stmt->cond()); | 1189 SetExpressionAsStatementPosition(stmt->cond()); |
1190 VisitForControl(stmt->cond(), | 1190 VisitForControl(stmt->cond(), |
1191 &body, | 1191 &body, |
1192 loop_statement.break_label(), | 1192 loop_statement.break_label(), |
1193 &body); | 1193 &body); |
1194 | 1194 |
1195 PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS); | 1195 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); |
1196 __ bind(&body); | 1196 __ bind(&body); |
1197 Visit(stmt->body()); | 1197 Visit(stmt->body()); |
1198 | 1198 |
1199 __ bind(loop_statement.continue_label()); | 1199 __ bind(loop_statement.continue_label()); |
1200 | 1200 |
1201 // Check stack before looping. | 1201 // Check stack before looping. |
1202 EmitBackEdgeBookkeeping(stmt, &loop); | 1202 EmitBackEdgeBookkeeping(stmt, &loop); |
1203 __ jmp(&loop); | 1203 __ jmp(&loop); |
1204 | 1204 |
1205 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); | 1205 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
1206 __ bind(loop_statement.break_label()); | 1206 __ bind(loop_statement.break_label()); |
1207 decrement_loop_depth(); | 1207 decrement_loop_depth(); |
1208 } | 1208 } |
1209 | 1209 |
1210 | 1210 |
1211 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { | 1211 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { |
1212 Comment cmnt(masm_, "[ ForStatement"); | 1212 Comment cmnt(masm_, "[ ForStatement"); |
1213 // Do not insert break location as we do it below. | 1213 // Do not insert break location as we do it below. |
1214 SetStatementPosition(stmt, SKIP_BREAK); | 1214 SetStatementPosition(stmt, SKIP_BREAK); |
1215 | 1215 |
1216 Label test, body; | 1216 Label test, body; |
1217 | 1217 |
1218 Iteration loop_statement(this, stmt); | 1218 Iteration loop_statement(this, stmt); |
1219 | 1219 |
1220 if (stmt->init() != NULL) { | 1220 if (stmt->init() != NULL) { |
1221 Visit(stmt->init()); | 1221 Visit(stmt->init()); |
1222 } | 1222 } |
1223 | 1223 |
1224 increment_loop_depth(); | 1224 increment_loop_depth(); |
1225 // Emit the test at the bottom of the loop (even if empty). | 1225 // Emit the test at the bottom of the loop (even if empty). |
1226 __ jmp(&test); | 1226 __ jmp(&test); |
1227 | 1227 |
1228 PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS); | 1228 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); |
1229 __ bind(&body); | 1229 __ bind(&body); |
1230 Visit(stmt->body()); | 1230 Visit(stmt->body()); |
1231 | 1231 |
1232 PrepareForBailoutForId(stmt->ContinueId(), BailoutState::NO_REGISTERS); | 1232 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); |
1233 __ bind(loop_statement.continue_label()); | 1233 __ bind(loop_statement.continue_label()); |
1234 if (stmt->next() != NULL) { | 1234 if (stmt->next() != NULL) { |
1235 SetStatementPosition(stmt->next()); | 1235 SetStatementPosition(stmt->next()); |
1236 Visit(stmt->next()); | 1236 Visit(stmt->next()); |
1237 } | 1237 } |
1238 | 1238 |
1239 // Check stack before looping. | 1239 // Check stack before looping. |
1240 EmitBackEdgeBookkeeping(stmt, &body); | 1240 EmitBackEdgeBookkeeping(stmt, &body); |
1241 | 1241 |
1242 __ bind(&test); | 1242 __ bind(&test); |
1243 if (stmt->cond() != NULL) { | 1243 if (stmt->cond() != NULL) { |
1244 SetExpressionAsStatementPosition(stmt->cond()); | 1244 SetExpressionAsStatementPosition(stmt->cond()); |
1245 VisitForControl(stmt->cond(), | 1245 VisitForControl(stmt->cond(), |
1246 &body, | 1246 &body, |
1247 loop_statement.break_label(), | 1247 loop_statement.break_label(), |
1248 loop_statement.break_label()); | 1248 loop_statement.break_label()); |
1249 } else { | 1249 } else { |
1250 __ jmp(&body); | 1250 __ jmp(&body); |
1251 } | 1251 } |
1252 | 1252 |
1253 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); | 1253 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
1254 __ bind(loop_statement.break_label()); | 1254 __ bind(loop_statement.break_label()); |
1255 decrement_loop_depth(); | 1255 decrement_loop_depth(); |
1256 } | 1256 } |
1257 | 1257 |
1258 | 1258 |
1259 void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { | 1259 void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { |
1260 Comment cmnt(masm_, "[ ForOfStatement"); | 1260 Comment cmnt(masm_, "[ ForOfStatement"); |
1261 | 1261 |
1262 Iteration loop_statement(this, stmt); | 1262 Iteration loop_statement(this, stmt); |
1263 increment_loop_depth(); | 1263 increment_loop_depth(); |
(...skipping 15 matching lines...) Expand all Loading... |
1279 &result_not_done, &result_not_done); | 1279 &result_not_done, &result_not_done); |
1280 __ bind(&result_not_done); | 1280 __ bind(&result_not_done); |
1281 | 1281 |
1282 // each = result.value | 1282 // each = result.value |
1283 VisitForEffect(stmt->assign_each()); | 1283 VisitForEffect(stmt->assign_each()); |
1284 | 1284 |
1285 // Generate code for the body of the loop. | 1285 // Generate code for the body of the loop. |
1286 Visit(stmt->body()); | 1286 Visit(stmt->body()); |
1287 | 1287 |
1288 // Check stack before looping. | 1288 // Check stack before looping. |
1289 PrepareForBailoutForId(stmt->BackEdgeId(), BailoutState::NO_REGISTERS); | 1289 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); |
1290 EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label()); | 1290 EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label()); |
1291 __ jmp(loop_statement.continue_label()); | 1291 __ jmp(loop_statement.continue_label()); |
1292 | 1292 |
1293 // Exit and decrement the loop depth. | 1293 // Exit and decrement the loop depth. |
1294 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); | 1294 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
1295 __ bind(loop_statement.break_label()); | 1295 __ bind(loop_statement.break_label()); |
1296 decrement_loop_depth(); | 1296 decrement_loop_depth(); |
1297 } | 1297 } |
1298 | 1298 |
1299 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { | 1299 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { |
1300 LoadFromFrameField(JavaScriptFrameConstants::kFunctionOffset, | 1300 LoadFromFrameField(JavaScriptFrameConstants::kFunctionOffset, |
1301 result_register()); | 1301 result_register()); |
1302 context()->Plug(result_register()); | 1302 context()->Plug(result_register()); |
1303 } | 1303 } |
1304 | 1304 |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1428 } | 1428 } |
1429 | 1429 |
1430 | 1430 |
1431 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { | 1431 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { |
1432 Comment cmnt(masm_, "[ DebuggerStatement"); | 1432 Comment cmnt(masm_, "[ DebuggerStatement"); |
1433 SetStatementPosition(stmt); | 1433 SetStatementPosition(stmt); |
1434 | 1434 |
1435 __ DebugBreak(); | 1435 __ DebugBreak(); |
1436 // Ignore the return value. | 1436 // Ignore the return value. |
1437 | 1437 |
1438 PrepareForBailoutForId(stmt->DebugBreakId(), BailoutState::NO_REGISTERS); | 1438 PrepareForBailoutForId(stmt->DebugBreakId(), NO_REGISTERS); |
1439 } | 1439 } |
1440 | 1440 |
1441 | 1441 |
1442 void FullCodeGenerator::VisitCaseClause(CaseClause* clause) { | 1442 void FullCodeGenerator::VisitCaseClause(CaseClause* clause) { |
1443 UNREACHABLE(); | 1443 UNREACHABLE(); |
1444 } | 1444 } |
1445 | 1445 |
1446 | 1446 |
1447 void FullCodeGenerator::VisitConditional(Conditional* expr) { | 1447 void FullCodeGenerator::VisitConditional(Conditional* expr) { |
1448 Comment cmnt(masm_, "[ Conditional"); | 1448 Comment cmnt(masm_, "[ Conditional"); |
1449 Label true_case, false_case, done; | 1449 Label true_case, false_case, done; |
1450 VisitForControl(expr->condition(), &true_case, &false_case, &true_case); | 1450 VisitForControl(expr->condition(), &true_case, &false_case, &true_case); |
1451 | 1451 |
1452 int original_stack_depth = operand_stack_depth_; | 1452 int original_stack_depth = operand_stack_depth_; |
1453 PrepareForBailoutForId(expr->ThenId(), BailoutState::NO_REGISTERS); | 1453 PrepareForBailoutForId(expr->ThenId(), NO_REGISTERS); |
1454 __ bind(&true_case); | 1454 __ bind(&true_case); |
1455 SetExpressionPosition(expr->then_expression()); | 1455 SetExpressionPosition(expr->then_expression()); |
1456 if (context()->IsTest()) { | 1456 if (context()->IsTest()) { |
1457 const TestContext* for_test = TestContext::cast(context()); | 1457 const TestContext* for_test = TestContext::cast(context()); |
1458 VisitForControl(expr->then_expression(), | 1458 VisitForControl(expr->then_expression(), |
1459 for_test->true_label(), | 1459 for_test->true_label(), |
1460 for_test->false_label(), | 1460 for_test->false_label(), |
1461 NULL); | 1461 NULL); |
1462 } else { | 1462 } else { |
1463 VisitInDuplicateContext(expr->then_expression()); | 1463 VisitInDuplicateContext(expr->then_expression()); |
1464 __ jmp(&done); | 1464 __ jmp(&done); |
1465 } | 1465 } |
1466 | 1466 |
1467 operand_stack_depth_ = original_stack_depth; | 1467 operand_stack_depth_ = original_stack_depth; |
1468 PrepareForBailoutForId(expr->ElseId(), BailoutState::NO_REGISTERS); | 1468 PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS); |
1469 __ bind(&false_case); | 1469 __ bind(&false_case); |
1470 SetExpressionPosition(expr->else_expression()); | 1470 SetExpressionPosition(expr->else_expression()); |
1471 VisitInDuplicateContext(expr->else_expression()); | 1471 VisitInDuplicateContext(expr->else_expression()); |
1472 // If control flow falls through Visit, merge it with true case here. | 1472 // If control flow falls through Visit, merge it with true case here. |
1473 if (!context()->IsTest()) { | 1473 if (!context()->IsTest()) { |
1474 __ bind(&done); | 1474 __ bind(&done); |
1475 } | 1475 } |
1476 } | 1476 } |
1477 | 1477 |
1478 | 1478 |
(...skipping 30 matching lines...) Expand all Loading... |
1509 } else { | 1509 } else { |
1510 PushOperand(isolate()->factory()->the_hole_value()); | 1510 PushOperand(isolate()->factory()->the_hole_value()); |
1511 } | 1511 } |
1512 | 1512 |
1513 VisitForStackValue(lit->constructor()); | 1513 VisitForStackValue(lit->constructor()); |
1514 | 1514 |
1515 PushOperand(Smi::FromInt(lit->start_position())); | 1515 PushOperand(Smi::FromInt(lit->start_position())); |
1516 PushOperand(Smi::FromInt(lit->end_position())); | 1516 PushOperand(Smi::FromInt(lit->end_position())); |
1517 | 1517 |
1518 CallRuntimeWithOperands(Runtime::kDefineClass); | 1518 CallRuntimeWithOperands(Runtime::kDefineClass); |
1519 PrepareForBailoutForId(lit->CreateLiteralId(), BailoutState::TOS_REGISTER); | 1519 PrepareForBailoutForId(lit->CreateLiteralId(), TOS_REG); |
1520 PushOperand(result_register()); | 1520 PushOperand(result_register()); |
1521 | 1521 |
1522 // Load the "prototype" from the constructor. | 1522 // Load the "prototype" from the constructor. |
1523 __ Move(LoadDescriptor::ReceiverRegister(), result_register()); | 1523 __ Move(LoadDescriptor::ReceiverRegister(), result_register()); |
1524 __ LoadRoot(LoadDescriptor::NameRegister(), | 1524 __ LoadRoot(LoadDescriptor::NameRegister(), |
1525 Heap::kprototype_stringRootIndex); | 1525 Heap::kprototype_stringRootIndex); |
1526 __ Move(LoadDescriptor::SlotRegister(), SmiFromSlot(lit->PrototypeSlot())); | 1526 __ Move(LoadDescriptor::SlotRegister(), SmiFromSlot(lit->PrototypeSlot())); |
1527 CallLoadIC(NOT_INSIDE_TYPEOF); | 1527 CallLoadIC(NOT_INSIDE_TYPEOF); |
1528 PrepareForBailoutForId(lit->PrototypeId(), BailoutState::TOS_REGISTER); | 1528 PrepareForBailoutForId(lit->PrototypeId(), TOS_REG); |
1529 PushOperand(result_register()); | 1529 PushOperand(result_register()); |
1530 | 1530 |
1531 EmitClassDefineProperties(lit); | 1531 EmitClassDefineProperties(lit); |
1532 DropOperands(1); | 1532 DropOperands(1); |
1533 | 1533 |
1534 // Set the constructor to have fast properties. | 1534 // Set the constructor to have fast properties. |
1535 CallRuntimeWithOperands(Runtime::kToFastProperties); | 1535 CallRuntimeWithOperands(Runtime::kToFastProperties); |
1536 | 1536 |
1537 if (lit->class_variable_proxy() != nullptr) { | 1537 if (lit->class_variable_proxy() != nullptr) { |
1538 EmitVariableAssignment(lit->class_variable_proxy()->var(), Token::INIT, | 1538 EmitVariableAssignment(lit->class_variable_proxy()->var(), Token::INIT, |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1659 | 1659 |
1660 if (expr->is_jsruntime()) { | 1660 if (expr->is_jsruntime()) { |
1661 Comment cmnt(masm_, "[ CallRuntime"); | 1661 Comment cmnt(masm_, "[ CallRuntime"); |
1662 EmitLoadJSRuntimeFunction(expr); | 1662 EmitLoadJSRuntimeFunction(expr); |
1663 | 1663 |
1664 // Push the arguments ("left-to-right"). | 1664 // Push the arguments ("left-to-right"). |
1665 for (int i = 0; i < arg_count; i++) { | 1665 for (int i = 0; i < arg_count; i++) { |
1666 VisitForStackValue(args->at(i)); | 1666 VisitForStackValue(args->at(i)); |
1667 } | 1667 } |
1668 | 1668 |
1669 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); | 1669 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
1670 EmitCallJSRuntimeFunction(expr); | 1670 EmitCallJSRuntimeFunction(expr); |
1671 context()->DropAndPlug(1, result_register()); | 1671 context()->DropAndPlug(1, result_register()); |
1672 | 1672 |
1673 } else { | 1673 } else { |
1674 const Runtime::Function* function = expr->function(); | 1674 const Runtime::Function* function = expr->function(); |
1675 switch (function->function_id) { | 1675 switch (function->function_id) { |
1676 #define CALL_INTRINSIC_GENERATOR(Name) \ | 1676 #define CALL_INTRINSIC_GENERATOR(Name) \ |
1677 case Runtime::kInline##Name: { \ | 1677 case Runtime::kInline##Name: { \ |
1678 Comment cmnt(masm_, "[ Inline" #Name); \ | 1678 Comment cmnt(masm_, "[ Inline" #Name); \ |
1679 return Emit##Name(expr); \ | 1679 return Emit##Name(expr); \ |
1680 } | 1680 } |
1681 FOR_EACH_FULL_CODE_INTRINSIC(CALL_INTRINSIC_GENERATOR) | 1681 FOR_EACH_FULL_CODE_INTRINSIC(CALL_INTRINSIC_GENERATOR) |
1682 #undef CALL_INTRINSIC_GENERATOR | 1682 #undef CALL_INTRINSIC_GENERATOR |
1683 default: { | 1683 default: { |
1684 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic"); | 1684 Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic"); |
1685 // Push the arguments ("left-to-right"). | 1685 // Push the arguments ("left-to-right"). |
1686 for (int i = 0; i < arg_count; i++) { | 1686 for (int i = 0; i < arg_count; i++) { |
1687 VisitForStackValue(args->at(i)); | 1687 VisitForStackValue(args->at(i)); |
1688 } | 1688 } |
1689 | 1689 |
1690 // Call the C runtime function. | 1690 // Call the C runtime function. |
1691 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); | 1691 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
1692 __ CallRuntime(expr->function(), arg_count); | 1692 __ CallRuntime(expr->function(), arg_count); |
1693 OperandStackDepthDecrement(arg_count); | 1693 OperandStackDepthDecrement(arg_count); |
1694 context()->Plug(result_register()); | 1694 context()->Plug(result_register()); |
1695 } | 1695 } |
1696 } | 1696 } |
1697 } | 1697 } |
1698 } | 1698 } |
1699 | 1699 |
1700 void FullCodeGenerator::VisitSpread(Spread* expr) { UNREACHABLE(); } | 1700 void FullCodeGenerator::VisitSpread(Spread* expr) { UNREACHABLE(); } |
1701 | 1701 |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1870 #endif // DEBUG | 1870 #endif // DEBUG |
1871 | 1871 |
1872 | 1872 |
1873 FullCodeGenerator::EnterBlockScopeIfNeeded::EnterBlockScopeIfNeeded( | 1873 FullCodeGenerator::EnterBlockScopeIfNeeded::EnterBlockScopeIfNeeded( |
1874 FullCodeGenerator* codegen, Scope* scope, BailoutId entry_id, | 1874 FullCodeGenerator* codegen, Scope* scope, BailoutId entry_id, |
1875 BailoutId declarations_id, BailoutId exit_id) | 1875 BailoutId declarations_id, BailoutId exit_id) |
1876 : codegen_(codegen), exit_id_(exit_id) { | 1876 : codegen_(codegen), exit_id_(exit_id) { |
1877 saved_scope_ = codegen_->scope(); | 1877 saved_scope_ = codegen_->scope(); |
1878 | 1878 |
1879 if (scope == NULL) { | 1879 if (scope == NULL) { |
1880 codegen_->PrepareForBailoutForId(entry_id, BailoutState::NO_REGISTERS); | 1880 codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS); |
1881 needs_block_context_ = false; | 1881 needs_block_context_ = false; |
1882 } else { | 1882 } else { |
1883 needs_block_context_ = scope->NeedsContext(); | 1883 needs_block_context_ = scope->NeedsContext(); |
1884 codegen_->scope_ = scope; | 1884 codegen_->scope_ = scope; |
1885 { | 1885 { |
1886 if (needs_block_context_) { | 1886 if (needs_block_context_) { |
1887 Comment cmnt(masm(), "[ Extend block context"); | 1887 Comment cmnt(masm(), "[ Extend block context"); |
1888 codegen_->PushOperand(scope->GetScopeInfo(codegen->isolate())); | 1888 codegen_->PushOperand(scope->GetScopeInfo(codegen->isolate())); |
1889 codegen_->PushFunctionArgumentForContextAllocation(); | 1889 codegen_->PushFunctionArgumentForContextAllocation(); |
1890 codegen_->CallRuntimeWithOperands(Runtime::kPushBlockContext); | 1890 codegen_->CallRuntimeWithOperands(Runtime::kPushBlockContext); |
1891 | 1891 |
1892 // Replace the context stored in the frame. | 1892 // Replace the context stored in the frame. |
1893 codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset, | 1893 codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset, |
1894 codegen_->context_register()); | 1894 codegen_->context_register()); |
1895 } | 1895 } |
1896 CHECK_EQ(0, scope->num_stack_slots()); | 1896 CHECK_EQ(0, scope->num_stack_slots()); |
1897 codegen_->PrepareForBailoutForId(entry_id, BailoutState::NO_REGISTERS); | 1897 codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS); |
1898 } | 1898 } |
1899 { | 1899 { |
1900 Comment cmnt(masm(), "[ Declarations"); | 1900 Comment cmnt(masm(), "[ Declarations"); |
1901 codegen_->VisitDeclarations(scope->declarations()); | 1901 codegen_->VisitDeclarations(scope->declarations()); |
1902 codegen_->PrepareForBailoutForId(declarations_id, | 1902 codegen_->PrepareForBailoutForId(declarations_id, NO_REGISTERS); |
1903 BailoutState::NO_REGISTERS); | |
1904 } | 1903 } |
1905 } | 1904 } |
1906 } | 1905 } |
1907 | 1906 |
1908 | 1907 |
1909 FullCodeGenerator::EnterBlockScopeIfNeeded::~EnterBlockScopeIfNeeded() { | 1908 FullCodeGenerator::EnterBlockScopeIfNeeded::~EnterBlockScopeIfNeeded() { |
1910 if (needs_block_context_) { | 1909 if (needs_block_context_) { |
1911 codegen_->LoadContextField(codegen_->context_register(), | 1910 codegen_->LoadContextField(codegen_->context_register(), |
1912 Context::PREVIOUS_INDEX); | 1911 Context::PREVIOUS_INDEX); |
1913 // Update local stack frame context field. | 1912 // Update local stack frame context field. |
1914 codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset, | 1913 codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset, |
1915 codegen_->context_register()); | 1914 codegen_->context_register()); |
1916 } | 1915 } |
1917 codegen_->PrepareForBailoutForId(exit_id_, BailoutState::NO_REGISTERS); | 1916 codegen_->PrepareForBailoutForId(exit_id_, NO_REGISTERS); |
1918 codegen_->scope_ = saved_scope_; | 1917 codegen_->scope_ = saved_scope_; |
1919 } | 1918 } |
1920 | 1919 |
1921 | 1920 |
1922 bool FullCodeGenerator::NeedsHoleCheckForLoad(VariableProxy* proxy) { | 1921 bool FullCodeGenerator::NeedsHoleCheckForLoad(VariableProxy* proxy) { |
1923 Variable* var = proxy->var(); | 1922 Variable* var = proxy->var(); |
1924 | 1923 |
1925 if (!var->binding_needs_init()) { | 1924 if (!var->binding_needs_init()) { |
1926 return false; | 1925 return false; |
1927 } | 1926 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1976 return var->scope()->is_nonlinear() || | 1975 return var->scope()->is_nonlinear() || |
1977 var->initializer_position() >= proxy->position(); | 1976 var->initializer_position() >= proxy->position(); |
1978 } | 1977 } |
1979 | 1978 |
1980 | 1979 |
1981 #undef __ | 1980 #undef __ |
1982 | 1981 |
1983 | 1982 |
1984 } // namespace internal | 1983 } // namespace internal |
1985 } // namespace v8 | 1984 } // namespace v8 |
OLD | NEW |