Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1317)

Side by Side Diff: src/interpreter/bytecode-generator.cc

Issue 1583783003: [Interpreter] Adds support for variable/function declarations in lookup slots. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fixes comments Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | test/cctest/interpreter/test-bytecode-generator.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | test/cctest/interpreter/test-bytecode-generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698