Chromium Code Reviews| 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 <stack> | 7 #include <stack> |
| 8 | 8 |
| 9 #include "src/compiler.h" | 9 #include "src/compiler.h" |
| 10 #include "src/objects.h" | 10 #include "src/objects.h" |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 38 if (scope()->is_function_scope() && scope()->function() != NULL) { | 38 if (scope()->is_function_scope() && scope()->function() != NULL) { |
| 39 VisitVariableDeclaration(scope()->function()); | 39 VisitVariableDeclaration(scope()->function()); |
| 40 } | 40 } |
| 41 | 41 |
| 42 // Visit declarations within the function scope. | 42 // Visit declarations within the function scope. |
| 43 VisitDeclarations(scope()->declarations()); | 43 VisitDeclarations(scope()->declarations()); |
| 44 | 44 |
| 45 // Visit statements in the function body. | 45 // Visit statements in the function body. |
| 46 VisitStatements(info->literal()->body()); | 46 VisitStatements(info->literal()->body()); |
| 47 | 47 |
| 48 // If the last bytecode wasn't a return, then return 'undefined' to avoid | |
| 49 // falling off the end. | |
| 50 if (!builder_.HasExplicitReturn()) { | |
| 51 builder_.LoadUndefined(); | |
| 52 builder_.Return(); | |
| 53 } | |
| 54 | |
| 55 set_scope(nullptr); | 48 set_scope(nullptr); |
| 56 set_info(nullptr); | 49 set_info(nullptr); |
| 57 return builder_.ToBytecodeArray(); | 50 return builder_.ToBytecodeArray(); |
| 58 } | 51 } |
| 59 | 52 |
| 60 | 53 |
| 61 void BytecodeGenerator::VisitBlock(Block* node) { | 54 void BytecodeGenerator::VisitBlock(Block* node) { |
| 55 builder().EnterBlock(); | |
| 62 if (node->scope() == NULL) { | 56 if (node->scope() == NULL) { |
| 63 // Visit statements in the same scope, no declarations. | 57 // Visit statements in the same scope, no declarations. |
| 64 VisitStatements(node->statements()); | 58 VisitStatements(node->statements()); |
| 65 } else { | 59 } else { |
| 66 // Visit declarations and statements in a block scope. | 60 // Visit declarations and statements in a block scope. |
| 67 if (node->scope()->ContextLocalCount() > 0) { | 61 if (node->scope()->ContextLocalCount() > 0) { |
| 68 UNIMPLEMENTED(); | 62 UNIMPLEMENTED(); |
| 69 } else { | 63 } else { |
| 70 VisitDeclarations(node->scope()->declarations()); | 64 VisitDeclarations(node->scope()->declarations()); |
| 71 VisitStatements(node->statements()); | 65 VisitStatements(node->statements()); |
| 72 } | 66 } |
| 73 } | 67 } |
| 68 builder().LeaveBlock(); | |
| 74 } | 69 } |
| 75 | 70 |
| 76 | 71 |
| 77 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { | 72 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { |
| 78 Variable* variable = decl->proxy()->var(); | 73 Variable* variable = decl->proxy()->var(); |
| 79 switch (variable->location()) { | 74 switch (variable->location()) { |
| 80 case VariableLocation::GLOBAL: | 75 case VariableLocation::GLOBAL: |
| 81 case VariableLocation::UNALLOCATED: | 76 case VariableLocation::UNALLOCATED: |
| 82 UNIMPLEMENTED(); | 77 UNIMPLEMENTED(); |
| 83 break; | 78 break; |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 107 UNIMPLEMENTED(); | 102 UNIMPLEMENTED(); |
| 108 } | 103 } |
| 109 | 104 |
| 110 | 105 |
| 111 void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { | 106 void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { |
| 112 Visit(stmt->expression()); | 107 Visit(stmt->expression()); |
| 113 } | 108 } |
| 114 | 109 |
| 115 | 110 |
| 116 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { | 111 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { |
| 117 UNIMPLEMENTED(); | 112 // For control-flow it could be useful to signal empty paths here. |
|
rmcilroy
2015/09/23 14:00:29
nit - TODO(oth):
oth
2015/09/24 11:15:27
Done.
| |
| 118 } | 113 } |
| 119 | 114 |
| 120 | 115 |
| 121 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) { UNIMPLEMENTED(); } | 116 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) { |
| 117 // TODO(oth): spot easy cases if (true/1/false/0)? | |
|
rmcilroy
2015/09/23 14:00:29
nit - clarify comment please - e.g.: spot easy cas
oth
2015/09/24 11:15:27
Done.
| |
| 118 BytecodeLabel else_start, else_end; | |
| 119 Visit(stmt->condition()); | |
| 120 builder().CastAccumulatorToBoolean(); | |
| 121 builder().JumpIfFalse(&else_start); | |
| 122 Visit(stmt->then_statement()); | |
| 123 builder().Jump(&else_end); | |
| 124 builder().Bind(&else_start); | |
| 125 Visit(stmt->else_statement()); | |
| 126 builder().Bind(&else_end); | |
|
rmcilroy
2015/09/23 14:00:29
nit - maybe some whitespace between condition, the
oth
2015/09/24 11:15:27
Done.
| |
| 127 } | |
| 122 | 128 |
| 123 | 129 |
| 124 void BytecodeGenerator::VisitSloppyBlockFunctionStatement( | 130 void BytecodeGenerator::VisitSloppyBlockFunctionStatement( |
| 125 SloppyBlockFunctionStatement* stmt) { | 131 SloppyBlockFunctionStatement* stmt) { |
| 126 Visit(stmt->statement()); | 132 Visit(stmt->statement()); |
| 127 } | 133 } |
| 128 | 134 |
| 129 | 135 |
| 130 void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { | 136 void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { |
| 131 UNIMPLEMENTED(); | 137 UNIMPLEMENTED(); |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 451 UNIMPLEMENTED(); | 457 UNIMPLEMENTED(); |
| 452 break; | 458 break; |
| 453 default: | 459 default: |
| 454 VisitArithmeticExpression(binop); | 460 VisitArithmeticExpression(binop); |
| 455 break; | 461 break; |
| 456 } | 462 } |
| 457 } | 463 } |
| 458 | 464 |
| 459 | 465 |
| 460 void BytecodeGenerator::VisitCompareOperation(CompareOperation* expr) { | 466 void BytecodeGenerator::VisitCompareOperation(CompareOperation* expr) { |
| 461 UNIMPLEMENTED(); | 467 Token::Value op = expr->op(); |
| 468 Expression* left = expr->left(); | |
| 469 Expression* right = expr->right(); | |
| 470 | |
| 471 TemporaryRegisterScope temporary_register_scope(&builder_); | |
| 472 Register temporary = temporary_register_scope.NewRegister(); | |
| 473 | |
| 474 Visit(left); | |
| 475 builder().StoreAccumulatorInRegister(temporary); | |
| 476 Visit(right); | |
| 477 builder().CompareOperation(op, temporary, language_mode()); | |
| 462 } | 478 } |
| 463 | 479 |
| 464 | 480 |
| 465 void BytecodeGenerator::VisitSpread(Spread* expr) { UNREACHABLE(); } | 481 void BytecodeGenerator::VisitSpread(Spread* expr) { UNREACHABLE(); } |
| 466 | 482 |
| 467 | 483 |
| 468 void BytecodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) { | 484 void BytecodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) { |
| 469 UNREACHABLE(); | 485 UNREACHABLE(); |
| 470 } | 486 } |
| 471 | 487 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 506 } | 522 } |
| 507 | 523 |
| 508 | 524 |
| 509 int BytecodeGenerator::feedback_index(FeedbackVectorICSlot slot) const { | 525 int BytecodeGenerator::feedback_index(FeedbackVectorICSlot slot) const { |
| 510 return info()->feedback_vector()->GetIndex(slot); | 526 return info()->feedback_vector()->GetIndex(slot); |
| 511 } | 527 } |
| 512 | 528 |
| 513 } // namespace interpreter | 529 } // namespace interpreter |
| 514 } // namespace internal | 530 } // namespace internal |
| 515 } // namespace v8 | 531 } // namespace v8 |
| OLD | NEW |