Bug 1661352: Transpile spread calls r=jandem

The assertion in emitLoadArgumentSlot was unnecessary. Spread calls always have an argc of 1, so `hasArgumentArray` and `!addArgc` cancel each other out in GetIndexOfArgument.

Depends on D88513

Differential Revision: https://phabricator.services.mozilla.com/D88514
This commit is contained in:
Iain Ireland 2020-08-28 17:24:47 +00:00
Родитель d32bc4c647
Коммит a69d3f2397
4 изменённых файлов: 38 добавлений и 20 удалений

Просмотреть файл

@ -186,6 +186,25 @@ class MOZ_STACK_CLASS CallInfo {
return true;
}
void initForSpreadCall(MBasicBlock* current) {
MOZ_ASSERT(args_.empty());
if (constructing()) {
setNewTarget(current->pop());
}
// Spread calls have one argument, an Array object containing the args.
static_assert(decltype(args_)::InlineLength >= 1,
"Appending one argument should be infallible");
MOZ_ALWAYS_TRUE(args_.append(current->pop()));
// Get |this| and |callee|
setThis(current->pop());
setCallee(current->pop());
argFormat_ = ArgFormat::Array;
}
void initForGetterCall(MDefinition* callee, MDefinition* thisVal) {
MOZ_ASSERT(args_.empty());
setCallee(callee);

Просмотреть файл

@ -2665,26 +2665,23 @@ bool WarpBuilder::build_FunWithProto(BytecodeLocation loc) {
}
bool WarpBuilder::build_SpreadCall(BytecodeLocation loc) {
MDefinition* argArr = current->pop();
MDefinition* argThis = current->pop();
MDefinition* argFunc = current->pop();
bool constructing = false;
CallInfo callInfo(alloc(), loc.toRawBytecode(), constructing,
loc.resultIsPopped());
callInfo.initForSpreadCall(current);
// 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();
if (auto* cacheIRSnapshot = getOpSnapshot<WarpCacheIR>(loc)) {
return TranspileCacheIRToMIR(this, loc, cacheIRSnapshot, callInfo);
}
return resumeAfter(apply, loc);
MInstruction* call = makeSpreadCall(callInfo);
if (!call) {
return false;
}
current->add(call);
current->push(call);
return resumeAfter(call, loc);
}
bool WarpBuilder::build_SpreadNew(BytecodeLocation loc) {

Просмотреть файл

@ -2982,8 +2982,7 @@ bool WarpCacheIRTranspiler::emitLoadValueTruthyResult(ValOperandId inputId) {
bool WarpCacheIRTranspiler::emitLoadArgumentSlot(ValOperandId resultId,
uint32_t slotIndex) {
// Reverse of GetIndexOfArgument specialized to !hasArgumentArray.
MOZ_ASSERT(!loc_.isSpreadOp());
// Reverse of GetIndexOfArgument.
// Layout:
// NewTarget | Args.. (reversed) | ThisValue | Callee
@ -3085,6 +3084,9 @@ bool WarpCacheIRTranspiler::updateCallInfo(MDefinition* callee,
case CallFlags::Standard:
MOZ_ASSERT(callInfo_->argFormat() == CallInfo::ArgFormat::Standard);
break;
case CallFlags::Spread:
MOZ_ASSERT(callInfo_->argFormat() == CallInfo::ArgFormat::Array);
break;
case CallFlags::FunCall:
// Note: setCallee above already changed the callee to the target
// function instead of the |call| function.

Просмотреть файл

@ -556,6 +556,7 @@ AbortReasonOr<WarpScriptSnapshot*> WarpScriptOracle::createScriptSnapshot() {
case JSOp::FunCall:
case JSOp::FunApply:
case JSOp::New:
case JSOp::SpreadCall:
case JSOp::ToNumeric:
case JSOp::Pos:
case JSOp::Inc:
@ -716,7 +717,6 @@ AbortReasonOr<WarpScriptSnapshot*> WarpScriptOracle::createScriptSnapshot() {
case JSOp::CheckIsObj:
case JSOp::CheckObjCoercible:
case JSOp::FunWithProto:
case JSOp::SpreadCall:
case JSOp::SpreadNew:
case JSOp::SpreadSuperCall:
case JSOp::OptimizeSpreadCall: