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

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

Issue 1378523005: [Interpreter] Add support for global declarations and load/store of global variables (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@int_toplevel
Patch Set: Fix test Created 5 years, 2 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 | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/bytecodes.h » ('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 <stack> 7 #include <stack>
8 8
9 #include "src/compiler.h" 9 #include "src/compiler.h"
10 #include "src/interpreter/control-flow-builders.h" 10 #include "src/interpreter/control-flow-builders.h"
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 current = current->outer(); 86 current = current->outer();
87 } while (current != nullptr); 87 } while (current != nullptr);
88 UNREACHABLE(); 88 UNREACHABLE();
89 } 89 }
90 90
91 91
92 BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone) 92 BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone)
93 : builder_(isolate, zone), 93 : builder_(isolate, zone),
94 info_(nullptr), 94 info_(nullptr),
95 scope_(nullptr), 95 scope_(nullptr),
96 control_scope_(nullptr) { 96 globals_(0, zone),
97 control_scope_(nullptr),
98 current_context_(Register::function_context()) {
97 InitializeAstVisitor(isolate, zone); 99 InitializeAstVisitor(isolate, zone);
98 } 100 }
99 101
100 102
101 BytecodeGenerator::~BytecodeGenerator() {} 103 BytecodeGenerator::~BytecodeGenerator() {}
102 104
103 105
104 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode(CompilationInfo* info) { 106 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode(CompilationInfo* info) {
105 set_info(info); 107 set_info(info);
106 set_scope(info->scope()); 108 set_scope(info->scope());
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 VisitDeclarations(node->scope()->declarations()); 140 VisitDeclarations(node->scope()->declarations());
139 VisitStatements(node->statements()); 141 VisitStatements(node->statements());
140 } 142 }
141 } 143 }
142 builder()->LeaveBlock(); 144 builder()->LeaveBlock();
143 } 145 }
144 146
145 147
146 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { 148 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
147 Variable* variable = decl->proxy()->var(); 149 Variable* variable = decl->proxy()->var();
150 VariableMode mode = decl->mode();
151 bool hole_init = mode == CONST || mode == CONST_LEGACY || mode == LET;
152 if (hole_init) {
153 UNIMPLEMENTED();
154 }
148 switch (variable->location()) { 155 switch (variable->location()) {
149 case VariableLocation::GLOBAL: 156 case VariableLocation::GLOBAL:
150 case VariableLocation::UNALLOCATED: 157 case VariableLocation::UNALLOCATED: {
151 UNIMPLEMENTED(); 158 Handle<Oddball> value = variable->binding_needs_init()
159 ? isolate()->factory()->the_hole_value()
160 : isolate()->factory()->undefined_value();
161 globals()->push_back(variable->name());
162 globals()->push_back(value);
152 break; 163 break;
164 }
153 case VariableLocation::PARAMETER: 165 case VariableLocation::PARAMETER:
154 case VariableLocation::LOCAL: 166 case VariableLocation::LOCAL:
155 // Details stored in scope, i.e. variable index. 167 // Details stored in scope, i.e. variable index.
156 break; 168 break;
157 case VariableLocation::CONTEXT: 169 case VariableLocation::CONTEXT:
158 case VariableLocation::LOOKUP: 170 case VariableLocation::LOOKUP:
159 UNIMPLEMENTED(); 171 UNIMPLEMENTED();
160 break; 172 break;
161 } 173 }
162 } 174 }
163 175
164 176
165 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { 177 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
166 UNIMPLEMENTED(); 178 Variable* variable = decl->proxy()->var();
179 switch (variable->location()) {
180 case VariableLocation::GLOBAL:
181 case VariableLocation::UNALLOCATED: {
182 Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
183 decl->fun(), info()->script(), info());
184 // Check for stack-overflow exception.
185 if (function.is_null()) return SetStackOverflow();
186 globals()->push_back(variable->name());
187 globals()->push_back(function);
188 break;
189 }
190 case VariableLocation::PARAMETER:
191 case VariableLocation::LOCAL:
192 case VariableLocation::CONTEXT:
193 case VariableLocation::LOOKUP:
194 UNIMPLEMENTED();
195 }
167 } 196 }
168 197
169 198
170 void BytecodeGenerator::VisitImportDeclaration(ImportDeclaration* decl) { 199 void BytecodeGenerator::VisitImportDeclaration(ImportDeclaration* decl) {
171 UNIMPLEMENTED(); 200 UNIMPLEMENTED();
172 } 201 }
173 202
174 203
175 void BytecodeGenerator::VisitExportDeclaration(ExportDeclaration* decl) { 204 void BytecodeGenerator::VisitExportDeclaration(ExportDeclaration* decl) {
176 UNIMPLEMENTED(); 205 UNIMPLEMENTED();
177 } 206 }
178 207
179 208
209 void BytecodeGenerator::VisitDeclarations(
210 ZoneList<Declaration*>* declarations) {
211 DCHECK(globals()->empty());
212 AstVisitor::VisitDeclarations(declarations);
213 if (globals()->empty()) return;
214 int array_index = 0;
215 Handle<FixedArray> data = isolate()->factory()->NewFixedArray(
216 static_cast<int>(globals()->size()), TENURED);
217 for (Handle<Object> obj : *globals()) data->set(array_index++, *obj);
218 int encoded_flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) |
219 DeclareGlobalsNativeFlag::encode(info()->is_native()) |
220 DeclareGlobalsLanguageMode::encode(language_mode());
221
222 TemporaryRegisterScope temporary_register_scope(&builder_);
223 Register pairs = temporary_register_scope.NewRegister();
224 builder()->LoadLiteral(data);
225 builder()->StoreAccumulatorInRegister(pairs);
226
227 Register flags = temporary_register_scope.NewRegister();
228 builder()->LoadLiteral(Smi::FromInt(encoded_flags));
229 builder()->StoreAccumulatorInRegister(flags);
230 DCHECK(flags.index() == pairs.index() + 1);
231
232 builder()->CallRuntime(Runtime::kDeclareGlobals, pairs, 2);
233 globals()->clear();
234 }
235
236
180 void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { 237 void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
181 Visit(stmt->expression()); 238 Visit(stmt->expression());
182 } 239 }
183 240
184 241
185 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { 242 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
186 // TODO(oth): For control-flow it could be useful to signal empty paths here. 243 // TODO(oth): For control-flow it could be useful to signal empty paths here.
187 } 244 }
188 245
189 246
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 UNIMPLEMENTED(); 441 UNIMPLEMENTED();
385 } 442 }
386 443
387 444
388 void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 445 void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
389 UNIMPLEMENTED(); 446 UNIMPLEMENTED();
390 } 447 }
391 448
392 449
393 void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) { 450 void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) {
394 VisitVariableLoad(proxy->var()); 451 VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot());
395 } 452 }
396 453
397 454
398 void BytecodeGenerator::VisitVariableLoad(Variable* variable) { 455 void BytecodeGenerator::VisitVariableLoad(Variable* variable,
456 FeedbackVectorSlot slot) {
399 switch (variable->location()) { 457 switch (variable->location()) {
400 case VariableLocation::LOCAL: { 458 case VariableLocation::LOCAL: {
401 Register source(variable->index()); 459 Register source(variable->index());
402 builder()->LoadAccumulatorWithRegister(source); 460 builder()->LoadAccumulatorWithRegister(source);
403 break; 461 break;
404 } 462 }
405 case VariableLocation::PARAMETER: { 463 case VariableLocation::PARAMETER: {
406 // The parameter indices are shifted by 1 (receiver is variable 464 // The parameter indices are shifted by 1 (receiver is variable
407 // index -1 but is parameter index 0 in BytecodeArrayBuilder). 465 // index -1 but is parameter index 0 in BytecodeArrayBuilder).
408 Register source(builder()->Parameter(variable->index() + 1)); 466 Register source(builder()->Parameter(variable->index() + 1));
409 builder()->LoadAccumulatorWithRegister(source); 467 builder()->LoadAccumulatorWithRegister(source);
410 break; 468 break;
411 } 469 }
412 case VariableLocation::GLOBAL: { 470 case VariableLocation::GLOBAL: {
413 // Global var, const, or let variable. 471 // Global var, const, or let variable.
414 // TODO(rmcilroy): If context chain depth is short enough, do this using 472 // TODO(rmcilroy): If context chain depth is short enough, do this using
415 // a generic version of LoadGlobalViaContextStub rather than calling the 473 // a generic version of LoadGlobalViaContextStub rather than calling the
416 // runtime. 474 // runtime.
417 DCHECK(variable->IsStaticGlobalObjectProperty()); 475 DCHECK(variable->IsStaticGlobalObjectProperty());
418 builder()->LoadGlobal(variable->index()); 476 builder()->LoadGlobal(variable->index());
419 break; 477 break;
420 } 478 }
421 case VariableLocation::UNALLOCATED: 479 case VariableLocation::UNALLOCATED: {
480 TemporaryRegisterScope temporary_register_scope(&builder_);
481 Register obj = temporary_register_scope.NewRegister();
482 builder()->LoadContextSlot(current_context(),
483 Context::GLOBAL_OBJECT_INDEX);
484 builder()->StoreAccumulatorInRegister(obj);
485 builder()->LoadLiteral(variable->name());
486 builder()->LoadNamedProperty(obj, feedback_index(slot), language_mode());
487 break;
488 }
422 case VariableLocation::CONTEXT: 489 case VariableLocation::CONTEXT:
423 case VariableLocation::LOOKUP: 490 case VariableLocation::LOOKUP:
424 UNIMPLEMENTED(); 491 UNIMPLEMENTED();
492 }
493 }
494
495
496 void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
497 FeedbackVectorSlot slot) {
498 switch (variable->location()) {
499 case VariableLocation::LOCAL: {
500 // TODO(rmcilroy): support const mode initialization.
501 Register destination(variable->index());
502 builder()->StoreAccumulatorInRegister(destination);
503 break;
504 }
505 case VariableLocation::PARAMETER: {
506 // The parameter indices are shifted by 1 (receiver is variable
507 // index -1 but is parameter index 0 in BytecodeArrayBuilder).
508 Register destination(builder()->Parameter(variable->index() + 1));
509 builder()->StoreAccumulatorInRegister(destination);
510 break;
511 }
512 case VariableLocation::GLOBAL: {
513 // Global var, const, or let variable.
514 // TODO(rmcilroy): If context chain depth is short enough, do this using
515 // a generic version of LoadGlobalViaContextStub rather than calling the
516 // runtime.
517 DCHECK(variable->IsStaticGlobalObjectProperty());
518 builder()->StoreGlobal(variable->index(), language_mode());
519 break;
520 }
521 case VariableLocation::UNALLOCATED: {
522 TemporaryRegisterScope temporary_register_scope(&builder_);
523 Register value = temporary_register_scope.NewRegister();
524 Register obj = temporary_register_scope.NewRegister();
525 Register name = temporary_register_scope.NewRegister();
526 // TODO(rmcilroy): Investigate whether we can avoid having to stash the
527 // value in a register.
528 builder()->StoreAccumulatorInRegister(value);
529 builder()->LoadContextSlot(current_context(),
530 Context::GLOBAL_OBJECT_INDEX);
531 builder()->StoreAccumulatorInRegister(obj);
532 builder()->LoadLiteral(variable->name());
533 builder()->StoreAccumulatorInRegister(name);
534 builder()->LoadAccumulatorWithRegister(value);
535 builder()->StoreNamedProperty(obj, name, feedback_index(slot),
536 language_mode());
537 break;
538 }
539 case VariableLocation::CONTEXT:
540 case VariableLocation::LOOKUP:
541 UNIMPLEMENTED();
425 } 542 }
426 } 543 }
427 544
428 545
429 void BytecodeGenerator::VisitAssignment(Assignment* expr) { 546 void BytecodeGenerator::VisitAssignment(Assignment* expr) {
430 DCHECK(expr->target()->IsValidReferenceExpression()); 547 DCHECK(expr->target()->IsValidReferenceExpression());
431 TemporaryRegisterScope temporary_register_scope(&builder_); 548 TemporaryRegisterScope temporary_register_scope(&builder_);
432 Register object, key; 549 Register object, key;
433 550
434 // Left-hand side can only be a property, a global or a variable slot. 551 // Left-hand side can only be a property, a global or a variable slot.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 UNIMPLEMENTED(); 584 UNIMPLEMENTED();
468 } else { 585 } else {
469 Visit(expr->value()); 586 Visit(expr->value());
470 } 587 }
471 588
472 // Store the value. 589 // Store the value.
473 FeedbackVectorSlot slot = expr->AssignmentSlot(); 590 FeedbackVectorSlot slot = expr->AssignmentSlot();
474 switch (assign_type) { 591 switch (assign_type) {
475 case VARIABLE: { 592 case VARIABLE: {
476 Variable* variable = expr->target()->AsVariableProxy()->var(); 593 Variable* variable = expr->target()->AsVariableProxy()->var();
477 DCHECK(variable->location() == VariableLocation::LOCAL); 594 VisitVariableAssignment(variable, slot);
478 Register destination(variable->index());
479 builder()->StoreAccumulatorInRegister(destination);
480 break; 595 break;
481 } 596 }
482 case NAMED_PROPERTY: 597 case NAMED_PROPERTY:
483 builder()->StoreNamedProperty(object, key, feedback_index(slot), 598 builder()->StoreNamedProperty(object, key, feedback_index(slot),
484 language_mode()); 599 language_mode());
485 break; 600 break;
486 case KEYED_PROPERTY: 601 case KEYED_PROPERTY:
487 builder()->StoreKeyedProperty(object, key, feedback_index(slot), 602 builder()->StoreKeyedProperty(object, key, feedback_index(slot),
488 language_mode()); 603 language_mode());
489 break; 604 break;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 // Perform a property load of the callee. 668 // Perform a property load of the callee.
554 VisitPropertyLoad(receiver, property); 669 VisitPropertyLoad(receiver, property);
555 builder()->StoreAccumulatorInRegister(callee); 670 builder()->StoreAccumulatorInRegister(callee);
556 break; 671 break;
557 } 672 }
558 case Call::GLOBAL_CALL: { 673 case Call::GLOBAL_CALL: {
559 // Receiver is undefined for global calls. 674 // Receiver is undefined for global calls.
560 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); 675 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver);
561 // Load callee as a global variable. 676 // Load callee as a global variable.
562 VariableProxy* proxy = callee_expr->AsVariableProxy(); 677 VariableProxy* proxy = callee_expr->AsVariableProxy();
563 VisitVariableLoad(proxy->var()); 678 VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot());
564 builder()->StoreAccumulatorInRegister(callee); 679 builder()->StoreAccumulatorInRegister(callee);
565 break; 680 break;
566 } 681 }
567 case Call::LOOKUP_SLOT_CALL: 682 case Call::LOOKUP_SLOT_CALL:
568 case Call::SUPER_CALL: 683 case Call::SUPER_CALL:
569 case Call::POSSIBLY_EVAL_CALL: 684 case Call::POSSIBLY_EVAL_CALL:
570 case Call::OTHER_CALL: 685 case Call::OTHER_CALL:
571 UNIMPLEMENTED(); 686 UNIMPLEMENTED();
572 } 687 }
573 688
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 849
735 Strength BytecodeGenerator::language_mode_strength() const { 850 Strength BytecodeGenerator::language_mode_strength() const {
736 return strength(language_mode()); 851 return strength(language_mode());
737 } 852 }
738 853
739 854
740 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 855 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
741 return info()->feedback_vector()->GetIndex(slot); 856 return info()->feedback_vector()->GetIndex(slot);
742 } 857 }
743 858
859
860 Register BytecodeGenerator::current_context() const { return current_context_; }
861
744 } // namespace interpreter 862 } // namespace interpreter
745 } // namespace internal 863 } // namespace internal
746 } // namespace v8 864 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/bytecodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698