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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/bytecodes.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/interpreter/bytecode-generator.cc
diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
index 9fd03fd016ea4d1417d971f5469700941c0f157d..423c438cf2c17910227d08fd4b873294538d2dbb 100644
--- a/src/interpreter/bytecode-generator.cc
+++ b/src/interpreter/bytecode-generator.cc
@@ -93,7 +93,9 @@ BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone)
: builder_(isolate, zone),
info_(nullptr),
scope_(nullptr),
- control_scope_(nullptr) {
+ globals_(0, zone),
+ control_scope_(nullptr),
+ current_context_(Register::function_context()) {
InitializeAstVisitor(isolate, zone);
}
@@ -145,11 +147,21 @@ void BytecodeGenerator::VisitBlock(Block* node) {
void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
Variable* variable = decl->proxy()->var();
+ VariableMode mode = decl->mode();
+ bool hole_init = mode == CONST || mode == CONST_LEGACY || mode == LET;
+ if (hole_init) {
+ UNIMPLEMENTED();
+ }
switch (variable->location()) {
case VariableLocation::GLOBAL:
- case VariableLocation::UNALLOCATED:
- UNIMPLEMENTED();
+ case VariableLocation::UNALLOCATED: {
+ Handle<Oddball> value = variable->binding_needs_init()
+ ? isolate()->factory()->the_hole_value()
+ : isolate()->factory()->undefined_value();
+ globals()->push_back(variable->name());
+ globals()->push_back(value);
break;
+ }
case VariableLocation::PARAMETER:
case VariableLocation::LOCAL:
// Details stored in scope, i.e. variable index.
@@ -163,7 +175,24 @@ void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
- UNIMPLEMENTED();
+ Variable* variable = decl->proxy()->var();
+ switch (variable->location()) {
+ case VariableLocation::GLOBAL:
+ case VariableLocation::UNALLOCATED: {
+ Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
+ decl->fun(), info()->script(), info());
+ // Check for stack-overflow exception.
+ if (function.is_null()) return SetStackOverflow();
+ globals()->push_back(variable->name());
+ globals()->push_back(function);
+ break;
+ }
+ case VariableLocation::PARAMETER:
+ case VariableLocation::LOCAL:
+ case VariableLocation::CONTEXT:
+ case VariableLocation::LOOKUP:
+ UNIMPLEMENTED();
+ }
}
@@ -177,6 +206,34 @@ void BytecodeGenerator::VisitExportDeclaration(ExportDeclaration* decl) {
}
+void BytecodeGenerator::VisitDeclarations(
+ ZoneList<Declaration*>* declarations) {
+ DCHECK(globals()->empty());
+ AstVisitor::VisitDeclarations(declarations);
+ if (globals()->empty()) return;
+ int array_index = 0;
+ Handle<FixedArray> data = isolate()->factory()->NewFixedArray(
+ static_cast<int>(globals()->size()), TENURED);
+ for (Handle<Object> obj : *globals()) data->set(array_index++, *obj);
+ int encoded_flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) |
+ DeclareGlobalsNativeFlag::encode(info()->is_native()) |
+ DeclareGlobalsLanguageMode::encode(language_mode());
+
+ TemporaryRegisterScope temporary_register_scope(&builder_);
+ Register pairs = temporary_register_scope.NewRegister();
+ builder()->LoadLiteral(data);
+ builder()->StoreAccumulatorInRegister(pairs);
+
+ Register flags = temporary_register_scope.NewRegister();
+ builder()->LoadLiteral(Smi::FromInt(encoded_flags));
+ builder()->StoreAccumulatorInRegister(flags);
+ DCHECK(flags.index() == pairs.index() + 1);
+
+ builder()->CallRuntime(Runtime::kDeclareGlobals, pairs, 2);
+ globals()->clear();
+}
+
+
void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
Visit(stmt->expression());
}
@@ -391,11 +448,12 @@ void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) {
- VisitVariableLoad(proxy->var());
+ VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot());
}
-void BytecodeGenerator::VisitVariableLoad(Variable* variable) {
+void BytecodeGenerator::VisitVariableLoad(Variable* variable,
+ FeedbackVectorSlot slot) {
switch (variable->location()) {
case VariableLocation::LOCAL: {
Register source(variable->index());
@@ -418,7 +476,66 @@ void BytecodeGenerator::VisitVariableLoad(Variable* variable) {
builder()->LoadGlobal(variable->index());
break;
}
- case VariableLocation::UNALLOCATED:
+ case VariableLocation::UNALLOCATED: {
+ TemporaryRegisterScope temporary_register_scope(&builder_);
+ Register obj = temporary_register_scope.NewRegister();
+ builder()->LoadContextSlot(current_context(),
+ Context::GLOBAL_OBJECT_INDEX);
+ builder()->StoreAccumulatorInRegister(obj);
+ builder()->LoadLiteral(variable->name());
+ builder()->LoadNamedProperty(obj, feedback_index(slot), language_mode());
+ break;
+ }
+ case VariableLocation::CONTEXT:
+ case VariableLocation::LOOKUP:
+ UNIMPLEMENTED();
+ }
+}
+
+
+void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
+ FeedbackVectorSlot slot) {
+ switch (variable->location()) {
+ case VariableLocation::LOCAL: {
+ // TODO(rmcilroy): support const mode initialization.
+ Register destination(variable->index());
+ builder()->StoreAccumulatorInRegister(destination);
+ break;
+ }
+ case VariableLocation::PARAMETER: {
+ // The parameter indices are shifted by 1 (receiver is variable
+ // index -1 but is parameter index 0 in BytecodeArrayBuilder).
+ Register destination(builder()->Parameter(variable->index() + 1));
+ builder()->StoreAccumulatorInRegister(destination);
+ break;
+ }
+ case VariableLocation::GLOBAL: {
+ // Global var, const, or let variable.
+ // TODO(rmcilroy): If context chain depth is short enough, do this using
+ // a generic version of LoadGlobalViaContextStub rather than calling the
+ // runtime.
+ DCHECK(variable->IsStaticGlobalObjectProperty());
+ builder()->StoreGlobal(variable->index(), language_mode());
+ break;
+ }
+ case VariableLocation::UNALLOCATED: {
+ TemporaryRegisterScope temporary_register_scope(&builder_);
+ Register value = temporary_register_scope.NewRegister();
+ Register obj = temporary_register_scope.NewRegister();
+ Register name = temporary_register_scope.NewRegister();
+ // TODO(rmcilroy): Investigate whether we can avoid having to stash the
+ // value in a register.
+ builder()->StoreAccumulatorInRegister(value);
+ builder()->LoadContextSlot(current_context(),
+ Context::GLOBAL_OBJECT_INDEX);
+ builder()->StoreAccumulatorInRegister(obj);
+ builder()->LoadLiteral(variable->name());
+ builder()->StoreAccumulatorInRegister(name);
+ builder()->LoadAccumulatorWithRegister(value);
+ builder()->StoreNamedProperty(obj, name, feedback_index(slot),
+ language_mode());
+ break;
+ }
case VariableLocation::CONTEXT:
case VariableLocation::LOOKUP:
UNIMPLEMENTED();
@@ -474,9 +591,7 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
switch (assign_type) {
case VARIABLE: {
Variable* variable = expr->target()->AsVariableProxy()->var();
- DCHECK(variable->location() == VariableLocation::LOCAL);
- Register destination(variable->index());
- builder()->StoreAccumulatorInRegister(destination);
+ VisitVariableAssignment(variable, slot);
break;
}
case NAMED_PROPERTY:
@@ -560,7 +675,7 @@ void BytecodeGenerator::VisitCall(Call* expr) {
builder()->LoadUndefined().StoreAccumulatorInRegister(receiver);
// Load callee as a global variable.
VariableProxy* proxy = callee_expr->AsVariableProxy();
- VisitVariableLoad(proxy->var());
+ VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot());
builder()->StoreAccumulatorInRegister(callee);
break;
}
@@ -741,6 +856,9 @@ int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
return info()->feedback_vector()->GetIndex(slot);
}
+
+Register BytecodeGenerator::current_context() const { return current_context_; }
+
} // namespace interpreter
} // namespace internal
} // namespace v8
« 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