mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 14:52:16 +00:00
Bug 1799288: Cover destructuring parameters in the parameters try-catch block for async functions. r=mgaudet
Differential Revision: https://phabricator.services.mozilla.com/D161600
This commit is contained in:
parent
bdc412e198
commit
06528cdbaa
@ -17,7 +17,7 @@
|
||||
using namespace js;
|
||||
using namespace js::frontend;
|
||||
|
||||
bool AsyncEmitter::prepareForParamsWithExpression() {
|
||||
bool AsyncEmitter::prepareForParamsWithExpressionOrDestructuring() {
|
||||
MOZ_ASSERT(state_ == State::Start);
|
||||
#ifdef DEBUG
|
||||
state_ = State::Parameters;
|
||||
@ -28,7 +28,7 @@ bool AsyncEmitter::prepareForParamsWithExpression() {
|
||||
return rejectTryCatch_->emitTry();
|
||||
}
|
||||
|
||||
bool AsyncEmitter::prepareForParamsWithoutExpression() {
|
||||
bool AsyncEmitter::prepareForParamsWithoutExpressionOrDestructuring() {
|
||||
MOZ_ASSERT(state_ == State::Start);
|
||||
#ifdef DEBUG
|
||||
state_ = State::Parameters;
|
||||
|
@ -25,11 +25,12 @@ struct BytecodeEmitter;
|
||||
// the number of hops required to reach the |.generator| variable. In order
|
||||
// to handle this, we can't reuse the same TryCatch emitter.
|
||||
//
|
||||
// Simple case - For a function without expression parameters:
|
||||
// Simple case - For a function without expression or destructuring
|
||||
// parameters:
|
||||
// `async function f(<params>) {<body>}`,
|
||||
// AsyncEmitter ae(this);
|
||||
//
|
||||
// ae.prepareForParamsWithoutExpression();
|
||||
// ae.prepareForParamsWithoutExpressionOrDestructuring();
|
||||
// // Emit Params.
|
||||
// ...
|
||||
// ae.paramsEpilogue(); // We need to emit the epilogue before the extra
|
||||
@ -43,11 +44,11 @@ struct BytecodeEmitter;
|
||||
//
|
||||
// ae.emitEndFunction();
|
||||
//
|
||||
// Complex case - For a function with expression parameters:
|
||||
// Complex case - For a function with expression or destructuring parameters:
|
||||
// `async function f(<expression>) {<body>}`,
|
||||
// AsyncEmitter ae(this);
|
||||
//
|
||||
// ae.prepareForParamsWithExpression();
|
||||
// ae.prepareForParamsWithExpressionOrDestructuring();
|
||||
//
|
||||
// // Emit Params.
|
||||
// ...
|
||||
@ -96,26 +97,26 @@ class MOZ_STACK_CLASS AsyncEmitter {
|
||||
// |
|
||||
// +----------+
|
||||
// |
|
||||
// | [Parameters with Expression]
|
||||
// | prepareForParamsWithExpression +------------+
|
||||
// +-------------------------------------| Parameters |-->+
|
||||
// | +------------+ |
|
||||
// | |
|
||||
// | [Parameters Without Expression] |
|
||||
// | prepareForParamsWithoutExpression +------------+ |
|
||||
// +-------------------------------------| Parameters |-->+
|
||||
// | +------------+ |
|
||||
// | [Modules] |
|
||||
// | prepareForModule +----------------+ |
|
||||
// +-------------------->| ModulePrologue |--+ |
|
||||
// +----------------+ | |
|
||||
// | |
|
||||
// | |
|
||||
// +-----------------------------------------+ |
|
||||
// | |
|
||||
// | |
|
||||
// V +------------+ paramsEpilogue |
|
||||
// +<--------------------| PostParams |<------------------+
|
||||
// | [Parameters with Expression or Destructuring]
|
||||
// | prepareForParamsWithExpressionOrDestructuring +------------+
|
||||
// +----------------------------------------------------| Parameters |-->+
|
||||
// | +------------+ |
|
||||
// | |
|
||||
// | [Parameters Without Expression or Destructuring] |
|
||||
// | prepareForParamsWithoutExpressionOrDestructuring +------------+ |
|
||||
// +----------------------------------------------------| Parameters |-->+
|
||||
// | +------------+ |
|
||||
// | [Modules] |
|
||||
// | prepareForModule +----------------+ |
|
||||
// +-------------------->| ModulePrologue |--+ |
|
||||
// +----------------+ | |
|
||||
// | |
|
||||
// | |
|
||||
// +-----------------------------------------+ |
|
||||
// | |
|
||||
// | |
|
||||
// V +------------+ paramsEpilogue |
|
||||
// +<--------------------| PostParams |<---------------------------------+
|
||||
// | +------------+
|
||||
// |
|
||||
// | [Script body]
|
||||
@ -158,8 +159,8 @@ class MOZ_STACK_CLASS AsyncEmitter {
|
||||
public:
|
||||
explicit AsyncEmitter(BytecodeEmitter* bce) : bce_(bce){};
|
||||
|
||||
[[nodiscard]] bool prepareForParamsWithoutExpression();
|
||||
[[nodiscard]] bool prepareForParamsWithExpression();
|
||||
[[nodiscard]] bool prepareForParamsWithoutExpressionOrDestructuring();
|
||||
[[nodiscard]] bool prepareForParamsWithExpressionOrDestructuring();
|
||||
[[nodiscard]] bool prepareForModule();
|
||||
[[nodiscard]] bool emitParamsEpilogue();
|
||||
[[nodiscard]] bool prepareForBody();
|
||||
|
@ -360,12 +360,12 @@ bool FunctionScriptEmitter::prepareForParameters() {
|
||||
}
|
||||
|
||||
if (funbox_->needsPromiseResult()) {
|
||||
if (funbox_->hasParameterExprs) {
|
||||
if (!asyncEmitter_->prepareForParamsWithExpression()) {
|
||||
if (funbox_->hasParameterExprs || funbox_->hasDestructuringArgs) {
|
||||
if (!asyncEmitter_->prepareForParamsWithExpressionOrDestructuring()) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!asyncEmitter_->prepareForParamsWithoutExpression()) {
|
||||
if (!asyncEmitter_->prepareForParamsWithoutExpressionOrDestructuring()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,56 @@
|
||||
// |reftest| skip-if(!xulRuntime.shell) -- needs drainJobQueue
|
||||
|
||||
class ExpectedError extends Error {
|
||||
name = "ExpectedError";
|
||||
}
|
||||
|
||||
class UnexpectedError extends Error {
|
||||
name = "UnexpectedError";
|
||||
}
|
||||
|
||||
function throwExpectedError() {
|
||||
throw new ExpectedError();
|
||||
}
|
||||
|
||||
async function throwsInParameterExpression(a = throwExpectedError()) {
|
||||
throw new UnexpectedError();
|
||||
}
|
||||
assertEventuallyThrows(throwsInParameterExpression(), ExpectedError);
|
||||
|
||||
async function throwsInObjectDestructuringParameterEmpty({}) {
|
||||
throw new UnexpectedError();
|
||||
}
|
||||
assertEventuallyThrows(throwsInObjectDestructuringParameterEmpty(), TypeError);
|
||||
|
||||
let objectThrowingExpectedError = {
|
||||
get a() {
|
||||
throw new ExpectedError();
|
||||
}
|
||||
}
|
||||
|
||||
async function throwsInObjectDestructuringParameter({a}) {
|
||||
throw new UnexpectedError();
|
||||
}
|
||||
assertEventuallyThrows(throwsInObjectDestructuringParameter(), TypeError);
|
||||
assertEventuallyThrows(throwsInObjectDestructuringParameter(objectThrowingExpectedError), ExpectedError);
|
||||
|
||||
let iteratorThrowingExpectedError = {
|
||||
[Symbol.iterator]() {
|
||||
throw new ExpectedError();
|
||||
}
|
||||
};
|
||||
|
||||
async function throwsInArrayDestructuringParameterEmpty([]) {
|
||||
throw new UnexpectedError();
|
||||
}
|
||||
assertEventuallyThrows(throwsInArrayDestructuringParameterEmpty(), TypeError);
|
||||
assertEventuallyThrows(throwsInArrayDestructuringParameterEmpty(iteratorThrowingExpectedError), ExpectedError);
|
||||
|
||||
async function throwsInArrayDestructuringParameter([a]) {
|
||||
throw new UnexpectedError();
|
||||
}
|
||||
assertEventuallyThrows(throwsInArrayDestructuringParameter(), TypeError);
|
||||
assertEventuallyThrows(throwsInArrayDestructuringParameter(iteratorThrowingExpectedError), ExpectedError);
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
Loading…
Reference in New Issue
Block a user