Bug 1739660 - Part 1: Support constructing in makeSpreadCall. r=iain

No change in behaviour, only changes `build_SpreadNew()` to call `makeSpreadCall()`
in preparation for the next patches in this stack.

Additionally moves the `MCreateThis::New` call from `WarpBuilder::buildCallOp()`
into a new method `WarpBuilder::buildCreateThis()`.

Differential Revision: https://phabricator.services.mozilla.com/D130489
This commit is contained in:
André Bargull 2021-11-16 12:19:14 +00:00
parent e68a9d44fd
commit 9aee391250
3 changed files with 37 additions and 30 deletions

View File

@ -1796,6 +1796,18 @@ bool WarpBuilder::transpileCall(BytecodeLocation loc,
return TranspileCacheIRToMIR(this, loc, cacheIRSnapshot, {argc}, callInfo);
}
void WarpBuilder::buildCreateThis(CallInfo& callInfo) {
MOZ_ASSERT(callInfo.constructing());
// Inline the this-object allocation on the caller-side.
MDefinition* callee = callInfo.callee();
MDefinition* newTarget = callInfo.getNewTarget();
auto* createThis = MCreateThis::New(alloc(), callee, newTarget);
current->add(createThis);
callInfo.thisArg()->setImplicitlyUsedUnchecked();
callInfo.setThis(createThis);
}
bool WarpBuilder::buildCallOp(BytecodeLocation loc) {
uint32_t argc = loc.getCallArgc();
JSOp op = loc.getOp();
@ -1831,13 +1843,7 @@ bool WarpBuilder::buildCallOp(BytecodeLocation loc) {
bool needsThisCheck = false;
if (callInfo.constructing()) {
// Inline the this-object allocation on the caller-side.
MDefinition* callee = callInfo.callee();
MDefinition* newTarget = callInfo.getNewTarget();
MCreateThis* createThis = MCreateThis::New(alloc(), callee, newTarget);
current->add(createThis);
callInfo.thisArg()->setImplicitlyUsedUnchecked();
callInfo.setThis(createThis);
buildCreateThis(callInfo);
needsThisCheck = true;
}
@ -2868,28 +2874,20 @@ bool WarpBuilder::build_SpreadCall(BytecodeLocation loc) {
}
bool WarpBuilder::build_SpreadNew(BytecodeLocation loc) {
MDefinition* newTarget = current->pop();
MDefinition* argArr = current->pop();
MDefinition* thisValue = current->pop();
MDefinition* callee = current->pop();
bool constructing = true;
CallInfo callInfo(alloc(), constructing, loc.resultIsPopped());
callInfo.initForSpreadCall(current);
// Inline the constructor on the caller-side.
MCreateThis* createThis = MCreateThis::New(alloc(), callee, newTarget);
current->add(createThis);
thisValue->setImplicitlyUsedUnchecked();
buildCreateThis(callInfo);
// 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);
apply->setBailoutKind(BailoutKind::TooManyArguments);
current->add(apply);
current->push(apply);
return resumeAfter(apply, loc);
MInstruction* call = makeSpreadCall(callInfo);
if (!call) {
return false;
}
call->setBailoutKind(BailoutKind::TooManyArguments);
current->add(call);
current->push(call);
return resumeAfter(call, loc);
}
bool WarpBuilder::build_SpreadSuperCall(BytecodeLocation loc) {

View File

@ -306,6 +306,8 @@ class MOZ_STACK_CLASS WarpBuilder : public WarpBuilderShared {
bool usesEnvironmentChain() const;
MDefinition* walkEnvironmentChain(uint32_t numHops);
void buildCreateThis(CallInfo& callInfo);
[[nodiscard]] bool transpileCall(BytecodeLocation loc,
const WarpCacheIR* cacheIRSnapshot,
CallInfo* callInfo);

View File

@ -64,13 +64,20 @@ MCall* WarpBuilderShared::makeCall(CallInfo& callInfo, bool needsThisCheck,
MInstruction* WarpBuilderShared::makeSpreadCall(CallInfo& callInfo,
bool isSameRealm,
WrappedFunction* target) {
// TODO: support SpreadNew and SpreadSuperCall
MOZ_ASSERT(!callInfo.constructing());
// Load dense elements of the argument array.
MElements* elements = MElements::New(alloc(), callInfo.arrayArg());
current->add(elements);
if (callInfo.constructing()) {
auto* construct =
MConstructArray::New(alloc(), target, callInfo.callee(), elements,
callInfo.thisArg(), callInfo.getNewTarget());
if (isSameRealm) {
construct->setNotCrossRealm();
}
return construct;
}
auto* apply = MApplyArray::New(alloc(), target, callInfo.callee(), elements,
callInfo.thisArg());