Index: src/interpreter/bytecode-generator.cc |
diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc |
index 022f41efa54ca550a3ffc6bd0c1d8c4e3e6d5294..7d71b8c0fc467b18f2f2fcff551524d6eae367c1 100644 |
--- a/src/interpreter/bytecode-generator.cc |
+++ b/src/interpreter/bytecode-generator.cc |
@@ -1035,9 +1035,34 @@ void BytecodeGenerator::VisitForInAssignment(Expression* expr, |
language_mode()); |
break; |
} |
- case NAMED_SUPER_PROPERTY: |
- case KEYED_SUPER_PROPERTY: |
- UNIMPLEMENTED(); |
+ case NAMED_SUPER_PROPERTY: { |
+ RegisterAllocationScope register_scope(this); |
+ Register value = register_allocator()->NewRegister(); |
+ builder()->StoreAccumulatorInRegister(value); |
+ SuperPropertyReference* super_property = |
+ property->obj()->AsSuperPropertyReference(); |
+ Register receiver = VisitForRegisterValue(super_property->this_var()); |
+ Register home_object = |
+ VisitForRegisterValue(super_property->home_object()); |
+ Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
+ builder()->LoadAccumulatorWithRegister(value); |
+ BuildNamedSuperStore(receiver, home_object, name); |
rmcilroy
2016/02/11 15:25:49
Could you adapt this function to expect the home_o
oth
2016/02/12 14:12:53
I'd wondered about this too. Have added PrepareNam
|
+ break; |
+ } |
+ case KEYED_SUPER_PROPERTY: { |
+ SuperPropertyReference* super_property = |
+ property->obj()->AsSuperPropertyReference(); |
+ RegisterAllocationScope register_scope(this); |
+ Register value = register_allocator()->NewRegister(); |
+ builder()->StoreAccumulatorInRegister(value); |
+ Register receiver = VisitForRegisterValue(super_property->this_var()); |
+ Register home_object = |
+ VisitForRegisterValue(super_property->home_object()); |
+ Register key = VisitForRegisterValue(property->key()); |
+ builder()->LoadAccumulatorWithRegister(value); |
+ BuildKeyedSuperStore(receiver, home_object, key); |
rmcilroy
2016/02/11 15:25:49
ditto
oth
2016/02/12 14:12:53
Acknowledged.
|
+ break; |
+ } |
} |
} |
@@ -1479,9 +1504,19 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
if (literal_key->value()->IsInternalizedString()) { |
if (property->emit_store()) { |
VisitForAccumulatorValue(property->value()); |
- builder()->StoreNamedProperty( |
- literal, literal_key->AsPropertyName(), |
- feedback_index(property->GetSlot(0)), language_mode()); |
+ if (FunctionLiteral::NeedsHomeObject(property->value())) { |
+ RegisterAllocationScope register_scope(this); |
+ Register value = register_allocator()->NewRegister(); |
+ builder()->StoreAccumulatorInRegister(value); |
+ builder()->StoreNamedProperty( |
+ literal, literal_key->AsPropertyName(), |
+ feedback_index(property->GetSlot(0)), language_mode()); |
+ VisitSetHomeObject(value, literal, property, 1); |
+ } else { |
+ builder()->StoreNamedProperty( |
+ literal, literal_key->AsPropertyName(), |
+ feedback_index(property->GetSlot(0)), language_mode()); |
+ } |
} else { |
VisitForEffect(property->value()); |
} |
@@ -1769,6 +1804,98 @@ Register BytecodeGenerator::VisitVariableLoadForRegisterValue( |
return register_scope.ResultRegister(); |
} |
+void BytecodeGenerator::BuildKeyedSuperLoad(Register receiver, |
rmcilroy
2016/02/11 15:25:49
BuildKeyedSuperPropertyLoad (and the same for the
oth
2016/02/12 14:12:53
Done.
|
+ Register home_object, |
+ Register key) { |
+ RegisterAllocationScope register_scope(this); |
+ Register args[4]; |
+ register_allocator()->PrepareForConsecutiveAllocations(arraysize(args)); |
+ for (size_t i = 0; i < arraysize(args); i++) { |
+ args[i] = register_allocator()->NextConsecutiveRegister(); |
+ } |
rmcilroy
2016/02/11 15:25:49
I'd prefer just to explicitly name each of the reg
oth
2016/02/12 14:12:53
Keeping this pattern as discussed and incorporated
|
+ |
+ builder() |
+ ->LoadLiteral(Smi::FromInt(static_cast<int>(language_mode()))) |
+ .StoreAccumulatorInRegister(args[3]) |
+ .MoveRegister(key, args[2]) |
+ .MoveRegister(home_object, args[1]) |
+ .MoveRegister(receiver, args[0]) |
+ .CallRuntime(Runtime::kLoadKeyedFromSuper, args[0], |
+ static_cast<int>(arraysize(args))); |
+} |
+ |
+void BytecodeGenerator::BuildKeyedSuperStore(Register receiver, |
+ Register home_object, |
+ Register key) { |
+ RegisterAllocationScope register_scope(this); |
+ Register args[4]; |
+ register_allocator()->PrepareForConsecutiveAllocations(arraysize(args)); |
+ for (size_t i = 0; i < arraysize(args); i++) { |
+ args[i] = register_allocator()->NextConsecutiveRegister(); |
+ } |
+ |
+ // Prepare arguments. Value to be stored is in the accumulator. |
+ builder() |
+ ->StoreAccumulatorInRegister(args[3]) |
+ .MoveRegister(key, args[2]) |
+ .MoveRegister(home_object, args[1]) |
+ .MoveRegister(receiver, args[0]); |
+ |
+ // Call runtime to perform store. |
+ Runtime::FunctionId function_id = is_strict(language_mode()) |
+ ? Runtime::kStoreKeyedToSuper_Strict |
+ : Runtime::kStoreKeyedToSuper_Sloppy; |
+ builder()->CallRuntime(function_id, args[0], |
+ static_cast<int>(arraysize(args))); |
+} |
+ |
+void BytecodeGenerator::BuildNamedSuperLoad(Register receiver, |
+ Register home_object, |
+ Handle<Name> name) { |
+ RegisterAllocationScope register_scope(this); |
+ Register args[4]; |
+ register_allocator()->PrepareForConsecutiveAllocations(arraysize(args)); |
+ for (size_t i = 0; i < arraysize(args); i++) { |
+ args[i] = register_allocator()->NextConsecutiveRegister(); |
+ } |
+ |
+ builder() |
+ ->LoadLiteral(Smi::FromInt(static_cast<int>(language_mode()))) |
+ .StoreAccumulatorInRegister(args[3]) |
+ .LoadLiteral(name) |
+ .StoreAccumulatorInRegister(args[2]) |
+ .MoveRegister(home_object, args[1]) |
+ .MoveRegister(receiver, args[0]) |
+ .CallRuntime(Runtime::kLoadFromSuper, args[0], |
+ static_cast<int>(arraysize(args))); |
+} |
+ |
+void BytecodeGenerator::BuildNamedSuperStore(Register receiver, |
+ Register home_object, |
+ Handle<Name> name) { |
+ RegisterAllocationScope register_scope(this); |
+ Register args[4]; |
+ register_allocator()->PrepareForConsecutiveAllocations(arraysize(args)); |
+ for (size_t i = 0; i < arraysize(args); i++) { |
+ args[i] = register_allocator()->NextConsecutiveRegister(); |
+ } |
+ |
+ // Prepare arguments. Value to be stored is in the accumulator. |
+ builder() |
+ ->StoreAccumulatorInRegister(args[3]) |
+ .LoadLiteral(name) |
+ .StoreAccumulatorInRegister(args[2]) |
+ .MoveRegister(home_object, args[1]) |
+ .MoveRegister(receiver, args[0]); |
+ |
+ // Call runtime to perform store. |
+ Runtime::FunctionId function_id = is_strict(language_mode()) |
+ ? Runtime::kStoreToSuper_Strict |
+ : Runtime::kStoreToSuper_Sloppy; |
+ builder()->CallRuntime(function_id, args[0], |
+ static_cast<int>(arraysize(args))); |
+} |
+ |
void BytecodeGenerator::BuildThrowIfHole(Handle<String> name) { |
Register name_reg = register_allocator()->NewRegister(); |
BytecodeLabel end_label; |
@@ -1977,8 +2104,8 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable, |
void BytecodeGenerator::VisitAssignment(Assignment* expr) { |
- DCHECK(expr->target()->IsValidReferenceExpression()); |
- Register object, key; |
+ DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); |
+ Register home_object, object, key; |
Handle<String> name; |
// Left-hand side can only be a property, a global or a variable slot. |
@@ -2008,9 +2135,22 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) { |
} |
break; |
} |
- case NAMED_SUPER_PROPERTY: |
- case KEYED_SUPER_PROPERTY: |
- UNIMPLEMENTED(); |
+ case NAMED_SUPER_PROPERTY: { |
+ object = VisitForRegisterValue( |
+ property->obj()->AsSuperPropertyReference()->this_var()); |
+ home_object = VisitForRegisterValue( |
+ property->obj()->AsSuperPropertyReference()->home_object()); |
+ name = property->key()->AsLiteral()->AsPropertyName(); |
+ break; |
+ } |
+ case KEYED_SUPER_PROPERTY: { |
+ object = VisitForRegisterValue( |
+ property->obj()->AsSuperPropertyReference()->this_var()); |
+ home_object = VisitForRegisterValue( |
+ property->obj()->AsSuperPropertyReference()->home_object()); |
+ key = VisitForRegisterValue(property->key()); |
+ break; |
+ } |
} |
// Evaluate the value and potentially handle compound assignments by loading |
@@ -2043,10 +2183,18 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) { |
.StoreAccumulatorInRegister(old_value); |
break; |
} |
- case NAMED_SUPER_PROPERTY: |
- case KEYED_SUPER_PROPERTY: |
- UNIMPLEMENTED(); |
+ case NAMED_SUPER_PROPERTY: { |
+ old_value = register_allocator()->NewRegister(); |
+ BuildNamedSuperLoad(object, home_object, name); |
+ builder()->StoreAccumulatorInRegister(old_value); |
break; |
+ } |
+ case KEYED_SUPER_PROPERTY: { |
+ old_value = register_allocator()->NewRegister(); |
+ BuildKeyedSuperLoad(object, home_object, key); |
+ builder()->StoreAccumulatorInRegister(old_value); |
+ break; |
+ } |
} |
VisitForAccumulatorValue(expr->value()); |
builder()->BinaryOperation(expr->binary_op(), old_value, |
@@ -2073,9 +2221,14 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) { |
builder()->StoreKeyedProperty(object, key, feedback_index(slot), |
language_mode()); |
break; |
- case NAMED_SUPER_PROPERTY: |
- case KEYED_SUPER_PROPERTY: |
- UNIMPLEMENTED(); |
+ case NAMED_SUPER_PROPERTY: { |
+ BuildNamedSuperStore(object, home_object, name); |
+ break; |
+ } |
+ case KEYED_SUPER_PROPERTY: { |
+ BuildKeyedSuperStore(object, home_object, key); |
+ break; |
+ } |
} |
execution_result()->SetResultInAccumulator(); |
} |
@@ -2113,23 +2266,106 @@ void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) { |
break; |
} |
case NAMED_SUPER_PROPERTY: |
+ VisitNamedSuperPropertyLoad(expr, Register::invalid_value()); |
+ break; |
case KEYED_SUPER_PROPERTY: |
- UNIMPLEMENTED(); |
+ VisitKeyedSuperPropertyLoad(expr, Register::invalid_value()); |
+ break; |
} |
execution_result()->SetResultInAccumulator(); |
} |
- |
void BytecodeGenerator::VisitPropertyLoadForAccumulator(Register obj, |
Property* expr) { |
AccumulatorResultScope result_scope(this); |
VisitPropertyLoad(obj, expr); |
} |
+void BytecodeGenerator::VisitNamedSuperPropertyLoad(Property* property, |
+ Register receiver_out) { |
+ RegisterAllocationScope register_scope(this); |
+ register_allocator()->PrepareForConsecutiveAllocations(4); |
+ Register receiver = register_allocator()->NextConsecutiveRegister(); |
+ Register home_object = register_allocator()->NextConsecutiveRegister(); |
+ Register property_name = register_allocator()->NextConsecutiveRegister(); |
+ Register language = register_allocator()->NextConsecutiveRegister(); |
+ |
+ SuperPropertyReference* super_ref = |
+ property->obj()->AsSuperPropertyReference(); |
+ Expression* key = property->key(); |
+ VisitForAccumulatorValue(super_ref->this_var()); |
+ builder()->StoreAccumulatorInRegister(receiver); |
+ |
+ VisitForAccumulatorValue(super_ref->home_object()); |
rmcilroy
2016/02/11 15:25:49
Could you use BuildNamedSuperLoad here?
oth
2016/02/12 14:12:53
Done.
|
+ builder() |
+ ->StoreAccumulatorInRegister(home_object) |
+ .LoadLiteral(key->AsLiteral()->AsPropertyName()) |
+ .StoreAccumulatorInRegister(property_name) |
+ .LoadLiteral(Smi::FromInt(static_cast<int>(language_mode()))) |
+ .StoreAccumulatorInRegister(language); |
+ builder()->CallRuntime(Runtime::kLoadFromSuper, receiver, 4); |
+ if (receiver_out.is_valid()) { |
rmcilroy
2016/02/11 15:25:49
nit - move this up to be below "builder()->StoreAc
oth
2016/02/12 14:12:53
Done.
|
+ builder()->MoveRegister(receiver, receiver_out); |
+ } |
+} |
+ |
+void BytecodeGenerator::VisitKeyedSuperPropertyLoad(Property* property, |
+ Register receiver_out) { |
+ RegisterAllocationScope register_scope(this); |
rmcilroy
2016/02/11 15:25:49
Same question here, could this use BuildKeyedSuper
oth
2016/02/12 14:12:53
Done.
|
+ register_allocator()->PrepareForConsecutiveAllocations(4); |
+ Register receiver = register_allocator()->NextConsecutiveRegister(); |
+ Register home = register_allocator()->NextConsecutiveRegister(); |
+ Register key = register_allocator()->NextConsecutiveRegister(); |
+ Register language = register_allocator()->NextConsecutiveRegister(); |
+ |
+ SuperPropertyReference* super_ref = |
+ property->obj()->AsSuperPropertyReference(); |
+ VisitForAccumulatorValue(super_ref->home_object()); |
+ builder()->StoreAccumulatorInRegister(home); |
+ |
+ VisitForAccumulatorValue(super_ref->this_var()); |
+ builder()->StoreAccumulatorInRegister(receiver); |
+ |
+ VisitForAccumulatorValue(property->key()); |
+ builder()->StoreAccumulatorInRegister(key); |
+ |
+ builder() |
+ ->LoadLiteral(Smi::FromInt(static_cast<int>(language_mode()))) |
+ .StoreAccumulatorInRegister(language); |
+ |
+ builder()->CallRuntime(Runtime::kLoadKeyedFromSuper, receiver, 4); |
+ if (receiver_out.is_valid()) { |
+ builder()->MoveRegister(receiver, receiver_out); |
+ } |
+} |
void BytecodeGenerator::VisitProperty(Property* expr) { |
- Register obj = VisitForRegisterValue(expr->obj()); |
- VisitPropertyLoad(obj, expr); |
rmcilroy
2016/02/11 15:25:49
Could you merge this back please (and make the Vi
oth
2016/02/12 14:12:53
Done.
|
+ LhsKind property_kind = Property::GetAssignType(expr); |
+ FeedbackVectorSlot slot = expr->PropertyFeedbackSlot(); |
+ switch (property_kind) { |
+ case VARIABLE: |
+ UNREACHABLE(); |
+ case NAMED_PROPERTY: { |
+ Register obj = VisitForRegisterValue(expr->obj()); |
+ builder()->LoadNamedProperty(obj, |
+ expr->key()->AsLiteral()->AsPropertyName(), |
+ feedback_index(slot), language_mode()); |
+ break; |
+ } |
+ case KEYED_PROPERTY: { |
+ Register obj = VisitForRegisterValue(expr->obj()); |
+ VisitForAccumulatorValue(expr->key()); |
+ builder()->LoadKeyedProperty(obj, feedback_index(slot), language_mode()); |
+ break; |
+ } |
+ case NAMED_SUPER_PROPERTY: |
+ VisitNamedSuperPropertyLoad(expr, Register::invalid_value()); |
+ break; |
+ case KEYED_SUPER_PROPERTY: |
+ VisitKeyedSuperPropertyLoad(expr, Register::invalid_value()); |
+ break; |
+ } |
+ execution_result()->SetResultInAccumulator(); |
} |
@@ -2165,11 +2401,14 @@ Register BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args) { |
return first_arg; |
} |
- |
void BytecodeGenerator::VisitCall(Call* expr) { |
Expression* callee_expr = expr->expression(); |
Call::CallType call_type = expr->GetCallType(isolate()); |
+ if (call_type == Call::SUPER_CALL) { |
+ return VisitCallSuper(expr); |
+ } |
+ |
// Prepare the callee and the receiver to the function call. This depends on |
// the semantics of the underlying call type. |
@@ -2227,10 +2466,21 @@ void BytecodeGenerator::VisitCall(Call* expr) { |
builder()->StoreAccumulatorInRegister(callee); |
break; |
} |
- case Call::NAMED_SUPER_PROPERTY_CALL: |
- case Call::KEYED_SUPER_PROPERTY_CALL: |
+ case Call::NAMED_SUPER_PROPERTY_CALL: { |
+ Property* property = callee_expr->AsProperty(); |
+ VisitNamedSuperPropertyLoad(property, receiver); |
+ builder()->StoreAccumulatorInRegister(callee); |
+ break; |
+ } |
+ case Call::KEYED_SUPER_PROPERTY_CALL: { |
+ Property* property = callee_expr->AsProperty(); |
+ VisitKeyedSuperPropertyLoad(property, receiver); |
+ builder()->StoreAccumulatorInRegister(callee); |
+ break; |
+ } |
case Call::SUPER_CALL: |
- UNIMPLEMENTED(); |
+ UNREACHABLE(); |
+ break; |
} |
// Evaluate all arguments to the function call and store in sequential |
@@ -2274,6 +2524,32 @@ void BytecodeGenerator::VisitCall(Call* expr) { |
execution_result()->SetResultInAccumulator(); |
} |
+void BytecodeGenerator::VisitCallSuper(Call* expr) { |
+ RegisterAllocationScope register_scope(this); |
+ SuperCallReference* super = expr->expression()->AsSuperCallReference(); |
+ DCHECK_NOT_NULL(super); |
rmcilroy
2016/02/11 15:25:49
I don't think this DCHECK is necessary (it will cr
oth
2016/02/12 14:12:53
Done.
|
+ |
+ // Prepare the constructor to the super call. |
+ Register constructor = register_allocator()->NewRegister(); |
+ Register this_function = constructor; |
rmcilroy
2016/02/11 15:25:49
Could you move this down below the CallRuntime wit
oth
2016/02/12 14:12:53
Done.
|
+ VisitForAccumulatorValue(super->this_function_var()); |
+ builder() |
+ ->StoreAccumulatorInRegister(this_function) |
+ .CallRuntime(Runtime::kInlineGetSuperConstructor, this_function, 1) |
+ .StoreAccumulatorInRegister(constructor); |
+ |
+ ZoneList<Expression*>* args = expr->arguments(); |
+ Register first_arg = VisitArguments(args); |
+ |
+ // The new target is loaded into the accumulator from the |
+ // {new.target} variable. |
+ VisitForAccumulatorValue(super->new_target_var()); |
+ |
+ // Call construct. |
+ builder()->SetExpressionPosition(expr); |
+ builder()->New(constructor, first_arg, args->length()); |
+ execution_result()->SetResultInAccumulator(); |
+} |
void BytecodeGenerator::VisitCallNew(CallNew* expr) { |
Register constructor = register_allocator()->NewRegister(); |
@@ -2282,8 +2558,13 @@ void BytecodeGenerator::VisitCallNew(CallNew* expr) { |
ZoneList<Expression*>* args = expr->arguments(); |
Register first_arg = VisitArguments(args); |
+ |
builder()->SetExpressionPosition(expr); |
- builder()->New(constructor, first_arg, args->length()); |
+ // The accumulator holds new target which is the same as the |
+ // constructor for CallNew. |
+ builder() |
+ ->LoadAccumulatorWithRegister(constructor) |
+ .New(constructor, first_arg, args->length()); |
execution_result()->SetResultInAccumulator(); |
} |
@@ -2433,7 +2714,7 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) { |
bool is_postfix = expr->is_postfix(); |
// Evaluate LHS expression and get old value. |
- Register obj, key, old_value; |
+ Register object, home_object, key, old_value; |
Handle<String> name; |
switch (assign_type) { |
case VARIABLE: { |
@@ -2444,26 +2725,41 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) { |
} |
case NAMED_PROPERTY: { |
FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); |
- obj = VisitForRegisterValue(property->obj()); |
+ object = VisitForRegisterValue(property->obj()); |
name = property->key()->AsLiteral()->AsPropertyName(); |
- builder()->LoadNamedProperty(obj, name, feedback_index(slot), |
+ builder()->LoadNamedProperty(object, name, feedback_index(slot), |
language_mode()); |
break; |
} |
case KEYED_PROPERTY: { |
FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); |
- obj = VisitForRegisterValue(property->obj()); |
+ object = VisitForRegisterValue(property->obj()); |
// Use visit for accumulator here since we need the key in the accumulator |
// for the LoadKeyedProperty. |
key = register_allocator()->NewRegister(); |
VisitForAccumulatorValue(property->key()); |
builder()->StoreAccumulatorInRegister(key).LoadKeyedProperty( |
- obj, feedback_index(slot), language_mode()); |
+ object, feedback_index(slot), language_mode()); |
+ break; |
+ } |
+ case NAMED_SUPER_PROPERTY: { |
+ object = VisitForRegisterValue( |
+ property->obj()->AsSuperPropertyReference()->this_var()); |
+ home_object = VisitForRegisterValue( |
+ property->obj()->AsSuperPropertyReference()->home_object()); |
+ name = property->key()->AsLiteral()->AsPropertyName(); |
+ BuildNamedSuperLoad(object, home_object, name); |
+ break; |
+ } |
+ case KEYED_SUPER_PROPERTY: { |
+ object = VisitForRegisterValue( |
+ property->obj()->AsSuperPropertyReference()->this_var()); |
+ home_object = VisitForRegisterValue( |
+ property->obj()->AsSuperPropertyReference()->home_object()); |
+ key = VisitForRegisterValue(property->key()); |
+ BuildKeyedSuperLoad(object, home_object, key); |
break; |
} |
- case NAMED_SUPER_PROPERTY: |
- case KEYED_SUPER_PROPERTY: |
- UNIMPLEMENTED(); |
} |
// Convert old value into a number. |
@@ -2489,18 +2785,23 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) { |
break; |
} |
case NAMED_PROPERTY: { |
- builder()->StoreNamedProperty(obj, name, feedback_index(feedback_slot), |
+ builder()->StoreNamedProperty(object, name, feedback_index(feedback_slot), |
language_mode()); |
break; |
} |
case KEYED_PROPERTY: { |
- builder()->StoreKeyedProperty(obj, key, feedback_index(feedback_slot), |
+ builder()->StoreKeyedProperty(object, key, feedback_index(feedback_slot), |
language_mode()); |
break; |
} |
- case NAMED_SUPER_PROPERTY: |
- case KEYED_SUPER_PROPERTY: |
- UNIMPLEMENTED(); |
+ case NAMED_SUPER_PROPERTY: { |
+ BuildNamedSuperStore(object, home_object, name); |
+ break; |
+ } |
+ case KEYED_SUPER_PROPERTY: { |
+ BuildKeyedSuperStore(object, home_object, key); |
+ break; |
+ } |
} |
// Restore old value for postfix expressions. |
@@ -2560,13 +2861,15 @@ void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) { |
void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) { |
- UNIMPLEMENTED(); |
+ // Handled by VisitCall(). |
+ UNREACHABLE(); |
} |
void BytecodeGenerator::VisitSuperPropertyReference( |
SuperPropertyReference* expr) { |
- UNIMPLEMENTED(); |
+ builder()->CallRuntime(Runtime::kThrowUnsupportedSuperError, Register(0), 0); |
+ execution_result()->SetResultInAccumulator(); |
} |
@@ -2739,14 +3042,17 @@ void BytecodeGenerator::VisitObjectLiteralAccessor( |
} |
} |
- |
void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object, |
ObjectLiteralProperty* property, |
int slot_number) { |
Expression* expr = property->value(); |
- if (!FunctionLiteral::NeedsHomeObject(expr)) return; |
- |
- UNIMPLEMENTED(); |
+ if (FunctionLiteral::NeedsHomeObject(expr)) { |
+ Handle<Name> name = isolate()->factory()->home_object_symbol(); |
+ FeedbackVectorSlot slot = property->GetSlot(slot_number); |
+ builder() |
+ ->LoadAccumulatorWithRegister(home_object) |
+ .StoreNamedProperty(value, name, feedback_index(slot), language_mode()); |
+ } |
} |
@@ -2779,9 +3085,6 @@ void BytecodeGenerator::VisitRestArgumentsArray(Variable* rest) { |
void BytecodeGenerator::VisitThisFunctionVariable(Variable* variable) { |
if (variable == nullptr) return; |
- // TODO(rmcilroy): Remove once we have tests which exercise this code path. |
- UNIMPLEMENTED(); |
- |
// Store the closure we were called with in the given variable. |
builder()->LoadAccumulatorWithRegister(Register::function_closure()); |
VisitVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid()); |