| Index: src/interpreter/bytecode-generator.cc
|
| diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
|
| index f262dfdfc8f1739201d6e3ef64f5edaa856e2169..5cd7af5956a469eec4f053234f9a0a8d3054c889 100644
|
| --- a/src/interpreter/bytecode-generator.cc
|
| +++ b/src/interpreter/bytecode-generator.cc
|
| @@ -418,6 +418,11 @@ class BytecodeGenerator::RegisterAllocationScope {
|
| return allocator_.NextConsecutiveRegister();
|
| }
|
|
|
| + template <size_t N>
|
| + void PrepareAndInitializeConsecutiveAllocations(Register (®isters)[N]) {
|
| + return allocator_.PrepareAndInitializeConsecutiveAllocations(registers, N);
|
| + }
|
| +
|
| bool RegisterIsAllocatedInThisScope(Register reg) const {
|
| return allocator_.RegisterIsAllocatedInThisScope(reg);
|
| }
|
| @@ -543,6 +548,24 @@ class BytecodeGenerator::RegisterResultScope final
|
| Register result_register_;
|
| };
|
|
|
| +class BytecodeGenerator::SuperPropertyArguments final {
|
| + public:
|
| + SuperPropertyArguments() {}
|
| +
|
| + Register (®isters())[4] { return args_; }
|
| + Register receiver() const { return args_[0]; }
|
| + Register home_object() const { return args_[1]; }
|
| + Register name_or_key() const { return args_[2]; }
|
| + Register store_value() const { return args_[3]; }
|
| + Register language_mode() const { return args_[3]; }
|
| + size_t size() const { return arraysize(args_); }
|
| +
|
| + private:
|
| + Register args_[4];
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(SuperPropertyArguments);
|
| +};
|
| +
|
| BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone)
|
| : isolate_(isolate),
|
| zone_(zone),
|
| @@ -559,7 +582,6 @@ BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone)
|
| InitializeAstVisitor(isolate);
|
| }
|
|
|
| -
|
| Handle<BytecodeArray> BytecodeGenerator::MakeBytecode(CompilationInfo* info) {
|
| set_info(info);
|
| set_scope(info->scope());
|
| @@ -1050,9 +1072,30 @@ 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);
|
| + SuperPropertyArguments super_args;
|
| + Register value = register_allocator()->NewRegister();
|
| + builder()->StoreAccumulatorInRegister(value);
|
| + PrepareNamedSuperPropertyArguments(
|
| + property->obj()->AsSuperPropertyReference(),
|
| + property->key()->AsLiteral()->AsPropertyName(), &super_args);
|
| + builder()->LoadAccumulatorWithRegister(value);
|
| + BuildNamedSuperPropertyStore(&super_args);
|
| + break;
|
| + }
|
| + case KEYED_SUPER_PROPERTY: {
|
| + RegisterAllocationScope register_scope(this);
|
| + SuperPropertyArguments super_args;
|
| + Register value = register_allocator()->NewRegister();
|
| + builder()->StoreAccumulatorInRegister(value);
|
| + PrepareKeyedSuperPropertyArguments(
|
| + property->obj()->AsSuperPropertyReference(), property->key(),
|
| + &super_args);
|
| + builder()->LoadAccumulatorWithRegister(value);
|
| + BuildKeyedSuperPropertyStore(&super_args);
|
| + break;
|
| + }
|
| }
|
| }
|
|
|
| @@ -1495,9 +1538,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());
|
| }
|
| @@ -1781,6 +1834,72 @@ Register BytecodeGenerator::VisitVariableLoadForRegisterValue(
|
| return register_scope.ResultRegister();
|
| }
|
|
|
| +void BytecodeGenerator::PrepareNamedSuperPropertyArguments(
|
| + SuperPropertyReference* super_property, Handle<Name> name,
|
| + SuperPropertyArguments* super_args) {
|
| + register_allocator()->PrepareAndInitializeConsecutiveAllocations(
|
| + super_args->registers());
|
| +
|
| + VisitForAccumulatorValue(super_property->this_var());
|
| + builder()->StoreAccumulatorInRegister(super_args->receiver());
|
| + VisitForAccumulatorValue(super_property->home_object());
|
| + builder()->StoreAccumulatorInRegister(super_args->home_object());
|
| + builder()->LoadLiteral(name).StoreAccumulatorInRegister(
|
| + super_args->name_or_key());
|
| +}
|
| +
|
| +void BytecodeGenerator::PrepareKeyedSuperPropertyArguments(
|
| + SuperPropertyReference* super_property, Expression* key,
|
| + SuperPropertyArguments* super_args) {
|
| + register_allocator()->PrepareAndInitializeConsecutiveAllocations(
|
| + super_args->registers());
|
| +
|
| + VisitForAccumulatorValue(super_property->this_var());
|
| + builder()->StoreAccumulatorInRegister(super_args->receiver());
|
| + VisitForAccumulatorValue(super_property->home_object());
|
| + builder()->StoreAccumulatorInRegister(super_args->home_object());
|
| + VisitForAccumulatorValue(key);
|
| + builder()->StoreAccumulatorInRegister(super_args->name_or_key());
|
| +}
|
| +
|
| +void BytecodeGenerator::BuildNamedSuperPropertyLoad(
|
| + SuperPropertyArguments* super_args) {
|
| + builder()
|
| + ->LoadLiteral(Smi::FromInt(static_cast<int>(language_mode())))
|
| + .StoreAccumulatorInRegister(super_args->language_mode());
|
| + builder()->CallRuntime(Runtime::kLoadFromSuper, super_args->receiver(),
|
| + super_args->size());
|
| +}
|
| +
|
| +void BytecodeGenerator::BuildKeyedSuperPropertyLoad(
|
| + SuperPropertyArguments* super_args) {
|
| + builder()
|
| + ->LoadLiteral(Smi::FromInt(static_cast<int>(language_mode())))
|
| + .StoreAccumulatorInRegister(super_args->language_mode());
|
| + builder()->CallRuntime(Runtime::kLoadKeyedFromSuper, super_args->receiver(),
|
| + super_args->size());
|
| +}
|
| +
|
| +void BytecodeGenerator::BuildNamedSuperPropertyStore(
|
| + SuperPropertyArguments* super_args) {
|
| + builder()->StoreAccumulatorInRegister(super_args->store_value());
|
| + Runtime::FunctionId function_id = is_strict(language_mode())
|
| + ? Runtime::kStoreToSuper_Strict
|
| + : Runtime::kStoreToSuper_Sloppy;
|
| + builder()->CallRuntime(function_id, super_args->receiver(),
|
| + super_args->size());
|
| +}
|
| +
|
| +void BytecodeGenerator::BuildKeyedSuperPropertyStore(
|
| + SuperPropertyArguments* super_args) {
|
| + builder()->StoreAccumulatorInRegister(super_args->store_value());
|
| + Runtime::FunctionId function_id = is_strict(language_mode())
|
| + ? Runtime::kStoreKeyedToSuper_Strict
|
| + : Runtime::kStoreKeyedToSuper_Sloppy;
|
| + builder()->CallRuntime(function_id, super_args->receiver(),
|
| + super_args->size());
|
| +}
|
| +
|
| void BytecodeGenerator::BuildThrowReferenceError(Handle<String> name) {
|
| RegisterAllocationScope register_scope(this);
|
| Register name_reg = register_allocator()->NewRegister();
|
| @@ -1988,8 +2107,9 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
|
|
|
|
|
| void BytecodeGenerator::VisitAssignment(Assignment* expr) {
|
| - DCHECK(expr->target()->IsValidReferenceExpression());
|
| + DCHECK(expr->target()->IsValidReferenceExpressionOrThis());
|
| Register object, key;
|
| + SuperPropertyArguments super_args;
|
| Handle<String> name;
|
|
|
| // Left-hand side can only be a property, a global or a variable slot.
|
| @@ -2019,9 +2139,18 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
|
| }
|
| break;
|
| }
|
| - case NAMED_SUPER_PROPERTY:
|
| - case KEYED_SUPER_PROPERTY:
|
| - UNIMPLEMENTED();
|
| + case NAMED_SUPER_PROPERTY: {
|
| + PrepareNamedSuperPropertyArguments(
|
| + property->obj()->AsSuperPropertyReference(),
|
| + property->key()->AsLiteral()->AsPropertyName(), &super_args);
|
| + break;
|
| + }
|
| + case KEYED_SUPER_PROPERTY: {
|
| + PrepareKeyedSuperPropertyArguments(
|
| + property->obj()->AsSuperPropertyReference(), property->key(),
|
| + &super_args);
|
| + break;
|
| + }
|
| }
|
|
|
| // Evaluate the value and potentially handle compound assignments by loading
|
| @@ -2054,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();
|
| + BuildNamedSuperPropertyLoad(&super_args);
|
| + builder()->StoreAccumulatorInRegister(old_value);
|
| break;
|
| + }
|
| + case KEYED_SUPER_PROPERTY: {
|
| + old_value = register_allocator()->NewRegister();
|
| + BuildKeyedSuperPropertyLoad(&super_args);
|
| + builder()->StoreAccumulatorInRegister(old_value);
|
| + break;
|
| + }
|
| }
|
| VisitForAccumulatorValue(expr->value());
|
| builder()->BinaryOperation(expr->binary_op(), old_value,
|
| @@ -2084,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: {
|
| + BuildNamedSuperPropertyStore(&super_args);
|
| + break;
|
| + }
|
| + case KEYED_SUPER_PROPERTY: {
|
| + BuildKeyedSuperPropertyStore(&super_args);
|
| + break;
|
| + }
|
| }
|
| execution_result()->SetResultInAccumulator();
|
| }
|
| @@ -2124,26 +2266,58 @@ 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 opt_receiver_out) {
|
| + RegisterAllocationScope register_scope(this);
|
| + SuperPropertyArguments super_args;
|
| + PrepareNamedSuperPropertyArguments(
|
| + property->obj()->AsSuperPropertyReference(),
|
| + property->key()->AsLiteral()->AsPropertyName(), &super_args);
|
| + if (opt_receiver_out.is_valid()) {
|
| + builder()->MoveRegister(super_args.receiver(), opt_receiver_out);
|
| + }
|
| + BuildNamedSuperPropertyLoad(&super_args);
|
| +}
|
| +
|
| +void BytecodeGenerator::VisitKeyedSuperPropertyLoad(Property* property,
|
| + Register opt_receiver_out) {
|
| + RegisterAllocationScope register_scope(this);
|
| + SuperPropertyArguments super_args;
|
| + PrepareKeyedSuperPropertyArguments(
|
| + property->obj()->AsSuperPropertyReference(), property->key(),
|
| + &super_args);
|
| + if (opt_receiver_out.is_valid()) {
|
| + builder()->MoveRegister(super_args.receiver(), opt_receiver_out);
|
| + }
|
| + BuildKeyedSuperPropertyLoad(&super_args);
|
| +}
|
|
|
| void BytecodeGenerator::VisitProperty(Property* expr) {
|
| - Register obj = VisitForRegisterValue(expr->obj());
|
| - VisitPropertyLoad(obj, expr);
|
| + LhsKind property_kind = Property::GetAssignType(expr);
|
| + if (property_kind != NAMED_SUPER_PROPERTY &&
|
| + property_kind != KEYED_SUPER_PROPERTY) {
|
| + Register obj = VisitForRegisterValue(expr->obj());
|
| + VisitPropertyLoad(obj, expr);
|
| + } else {
|
| + VisitPropertyLoad(Register::invalid_value(), expr);
|
| + }
|
| }
|
|
|
| -
|
| Register BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args) {
|
| if (args->length() == 0) {
|
| return Register();
|
| @@ -2176,11 +2350,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.
|
|
|
| @@ -2238,10 +2415,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
|
| @@ -2285,6 +2473,32 @@ void BytecodeGenerator::VisitCall(Call* expr) {
|
| execution_result()->SetResultInAccumulator();
|
| }
|
|
|
| +void BytecodeGenerator::VisitCallSuper(Call* expr) {
|
| + RegisterAllocationScope register_scope(this);
|
| + SuperCallReference* super = expr->expression()->AsSuperCallReference();
|
| +
|
| + // Prepare the constructor to the super call.
|
| + Register this_function = register_allocator()->NewRegister();
|
| + VisitForAccumulatorValue(super->this_function_var());
|
| + builder()
|
| + ->StoreAccumulatorInRegister(this_function)
|
| + .CallRuntime(Runtime::kInlineGetSuperConstructor, this_function, 1);
|
| +
|
| + Register constructor = this_function; // Re-use dead this_function register.
|
| + builder()->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();
|
| @@ -2293,8 +2507,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();
|
| }
|
|
|
| @@ -2448,7 +2667,8 @@ 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, key, old_value;
|
| + SuperPropertyArguments super_args;
|
| Handle<String> name;
|
| switch (assign_type) {
|
| case VARIABLE: {
|
| @@ -2459,26 +2679,37 @@ 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: {
|
| + PrepareNamedSuperPropertyArguments(
|
| + property->obj()->AsSuperPropertyReference(),
|
| + property->key()->AsLiteral()->AsPropertyName(), &super_args);
|
| + BuildNamedSuperPropertyLoad(&super_args);
|
| + break;
|
| + }
|
| + case KEYED_SUPER_PROPERTY: {
|
| + PrepareKeyedSuperPropertyArguments(
|
| + property->obj()->AsSuperPropertyReference(), property->key(),
|
| + &super_args);
|
| + BuildKeyedSuperPropertyLoad(&super_args);
|
| break;
|
| }
|
| - case NAMED_SUPER_PROPERTY:
|
| - case KEYED_SUPER_PROPERTY:
|
| - UNIMPLEMENTED();
|
| }
|
|
|
| // Convert old value into a number.
|
| @@ -2504,18 +2735,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: {
|
| + BuildNamedSuperPropertyStore(&super_args);
|
| + break;
|
| + }
|
| + case KEYED_SUPER_PROPERTY: {
|
| + BuildKeyedSuperPropertyStore(&super_args);
|
| + break;
|
| + }
|
| }
|
|
|
| // Restore old value for postfix expressions.
|
| @@ -2575,13 +2811,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();
|
| }
|
|
|
|
|
| @@ -2754,14 +2992,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());
|
| + }
|
| }
|
|
|
|
|
| @@ -2794,9 +3035,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());
|
|
|