[Turbofan] Fix CallSuper argument order in BytecodeGraphBuilder.
The constructor and new.target arguments were passed to CallConstruct in the wrong order by BytecodeGraphBuilder, which caused subclassing to be incorrect when optimizing from bytecode. Also clean up some unecessary functions in interpreter.cc found while figuring this out. BUG=chromium:642409 Review-Url: https://codereview.chromium.org/2312103002 Cr-Commit-Position: refs/heads/master@{#39204}
This commit is contained in:
parent
1001ddf20f
commit
c950256013
@ -1151,13 +1151,13 @@ Node* BytecodeGraphBuilder::ProcessCallNewArguments(
|
||||
const Operator* call_new_op, Node* callee, Node* new_target,
|
||||
interpreter::Register first_arg, size_t arity) {
|
||||
Node** all = local_zone()->NewArray<Node*>(arity);
|
||||
all[0] = new_target;
|
||||
all[0] = callee;
|
||||
int first_arg_index = first_arg.index();
|
||||
for (int i = 1; i < static_cast<int>(arity) - 1; ++i) {
|
||||
all[i] = environment()->LookupRegister(
|
||||
interpreter::Register(first_arg_index + i - 1));
|
||||
}
|
||||
all[arity - 1] = callee;
|
||||
all[arity - 1] = new_target;
|
||||
Node* value = MakeNode(call_new_op, static_cast<int>(arity), all, false);
|
||||
return value;
|
||||
}
|
||||
|
@ -1469,7 +1469,12 @@ void Interpreter::DoTailCall(InterpreterAssembler* assembler) {
|
||||
DoJSCall(assembler, TailCallMode::kAllow);
|
||||
}
|
||||
|
||||
void Interpreter::DoCallRuntimeCommon(InterpreterAssembler* assembler) {
|
||||
// CallRuntime <function_id> <first_arg> <arg_count>
|
||||
//
|
||||
// Call the runtime function |function_id| with the first argument in
|
||||
// register |first_arg| and |arg_count| arguments in subsequent
|
||||
// registers.
|
||||
void Interpreter::DoCallRuntime(InterpreterAssembler* assembler) {
|
||||
Node* function_id = __ BytecodeOperandRuntimeId(0);
|
||||
Node* first_arg_reg = __ BytecodeOperandReg(1);
|
||||
Node* first_arg = __ RegisterLocation(first_arg_reg);
|
||||
@ -1480,15 +1485,6 @@ void Interpreter::DoCallRuntimeCommon(InterpreterAssembler* assembler) {
|
||||
__ Dispatch();
|
||||
}
|
||||
|
||||
// CallRuntime <function_id> <first_arg> <arg_count>
|
||||
//
|
||||
// Call the runtime function |function_id| with the first argument in
|
||||
// register |first_arg| and |arg_count| arguments in subsequent
|
||||
// registers.
|
||||
void Interpreter::DoCallRuntime(InterpreterAssembler* assembler) {
|
||||
DoCallRuntimeCommon(assembler);
|
||||
}
|
||||
|
||||
// InvokeIntrinsic <function_id> <first_arg> <arg_count>
|
||||
//
|
||||
// Implements the semantic equivalent of calling the runtime function
|
||||
@ -1506,7 +1502,13 @@ void Interpreter::DoInvokeIntrinsic(InterpreterAssembler* assembler) {
|
||||
__ Dispatch();
|
||||
}
|
||||
|
||||
void Interpreter::DoCallRuntimeForPairCommon(InterpreterAssembler* assembler) {
|
||||
// CallRuntimeForPair <function_id> <first_arg> <arg_count> <first_return>
|
||||
//
|
||||
// Call the runtime function |function_id| which returns a pair, with the
|
||||
// first argument in register |first_arg| and |arg_count| arguments in
|
||||
// subsequent registers. Returns the result in <first_return> and
|
||||
// <first_return + 1>
|
||||
void Interpreter::DoCallRuntimeForPair(InterpreterAssembler* assembler) {
|
||||
// Call the runtime function.
|
||||
Node* function_id = __ BytecodeOperandRuntimeId(0);
|
||||
Node* first_arg_reg = __ BytecodeOperandReg(1);
|
||||
@ -1526,17 +1528,11 @@ void Interpreter::DoCallRuntimeForPairCommon(InterpreterAssembler* assembler) {
|
||||
__ Dispatch();
|
||||
}
|
||||
|
||||
// CallRuntimeForPair <function_id> <first_arg> <arg_count> <first_return>
|
||||
// CallJSRuntime <context_index> <receiver> <arg_count>
|
||||
//
|
||||
// Call the runtime function |function_id| which returns a pair, with the
|
||||
// first argument in register |first_arg| and |arg_count| arguments in
|
||||
// subsequent registers. Returns the result in <first_return> and
|
||||
// <first_return + 1>
|
||||
void Interpreter::DoCallRuntimeForPair(InterpreterAssembler* assembler) {
|
||||
DoCallRuntimeForPairCommon(assembler);
|
||||
}
|
||||
|
||||
void Interpreter::DoCallJSRuntimeCommon(InterpreterAssembler* assembler) {
|
||||
// Call the JS runtime function that has the |context_index| with the receiver
|
||||
// in register |receiver| and |arg_count| arguments in subsequent registers.
|
||||
void Interpreter::DoCallJSRuntime(InterpreterAssembler* assembler) {
|
||||
Node* context_index = __ BytecodeOperandIdx(0);
|
||||
Node* receiver_reg = __ BytecodeOperandReg(1);
|
||||
Node* first_arg = __ RegisterLocation(receiver_reg);
|
||||
@ -1557,15 +1553,13 @@ void Interpreter::DoCallJSRuntimeCommon(InterpreterAssembler* assembler) {
|
||||
__ Dispatch();
|
||||
}
|
||||
|
||||
// CallJSRuntime <context_index> <receiver> <arg_count>
|
||||
// New <constructor> <first_arg> <arg_count>
|
||||
//
|
||||
// Call the JS runtime function that has the |context_index| with the receiver
|
||||
// in register |receiver| and |arg_count| arguments in subsequent registers.
|
||||
void Interpreter::DoCallJSRuntime(InterpreterAssembler* assembler) {
|
||||
DoCallJSRuntimeCommon(assembler);
|
||||
}
|
||||
|
||||
void Interpreter::DoCallConstruct(InterpreterAssembler* assembler) {
|
||||
// Call operator new with |constructor| and the first argument in
|
||||
// register |first_arg| and |arg_count| arguments in subsequent
|
||||
// registers. The new.target is in the accumulator.
|
||||
//
|
||||
void Interpreter::DoNew(InterpreterAssembler* assembler) {
|
||||
Callable ic = CodeFactory::InterpreterPushArgsAndConstruct(isolate_);
|
||||
Node* new_target = __ GetAccumulator();
|
||||
Node* constructor_reg = __ BytecodeOperandReg(0);
|
||||
@ -1582,16 +1576,6 @@ void Interpreter::DoCallConstruct(InterpreterAssembler* assembler) {
|
||||
__ Dispatch();
|
||||
}
|
||||
|
||||
// New <constructor> <first_arg> <arg_count>
|
||||
//
|
||||
// Call operator new with |constructor| and the first argument in
|
||||
// register |first_arg| and |arg_count| arguments in subsequent
|
||||
// registers. The new.target is in the accumulator.
|
||||
//
|
||||
void Interpreter::DoNew(InterpreterAssembler* assembler) {
|
||||
DoCallConstruct(assembler);
|
||||
}
|
||||
|
||||
// TestEqual <src>
|
||||
//
|
||||
// Test if the value in the <src> register equals the accumulator.
|
||||
|
@ -124,18 +124,6 @@ class Interpreter {
|
||||
// Generates code to perform a JS call that collects type feedback.
|
||||
void DoJSCall(InterpreterAssembler* assembler, TailCallMode tail_call_mode);
|
||||
|
||||
// Generates code to perform a runtime call.
|
||||
void DoCallRuntimeCommon(InterpreterAssembler* assembler);
|
||||
|
||||
// Generates code to perform a runtime call returning a pair.
|
||||
void DoCallRuntimeForPairCommon(InterpreterAssembler* assembler);
|
||||
|
||||
// Generates code to perform a JS runtime call.
|
||||
void DoCallJSRuntimeCommon(InterpreterAssembler* assembler);
|
||||
|
||||
// Generates code to perform a constructor call.
|
||||
void DoCallConstruct(InterpreterAssembler* assembler);
|
||||
|
||||
// Generates code to perform delete via function_id.
|
||||
void DoDelete(Runtime::FunctionId function_id,
|
||||
InterpreterAssembler* assembler);
|
||||
@ -148,9 +136,6 @@ class Interpreter {
|
||||
void DoStaLookupSlot(LanguageMode language_mode,
|
||||
InterpreterAssembler* assembler);
|
||||
|
||||
// Generates a node with the undefined constant.
|
||||
compiler::Node* BuildLoadUndefined(InterpreterAssembler* assembler);
|
||||
|
||||
// Generates code to load a context slot.
|
||||
compiler::Node* BuildLoadContextSlot(InterpreterAssembler* assembler);
|
||||
|
||||
|
22
test/mjsunit/regress/regress-642409.js
Normal file
22
test/mjsunit/regress/regress-642409.js
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright 2016 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
|
||||
|
||||
class SuperClass {
|
||||
}
|
||||
|
||||
class SubClass extends SuperClass {
|
||||
constructor() {
|
||||
super();
|
||||
this.doSomething();
|
||||
}
|
||||
doSomething() {
|
||||
}
|
||||
}
|
||||
|
||||
new SubClass();
|
||||
new SubClass();
|
||||
%OptimizeFunctionOnNextCall(SubClass);
|
||||
new SubClass();
|
Loading…
Reference in New Issue
Block a user