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 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 Register destination(builder()->Parameter(variable->index() + 1)); | 473 Register destination(builder()->Parameter(variable->index() + 1)); |
474 builder()->LoadTheHole().StoreAccumulatorInRegister(destination); | 474 builder()->LoadTheHole().StoreAccumulatorInRegister(destination); |
475 } | 475 } |
476 break; | 476 break; |
477 case VariableLocation::CONTEXT: | 477 case VariableLocation::CONTEXT: |
478 if (hole_init) { | 478 if (hole_init) { |
479 builder()->LoadTheHole().StoreContextSlot(execution_context()->reg(), | 479 builder()->LoadTheHole().StoreContextSlot(execution_context()->reg(), |
480 variable->index()); | 480 variable->index()); |
481 } | 481 } |
482 break; | 482 break; |
483 case VariableLocation::LOOKUP: | 483 case VariableLocation::LOOKUP: { |
484 UNIMPLEMENTED(); | 484 DCHECK(IsDeclaredVariableMode(mode)); |
| 485 |
| 486 register_allocator()->PrepareForConsecutiveAllocations(3); |
| 487 Register name = register_allocator()->NextConsecutiveRegister(); |
| 488 Register init_value = register_allocator()->NextConsecutiveRegister(); |
| 489 Register attributes = register_allocator()->NextConsecutiveRegister(); |
| 490 |
| 491 builder()->LoadLiteral(variable->name()).StoreAccumulatorInRegister(name); |
| 492 if (hole_init) { |
| 493 builder()->LoadTheHole().StoreAccumulatorInRegister(init_value); |
| 494 } else { |
| 495 // For variables, we must not use an initial value (such as 'undefined') |
| 496 // because we may have a (legal) redeclaration and we must not destroy |
| 497 // the current value. |
| 498 builder() |
| 499 ->LoadLiteral(Smi::FromInt(0)) |
| 500 .StoreAccumulatorInRegister(init_value); |
| 501 } |
| 502 builder() |
| 503 ->LoadLiteral(Smi::FromInt(variable->DeclarationPropertyAttributes())) |
| 504 .StoreAccumulatorInRegister(attributes) |
| 505 .CallRuntime(Runtime::kDeclareLookupSlot, name, 3); |
485 break; | 506 break; |
| 507 } |
486 } | 508 } |
487 } | 509 } |
488 | 510 |
489 | 511 |
490 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { | 512 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { |
491 Variable* variable = decl->proxy()->var(); | 513 Variable* variable = decl->proxy()->var(); |
492 switch (variable->location()) { | 514 switch (variable->location()) { |
493 case VariableLocation::GLOBAL: | 515 case VariableLocation::GLOBAL: |
494 case VariableLocation::UNALLOCATED: { | 516 case VariableLocation::UNALLOCATED: { |
495 Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo( | 517 Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo( |
(...skipping 10 matching lines...) Expand all Loading... |
506 VisitVariableAssignment(variable, FeedbackVectorSlot::Invalid()); | 528 VisitVariableAssignment(variable, FeedbackVectorSlot::Invalid()); |
507 break; | 529 break; |
508 } | 530 } |
509 case VariableLocation::CONTEXT: { | 531 case VariableLocation::CONTEXT: { |
510 DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope())); | 532 DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope())); |
511 VisitForAccumulatorValue(decl->fun()); | 533 VisitForAccumulatorValue(decl->fun()); |
512 builder()->StoreContextSlot(execution_context()->reg(), | 534 builder()->StoreContextSlot(execution_context()->reg(), |
513 variable->index()); | 535 variable->index()); |
514 break; | 536 break; |
515 } | 537 } |
516 case VariableLocation::LOOKUP: | 538 case VariableLocation::LOOKUP: { |
517 UNIMPLEMENTED(); | 539 register_allocator()->PrepareForConsecutiveAllocations(3); |
| 540 Register name = register_allocator()->NextConsecutiveRegister(); |
| 541 Register literal = register_allocator()->NextConsecutiveRegister(); |
| 542 Register attributes = register_allocator()->NextConsecutiveRegister(); |
| 543 builder()->LoadLiteral(variable->name()).StoreAccumulatorInRegister(name); |
| 544 |
| 545 VisitForAccumulatorValue(decl->fun()); |
| 546 builder() |
| 547 ->StoreAccumulatorInRegister(literal) |
| 548 .LoadLiteral(Smi::FromInt(variable->DeclarationPropertyAttributes())) |
| 549 .StoreAccumulatorInRegister(attributes) |
| 550 .CallRuntime(Runtime::kDeclareLookupSlot, name, 3); |
| 551 } |
518 } | 552 } |
519 } | 553 } |
520 | 554 |
521 | 555 |
522 void BytecodeGenerator::VisitImportDeclaration(ImportDeclaration* decl) { | 556 void BytecodeGenerator::VisitImportDeclaration(ImportDeclaration* decl) { |
523 UNIMPLEMENTED(); | 557 UNIMPLEMENTED(); |
524 } | 558 } |
525 | 559 |
526 | 560 |
527 void BytecodeGenerator::VisitExportDeclaration(ExportDeclaration* decl) { | 561 void BytecodeGenerator::VisitExportDeclaration(ExportDeclaration* decl) { |
528 UNIMPLEMENTED(); | 562 UNIMPLEMENTED(); |
529 } | 563 } |
530 | 564 |
531 | 565 |
532 void BytecodeGenerator::VisitDeclarations( | 566 void BytecodeGenerator::VisitDeclarations( |
533 ZoneList<Declaration*>* declarations) { | 567 ZoneList<Declaration*>* declarations) { |
534 RegisterAllocationScope register_scope(this); | 568 RegisterAllocationScope register_scope(this); |
535 DCHECK(globals()->empty()); | 569 DCHECK(globals()->empty()); |
536 AstVisitor::VisitDeclarations(declarations); | 570 for (int i = 0; i < declarations->length(); i++) { |
| 571 RegisterAllocationScope register_scope(this); |
| 572 Visit(declarations->at(i)); |
| 573 } |
537 if (globals()->empty()) return; | 574 if (globals()->empty()) return; |
538 int array_index = 0; | 575 int array_index = 0; |
539 Handle<FixedArray> data = isolate()->factory()->NewFixedArray( | 576 Handle<FixedArray> data = isolate()->factory()->NewFixedArray( |
540 static_cast<int>(globals()->size()), TENURED); | 577 static_cast<int>(globals()->size()), TENURED); |
541 for (Handle<Object> obj : *globals()) data->set(array_index++, *obj); | 578 for (Handle<Object> obj : *globals()) data->set(array_index++, *obj); |
542 int encoded_flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) | | 579 int encoded_flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) | |
543 DeclareGlobalsNativeFlag::encode(info()->is_native()) | | 580 DeclareGlobalsNativeFlag::encode(info()->is_native()) | |
544 DeclareGlobalsLanguageMode::encode(language_mode()); | 581 DeclareGlobalsLanguageMode::encode(language_mode()); |
545 | 582 |
546 Register pairs = register_allocator()->NewRegister(); | 583 Register pairs = register_allocator()->NewRegister(); |
(...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1312 builder() | 1349 builder() |
1313 ->LoadContextSlot(context_reg, Context::PREVIOUS_INDEX) | 1350 ->LoadContextSlot(context_reg, Context::PREVIOUS_INDEX) |
1314 .StoreAccumulatorInRegister(context_reg); | 1351 .StoreAccumulatorInRegister(context_reg); |
1315 } | 1352 } |
1316 builder()->LoadAccumulatorWithRegister(value_temp); | 1353 builder()->LoadAccumulatorWithRegister(value_temp); |
1317 } | 1354 } |
1318 builder()->StoreContextSlot(context_reg, variable->index()); | 1355 builder()->StoreContextSlot(context_reg, variable->index()); |
1319 break; | 1356 break; |
1320 } | 1357 } |
1321 case VariableLocation::LOOKUP: { | 1358 case VariableLocation::LOOKUP: { |
| 1359 // TODO(mythria): Use Runtime::kInitializeLegacyConstLookupSlot for |
| 1360 // initializations of const declarations. |
1322 builder()->StoreLookupSlot(variable->name(), language_mode()); | 1361 builder()->StoreLookupSlot(variable->name(), language_mode()); |
1323 break; | 1362 break; |
1324 } | 1363 } |
1325 } | 1364 } |
1326 } | 1365 } |
1327 | 1366 |
1328 | 1367 |
1329 void BytecodeGenerator::VisitAssignment(Assignment* expr) { | 1368 void BytecodeGenerator::VisitAssignment(Assignment* expr) { |
1330 DCHECK(expr->target()->IsValidReferenceExpression()); | 1369 DCHECK(expr->target()->IsValidReferenceExpression()); |
1331 Register object, key; | 1370 Register object, key; |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1552 if (callee_expr->AsVariableProxy()->var()->IsLookupSlot()) { | 1591 if (callee_expr->AsVariableProxy()->var()->IsLookupSlot()) { |
1553 RegisterAllocationScope inner_register_scope(this); | 1592 RegisterAllocationScope inner_register_scope(this); |
1554 register_allocator()->PrepareForConsecutiveAllocations(2); | 1593 register_allocator()->PrepareForConsecutiveAllocations(2); |
1555 Register context = register_allocator()->NextConsecutiveRegister(); | 1594 Register context = register_allocator()->NextConsecutiveRegister(); |
1556 Register name = register_allocator()->NextConsecutiveRegister(); | 1595 Register name = register_allocator()->NextConsecutiveRegister(); |
1557 | 1596 |
1558 // Call LoadLookupSlot to get the callee and receiver. | 1597 // Call LoadLookupSlot to get the callee and receiver. |
1559 DCHECK(Register::AreContiguous(callee, receiver)); | 1598 DCHECK(Register::AreContiguous(callee, receiver)); |
1560 Variable* variable = callee_expr->AsVariableProxy()->var(); | 1599 Variable* variable = callee_expr->AsVariableProxy()->var(); |
1561 builder() | 1600 builder() |
1562 ->MoveRegister(Register::function_context(), context) | 1601 ->MoveRegister(execution_context()->reg(), context) |
1563 .LoadLiteral(variable->name()) | 1602 .LoadLiteral(variable->name()) |
1564 .StoreAccumulatorInRegister(name) | 1603 .StoreAccumulatorInRegister(name) |
1565 .CallRuntimeForPair(Runtime::kLoadLookupSlot, context, 2, callee); | 1604 .CallRuntimeForPair(Runtime::kLoadLookupSlot, context, 2, callee); |
1566 break; | 1605 break; |
1567 } | 1606 } |
1568 // Fall through. | 1607 // Fall through. |
1569 DCHECK_EQ(call_type, Call::POSSIBLY_EVAL_CALL); | 1608 DCHECK_EQ(call_type, Call::POSSIBLY_EVAL_CALL); |
1570 } | 1609 } |
1571 case Call::OTHER_CALL: { | 1610 case Call::OTHER_CALL: { |
1572 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); | 1611 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); |
(...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2173 } | 2212 } |
2174 | 2213 |
2175 | 2214 |
2176 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 2215 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
2177 return info()->feedback_vector()->GetIndex(slot); | 2216 return info()->feedback_vector()->GetIndex(slot); |
2178 } | 2217 } |
2179 | 2218 |
2180 } // namespace interpreter | 2219 } // namespace interpreter |
2181 } // namespace internal | 2220 } // namespace internal |
2182 } // namespace v8 | 2221 } // namespace v8 |
OLD | NEW |