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

Unified Diff: src/interpreter/bytecode-generator.cc

Issue 1689573004: [interpreter] Support for ES6 super keyword. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Update test262.status. Created 4 years, 10 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
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());

Powered by Google App Engine
This is Rietveld 408576698