OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/interpreter/bytecode-generator.h" | 5 #include "src/interpreter/bytecode-generator.h" |
6 | 6 |
7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
8 #include "src/interpreter/control-flow-builders.h" | 8 #include "src/interpreter/control-flow-builders.h" |
9 #include "src/objects.h" | 9 #include "src/objects.h" |
10 #include "src/parser.h" | 10 #include "src/parser.h" |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 | 367 |
368 // Visit declarations within the function scope. | 368 // Visit declarations within the function scope. |
369 VisitDeclarations(scope()->declarations()); | 369 VisitDeclarations(scope()->declarations()); |
370 | 370 |
371 // Visit statements in the function body. | 371 // Visit statements in the function body. |
372 VisitStatements(info()->literal()->body()); | 372 VisitStatements(info()->literal()->body()); |
373 } | 373 } |
374 | 374 |
375 | 375 |
376 void BytecodeGenerator::VisitBlock(Block* stmt) { | 376 void BytecodeGenerator::VisitBlock(Block* stmt) { |
377 builder()->EnterBlock(); | |
378 if (stmt->scope() == NULL) { | 377 if (stmt->scope() == NULL) { |
379 // Visit statements in the same scope, no declarations. | 378 // Visit statements in the same scope, no declarations. |
380 VisitStatements(stmt->statements()); | 379 VisitStatements(stmt->statements()); |
381 } else { | 380 } else { |
382 // Visit declarations and statements in a block scope. | 381 // Visit declarations and statements in a block scope. |
383 if (stmt->scope()->NeedsContext()) { | 382 if (stmt->scope()->NeedsContext()) { |
384 VisitNewLocalBlockContext(stmt->scope()); | 383 VisitNewLocalBlockContext(stmt->scope()); |
385 ContextScope scope(this, stmt->scope()); | 384 ContextScope scope(this, stmt->scope()); |
386 VisitDeclarations(stmt->scope()->declarations()); | 385 VisitDeclarations(stmt->scope()->declarations()); |
387 VisitStatements(stmt->statements()); | 386 VisitStatements(stmt->statements()); |
388 } else { | 387 } else { |
389 VisitDeclarations(stmt->scope()->declarations()); | 388 VisitDeclarations(stmt->scope()->declarations()); |
390 VisitStatements(stmt->statements()); | 389 VisitStatements(stmt->statements()); |
391 } | 390 } |
392 } | 391 } |
393 builder()->LeaveBlock(); | |
394 } | 392 } |
395 | 393 |
396 | 394 |
397 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { | 395 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { |
398 Variable* variable = decl->proxy()->var(); | 396 Variable* variable = decl->proxy()->var(); |
399 VariableMode mode = decl->mode(); | 397 VariableMode mode = decl->mode(); |
400 // Const and let variables are initialized with the hole so that we can | 398 // Const and let variables are initialized with the hole so that we can |
401 // check that they are only assigned once. | 399 // check that they are only assigned once. |
402 bool hole_init = mode == CONST || mode == CONST_LEGACY || mode == LET; | 400 bool hole_init = mode == CONST || mode == CONST_LEGACY || mode == LET; |
403 switch (variable->location()) { | 401 switch (variable->location()) { |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
775 if (stmt->subject()->IsNullLiteral() || | 773 if (stmt->subject()->IsNullLiteral() || |
776 stmt->subject()->IsUndefinedLiteral(isolate())) { | 774 stmt->subject()->IsUndefinedLiteral(isolate())) { |
777 // ForIn generates lots of code, skip if it wouldn't produce any effects. | 775 // ForIn generates lots of code, skip if it wouldn't produce any effects. |
778 return; | 776 return; |
779 } | 777 } |
780 | 778 |
781 LoopBuilder loop_builder(builder()); | 779 LoopBuilder loop_builder(builder()); |
782 ControlScopeForIteration control_scope(this, stmt, &loop_builder); | 780 ControlScopeForIteration control_scope(this, stmt, &loop_builder); |
783 | 781 |
784 // Prepare the state for executing ForIn. | 782 // Prepare the state for executing ForIn. |
785 builder()->EnterBlock(); | |
786 VisitForAccumulatorValue(stmt->subject()); | 783 VisitForAccumulatorValue(stmt->subject()); |
787 loop_builder.BreakIfUndefined(); | 784 loop_builder.BreakIfUndefined(); |
788 loop_builder.BreakIfNull(); | 785 loop_builder.BreakIfNull(); |
789 | 786 |
790 Register receiver = execution_result()->NewRegister(); | 787 Register receiver = execution_result()->NewRegister(); |
791 builder()->CastAccumulatorToJSObject(); | 788 builder()->CastAccumulatorToJSObject(); |
792 builder()->StoreAccumulatorInRegister(receiver); | 789 builder()->StoreAccumulatorInRegister(receiver); |
793 builder()->CallRuntime(Runtime::kGetPropertyNamesFast, receiver, 1); | 790 builder()->CallRuntime(Runtime::kGetPropertyNamesFast, receiver, 1); |
794 builder()->ForInPrepare(receiver); | 791 builder()->ForInPrepare(receiver); |
795 loop_builder.BreakIfUndefined(); | 792 loop_builder.BreakIfUndefined(); |
(...skipping 25 matching lines...) Expand all Loading... |
821 // even an empty body will have this assignment. | 818 // even an empty body will have this assignment. |
822 Visit(stmt->body()); | 819 Visit(stmt->body()); |
823 | 820 |
824 // Increment the index and start loop again. | 821 // Increment the index and start loop again. |
825 builder() | 822 builder() |
826 ->Bind(&continue_label) | 823 ->Bind(&continue_label) |
827 .LoadAccumulatorWithRegister(index) | 824 .LoadAccumulatorWithRegister(index) |
828 .CountOperation(Token::Value::ADD, language_mode_strength()) | 825 .CountOperation(Token::Value::ADD, language_mode_strength()) |
829 .Jump(&condition_label); | 826 .Jump(&condition_label); |
830 | 827 |
831 // End of loop | 828 // End of the loop. |
832 builder()->Bind(&break_label).LeaveBlock(); | 829 builder()->Bind(&break_label); |
833 | 830 |
834 loop_builder.SetBreakTarget(break_label); | 831 loop_builder.SetBreakTarget(break_label); |
835 loop_builder.SetContinueTarget(continue_label); | 832 loop_builder.SetContinueTarget(continue_label); |
836 } | 833 } |
837 | 834 |
838 | 835 |
839 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { | 836 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { |
840 UNIMPLEMENTED(); | 837 UNIMPLEMENTED(); |
841 } | 838 } |
842 | 839 |
(...skipping 1320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2163 } | 2160 } |
2164 | 2161 |
2165 | 2162 |
2166 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 2163 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
2167 return info()->feedback_vector()->GetIndex(slot); | 2164 return info()->feedback_vector()->GetIndex(slot); |
2168 } | 2165 } |
2169 | 2166 |
2170 } // namespace interpreter | 2167 } // namespace interpreter |
2171 } // namespace internal | 2168 } // namespace internal |
2172 } // namespace v8 | 2169 } // namespace v8 |
OLD | NEW |