Commit 07884202 authored by klaasb's avatar klaasb Committed by Commit bot

[interpreter] Add CreateWithContext bytecode

Generates a JSCreateWithContext node for TurboFan to optimize.

BUG=v8:4280
LOG=n

Review-Url: https://codereview.chromium.org/2255793002
Cr-Commit-Position: refs/heads/master@{#38723}
parent 978347e0
......@@ -942,6 +942,15 @@ void BytecodeGraphBuilder::VisitCreateFunctionContext() {
environment()->BindAccumulator(context);
}
void BytecodeGraphBuilder::VisitCreateWithContext() {
Node* object =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
const Operator* op = javascript()->CreateWithContext();
Node* context = NewNode(op, object, environment()->LookupAccumulator());
environment()->BindAccumulator(context);
}
void BytecodeGraphBuilder::BuildCreateArguments(CreateArgumentsType type) {
FrameStateBeforeAndAfter states(this);
const Operator* op = javascript()->CreateArguments(type);
......
......@@ -350,6 +350,11 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CreateFunctionContext(int slots) {
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateWithContext(Register object) {
Output(Bytecode::kCreateWithContext, RegisterOperand(object));
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments(
CreateArgumentsType type) {
// TODO(rmcilroy): Consider passing the type as a bytecode operand rather
......
......@@ -142,6 +142,10 @@ class BytecodeArrayBuilder final : public ZoneObject {
// Create a new context with size |slots|.
BytecodeArrayBuilder& CreateFunctionContext(int slots);
// Creates a new context for a with-statement with the |object| in a register
// and the closure in the accumulator.
BytecodeArrayBuilder& CreateWithContext(Register object);
// Create a new arguments object in the accumulator.
BytecodeArrayBuilder& CreateArguments(CreateArgumentsType type);
......
......@@ -3219,14 +3219,11 @@ void BytecodeGenerator::VisitNewLocalBlockContext(Scope* scope) {
void BytecodeGenerator::VisitNewLocalWithContext() {
AccumulatorResultScope accumulator_execution_result(this);
register_allocator()->PrepareForConsecutiveAllocations(2);
Register extension_object = register_allocator()->NextConsecutiveRegister();
Register closure = register_allocator()->NextConsecutiveRegister();
Register extension_object = register_allocator()->NewRegister();
builder()->CastAccumulatorToJSObject(extension_object);
VisitFunctionClosureForContext();
builder()->StoreAccumulatorInRegister(closure).CallRuntime(
Runtime::kPushWithContext, extension_object, 2);
builder()->CreateWithContext(extension_object);
execution_result()->SetResultInAccumulator();
}
......
......@@ -237,6 +237,7 @@ namespace interpreter {
V(CreateBlockContext, AccumulatorUse::kReadWrite, OperandType::kIdx) \
/* TODO(klaasb) rename Idx or add unsigned Imm OperandType? */ \
V(CreateFunctionContext, AccumulatorUse::kWrite, OperandType::kIdx) \
V(CreateWithContext, AccumulatorUse::kReadWrite, OperandType::kReg) \
\
/* Arguments allocation */ \
V(CreateMappedArguments, AccumulatorUse::kWrite) \
......
......@@ -1821,6 +1821,20 @@ void Interpreter::DoCreateFunctionContext(InterpreterAssembler* assembler) {
__ Dispatch();
}
// CreateWithContext <register>
//
// Creates a new context for a with-statement with the object in |register| and
// the closure in the accumulator.
void Interpreter::DoCreateWithContext(InterpreterAssembler* assembler) {
Node* reg_index = __ BytecodeOperandReg(0);
Node* object = __ LoadRegister(reg_index);
Node* closure = __ GetAccumulator();
Node* context = __ GetContext();
__ SetAccumulator(
__ CallRuntime(Runtime::kPushWithContext, context, object, closure));
__ Dispatch();
}
// CreateMappedArguments
//
// Creates a new mapped arguments object.
......
......@@ -11,16 +11,16 @@ wrap: yes
snippet: "
with ({x:42}) { return x; }
"
frame size: 4
frame size: 3
parameter count: 1
bytecode array length: 25
bytecode array length: 21
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), R(1),
B(Ldar), R(1),
B(ToObject), R(2),
B(Mov), R(closure), R(3),
B(CallRuntime), U16(Runtime::kPushWithContext), R(2), U8(2),
B(Ldar), R(closure),
B(CreateWithContext), R(2),
B(PushContext), R(0),
/* 50 S> */ B(LdaLookupSlot), U8(1),
B(PopContext), R(0),
......
......@@ -107,6 +107,8 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
// Emit create context operation.
builder.CreateFunctionContext(1);
builder.CreateWithContext(reg);
// Emit literal creation operations.
builder.CreateRegExpLiteral(factory->NewStringFromStaticChars("a"), 0, 0)
.CreateArrayLiteral(factory->NewFixedArray(1), 0, 0)
......
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