Commit 0ac0e528 authored by ishell's avatar ishell Committed by Commit bot

[turbofan] Fix new.target when a function is inlined to a constructor.

Review URL: https://codereview.chromium.org/1432493003

Cr-Commit-Position: refs/heads/master@{#31754}
parent 60e8877e
......@@ -3255,6 +3255,7 @@ Node* AstGraphBuilder::BuildNewTargetVariable(Variable* new_target_var) {
const Operator* op =
javascript()->CallRuntime(Runtime::kGetOriginalConstructor, 0);
Node* object = NewNode(op);
PrepareFrameState(object, BailoutId::None());
// Assign the object to the {new.target} variable. This should never lazy
// deopt, so it is fine to send invalid bailout id.
......
......@@ -227,7 +227,6 @@ int Linkage::FrameStateInputCount(Runtime::FunctionId function) {
case Runtime::kFinalizeClassDefinition: // TODO(conradw): Is it safe?
case Runtime::kForInDone:
case Runtime::kForInStep:
case Runtime::kGetOriginalConstructor:
case Runtime::kNewClosure:
case Runtime::kNewClosure_Tenured:
case Runtime::kNewFunctionContext:
......
......@@ -749,7 +749,7 @@ bool JavaScriptFrame::IsConstructor() const {
}
bool JavaScriptFrame::HasInlinedFrames() {
bool JavaScriptFrame::HasInlinedFrames() const {
List<JSFunction*> functions(1);
GetFunctions(&functions);
return functions.length() > 1;
......@@ -757,6 +757,7 @@ bool JavaScriptFrame::HasInlinedFrames() {
Object* JavaScriptFrame::GetOriginalConstructor() const {
DCHECK(!HasInlinedFrames());
Address fp = caller_fp();
if (has_adapted_arguments()) {
// Skip the arguments adaptor frame and look at the real caller.
......@@ -799,7 +800,7 @@ Address JavaScriptFrame::GetCallerStackPointer() const {
}
void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) {
void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) const {
DCHECK(functions->length() == 0);
functions->Add(function());
}
......@@ -1041,7 +1042,7 @@ int OptimizedFrame::LookupExceptionHandlerInTable(
DeoptimizationInputData* OptimizedFrame::GetDeoptimizationData(
int* deopt_index) {
int* deopt_index) const {
DCHECK(is_optimized());
JSFunction* opt_function = function();
......@@ -1065,7 +1066,7 @@ DeoptimizationInputData* OptimizedFrame::GetDeoptimizationData(
}
void OptimizedFrame::GetFunctions(List<JSFunction*>* functions) {
void OptimizedFrame::GetFunctions(List<JSFunction*>* functions) const {
DCHECK(functions->length() == 0);
DCHECK(is_optimized());
......
This diff is collapsed.
......@@ -542,8 +542,10 @@ RUNTIME_FUNCTION(Runtime_GetOriginalConstructor) {
DCHECK(args.length() == 0);
JavaScriptFrameIterator it(isolate);
JavaScriptFrame* frame = it.frame();
return frame->IsConstructor() ? frame->GetOriginalConstructor()
: isolate->heap()->undefined_value();
// Currently we don't inline [[Construct]] calls.
return frame->IsConstructor() && !frame->HasInlinedFrames()
? frame->GetOriginalConstructor()
: isolate->heap()->undefined_value();
}
......
......@@ -385,6 +385,23 @@
})();
// Has to be top-level to be inlined.
function get_new_target() { return new.target; }
(function TestInlining() {
"use strict";
new function() { assertEquals(undefined, get_new_target()); }
new function() { assertEquals(get_new_target, new get_new_target()); }
class A extends get_new_target {
constructor() {
var new_target = super();
this.new_target = new_target;
}
}
assertEquals(A, new A().new_target);
})();
(function TestEarlyErrors() {
assertThrows(function() { Function("new.target = 42"); }, ReferenceError);
assertThrows(function() { Function("var foo = 1; new.target = foo = 42"); }, ReferenceError);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment