| 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 |