зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1618198 part 25 - Support FunCall/FunApply and spread calls. r=iain
This needs more work to make it fast, especially JSOp::OptimizeSpreadCall. Differential Revision: https://phabricator.services.mozilla.com/D67835 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
997a680d00
Коммит
9ac848694a
|
@ -1387,7 +1387,7 @@ bool WarpBuilder::buildCallOp(BytecodeLocation loc) {
|
|||
uint32_t argc = loc.getCallArgc();
|
||||
JSOp op = loc.getOp();
|
||||
bool constructing = IsConstructOp(op);
|
||||
bool ignoresReturnValue = (op == JSOp::CallIgnoresRv);
|
||||
bool ignoresReturnValue = (op == JSOp::CallIgnoresRv || loc.resultIsPopped());
|
||||
|
||||
CallInfo callInfo(alloc(), loc.toRawBytecode(), constructing,
|
||||
ignoresReturnValue);
|
||||
|
@ -1455,6 +1455,14 @@ bool WarpBuilder::build_CallIter(BytecodeLocation loc) {
|
|||
return buildCallOp(loc);
|
||||
}
|
||||
|
||||
bool WarpBuilder::build_FunCall(BytecodeLocation loc) {
|
||||
return buildCallOp(loc);
|
||||
}
|
||||
|
||||
bool WarpBuilder::build_FunApply(BytecodeLocation loc) {
|
||||
return buildCallOp(loc);
|
||||
}
|
||||
|
||||
bool WarpBuilder::build_New(BytecodeLocation loc) { return buildCallOp(loc); }
|
||||
|
||||
bool WarpBuilder::build_SuperCall(BytecodeLocation loc) {
|
||||
|
@ -2292,3 +2300,63 @@ bool WarpBuilder::build_FunWithProto(BytecodeLocation loc) {
|
|||
current->push(ins);
|
||||
return resumeAfter(ins, loc);
|
||||
}
|
||||
|
||||
bool WarpBuilder::build_SpreadCall(BytecodeLocation loc) {
|
||||
MDefinition* argArr = current->pop();
|
||||
MDefinition* argThis = current->pop();
|
||||
MDefinition* argFunc = current->pop();
|
||||
|
||||
// Load dense elements of the argument array. Note that the bytecode ensures
|
||||
// this is an array.
|
||||
MElements* elements = MElements::New(alloc(), argArr);
|
||||
current->add(elements);
|
||||
|
||||
WrappedFunction* wrappedTarget = nullptr;
|
||||
auto* apply =
|
||||
MApplyArray::New(alloc(), wrappedTarget, argFunc, elements, argThis);
|
||||
current->add(apply);
|
||||
current->push(apply);
|
||||
|
||||
if (loc.resultIsPopped()) {
|
||||
apply->setIgnoresReturnValue();
|
||||
}
|
||||
|
||||
return resumeAfter(apply, loc);
|
||||
}
|
||||
|
||||
bool WarpBuilder::build_SpreadNew(BytecodeLocation loc) {
|
||||
MDefinition* newTarget = current->pop();
|
||||
MDefinition* argArr = current->pop();
|
||||
MDefinition* thisValue = current->pop();
|
||||
MDefinition* callee = current->pop();
|
||||
|
||||
// Inline the constructor on the caller-side.
|
||||
MCreateThis* createThis = MCreateThis::New(alloc(), callee, newTarget);
|
||||
current->add(createThis);
|
||||
thisValue->setImplicitlyUsedUnchecked();
|
||||
|
||||
// Load dense elements of the argument array. Note that the bytecode ensures
|
||||
// this is an array.
|
||||
MElements* elements = MElements::New(alloc(), argArr);
|
||||
current->add(elements);
|
||||
|
||||
WrappedFunction* wrappedTarget = nullptr;
|
||||
auto* apply = MConstructArray::New(alloc(), wrappedTarget, callee, elements,
|
||||
createThis, newTarget);
|
||||
current->add(apply);
|
||||
current->push(apply);
|
||||
return resumeAfter(apply, loc);
|
||||
}
|
||||
|
||||
bool WarpBuilder::build_SpreadSuperCall(BytecodeLocation loc) {
|
||||
return build_SpreadNew(loc);
|
||||
}
|
||||
|
||||
bool WarpBuilder::build_OptimizeSpreadCall(BytecodeLocation loc) {
|
||||
// TODO: like IonBuilder's slow path always deoptimize for now. Consider using
|
||||
// an IC for this so that we can optimize by inlining Baseline's CacheIR.
|
||||
MDefinition* arr = current->peek(-1);
|
||||
arr->setImplicitlyUsedUnchecked();
|
||||
pushConstant(BooleanValue(false));
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -122,6 +122,8 @@ namespace jit {
|
|||
_(Call) \
|
||||
_(CallIgnoresRv) \
|
||||
_(CallIter) \
|
||||
_(FunCall) \
|
||||
_(FunApply) \
|
||||
_(New) \
|
||||
_(SuperCall) \
|
||||
_(FunctionThis) \
|
||||
|
@ -202,6 +204,10 @@ namespace jit {
|
|||
_(Lambda) \
|
||||
_(LambdaArrow) \
|
||||
_(FunWithProto) \
|
||||
_(SpreadCall) \
|
||||
_(SpreadNew) \
|
||||
_(SpreadSuperCall) \
|
||||
_(OptimizeSpreadCall) \
|
||||
_(SetRval) \
|
||||
_(Return) \
|
||||
_(RetRval)
|
||||
|
|
|
@ -194,6 +194,11 @@ class BytecodeLocation {
|
|||
|
||||
bool isNameOp() const { return IsNameOp(getOp()); }
|
||||
|
||||
bool resultIsPopped() const {
|
||||
MOZ_ASSERT(StackDefs(rawBytecode_) == 1);
|
||||
return BytecodeIsPopped(rawBytecode_);
|
||||
}
|
||||
|
||||
// Accessors:
|
||||
JSOp getOp() const { return JSOp(*rawBytecode_); }
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче