mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-23 23:57:31 +09:00
Bug 1454285 - Part 2: Disallow using innermostEmitterScope while the value does not match the bytecode environment.
Tag #1287
This commit is contained in:
parent
85d4d59f04
commit
d16b90c099
2 changed files with 76 additions and 32 deletions
|
|
@ -100,7 +100,7 @@ class BytecodeEmitter::NestableControl : public Nestable<BytecodeEmitter::Nestab
|
||||||
NestableControl(BytecodeEmitter* bce, StatementKind kind)
|
NestableControl(BytecodeEmitter* bce, StatementKind kind)
|
||||||
: Nestable<NestableControl>(&bce->innermostNestableControl),
|
: Nestable<NestableControl>(&bce->innermostNestableControl),
|
||||||
kind_(kind),
|
kind_(kind),
|
||||||
emitterScope_(bce->innermostEmitterScope)
|
emitterScope_(bce->innermostEmitterScopeNoCheck())
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -426,7 +426,7 @@ class BytecodeEmitter::EmitterScope : public Nestable<BytecodeEmitter::EmitterSc
|
||||||
// enclosing BCE.
|
// enclosing BCE.
|
||||||
if ((*bce)->parent) {
|
if ((*bce)->parent) {
|
||||||
*bce = (*bce)->parent;
|
*bce = (*bce)->parent;
|
||||||
return (*bce)->innermostEmitterScope;
|
return (*bce)->innermostEmitterScopeNoCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
@ -460,7 +460,7 @@ class BytecodeEmitter::EmitterScope : public Nestable<BytecodeEmitter::EmitterSc
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit EmitterScope(BytecodeEmitter* bce)
|
explicit EmitterScope(BytecodeEmitter* bce)
|
||||||
: Nestable<EmitterScope>(&bce->innermostEmitterScope),
|
: Nestable<EmitterScope>(&bce->innermostEmitterScope_),
|
||||||
nameCache_(bce->cx->frontendCollectionPool()),
|
nameCache_(bce->cx->frontendCollectionPool()),
|
||||||
hasEnvironment_(false),
|
hasEnvironment_(false),
|
||||||
environmentChainLength_(0),
|
environmentChainLength_(0),
|
||||||
|
|
@ -866,7 +866,7 @@ BytecodeEmitter::EmitterScope::enterLexical(BytecodeEmitter* bce, ScopeKind kind
|
||||||
Handle<LexicalScope::Data*> bindings)
|
Handle<LexicalScope::Data*> bindings)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(kind != ScopeKind::NamedLambda && kind != ScopeKind::StrictNamedLambda);
|
MOZ_ASSERT(kind != ScopeKind::NamedLambda && kind != ScopeKind::StrictNamedLambda);
|
||||||
MOZ_ASSERT(this == bce->innermostEmitterScope);
|
MOZ_ASSERT(this == bce->innermostEmitterScopeNoCheck());
|
||||||
|
|
||||||
if (!ensureCache(bce))
|
if (!ensureCache(bce))
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -935,7 +935,7 @@ BytecodeEmitter::EmitterScope::enterLexical(BytecodeEmitter* bce, ScopeKind kind
|
||||||
bool
|
bool
|
||||||
BytecodeEmitter::EmitterScope::enterNamedLambda(BytecodeEmitter* bce, FunctionBox* funbox)
|
BytecodeEmitter::EmitterScope::enterNamedLambda(BytecodeEmitter* bce, FunctionBox* funbox)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(this == bce->innermostEmitterScope);
|
MOZ_ASSERT(this == bce->innermostEmitterScopeNoCheck());
|
||||||
MOZ_ASSERT(funbox->namedLambdaBindings());
|
MOZ_ASSERT(funbox->namedLambdaBindings());
|
||||||
|
|
||||||
if (!ensureCache(bce))
|
if (!ensureCache(bce))
|
||||||
|
|
@ -1002,7 +1002,7 @@ BytecodeEmitter::EmitterScope::enterComprehensionFor(BytecodeEmitter* bce,
|
||||||
bool
|
bool
|
||||||
BytecodeEmitter::EmitterScope::enterParameterExpressionVar(BytecodeEmitter* bce)
|
BytecodeEmitter::EmitterScope::enterParameterExpressionVar(BytecodeEmitter* bce)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(this == bce->innermostEmitterScope);
|
MOZ_ASSERT(this == bce->innermostEmitterScopeNoCheck());
|
||||||
|
|
||||||
if (!ensureCache(bce))
|
if (!ensureCache(bce))
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1035,7 +1035,7 @@ BytecodeEmitter::EmitterScope::enterParameterExpressionVar(BytecodeEmitter* bce)
|
||||||
bool
|
bool
|
||||||
BytecodeEmitter::EmitterScope::enterFunction(BytecodeEmitter* bce, FunctionBox* funbox)
|
BytecodeEmitter::EmitterScope::enterFunction(BytecodeEmitter* bce, FunctionBox* funbox)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(this == bce->innermostEmitterScope);
|
MOZ_ASSERT(this == bce->innermostEmitterScopeNoCheck());
|
||||||
|
|
||||||
// If there are parameter expressions, there is an extra var scope.
|
// If there are parameter expressions, there is an extra var scope.
|
||||||
if (!funbox->hasExtraBodyVarScope())
|
if (!funbox->hasExtraBodyVarScope())
|
||||||
|
|
@ -1126,7 +1126,7 @@ BytecodeEmitter::EmitterScope::enterFunctionExtraBodyVar(BytecodeEmitter* bce, F
|
||||||
MOZ_ASSERT(funbox->hasParameterExprs);
|
MOZ_ASSERT(funbox->hasParameterExprs);
|
||||||
MOZ_ASSERT(funbox->extraVarScopeBindings() ||
|
MOZ_ASSERT(funbox->extraVarScopeBindings() ||
|
||||||
funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings());
|
funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings());
|
||||||
MOZ_ASSERT(this == bce->innermostEmitterScope);
|
MOZ_ASSERT(this == bce->innermostEmitterScopeNoCheck());
|
||||||
|
|
||||||
// The extra var scope is never popped once it's entered. It replaces the
|
// The extra var scope is never popped once it's entered. It replaces the
|
||||||
// function scope as the var emitter scope.
|
// function scope as the var emitter scope.
|
||||||
|
|
@ -1212,7 +1212,7 @@ class DynamicBindingIter : public BindingIter
|
||||||
bool
|
bool
|
||||||
BytecodeEmitter::EmitterScope::enterGlobal(BytecodeEmitter* bce, GlobalSharedContext* globalsc)
|
BytecodeEmitter::EmitterScope::enterGlobal(BytecodeEmitter* bce, GlobalSharedContext* globalsc)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(this == bce->innermostEmitterScope);
|
MOZ_ASSERT(this == bce->innermostEmitterScopeNoCheck());
|
||||||
|
|
||||||
bce->setVarEmitterScope(this);
|
bce->setVarEmitterScope(this);
|
||||||
|
|
||||||
|
|
@ -1272,7 +1272,7 @@ BytecodeEmitter::EmitterScope::enterGlobal(BytecodeEmitter* bce, GlobalSharedCon
|
||||||
bool
|
bool
|
||||||
BytecodeEmitter::EmitterScope::enterEval(BytecodeEmitter* bce, EvalSharedContext* evalsc)
|
BytecodeEmitter::EmitterScope::enterEval(BytecodeEmitter* bce, EvalSharedContext* evalsc)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(this == bce->innermostEmitterScope);
|
MOZ_ASSERT(this == bce->innermostEmitterScopeNoCheck());
|
||||||
|
|
||||||
bce->setVarEmitterScope(this);
|
bce->setVarEmitterScope(this);
|
||||||
|
|
||||||
|
|
@ -1327,7 +1327,7 @@ BytecodeEmitter::EmitterScope::enterEval(BytecodeEmitter* bce, EvalSharedContext
|
||||||
bool
|
bool
|
||||||
BytecodeEmitter::EmitterScope::enterModule(BytecodeEmitter* bce, ModuleSharedContext* modulesc)
|
BytecodeEmitter::EmitterScope::enterModule(BytecodeEmitter* bce, ModuleSharedContext* modulesc)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(this == bce->innermostEmitterScope);
|
MOZ_ASSERT(this == bce->innermostEmitterScopeNoCheck());
|
||||||
|
|
||||||
bce->setVarEmitterScope(this);
|
bce->setVarEmitterScope(this);
|
||||||
|
|
||||||
|
|
@ -1384,7 +1384,7 @@ BytecodeEmitter::EmitterScope::enterModule(BytecodeEmitter* bce, ModuleSharedCon
|
||||||
bool
|
bool
|
||||||
BytecodeEmitter::EmitterScope::enterWith(BytecodeEmitter* bce)
|
BytecodeEmitter::EmitterScope::enterWith(BytecodeEmitter* bce)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(this == bce->innermostEmitterScope);
|
MOZ_ASSERT(this == bce->innermostEmitterScopeNoCheck());
|
||||||
|
|
||||||
if (!ensureCache(bce))
|
if (!ensureCache(bce))
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1412,7 +1412,7 @@ BytecodeEmitter::EmitterScope::leave(BytecodeEmitter* bce, bool nonLocal)
|
||||||
{
|
{
|
||||||
// If we aren't leaving the scope due to a non-local jump (e.g., break),
|
// If we aren't leaving the scope due to a non-local jump (e.g., break),
|
||||||
// we must be the innermost scope.
|
// we must be the innermost scope.
|
||||||
MOZ_ASSERT_IF(!nonLocal, this == bce->innermostEmitterScope);
|
MOZ_ASSERT_IF(!nonLocal, this == bce->innermostEmitterScopeNoCheck());
|
||||||
|
|
||||||
ScopeKind kind = scope(bce)->kind();
|
ScopeKind kind = scope(bce)->kind();
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
|
|
@ -2123,7 +2123,7 @@ class ForOfLoopControl : public LoopControl
|
||||||
|
|
||||||
bool emitIteratorCloseInInnermostScope(BytecodeEmitter* bce,
|
bool emitIteratorCloseInInnermostScope(BytecodeEmitter* bce,
|
||||||
CompletionKind completionKind = CompletionKind::Normal) {
|
CompletionKind completionKind = CompletionKind::Normal) {
|
||||||
return emitIteratorCloseInScope(bce, *bce->innermostEmitterScope, completionKind);
|
return emitIteratorCloseInScope(bce, *bce->innermostEmitterScope(), completionKind);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emitIteratorCloseInScope(BytecodeEmitter* bce,
|
bool emitIteratorCloseInScope(BytecodeEmitter* bce,
|
||||||
|
|
@ -2201,8 +2201,11 @@ BytecodeEmitter::BytecodeEmitter(BytecodeEmitter* parent,
|
||||||
bodyScopeIndex(UINT32_MAX),
|
bodyScopeIndex(UINT32_MAX),
|
||||||
varEmitterScope(nullptr),
|
varEmitterScope(nullptr),
|
||||||
innermostNestableControl(nullptr),
|
innermostNestableControl(nullptr),
|
||||||
innermostEmitterScope(nullptr),
|
innermostEmitterScope_(nullptr),
|
||||||
innermostTDZCheckCache(nullptr),
|
innermostTDZCheckCache(nullptr),
|
||||||
|
#ifdef DEBUG
|
||||||
|
unstableEmitterScope(false),
|
||||||
|
#endif
|
||||||
constList(cx),
|
constList(cx),
|
||||||
scopeList(cx),
|
scopeList(cx),
|
||||||
tryNoteList(cx),
|
tryNoteList(cx),
|
||||||
|
|
@ -2259,13 +2262,13 @@ BytecodeEmitter::findInnermostNestableControl(Predicate predicate) const
|
||||||
NameLocation
|
NameLocation
|
||||||
BytecodeEmitter::lookupName(JSAtom* name)
|
BytecodeEmitter::lookupName(JSAtom* name)
|
||||||
{
|
{
|
||||||
return innermostEmitterScope->lookup(this, name);
|
return innermostEmitterScope()->lookup(this, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<NameLocation>
|
Maybe<NameLocation>
|
||||||
BytecodeEmitter::locationOfNameBoundInScope(JSAtom* name, EmitterScope* target)
|
BytecodeEmitter::locationOfNameBoundInScope(JSAtom* name, EmitterScope* target)
|
||||||
{
|
{
|
||||||
return innermostEmitterScope->locationBoundInScope(this, name, target);
|
return innermostEmitterScope()->locationBoundInScope(this, name, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<NameLocation>
|
Maybe<NameLocation>
|
||||||
|
|
@ -2726,7 +2729,7 @@ class NonLocalExitControl
|
||||||
: bce_(bce),
|
: bce_(bce),
|
||||||
savedScopeNoteIndex_(bce->scopeNoteList.length()),
|
savedScopeNoteIndex_(bce->scopeNoteList.length()),
|
||||||
savedDepth_(bce->stackDepth),
|
savedDepth_(bce->stackDepth),
|
||||||
openScopeNoteIndex_(bce->innermostEmitterScope->noteIndex()),
|
openScopeNoteIndex_(bce->innermostEmitterScope()->noteIndex()),
|
||||||
kind_(kind)
|
kind_(kind)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
@ -2772,9 +2775,11 @@ NonLocalExitControl::prepareForNonLocalJump(BytecodeEmitter::NestableControl* ta
|
||||||
using NestableControl = BytecodeEmitter::NestableControl;
|
using NestableControl = BytecodeEmitter::NestableControl;
|
||||||
using EmitterScope = BytecodeEmitter::EmitterScope;
|
using EmitterScope = BytecodeEmitter::EmitterScope;
|
||||||
|
|
||||||
EmitterScope* es = bce_->innermostEmitterScope;
|
EmitterScope* es = bce_->innermostEmitterScope();
|
||||||
int npops = 0;
|
int npops = 0;
|
||||||
|
|
||||||
|
AutoCheckUnstableEmitterScope cues(bce_);
|
||||||
|
|
||||||
// For 'continue', 'break', and 'return' statements, emit IteratorClose
|
// For 'continue', 'break', and 'return' statements, emit IteratorClose
|
||||||
// bytecode inline. 'continue' statements do not call IteratorClose for
|
// bytecode inline. 'continue' statements do not call IteratorClose for
|
||||||
// the loop they are continuing.
|
// the loop they are continuing.
|
||||||
|
|
@ -2895,7 +2900,7 @@ BytecodeEmitter::emitGoto(NestableControl* target, JumpList* jumplist, SrcNoteTy
|
||||||
Scope*
|
Scope*
|
||||||
BytecodeEmitter::innermostScope() const
|
BytecodeEmitter::innermostScope() const
|
||||||
{
|
{
|
||||||
return innermostEmitterScope->scope(this);
|
return innermostEmitterScope()->scope(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -3555,7 +3560,7 @@ BytecodeEmitter::needsImplicitThis()
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Otherwise see if the current point is under a 'with'.
|
// Otherwise see if the current point is under a 'with'.
|
||||||
for (EmitterScope* es = innermostEmitterScope; es; es = es->enclosingInFrame()) {
|
for (EmitterScope* es = innermostEmitterScope(); es; es = es->enclosingInFrame()) {
|
||||||
if (es->scope(this)->kind() == ScopeKind::With)
|
if (es->scope(this)->kind() == ScopeKind::With)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -5206,7 +5211,7 @@ BytecodeEmitter::emitSetOrInitializeDestructuring(ParseNode* target, Destructuri
|
||||||
// destructuring declaration needs to initialize the name in
|
// destructuring declaration needs to initialize the name in
|
||||||
// the function scope. The innermost scope is the var scope,
|
// the function scope. The innermost scope is the var scope,
|
||||||
// and its enclosing scope is the function scope.
|
// and its enclosing scope is the function scope.
|
||||||
EmitterScope* funScope = innermostEmitterScope->enclosingInFrame();
|
EmitterScope* funScope = innermostEmitterScope()->enclosingInFrame();
|
||||||
NameLocation paramLoc = *locationOfNameBoundInScope(name, funScope);
|
NameLocation paramLoc = *locationOfNameBoundInScope(name, funScope);
|
||||||
if (!emitSetOrInitializeNameAtLocation(name, paramLoc, emitSwapScopeAndRhs, true))
|
if (!emitSetOrInitializeNameAtLocation(name, paramLoc, emitSwapScopeAndRhs, true))
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -7308,7 +7313,7 @@ BytecodeEmitter::emitForOf(ParseNode* forOfLoop, EmitterScope* headLexicalEmitte
|
||||||
// bindings inducing an environment, recreate the current environment.
|
// bindings inducing an environment, recreate the current environment.
|
||||||
DebugOnly<ParseNode*> forOfTarget = forOfHead->pn_kid1;
|
DebugOnly<ParseNode*> forOfTarget = forOfHead->pn_kid1;
|
||||||
MOZ_ASSERT(forOfTarget->isKind(PNK_LET) || forOfTarget->isKind(PNK_CONST));
|
MOZ_ASSERT(forOfTarget->isKind(PNK_LET) || forOfTarget->isKind(PNK_CONST));
|
||||||
MOZ_ASSERT(headLexicalEmitterScope == innermostEmitterScope);
|
MOZ_ASSERT(headLexicalEmitterScope == innermostEmitterScope());
|
||||||
MOZ_ASSERT(headLexicalEmitterScope->scope(this)->kind() == ScopeKind::Lexical);
|
MOZ_ASSERT(headLexicalEmitterScope->scope(this)->kind() == ScopeKind::Lexical);
|
||||||
|
|
||||||
if (headLexicalEmitterScope->hasEnvironment()) {
|
if (headLexicalEmitterScope->hasEnvironment()) {
|
||||||
|
|
@ -7490,7 +7495,7 @@ BytecodeEmitter::emitForIn(ParseNode* forInLoop, EmitterScope* headLexicalEmitte
|
||||||
// it must be the innermost one. If that scope has closed-over
|
// it must be the innermost one. If that scope has closed-over
|
||||||
// bindings inducing an environment, recreate the current environment.
|
// bindings inducing an environment, recreate the current environment.
|
||||||
MOZ_ASSERT(forInTarget->isKind(PNK_LET) || forInTarget->isKind(PNK_CONST));
|
MOZ_ASSERT(forInTarget->isKind(PNK_LET) || forInTarget->isKind(PNK_CONST));
|
||||||
MOZ_ASSERT(headLexicalEmitterScope == innermostEmitterScope);
|
MOZ_ASSERT(headLexicalEmitterScope == innermostEmitterScope());
|
||||||
MOZ_ASSERT(headLexicalEmitterScope->scope(this)->kind() == ScopeKind::Lexical);
|
MOZ_ASSERT(headLexicalEmitterScope->scope(this)->kind() == ScopeKind::Lexical);
|
||||||
|
|
||||||
if (headLexicalEmitterScope->hasEnvironment()) {
|
if (headLexicalEmitterScope->hasEnvironment()) {
|
||||||
|
|
@ -7619,7 +7624,7 @@ BytecodeEmitter::emitCStyleFor(ParseNode* pn, EmitterScope* headLexicalEmitterSc
|
||||||
// exists for the head, it must be the innermost one. If that scope
|
// exists for the head, it must be the innermost one. If that scope
|
||||||
// has closed-over bindings inducing an environment, recreate the
|
// has closed-over bindings inducing an environment, recreate the
|
||||||
// current environment.
|
// current environment.
|
||||||
MOZ_ASSERT(headLexicalEmitterScope == innermostEmitterScope);
|
MOZ_ASSERT(headLexicalEmitterScope == innermostEmitterScope());
|
||||||
MOZ_ASSERT(headLexicalEmitterScope->scope(this)->kind() == ScopeKind::Lexical);
|
MOZ_ASSERT(headLexicalEmitterScope->scope(this)->kind() == ScopeKind::Lexical);
|
||||||
|
|
||||||
if (headLexicalEmitterScope->hasEnvironment()) {
|
if (headLexicalEmitterScope->hasEnvironment()) {
|
||||||
|
|
@ -7667,7 +7672,7 @@ BytecodeEmitter::emitCStyleFor(ParseNode* pn, EmitterScope* headLexicalEmitterSc
|
||||||
|
|
||||||
// ES 13.7.4.8 step 3.e. The per-iteration freshening.
|
// ES 13.7.4.8 step 3.e. The per-iteration freshening.
|
||||||
if (forLoopRequiresFreshening) {
|
if (forLoopRequiresFreshening) {
|
||||||
MOZ_ASSERT(headLexicalEmitterScope == innermostEmitterScope);
|
MOZ_ASSERT(headLexicalEmitterScope == innermostEmitterScope());
|
||||||
MOZ_ASSERT(headLexicalEmitterScope->scope(this)->kind() == ScopeKind::Lexical);
|
MOZ_ASSERT(headLexicalEmitterScope->scope(this)->kind() == ScopeKind::Lexical);
|
||||||
|
|
||||||
if (headLexicalEmitterScope->hasEnvironment()) {
|
if (headLexicalEmitterScope->hasEnvironment()) {
|
||||||
|
|
@ -10367,7 +10372,7 @@ BytecodeEmitter::emitFunctionFormalParameters(ParseNode* pn)
|
||||||
{
|
{
|
||||||
ParseNode* funBody = pn->last();
|
ParseNode* funBody = pn->last();
|
||||||
FunctionBox* funbox = sc->asFunctionBox();
|
FunctionBox* funbox = sc->asFunctionBox();
|
||||||
EmitterScope* funScope = innermostEmitterScope;
|
EmitterScope* funScope = innermostEmitterScope();
|
||||||
|
|
||||||
bool hasParameterExprs = funbox->hasParameterExprs;
|
bool hasParameterExprs = funbox->hasParameterExprs;
|
||||||
bool hasRest = funbox->hasRest();
|
bool hasRest = funbox->hasRest();
|
||||||
|
|
|
||||||
|
|
@ -228,9 +228,23 @@ struct MOZ_STACK_CLASS BytecodeEmitter
|
||||||
|
|
||||||
EmitterScope* varEmitterScope;
|
EmitterScope* varEmitterScope;
|
||||||
NestableControl* innermostNestableControl;
|
NestableControl* innermostNestableControl;
|
||||||
EmitterScope* innermostEmitterScope;
|
EmitterScope* innermostEmitterScope_;
|
||||||
TDZCheckCache* innermostTDZCheckCache;
|
TDZCheckCache* innermostTDZCheckCache;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
bool unstableEmitterScope;
|
||||||
|
|
||||||
|
friend class AutoCheckUnstableEmitterScope;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EmitterScope* innermostEmitterScope() const {
|
||||||
|
MOZ_ASSERT(!unstableEmitterScope);
|
||||||
|
return innermostEmitterScopeNoCheck();
|
||||||
|
}
|
||||||
|
EmitterScope* innermostEmitterScopeNoCheck() const {
|
||||||
|
return innermostEmitterScope_;
|
||||||
|
}
|
||||||
|
|
||||||
CGConstList constList; /* constants to be included with the script */
|
CGConstList constList; /* constants to be included with the script */
|
||||||
CGObjectList objectList; /* list of emitted objects */
|
CGObjectList objectList; /* list of emitted objects */
|
||||||
CGScopeList scopeList; /* list of emitted scopes */
|
CGScopeList scopeList; /* list of emitted scopes */
|
||||||
|
|
@ -319,7 +333,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter
|
||||||
EmitterScope* source);
|
EmitterScope* source);
|
||||||
|
|
||||||
mozilla::Maybe<NameLocation> locationOfNameBoundInFunctionScope(JSAtom* name) {
|
mozilla::Maybe<NameLocation> locationOfNameBoundInFunctionScope(JSAtom* name) {
|
||||||
return locationOfNameBoundInFunctionScope(name, innermostEmitterScope);
|
return locationOfNameBoundInFunctionScope(name, innermostEmitterScope());
|
||||||
}
|
}
|
||||||
|
|
||||||
void setVarEmitterScope(EmitterScope* emitterScope) {
|
void setVarEmitterScope(EmitterScope* emitterScope) {
|
||||||
|
|
@ -610,7 +624,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter
|
||||||
MOZ_MUST_USE bool emitToIteratorResult(bool done);
|
MOZ_MUST_USE bool emitToIteratorResult(bool done);
|
||||||
|
|
||||||
MOZ_MUST_USE bool emitGetDotGeneratorInInnermostScope() {
|
MOZ_MUST_USE bool emitGetDotGeneratorInInnermostScope() {
|
||||||
return emitGetDotGeneratorInScope(*innermostEmitterScope);
|
return emitGetDotGeneratorInScope(*innermostEmitterScope());
|
||||||
}
|
}
|
||||||
MOZ_MUST_USE bool emitGetDotGeneratorInScope(EmitterScope& currentScope);
|
MOZ_MUST_USE bool emitGetDotGeneratorInScope(EmitterScope& currentScope);
|
||||||
|
|
||||||
|
|
@ -619,7 +633,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter
|
||||||
MOZ_MUST_USE bool emitYieldOp(JSOp op);
|
MOZ_MUST_USE bool emitYieldOp(JSOp op);
|
||||||
MOZ_MUST_USE bool emitYieldStar(ParseNode* iter);
|
MOZ_MUST_USE bool emitYieldStar(ParseNode* iter);
|
||||||
MOZ_MUST_USE bool emitAwaitInInnermostScope() {
|
MOZ_MUST_USE bool emitAwaitInInnermostScope() {
|
||||||
return emitAwaitInScope(*innermostEmitterScope);
|
return emitAwaitInScope(*innermostEmitterScope());
|
||||||
}
|
}
|
||||||
MOZ_MUST_USE bool emitAwaitInInnermostScope(ParseNode* pn);
|
MOZ_MUST_USE bool emitAwaitInInnermostScope(ParseNode* pn);
|
||||||
MOZ_MUST_USE bool emitAwaitInScope(EmitterScope& currentScope);
|
MOZ_MUST_USE bool emitAwaitInScope(EmitterScope& currentScope);
|
||||||
|
|
@ -729,7 +743,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter
|
||||||
MOZ_MUST_USE bool emitIteratorCloseInInnermostScope(IteratorKind iterKind = IteratorKind::Sync,
|
MOZ_MUST_USE bool emitIteratorCloseInInnermostScope(IteratorKind iterKind = IteratorKind::Sync,
|
||||||
CompletionKind completionKind = CompletionKind::Normal,
|
CompletionKind completionKind = CompletionKind::Normal,
|
||||||
bool allowSelfHosted = false) {
|
bool allowSelfHosted = false) {
|
||||||
return emitIteratorCloseInScope(*innermostEmitterScope, iterKind, completionKind,
|
return emitIteratorCloseInScope(*innermostEmitterScope(), iterKind, completionKind,
|
||||||
allowSelfHosted);
|
allowSelfHosted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -829,6 +843,31 @@ struct MOZ_STACK_CLASS BytecodeEmitter
|
||||||
MOZ_MUST_USE bool emitSuperElemOp(ParseNode* pn, JSOp op, bool isCall = false);
|
MOZ_MUST_USE bool emitSuperElemOp(ParseNode* pn, JSOp op, bool isCall = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MOZ_RAII AutoCheckUnstableEmitterScope {
|
||||||
|
#ifdef DEBUG
|
||||||
|
bool prev_;
|
||||||
|
BytecodeEmitter* bce_;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public:
|
||||||
|
AutoCheckUnstableEmitterScope() = delete;
|
||||||
|
explicit AutoCheckUnstableEmitterScope(BytecodeEmitter* bce)
|
||||||
|
#ifdef DEBUG
|
||||||
|
: bce_(bce)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
prev_ = bce_->unstableEmitterScope;
|
||||||
|
bce_->unstableEmitterScope = true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
~AutoCheckUnstableEmitterScope() {
|
||||||
|
#ifdef DEBUG
|
||||||
|
bce_->unstableEmitterScope = prev_;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} /* namespace frontend */
|
} /* namespace frontend */
|
||||||
} /* namespace js */
|
} /* namespace js */
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue