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 "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
| 8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
| 9 #include "src/interpreter/bytecode-register-allocator.h" | 9 #include "src/interpreter/bytecode-register-allocator.h" |
| 10 #include "src/interpreter/control-flow-builders.h" | 10 #include "src/interpreter/control-flow-builders.h" |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 438 } else { | 438 } else { |
| 439 VisitDeclarations(stmt->scope()->declarations()); | 439 VisitDeclarations(stmt->scope()->declarations()); |
| 440 VisitStatements(stmt->statements()); | 440 VisitStatements(stmt->statements()); |
| 441 } | 441 } |
| 442 } | 442 } |
| 443 if (stmt->labels() != nullptr) block_builder.EndBlock(); | 443 if (stmt->labels() != nullptr) block_builder.EndBlock(); |
| 444 } | 444 } |
| 445 | 445 |
| 446 | 446 |
| 447 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { | 447 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { |
| 448 RegisterAllocationScope register_scope(this); | |
|
rmcilroy
2016/01/15 14:17:20
Instead of adding these, could you instead modify
mythria
2016/01/15 17:10:36
Done.
| |
| 449 | |
| 448 Variable* variable = decl->proxy()->var(); | 450 Variable* variable = decl->proxy()->var(); |
| 449 VariableMode mode = decl->mode(); | 451 VariableMode mode = decl->mode(); |
| 450 // Const and let variables are initialized with the hole so that we can | 452 // Const and let variables are initialized with the hole so that we can |
| 451 // check that they are only assigned once. | 453 // check that they are only assigned once. |
| 452 bool hole_init = mode == CONST || mode == CONST_LEGACY || mode == LET; | 454 bool hole_init = mode == CONST || mode == CONST_LEGACY || mode == LET; |
| 453 switch (variable->location()) { | 455 switch (variable->location()) { |
| 454 case VariableLocation::GLOBAL: | 456 case VariableLocation::GLOBAL: |
| 455 case VariableLocation::UNALLOCATED: { | 457 case VariableLocation::UNALLOCATED: { |
| 456 Handle<Oddball> value = variable->binding_needs_init() | 458 Handle<Oddball> value = variable->binding_needs_init() |
| 457 ? isolate()->factory()->the_hole_value() | 459 ? isolate()->factory()->the_hole_value() |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 473 Register destination(builder()->Parameter(variable->index() + 1)); | 475 Register destination(builder()->Parameter(variable->index() + 1)); |
| 474 builder()->LoadTheHole().StoreAccumulatorInRegister(destination); | 476 builder()->LoadTheHole().StoreAccumulatorInRegister(destination); |
| 475 } | 477 } |
| 476 break; | 478 break; |
| 477 case VariableLocation::CONTEXT: | 479 case VariableLocation::CONTEXT: |
| 478 if (hole_init) { | 480 if (hole_init) { |
| 479 builder()->LoadTheHole().StoreContextSlot(execution_context()->reg(), | 481 builder()->LoadTheHole().StoreContextSlot(execution_context()->reg(), |
| 480 variable->index()); | 482 variable->index()); |
| 481 } | 483 } |
| 482 break; | 484 break; |
| 483 case VariableLocation::LOOKUP: | 485 case VariableLocation::LOOKUP: { |
| 484 UNIMPLEMENTED(); | 486 DCHECK(IsDeclaredVariableMode(mode)); |
| 487 | |
| 488 register_allocator()->PrepareForConsecutiveAllocations(3); | |
| 489 Register name = register_allocator()->NextConsecutiveRegister(); | |
| 490 Register init_value = register_allocator()->NextConsecutiveRegister(); | |
| 491 Register attributes = register_allocator()->NextConsecutiveRegister(); | |
| 492 | |
| 493 builder()->LoadLiteral(variable->name()).StoreAccumulatorInRegister(name); | |
| 494 if (hole_init) { | |
| 495 builder()->LoadTheHole().StoreAccumulatorInRegister(init_value); | |
| 496 } else { | |
| 497 // For variables, we must not use an initial value (such as 'undefined') | |
| 498 // because we may have a (legal) redeclaration and we must not destroy | |
| 499 // the current value. | |
| 500 builder() | |
| 501 ->LoadLiteral(Smi::FromInt(0)) | |
| 502 .StoreAccumulatorInRegister(init_value); | |
| 503 } | |
| 504 builder() | |
| 505 ->LoadLiteral(Smi::FromInt(variable->DeclarationPropertyAttributes())) | |
| 506 .StoreAccumulatorInRegister(attributes) | |
| 507 .CallRuntime(Runtime::kDeclareLookupSlot, name, 3); | |
| 485 break; | 508 break; |
| 509 } | |
| 486 } | 510 } |
| 487 } | 511 } |
| 488 | 512 |
| 489 | 513 |
| 490 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { | 514 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { |
| 515 RegisterAllocationScope register_scope(this); | |
|
rmcilroy
2016/01/15 14:17:20
Also remove this once the above comment is done.
mythria
2016/01/15 17:10:36
Done.
| |
| 516 | |
| 491 Variable* variable = decl->proxy()->var(); | 517 Variable* variable = decl->proxy()->var(); |
| 492 switch (variable->location()) { | 518 switch (variable->location()) { |
| 493 case VariableLocation::GLOBAL: | 519 case VariableLocation::GLOBAL: |
| 494 case VariableLocation::UNALLOCATED: { | 520 case VariableLocation::UNALLOCATED: { |
| 495 Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo( | 521 Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo( |
| 496 decl->fun(), info()->script(), info()); | 522 decl->fun(), info()->script(), info()); |
| 497 // Check for stack-overflow exception. | 523 // Check for stack-overflow exception. |
| 498 if (function.is_null()) return SetStackOverflow(); | 524 if (function.is_null()) return SetStackOverflow(); |
| 499 globals()->push_back(variable->name()); | 525 globals()->push_back(variable->name()); |
| 500 globals()->push_back(function); | 526 globals()->push_back(function); |
| 501 break; | 527 break; |
| 502 } | 528 } |
| 503 case VariableLocation::PARAMETER: | 529 case VariableLocation::PARAMETER: |
| 504 case VariableLocation::LOCAL: { | 530 case VariableLocation::LOCAL: { |
| 505 VisitForAccumulatorValue(decl->fun()); | 531 VisitForAccumulatorValue(decl->fun()); |
| 506 VisitVariableAssignment(variable, FeedbackVectorSlot::Invalid()); | 532 VisitVariableAssignment(variable, FeedbackVectorSlot::Invalid()); |
| 507 break; | 533 break; |
| 508 } | 534 } |
| 509 case VariableLocation::CONTEXT: { | 535 case VariableLocation::CONTEXT: { |
| 510 DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope())); | 536 DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope())); |
| 511 VisitForAccumulatorValue(decl->fun()); | 537 VisitForAccumulatorValue(decl->fun()); |
| 512 builder()->StoreContextSlot(execution_context()->reg(), | 538 builder()->StoreContextSlot(execution_context()->reg(), |
| 513 variable->index()); | 539 variable->index()); |
| 514 break; | 540 break; |
| 515 } | 541 } |
| 516 case VariableLocation::LOOKUP: | 542 case VariableLocation::LOOKUP: { |
| 517 UNIMPLEMENTED(); | 543 register_allocator()->PrepareForConsecutiveAllocations(3); |
| 544 Register name = register_allocator()->NextConsecutiveRegister(); | |
| 545 Register literal = register_allocator()->NextConsecutiveRegister(); | |
| 546 Register attributes = register_allocator()->NextConsecutiveRegister(); | |
| 547 builder()->LoadLiteral(variable->name()).StoreAccumulatorInRegister(name); | |
| 548 | |
| 549 VisitForAccumulatorValue(decl->fun()); | |
| 550 builder() | |
| 551 ->StoreAccumulatorInRegister(literal) | |
| 552 .LoadLiteral(Smi::FromInt(variable->DeclarationPropertyAttributes())) | |
| 553 .StoreAccumulatorInRegister(attributes) | |
| 554 .CallRuntime(Runtime::kDeclareLookupSlot, name, 3); | |
| 555 } | |
| 518 } | 556 } |
| 519 } | 557 } |
| 520 | 558 |
| 521 | 559 |
| 522 void BytecodeGenerator::VisitImportDeclaration(ImportDeclaration* decl) { | 560 void BytecodeGenerator::VisitImportDeclaration(ImportDeclaration* decl) { |
| 523 UNIMPLEMENTED(); | 561 UNIMPLEMENTED(); |
| 524 } | 562 } |
| 525 | 563 |
| 526 | 564 |
| 527 void BytecodeGenerator::VisitExportDeclaration(ExportDeclaration* decl) { | 565 void BytecodeGenerator::VisitExportDeclaration(ExportDeclaration* decl) { |
| (...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1312 builder() | 1350 builder() |
| 1313 ->LoadContextSlot(context_reg, Context::PREVIOUS_INDEX) | 1351 ->LoadContextSlot(context_reg, Context::PREVIOUS_INDEX) |
| 1314 .StoreAccumulatorInRegister(context_reg); | 1352 .StoreAccumulatorInRegister(context_reg); |
| 1315 } | 1353 } |
| 1316 builder()->LoadAccumulatorWithRegister(value_temp); | 1354 builder()->LoadAccumulatorWithRegister(value_temp); |
| 1317 } | 1355 } |
| 1318 builder()->StoreContextSlot(context_reg, variable->index()); | 1356 builder()->StoreContextSlot(context_reg, variable->index()); |
| 1319 break; | 1357 break; |
| 1320 } | 1358 } |
| 1321 case VariableLocation::LOOKUP: { | 1359 case VariableLocation::LOOKUP: { |
| 1360 // TODO(mythria): Use Runtime::kInitializeLegacyConstLookupSlot for | |
| 1361 // initializations of const declarations. | |
| 1322 builder()->StoreLookupSlot(variable->name(), language_mode()); | 1362 builder()->StoreLookupSlot(variable->name(), language_mode()); |
| 1323 break; | 1363 break; |
| 1324 } | 1364 } |
| 1325 } | 1365 } |
| 1326 } | 1366 } |
| 1327 | 1367 |
| 1328 | 1368 |
| 1329 void BytecodeGenerator::VisitAssignment(Assignment* expr) { | 1369 void BytecodeGenerator::VisitAssignment(Assignment* expr) { |
| 1330 DCHECK(expr->target()->IsValidReferenceExpression()); | 1370 DCHECK(expr->target()->IsValidReferenceExpression()); |
| 1331 Register object, key; | 1371 Register object, key; |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1552 if (callee_expr->AsVariableProxy()->var()->IsLookupSlot()) { | 1592 if (callee_expr->AsVariableProxy()->var()->IsLookupSlot()) { |
| 1553 RegisterAllocationScope inner_register_scope(this); | 1593 RegisterAllocationScope inner_register_scope(this); |
| 1554 register_allocator()->PrepareForConsecutiveAllocations(2); | 1594 register_allocator()->PrepareForConsecutiveAllocations(2); |
| 1555 Register context = register_allocator()->NextConsecutiveRegister(); | 1595 Register context = register_allocator()->NextConsecutiveRegister(); |
| 1556 Register name = register_allocator()->NextConsecutiveRegister(); | 1596 Register name = register_allocator()->NextConsecutiveRegister(); |
| 1557 | 1597 |
| 1558 // Call LoadLookupSlot to get the callee and receiver. | 1598 // Call LoadLookupSlot to get the callee and receiver. |
| 1559 DCHECK(Register::AreContiguous(callee, receiver)); | 1599 DCHECK(Register::AreContiguous(callee, receiver)); |
| 1560 Variable* variable = callee_expr->AsVariableProxy()->var(); | 1600 Variable* variable = callee_expr->AsVariableProxy()->var(); |
| 1561 builder() | 1601 builder() |
| 1562 ->MoveRegister(Register::function_context(), context) | 1602 ->MoveRegister(execution_context()->reg(), context) |
| 1563 .LoadLiteral(variable->name()) | 1603 .LoadLiteral(variable->name()) |
| 1564 .StoreAccumulatorInRegister(name) | 1604 .StoreAccumulatorInRegister(name) |
| 1565 .CallRuntimeForPair(Runtime::kLoadLookupSlot, context, 2, callee); | 1605 .CallRuntimeForPair(Runtime::kLoadLookupSlot, context, 2, callee); |
| 1566 break; | 1606 break; |
| 1567 } | 1607 } |
| 1568 // Fall through. | 1608 // Fall through. |
| 1569 DCHECK_EQ(call_type, Call::POSSIBLY_EVAL_CALL); | 1609 DCHECK_EQ(call_type, Call::POSSIBLY_EVAL_CALL); |
| 1570 } | 1610 } |
| 1571 case Call::OTHER_CALL: { | 1611 case Call::OTHER_CALL: { |
| 1572 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); | 1612 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); |
| (...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2173 } | 2213 } |
| 2174 | 2214 |
| 2175 | 2215 |
| 2176 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 2216 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
| 2177 return info()->feedback_vector()->GetIndex(slot); | 2217 return info()->feedback_vector()->GetIndex(slot); |
| 2178 } | 2218 } |
| 2179 | 2219 |
| 2180 } // namespace interpreter | 2220 } // namespace interpreter |
| 2181 } // namespace internal | 2221 } // namespace internal |
| 2182 } // namespace v8 | 2222 } // namespace v8 |
| OLD | NEW |