| Index: src/compiler/bytecode-graph-builder.cc
|
| diff --git a/src/compiler/bytecode-graph-builder.cc b/src/compiler/bytecode-graph-builder.cc
|
| index eff5fd0cfa895258aba70718746c54754725e224..06977529dbd19104566a2c7b84fdad8840220ec9 100644
|
| --- a/src/compiler/bytecode-graph-builder.cc
|
| +++ b/src/compiler/bytecode-graph-builder.cc
|
| @@ -134,6 +134,12 @@ Node* BytecodeGraphBuilder::GetFunctionClosure() {
|
| }
|
|
|
|
|
| +Node* BytecodeGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
|
| + return NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object,
|
| + jsgraph()->IntPtrConstant(offset - kHeapObjectTag));
|
| +}
|
| +
|
| +
|
| Node* BytecodeGraphBuilder::BuildLoadImmutableObjectField(Node* object,
|
| int offset) {
|
| return graph()->NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object,
|
| @@ -142,6 +148,21 @@ Node* BytecodeGraphBuilder::BuildLoadImmutableObjectField(Node* object,
|
| }
|
|
|
|
|
| +Node* BytecodeGraphBuilder::BuildLoadGlobalObject() {
|
| + const Operator* load_op =
|
| + javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true);
|
| + return NewNode(load_op, GetFunctionContext());
|
| +}
|
| +
|
| +
|
| +Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) {
|
| + Node* global = BuildLoadGlobalObject();
|
| + Node* native_context =
|
| + BuildLoadObjectField(global, JSGlobalObject::kNativeContextOffset);
|
| + return NewNode(javascript()->LoadContext(0, index, true), native_context);
|
| +}
|
| +
|
| +
|
| Node* BytecodeGraphBuilder::BuildLoadFeedbackVector() {
|
| if (!feedback_vector_.is_set()) {
|
| Node* closure = GetFunctionClosure();
|
| @@ -650,11 +671,11 @@ void BytecodeGraphBuilder::VisitCreateObjectLiteral(
|
|
|
|
|
| Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
|
| - interpreter::Register callee,
|
| + Node* callee,
|
| interpreter::Register receiver,
|
| size_t arity) {
|
| - Node** all = info()->zone()->NewArray<Node*>(arity);
|
| - all[0] = environment()->LookupRegister(callee);
|
| + Node** all = info()->zone()->NewArray<Node*>(static_cast<int>(arity));
|
| + all[0] = callee;
|
| all[1] = environment()->LookupRegister(receiver);
|
| int receiver_index = receiver.index();
|
| for (int i = 2; i < static_cast<int>(arity); ++i) {
|
| @@ -672,7 +693,7 @@ void BytecodeGraphBuilder::BuildCall(
|
| // register has been loaded with null / undefined explicitly or we are sure it
|
| // is not null / undefined.
|
| ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny;
|
| - interpreter::Register callee = iterator.GetRegisterOperand(0);
|
| + Node* callee = environment()->LookupRegister(iterator.GetRegisterOperand(0));
|
| interpreter::Register receiver = iterator.GetRegisterOperand(1);
|
| size_t arg_count = iterator.GetCountOperand(2);
|
| VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(3));
|
| @@ -697,21 +718,78 @@ void BytecodeGraphBuilder::VisitCallWide(
|
| }
|
|
|
|
|
| -void BytecodeGraphBuilder::VisitCallRuntime(
|
| +void BytecodeGraphBuilder::VisitCallJSRuntime(
|
| const interpreter::BytecodeArrayIterator& iterator) {
|
| - UNIMPLEMENTED();
|
| + Node* callee = BuildLoadNativeContextField(iterator.GetIndexOperand(0));
|
| + interpreter::Register receiver = iterator.GetRegisterOperand(1);
|
| + size_t arg_count = iterator.GetCountOperand(2);
|
| +
|
| + // Create node to perform the JS runtime call.
|
| + const Operator* call =
|
| + javascript()->CallFunction(arg_count + 2, language_mode());
|
| + Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 2);
|
| + AddEmptyFrameStateInputs(value);
|
| + environment()->BindAccumulator(value);
|
| }
|
|
|
|
|
| -void BytecodeGraphBuilder::VisitCallJSRuntime(
|
| +Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
|
| + const Operator* call_runtime_op, interpreter::Register first_arg,
|
| + size_t arity) {
|
| + Node** all = info()->zone()->NewArray<Node*>(arity);
|
| + int first_arg_index = first_arg.index();
|
| + for (int i = 0; i < static_cast<int>(arity); ++i) {
|
| + all[i] = environment()->LookupRegister(
|
| + interpreter::Register(first_arg_index + i));
|
| + }
|
| + Node* value = MakeNode(call_runtime_op, static_cast<int>(arity), all, false);
|
| + return value;
|
| +}
|
| +
|
| +
|
| +void BytecodeGraphBuilder::VisitCallRuntime(
|
| const interpreter::BytecodeArrayIterator& iterator) {
|
| - UNIMPLEMENTED();
|
| + Runtime::FunctionId functionId =
|
| + static_cast<Runtime::FunctionId>(iterator.GetIndexOperand(0));
|
| + interpreter::Register first_arg = iterator.GetRegisterOperand(1);
|
| + size_t arg_count = iterator.GetCountOperand(2);
|
| +
|
| + // Create node to perform the runtime call.
|
| + const Operator* call = javascript()->CallRuntime(functionId, arg_count);
|
| + Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count);
|
| + AddEmptyFrameStateInputs(value);
|
| + environment()->BindAccumulator(value);
|
| +}
|
| +
|
| +
|
| +Node* BytecodeGraphBuilder::ProcessCallNewArguments(
|
| + const Operator* call_new_op, interpreter::Register callee,
|
| + interpreter::Register first_arg, size_t arity) {
|
| + Node** all = info()->zone()->NewArray<Node*>(arity);
|
| + all[0] = environment()->LookupRegister(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));
|
| + }
|
| + // Original constructor is the same as the callee.
|
| + all[arity - 1] = environment()->LookupRegister(callee);
|
| + Node* value = MakeNode(call_new_op, static_cast<int>(arity), all, false);
|
| + return value;
|
| }
|
|
|
|
|
| void BytecodeGraphBuilder::VisitNew(
|
| const interpreter::BytecodeArrayIterator& iterator) {
|
| - UNIMPLEMENTED();
|
| + interpreter::Register callee = iterator.GetRegisterOperand(0);
|
| + interpreter::Register first_arg = iterator.GetRegisterOperand(1);
|
| + size_t arg_count = iterator.GetCountOperand(2);
|
| +
|
| + const Operator* call =
|
| + javascript()->CallConstruct(static_cast<int>(arg_count) + 2);
|
| + Node* value = ProcessCallNewArguments(call, callee, first_arg, arg_count + 2);
|
| + AddEmptyFrameStateInputs(value);
|
| + environment()->BindAccumulator(value);
|
| }
|
|
|
|
|
|
|