Commit f5e6dcb6 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Add support to lower Function.prototype.call.

Support lowering of Function.prototype.call in the JSBuiltinReducer,
which is actually straightforward because of the way we represent JS
calls in TurboFan.  Currently we cannot inline the actual target yet,
since inlining still runs before typed lowering, but that will be
possible as well soon(ish).

R=jarin@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#31938}
parent 6e0aa37c
......@@ -91,6 +91,41 @@ JSBuiltinReducer::JSBuiltinReducer(Editor* editor, JSGraph* jsgraph)
: AdvancedReducer(editor), jsgraph_(jsgraph) {}
// ES6 section 19.2.3.3 Function.prototype.call (thisArg, ...args)
Reduction JSBuiltinReducer::ReduceFunctionCall(Node* node) {
DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode());
CallFunctionParameters const& p = CallFunctionParametersOf(node->op());
Handle<JSFunction> apply = Handle<JSFunction>::cast(
HeapObjectMatcher(NodeProperties::GetValueInput(node, 0)).Value());
// Change context of {node} to the Function.prototype.call context,
// to ensure any exception is thrown in the correct context.
NodeProperties::ReplaceContextInput(
node, jsgraph()->HeapConstant(handle(apply->context(), isolate())));
// Remove the target from {node} and use the receiver as target instead, and
// the thisArg becomes the new target. If thisArg was not provided, insert
// undefined instead.
size_t arity = p.arity();
DCHECK_LE(2u, arity);
ConvertReceiverMode convert_mode;
if (arity == 2) {
// The thisArg was not provided, use undefined as receiver.
convert_mode = ConvertReceiverMode::kNullOrUndefined;
node->ReplaceInput(0, node->InputAt(1));
node->ReplaceInput(1, jsgraph()->UndefinedConstant());
} else {
// Just remove the target, which is the first value input.
convert_mode = ConvertReceiverMode::kAny;
node->RemoveInput(0);
--arity;
}
// TODO(turbofan): Migrate the call count to the new operator?
NodeProperties::ChangeOp(node, javascript()->CallFunction(
arity, p.language_mode(), VectorSlotPair(),
convert_mode, p.tail_call_mode()));
return Changed(node);
}
// ECMA-262, section 15.8.2.11.
Reduction JSBuiltinReducer::ReduceMathMax(Node* node) {
JSCallReduction r(node);
......@@ -150,6 +185,8 @@ Reduction JSBuiltinReducer::Reduce(Node* node) {
// Dispatch according to the BuiltinFunctionId if present.
if (!r.HasBuiltinFunctionId()) return NoChange();
switch (r.GetBuiltinFunctionId()) {
case kFunctionCall:
return ReduceFunctionCall(node);
case kMathMax:
reduction = ReduceMathMax(node);
break;
......@@ -174,6 +211,9 @@ Reduction JSBuiltinReducer::Reduce(Node* node) {
Graph* JSBuiltinReducer::graph() const { return jsgraph()->graph(); }
Isolate* JSBuiltinReducer::isolate() const { return jsgraph()->isolate(); }
CommonOperatorBuilder* JSBuiltinReducer::common() const {
return jsgraph()->common();
}
......@@ -188,6 +228,11 @@ SimplifiedOperatorBuilder* JSBuiltinReducer::simplified() const {
return jsgraph()->simplified();
}
JSOperatorBuilder* JSBuiltinReducer::javascript() const {
return jsgraph()->javascript();
}
} // namespace compiler
} // namespace internal
} // namespace v8
......@@ -14,6 +14,7 @@ namespace compiler {
// Forward declarations.
class CommonOperatorBuilder;
class JSGraph;
class JSOperatorBuilder;
class MachineOperatorBuilder;
class SimplifiedOperatorBuilder;
......@@ -26,15 +27,18 @@ class JSBuiltinReducer final : public AdvancedReducer {
Reduction Reduce(Node* node) final;
private:
Reduction ReduceFunctionCall(Node* node);
Reduction ReduceMathMax(Node* node);
Reduction ReduceMathImul(Node* node);
Reduction ReduceMathFround(Node* node);
JSGraph* jsgraph() const { return jsgraph_; }
Graph* graph() const;
JSGraph* jsgraph() const { return jsgraph_; }
Isolate* isolate() const;
CommonOperatorBuilder* common() const;
MachineOperatorBuilder* machine() const;
SimplifiedOperatorBuilder* simplified() const;
JSOperatorBuilder* javascript() const;
JSGraph* jsgraph_;
};
......
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