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 |