Commit 83e9ea1e authored by mstarzinger's avatar mstarzinger Committed by Commit bot

[turbofan] Ensure inlined constructor calls still throw.

This makes sure that inlining a constructor call to a function which
cannot be used as a constructor (e.g. strong mode function) still does
throw correctly when the implicit receiver is created.

R=bmeurer@chromium.org
TEST=mjsunit/regress/regress-inline-strong-as-construct
BUG=v8:4544
LOG=n

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

Cr-Commit-Position: refs/heads/master@{#31982}
parent 84b4e1d4
...@@ -454,7 +454,7 @@ Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) { ...@@ -454,7 +454,7 @@ Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) {
Node* context = NodeProperties::GetContextInput(node); Node* context = NodeProperties::GetContextInput(node);
Node* create = jsgraph_->graph()->NewNode(jsgraph_->javascript()->Create(), Node* create = jsgraph_->graph()->NewNode(jsgraph_->javascript()->Create(),
call.target(), call.new_target(), call.target(), call.new_target(),
context, effect); context, frame_state, effect);
NodeProperties::ReplaceEffectInput(node, create); NodeProperties::ReplaceEffectInput(node, create);
// TODO(4544): For now Runtime_GetNewTarget depends on the actual target to // TODO(4544): For now Runtime_GetNewTarget depends on the actual target to
// coincide with the new target. Fix this! // coincide with the new target. Fix this!
......
...@@ -1345,6 +1345,8 @@ Reduction JSTypedLowering::ReduceJSCreate(Node* node) { ...@@ -1345,6 +1345,8 @@ Reduction JSTypedLowering::ReduceJSCreate(Node* node) {
target_type->AsConstant()->Value()->IsJSFunction()) { target_type->AsConstant()->Value()->IsJSFunction()) {
Handle<JSFunction> constructor = Handle<JSFunction> constructor =
Handle<JSFunction>::cast(target_type->AsConstant()->Value()); Handle<JSFunction>::cast(target_type->AsConstant()->Value());
// Check that function is a constructor.
if (!constructor->IsConstructor()) return NoChange();
// Force completion of inobject slack tracking before // Force completion of inobject slack tracking before
// generating code to finalize the instance size. // generating code to finalize the instance size.
if (constructor->IsInobjectSlackTrackingInProgress()) { if (constructor->IsInobjectSlackTrackingInProgress()) {
......
...@@ -230,7 +230,6 @@ int Linkage::FrameStateInputCount(Runtime::FunctionId function) { ...@@ -230,7 +230,6 @@ int Linkage::FrameStateInputCount(Runtime::FunctionId function) {
case Runtime::kNewClosure: case Runtime::kNewClosure:
case Runtime::kNewClosure_Tenured: case Runtime::kNewClosure_Tenured:
case Runtime::kNewFunctionContext: case Runtime::kNewFunctionContext:
case Runtime::kNewObject:
case Runtime::kPushBlockContext: case Runtime::kPushBlockContext:
case Runtime::kPushCatchContext: case Runtime::kPushCatchContext:
case Runtime::kReThrow: case Runtime::kReThrow:
......
...@@ -49,6 +49,7 @@ int OperatorProperties::GetFrameStateInputCount(const Operator* op) { ...@@ -49,6 +49,7 @@ int OperatorProperties::GetFrameStateInputCount(const Operator* op) {
case IrOpcode::kJSInstanceOf: case IrOpcode::kJSInstanceOf:
// Object operations // Object operations
case IrOpcode::kJSCreate:
case IrOpcode::kJSCreateArguments: case IrOpcode::kJSCreateArguments:
case IrOpcode::kJSCreateLiteralArray: case IrOpcode::kJSCreateLiteralArray:
case IrOpcode::kJSCreateLiteralObject: case IrOpcode::kJSCreateLiteralObject:
......
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --strong-mode
// This tests that inlining a constructor call to a function which cannot be
// used as a constructor (e.g. strong mode function) still throws correctly.
function g() {
"use strong";
}
function f() {
return new g();
}
assertThrows(f);
assertThrows(f);
%OptimizeFunctionOnNextCall(f);
assertThrows(f);
...@@ -78,7 +78,7 @@ const SharedOperator kSharedOperators[] = { ...@@ -78,7 +78,7 @@ const SharedOperator kSharedOperators[] = {
SHARED(ToName, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2), SHARED(ToName, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2),
SHARED(ToObject, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2), SHARED(ToObject, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2),
SHARED(Yield, Operator::kNoProperties, 1, 0, 1, 1, 1, 1, 2), SHARED(Yield, Operator::kNoProperties, 1, 0, 1, 1, 1, 1, 2),
SHARED(Create, Operator::kEliminatable, 2, 0, 1, 0, 1, 1, 0), SHARED(Create, Operator::kEliminatable, 2, 1, 1, 0, 1, 1, 0),
SHARED(HasProperty, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), SHARED(HasProperty, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
SHARED(TypeOf, Operator::kEliminatable, 1, 0, 1, 0, 1, 1, 0), SHARED(TypeOf, Operator::kEliminatable, 1, 0, 1, 0, 1, 1, 0),
SHARED(InstanceOf, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), SHARED(InstanceOf, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
......
...@@ -988,7 +988,7 @@ TEST_F(JSTypedLoweringTest, JSCreate) { ...@@ -988,7 +988,7 @@ TEST_F(JSTypedLoweringTest, JSCreate) {
Node* const context = Parameter(Type::Any()); Node* const context = Parameter(Type::Any());
Node* const effect = graph()->start(); Node* const effect = graph()->start();
Reduction r = Reduce(graph()->NewNode(javascript()->Create(), target, target, Reduction r = Reduce(graph()->NewNode(javascript()->Create(), target, target,
context, effect)); context, EmptyFrameState(), effect));
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
EXPECT_THAT( EXPECT_THAT(
r.replacement(), r.replacement(),
......
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