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

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: Rebased the patch and fixed a typo in a comment. 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 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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