Index: src/interpreter/bytecode-generator.cc |
diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc |
index 9c82b4702eaa19846bfe820fd38734d8b6eab5fc..b1cac30d3690aac041209b0d27e18d29c6df4638 100644 |
--- a/src/interpreter/bytecode-generator.cc |
+++ b/src/interpreter/bytecode-generator.cc |
@@ -713,12 +713,10 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
// contains computed properties with an uninitialized value. |
if (literal_key->value()->IsInternalizedString()) { |
if (property->emit_store()) { |
- Register name = inner_temporary_register_scope.NewRegister(); |
- builder() |
- ->LoadLiteral(literal_key->AsPropertyName()) |
- .StoreAccumulatorInRegister(name); |
+ size_t name_index = |
+ builder()->GetConstantPoolEntry(literal_key->AsPropertyName()); |
VisitForAccumulatorValue(property->value()); |
- builder()->StoreNamedProperty(literal, name, |
+ builder()->StoreNamedProperty(literal, name_index, |
feedback_index(property->GetSlot(0)), |
language_mode()); |
} else { |
@@ -939,13 +937,8 @@ void BytecodeGenerator::VisitVariableLoad(Variable* variable, |
} |
case VariableLocation::GLOBAL: |
case VariableLocation::UNALLOCATED: { |
- TemporaryRegisterScope temporary_register_scope(builder()); |
- Register obj = temporary_register_scope.NewRegister(); |
- builder()->LoadContextSlot(execution_context()->reg(), |
- Context::GLOBAL_OBJECT_INDEX); |
- builder()->StoreAccumulatorInRegister(obj); |
- builder()->LoadLiteral(variable->name()); |
- builder()->LoadNamedProperty(obj, feedback_index(slot), language_mode()); |
+ size_t name_index = builder()->GetConstantPoolEntry(variable->name()); |
+ builder()->LoadGlobal(name_index, feedback_index(slot), language_mode()); |
execution_result()->SetResultInAccumulator(); |
break; |
} |
@@ -987,21 +980,8 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable, |
} |
case VariableLocation::GLOBAL: |
case VariableLocation::UNALLOCATED: { |
- Register value = execution_result()->NewRegister(); |
- Register obj = execution_result()->NewRegister(); |
- Register name = execution_result()->NewRegister(); |
- |
- // TODO(rmcilroy): Investigate whether we can avoid having to stash the |
- // value in a register. |
- builder()->StoreAccumulatorInRegister(value); |
- builder()->LoadContextSlot(execution_context()->reg(), |
- 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()); |
+ size_t name_index = builder()->GetConstantPoolEntry(variable->name()); |
+ builder()->StoreGlobal(name_index, feedback_index(slot), language_mode()); |
break; |
} |
case VariableLocation::CONTEXT: { |
@@ -1023,6 +1003,7 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable, |
void BytecodeGenerator::VisitAssignment(Assignment* expr) { |
DCHECK(expr->target()->IsValidReferenceExpression()); |
Register object, key; |
+ size_t name_index = kMaxUInt32; |
// Left-hand side can only be a property, a global or a variable slot. |
Property* property = expr->target()->AsProperty(); |
@@ -1035,9 +1016,8 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) { |
break; |
case NAMED_PROPERTY: { |
object = VisitForRegisterValue(property->obj()); |
- key = execution_result()->NewRegister(); |
- builder()->LoadLiteral(property->key()->AsLiteral()->AsPropertyName()); |
- builder()->StoreAccumulatorInRegister(key); |
+ name_index = builder()->GetConstantPoolEntry( |
+ property->key()->AsLiteral()->AsPropertyName()); |
break; |
} |
case KEYED_PROPERTY: { |
@@ -1069,7 +1049,7 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) { |
break; |
} |
case NAMED_PROPERTY: |
- builder()->StoreNamedProperty(object, key, feedback_index(slot), |
+ builder()->StoreNamedProperty(object, name_index, feedback_index(slot), |
language_mode()); |
break; |
case KEYED_PROPERTY: |
@@ -1100,8 +1080,10 @@ void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) { |
case VARIABLE: |
UNREACHABLE(); |
case NAMED_PROPERTY: { |
- builder()->LoadLiteral(expr->key()->AsLiteral()->AsPropertyName()); |
- builder()->LoadNamedProperty(obj, feedback_index(slot), language_mode()); |
+ size_t name_index = builder()->GetConstantPoolEntry( |
+ expr->key()->AsLiteral()->AsPropertyName()); |
+ builder()->LoadNamedProperty(obj, name_index, feedback_index(slot), |
+ language_mode()); |
break; |
} |
case KEYED_PROPERTY: { |
@@ -1117,6 +1099,13 @@ void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) { |
} |
+void BytecodeGenerator::VisitPropertyLoadForAccumulator(Register obj, |
+ Property* expr) { |
+ AccumulatorResultScope result_scope(this); |
+ VisitPropertyLoad(obj, expr); |
+} |
+ |
+ |
void BytecodeGenerator::VisitProperty(Property* expr) { |
Register obj = VisitForRegisterValue(expr->obj()); |
VisitPropertyLoad(obj, expr); |
@@ -1173,13 +1162,10 @@ void BytecodeGenerator::VisitCall(Call* expr) { |
if (property->IsSuperAccess()) { |
UNIMPLEMENTED(); |
} |
+ |
VisitForAccumulatorValue(property->obj()); |
builder()->StoreAccumulatorInRegister(receiver); |
- // Need a result scope here to keep our consecutive |
- // temporaries. |
- AccumulatorResultScope accumulator_execution_result(this); |
- // Perform a property load of the callee. |
- VisitPropertyLoad(receiver, property); |
+ VisitPropertyLoadForAccumulator(receiver, property); |
builder()->StoreAccumulatorInRegister(callee); |
break; |
} |
@@ -1273,6 +1259,8 @@ void BytecodeGenerator::VisitVoid(UnaryOperation* expr) { |
void BytecodeGenerator::VisitTypeOf(UnaryOperation* expr) { |
+ // TODO(rmcilroy): Set TypeofMode to INSIDE_TYPEOF for any loadICs performed |
+ // while visiting the expression. |
VisitForAccumulatorValue(expr->expression()); |
builder()->TypeOf(); |
execution_result()->SetResultInAccumulator(); |
@@ -1389,7 +1377,52 @@ void BytecodeGenerator::VisitSuperPropertyReference( |
} |
+void BytecodeGenerator::VisitCommaExpression(BinaryOperation* binop) { |
+ VisitForEffect(binop->left()); |
+ Visit(binop->right()); |
+} |
+ |
+ |
+void BytecodeGenerator::VisitLogicalOrExpression(BinaryOperation* binop) { |
+ Expression* left = binop->left(); |
+ Expression* right = binop->right(); |
+ |
+ // Short-circuit evaluation- If it is known that left is always true, |
+ // no need to visit right |
+ if (left->ToBooleanIsTrue()) { |
+ VisitForAccumulatorValue(left); |
+ } else { |
+ BytecodeLabel end_label; |
+ VisitForAccumulatorValue(left); |
+ builder()->JumpIfToBooleanTrue(&end_label); |
+ VisitForAccumulatorValue(right); |
+ builder()->Bind(&end_label); |
+ } |
+ execution_result()->SetResultInAccumulator(); |
+} |
+ |
+ |
+void BytecodeGenerator::VisitLogicalAndExpression(BinaryOperation* binop) { |
+ Expression* left = binop->left(); |
+ Expression* right = binop->right(); |
+ |
+ // Short-circuit evaluation- If it is known that left is always false, |
+ // no need to visit right |
+ if (left->ToBooleanIsFalse()) { |
+ VisitForAccumulatorValue(left); |
+ } else { |
+ BytecodeLabel end_label; |
+ VisitForAccumulatorValue(left); |
+ builder()->JumpIfToBooleanFalse(&end_label); |
+ VisitForAccumulatorValue(right); |
+ builder()->Bind(&end_label); |
+ } |
+ execution_result()->SetResultInAccumulator(); |
+} |
+ |
+ |
void BytecodeGenerator::VisitNewLocalFunctionContext() { |
+ AccumulatorResultScope accumulator_execution_result(this); |
Scope* scope = this->scope(); |
// Allocate a new local context. |
@@ -1408,6 +1441,7 @@ void BytecodeGenerator::VisitNewLocalFunctionContext() { |
builder()->CallRuntime(Runtime::kNewFunctionContext, |
Register::function_closure(), 1); |
} |
+ execution_result()->SetResultInAccumulator(); |
} |
@@ -1436,6 +1470,7 @@ void BytecodeGenerator::VisitBuildLocalActivationContext() { |
void BytecodeGenerator::VisitNewLocalBlockContext(Scope* scope) { |
+ AccumulatorResultScope accumulator_execution_result(this); |
DCHECK(scope->is_block_scope()); |
// Allocate a new local block context. |
@@ -1450,49 +1485,6 @@ void BytecodeGenerator::VisitNewLocalBlockContext(Scope* scope) { |
builder() |
->StoreAccumulatorInRegister(closure) |
.CallRuntime(Runtime::kPushBlockContext, scope_info, 2); |
-} |
- |
- |
-void BytecodeGenerator::VisitCommaExpression(BinaryOperation* binop) { |
- VisitForEffect(binop->left()); |
- Visit(binop->right()); |
-} |
- |
- |
-void BytecodeGenerator::VisitLogicalOrExpression(BinaryOperation* binop) { |
- Expression* left = binop->left(); |
- Expression* right = binop->right(); |
- |
- // Short-circuit evaluation- If it is known that left is always true, |
- // no need to visit right |
- if (left->ToBooleanIsTrue()) { |
- VisitForAccumulatorValue(left); |
- } else { |
- BytecodeLabel end_label; |
- VisitForAccumulatorValue(left); |
- builder()->JumpIfToBooleanTrue(&end_label); |
- VisitForAccumulatorValue(right); |
- builder()->Bind(&end_label); |
- } |
- execution_result()->SetResultInAccumulator(); |
-} |
- |
- |
-void BytecodeGenerator::VisitLogicalAndExpression(BinaryOperation* binop) { |
- Expression* left = binop->left(); |
- Expression* right = binop->right(); |
- |
- // Short-circuit evaluation- If it is known that left is always false, |
- // no need to visit right |
- if (left->ToBooleanIsFalse()) { |
- VisitForAccumulatorValue(left); |
- } else { |
- BytecodeLabel end_label; |
- VisitForAccumulatorValue(left); |
- builder()->JumpIfToBooleanFalse(&end_label); |
- VisitForAccumulatorValue(right); |
- builder()->Bind(&end_label); |
- } |
execution_result()->SetResultInAccumulator(); |
} |
@@ -1516,23 +1508,12 @@ void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object, |
Expression* expr = property->value(); |
if (!FunctionLiteral::NeedsHomeObject(expr)) return; |
- // TODO(rmcilroy): Remove UNIMPLEMENTED once we have tests for setting the |
- // home object. |
UNIMPLEMENTED(); |
- |
- TemporaryRegisterScope temporary_register_scope(builder()); |
- Register name = temporary_register_scope.NewRegister(); |
- isolate()->factory()->home_object_symbol(); |
- builder() |
- ->LoadLiteral(isolate()->factory()->home_object_symbol()) |
- .StoreAccumulatorInRegister(name) |
- .StoreNamedProperty(home_object, name, |
- feedback_index(property->GetSlot(slot_number)), |
- language_mode()); |
} |
void BytecodeGenerator::VisitFunctionClosureForContext() { |
+ AccumulatorResultScope accumulator_execution_result(this); |
Scope* closure_scope = execution_context()->scope()->ClosureScope(); |
if (closure_scope->is_script_scope() || |
closure_scope->is_module_scope()) { |
@@ -1544,6 +1525,7 @@ void BytecodeGenerator::VisitFunctionClosureForContext() { |
DCHECK(closure_scope->is_function_scope()); |
builder()->LoadAccumulatorWithRegister(Register::function_closure()); |
} |
+ execution_result()->SetResultInAccumulator(); |
} |