diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc index 25c7094dce..02061a7514 100644 --- a/src/interpreter/bytecode-generator.cc +++ b/src/interpreter/bytecode-generator.cc @@ -2050,9 +2050,6 @@ void BytecodeGenerator::VisitThisFunctionVariable(Variable* variable) { void BytecodeGenerator::VisitNewTargetVariable(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 this_function_var. builder()->CallRuntime(Runtime::kGetOriginalConstructor, Register(), 0); VisitVariableAssignment(variable, FeedbackVectorSlot::Invalid()); diff --git a/test/cctest/interpreter/test-bytecode-generator.cc b/test/cctest/interpreter/test-bytecode-generator.cc index 4b256e1655..c29eb9659d 100644 --- a/test/cctest/interpreter/test-bytecode-generator.cc +++ b/test/cctest/interpreter/test-bytecode-generator.cc @@ -5188,6 +5188,32 @@ TEST(ThisFunction) { } } + +TEST(NewTarget) { + InitializedHandleScope handle_scope; + BytecodeGeneratorHelper helper; + + ExpectedSnippet snippets[] = { + {"return new.target;", + 1 * kPointerSize, + 1, + 10, + { + B(CallRuntime), U16(Runtime::kGetOriginalConstructor), R(0), // + U8(0), // + B(Star), R(0), // + B(Ldar), R(0), // + B(Return), // + }}, + }; + + for (size_t i = 0; i < arraysize(snippets); i++) { + Handle bytecode_array = + helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); + CheckBytecodeArrayEqual(snippets[i], bytecode_array); + } +} + } // namespace interpreter } // namespace internal } // namespace v8 diff --git a/test/cctest/interpreter/test-interpreter.cc b/test/cctest/interpreter/test-interpreter.cc index 03501aaba7..d274fa73cb 100644 --- a/test/cctest/interpreter/test-interpreter.cc +++ b/test/cctest/interpreter/test-interpreter.cc @@ -2933,6 +2933,24 @@ TEST(InterpreterThisFunction) { CHECK(return_value->SameValue(*factory->NewStringFromStaticChars("f"))); } + +TEST(InterpreterNewTarget) { + HandleAndZoneScope handles; + i::Isolate* isolate = handles.main_isolate(); + i::Factory* factory = isolate->factory(); + + // TODO(rmcilroy): Add tests that we get the original constructor for + // superclass constructors once we have class support. + InterpreterTester tester(handles.main_isolate(), + "function f() { this.a = new.target; }"); + auto callable = tester.GetCallable<>(); + callable().ToHandleChecked(); + + Handle new_target_name = v8::Utils::OpenHandle( + *CompileRun("(function() { return (new f()).a.name; })();")); + CHECK(new_target_name->SameValue(*factory->NewStringFromStaticChars("f"))); +} + } // namespace interpreter } // namespace internal } // namespace v8