mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-25 00:27:29 +09:00
Issue #2155 - Move NestableControl classes except ForOfLoopControl to BytecodeControlStructures.{cpp.h}
Based-on: m-c 1460489/3
This commit is contained in:
parent
81691afbc3
commit
a8ac1cac3d
5 changed files with 277 additions and 237 deletions
84
js/src/frontend/BytecodeControlStructures.cpp
Normal file
84
js/src/frontend/BytecodeControlStructures.cpp
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "frontend/BytecodeControlStructures.h"
|
||||||
|
|
||||||
|
#include "frontend/BytecodeEmitter.h"
|
||||||
|
#include "frontend/EmitterScope.h"
|
||||||
|
|
||||||
|
using namespace js;
|
||||||
|
using namespace js::frontend;
|
||||||
|
|
||||||
|
NestableControl::NestableControl(BytecodeEmitter* bce, StatementKind kind)
|
||||||
|
: Nestable<NestableControl>(&bce->innermostNestableControl),
|
||||||
|
kind_(kind),
|
||||||
|
emitterScope_(bce->innermostEmitterScopeNoCheck())
|
||||||
|
{}
|
||||||
|
|
||||||
|
BreakableControl::BreakableControl(BytecodeEmitter* bce, StatementKind kind)
|
||||||
|
: NestableControl(bce, kind)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(is<BreakableControl>());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
BreakableControl::patchBreaks(BytecodeEmitter* bce)
|
||||||
|
{
|
||||||
|
return bce->emitJumpTargetAndPatch(breaks);
|
||||||
|
}
|
||||||
|
|
||||||
|
LabelControl::LabelControl(BytecodeEmitter* bce, JSAtom* label, ptrdiff_t startOffset)
|
||||||
|
: BreakableControl(bce, StatementKind::Label),
|
||||||
|
label_(bce->cx, label),
|
||||||
|
startOffset_(startOffset)
|
||||||
|
{}
|
||||||
|
|
||||||
|
LoopControl::LoopControl(BytecodeEmitter* bce, StatementKind loopKind)
|
||||||
|
: BreakableControl(bce, loopKind),
|
||||||
|
tdzCache_(bce),
|
||||||
|
continueTarget({ -1 })
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(is<LoopControl>());
|
||||||
|
|
||||||
|
LoopControl* enclosingLoop = findNearest<LoopControl>(enclosing());
|
||||||
|
|
||||||
|
stackDepth_ = bce->stackDepth;
|
||||||
|
loopDepth_ = enclosingLoop ? enclosingLoop->loopDepth_ + 1 : 1;
|
||||||
|
|
||||||
|
int loopSlots;
|
||||||
|
if (loopKind == StatementKind::Spread || loopKind == StatementKind::ForOfLoop)
|
||||||
|
loopSlots = 3;
|
||||||
|
else if (loopKind == StatementKind::ForInLoop)
|
||||||
|
loopSlots = 2;
|
||||||
|
else
|
||||||
|
loopSlots = 0;
|
||||||
|
|
||||||
|
MOZ_ASSERT(loopSlots <= stackDepth_);
|
||||||
|
|
||||||
|
if (enclosingLoop) {
|
||||||
|
canIonOsr_ = (enclosingLoop->canIonOsr_ &&
|
||||||
|
stackDepth_ == enclosingLoop->stackDepth_ + loopSlots);
|
||||||
|
} else {
|
||||||
|
canIonOsr_ = stackDepth_ == loopSlots;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
LoopControl::patchBreaksAndContinues(BytecodeEmitter* bce)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(continueTarget.offset != -1);
|
||||||
|
if (!patchBreaks(bce))
|
||||||
|
return false;
|
||||||
|
bce->patchJumpsToTarget(continues, continueTarget);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TryFinallyControl::TryFinallyControl(BytecodeEmitter* bce, StatementKind kind)
|
||||||
|
: NestableControl(bce, kind),
|
||||||
|
emittingSubroutine_(false)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(is<TryFinallyControl>());
|
||||||
|
}
|
||||||
175
js/src/frontend/BytecodeControlStructures.h
Normal file
175
js/src/frontend/BytecodeControlStructures.h
Normal file
|
|
@ -0,0 +1,175 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef frontend_BytecodeControlStructures_h
|
||||||
|
#define frontend_BytecodeControlStructures_h
|
||||||
|
|
||||||
|
#include "mozilla/Attributes.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "ds/Nestable.h"
|
||||||
|
#include "frontend/JumpList.h"
|
||||||
|
#include "frontend/SharedContext.h"
|
||||||
|
#include "frontend/TDZCheckCache.h"
|
||||||
|
#include "gc/Rooting.h"
|
||||||
|
#include "vm/String.h"
|
||||||
|
|
||||||
|
namespace js {
|
||||||
|
namespace frontend {
|
||||||
|
|
||||||
|
struct BytecodeEmitter;
|
||||||
|
class EmitterScope;
|
||||||
|
|
||||||
|
class NestableControl : public Nestable<NestableControl>
|
||||||
|
{
|
||||||
|
StatementKind kind_;
|
||||||
|
|
||||||
|
// The innermost scope when this was pushed.
|
||||||
|
EmitterScope* emitterScope_;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
NestableControl(BytecodeEmitter* bce, StatementKind kind);
|
||||||
|
|
||||||
|
public:
|
||||||
|
using Nestable<NestableControl>::enclosing;
|
||||||
|
using Nestable<NestableControl>::findNearest;
|
||||||
|
|
||||||
|
StatementKind kind() const {
|
||||||
|
return kind_;
|
||||||
|
}
|
||||||
|
|
||||||
|
EmitterScope* emitterScope() const {
|
||||||
|
return emitterScope_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool is() const;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T& as() {
|
||||||
|
MOZ_ASSERT(this->is<T>());
|
||||||
|
return static_cast<T&>(*this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class BreakableControl : public NestableControl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Offset of the last break.
|
||||||
|
JumpList breaks;
|
||||||
|
|
||||||
|
BreakableControl(BytecodeEmitter* bce, StatementKind kind);
|
||||||
|
|
||||||
|
MOZ_MUST_USE bool patchBreaks(BytecodeEmitter* bce);
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
inline bool
|
||||||
|
NestableControl::is<BreakableControl>() const
|
||||||
|
{
|
||||||
|
return StatementKindIsUnlabeledBreakTarget(kind_) || kind_ == StatementKind::Label;
|
||||||
|
}
|
||||||
|
|
||||||
|
class LabelControl : public BreakableControl
|
||||||
|
{
|
||||||
|
RootedAtom label_;
|
||||||
|
|
||||||
|
// The code offset when this was pushed. Used for effectfulness checking.
|
||||||
|
ptrdiff_t startOffset_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
LabelControl(BytecodeEmitter* bce, JSAtom* label, ptrdiff_t startOffset);
|
||||||
|
|
||||||
|
HandleAtom label() const {
|
||||||
|
return label_;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptrdiff_t startOffset() const {
|
||||||
|
return startOffset_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
inline bool
|
||||||
|
NestableControl::is<LabelControl>() const
|
||||||
|
{
|
||||||
|
return kind_ == StatementKind::Label;
|
||||||
|
}
|
||||||
|
|
||||||
|
class LoopControl : public BreakableControl
|
||||||
|
{
|
||||||
|
// Loops' children are emitted in dominance order, so they can always
|
||||||
|
// have a TDZCheckCache.
|
||||||
|
TDZCheckCache tdzCache_;
|
||||||
|
|
||||||
|
// Stack depth when this loop was pushed on the control stack.
|
||||||
|
int32_t stackDepth_;
|
||||||
|
|
||||||
|
// The loop nesting depth. Used as a hint to Ion.
|
||||||
|
uint32_t loopDepth_;
|
||||||
|
|
||||||
|
// Can we OSR into Ion from here? True unless there is non-loop state on the stack.
|
||||||
|
bool canIonOsr_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// The target of continue statement jumps, e.g., the update portion of a
|
||||||
|
// for(;;) loop.
|
||||||
|
JumpTarget continueTarget;
|
||||||
|
|
||||||
|
// Offset of the last continue in the loop.
|
||||||
|
JumpList continues;
|
||||||
|
|
||||||
|
LoopControl(BytecodeEmitter* bce, StatementKind loopKind);
|
||||||
|
|
||||||
|
uint32_t loopDepth() const {
|
||||||
|
return loopDepth_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool canIonOsr() const {
|
||||||
|
return canIonOsr_;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_MUST_USE bool patchBreaksAndContinues(BytecodeEmitter* bce);
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
inline bool
|
||||||
|
NestableControl::is<LoopControl>() const
|
||||||
|
{
|
||||||
|
return StatementKindIsLoop(kind_);
|
||||||
|
}
|
||||||
|
|
||||||
|
class TryFinallyControl : public NestableControl
|
||||||
|
{
|
||||||
|
bool emittingSubroutine_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// The subroutine when emitting a finally block.
|
||||||
|
JumpList gosubs;
|
||||||
|
|
||||||
|
// Offset of the last catch guard, if any.
|
||||||
|
JumpList guardJump;
|
||||||
|
|
||||||
|
TryFinallyControl(BytecodeEmitter* bce, StatementKind kind);
|
||||||
|
|
||||||
|
void setEmittingSubroutine() {
|
||||||
|
emittingSubroutine_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool emittingSubroutine() const {
|
||||||
|
return emittingSubroutine_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
inline bool
|
||||||
|
NestableControl::is<TryFinallyControl>() const
|
||||||
|
{
|
||||||
|
return kind_ == StatementKind::Try || kind_ == StatementKind::Finally;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace frontend */
|
||||||
|
} /* namespace js */
|
||||||
|
|
||||||
|
#endif /* frontend_BytecodeControlStructures_h */
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
#include "jsutil.h"
|
#include "jsutil.h"
|
||||||
|
|
||||||
#include "ds/Nestable.h"
|
#include "ds/Nestable.h"
|
||||||
|
#include "frontend/BytecodeControlStructures.h"
|
||||||
#include "frontend/CallOrNewEmitter.h"
|
#include "frontend/CallOrNewEmitter.h"
|
||||||
#include "frontend/ElemOpEmitter.h"
|
#include "frontend/ElemOpEmitter.h"
|
||||||
#include "frontend/EmitterScope.h"
|
#include "frontend/EmitterScope.h"
|
||||||
|
|
@ -62,11 +63,6 @@ using mozilla::NumberIsInt32;
|
||||||
using mozilla::PodCopy;
|
using mozilla::PodCopy;
|
||||||
using mozilla::Some;
|
using mozilla::Some;
|
||||||
|
|
||||||
class BreakableControl;
|
|
||||||
class LabelControl;
|
|
||||||
class LoopControl;
|
|
||||||
class ForOfLoopControl;
|
|
||||||
class TryFinallyControl;
|
|
||||||
class OptionalEmitter;
|
class OptionalEmitter;
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
@ -89,222 +85,6 @@ GetCallArgsAndCount(ParseNode* callNode, ParseNode** argumentNode)
|
||||||
return callNode->pn_count - 1;
|
return callNode->pn_count - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
class BytecodeEmitter::NestableControl : public Nestable<BytecodeEmitter::NestableControl>
|
|
||||||
{
|
|
||||||
StatementKind kind_;
|
|
||||||
|
|
||||||
// The innermost scope when this was pushed.
|
|
||||||
EmitterScope* emitterScope_;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
NestableControl(BytecodeEmitter* bce, StatementKind kind)
|
|
||||||
: Nestable<NestableControl>(&bce->innermostNestableControl),
|
|
||||||
kind_(kind),
|
|
||||||
emitterScope_(bce->innermostEmitterScopeNoCheck())
|
|
||||||
{ }
|
|
||||||
|
|
||||||
public:
|
|
||||||
using Nestable<NestableControl>::enclosing;
|
|
||||||
using Nestable<NestableControl>::findNearest;
|
|
||||||
|
|
||||||
StatementKind kind() const {
|
|
||||||
return kind_;
|
|
||||||
}
|
|
||||||
|
|
||||||
EmitterScope* emitterScope() const {
|
|
||||||
return emitterScope_;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool is() const;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T& as() {
|
|
||||||
MOZ_ASSERT(this->is<T>());
|
|
||||||
return static_cast<T&>(*this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Template specializations are disallowed in different namespaces; specialize
|
|
||||||
// all the NestableControl subtypes up front.
|
|
||||||
namespace js {
|
|
||||||
namespace frontend {
|
|
||||||
|
|
||||||
template <>
|
|
||||||
bool
|
|
||||||
BytecodeEmitter::NestableControl::is<BreakableControl>() const
|
|
||||||
{
|
|
||||||
return StatementKindIsUnlabeledBreakTarget(kind_) || kind_ == StatementKind::Label;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
bool
|
|
||||||
BytecodeEmitter::NestableControl::is<LabelControl>() const
|
|
||||||
{
|
|
||||||
return kind_ == StatementKind::Label;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
bool
|
|
||||||
BytecodeEmitter::NestableControl::is<LoopControl>() const
|
|
||||||
{
|
|
||||||
return StatementKindIsLoop(kind_);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
bool
|
|
||||||
BytecodeEmitter::NestableControl::is<ForOfLoopControl>() const
|
|
||||||
{
|
|
||||||
return kind_ == StatementKind::ForOfLoop;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
bool
|
|
||||||
BytecodeEmitter::NestableControl::is<TryFinallyControl>() const
|
|
||||||
{
|
|
||||||
return kind_ == StatementKind::Try || kind_ == StatementKind::Finally;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace frontend
|
|
||||||
} // namespace js
|
|
||||||
|
|
||||||
class BreakableControl : public BytecodeEmitter::NestableControl
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// Offset of the last break.
|
|
||||||
JumpList breaks;
|
|
||||||
|
|
||||||
BreakableControl(BytecodeEmitter* bce, StatementKind kind)
|
|
||||||
: NestableControl(bce, kind)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(is<BreakableControl>());
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_MUST_USE bool patchBreaks(BytecodeEmitter* bce) {
|
|
||||||
return bce->emitJumpTargetAndPatch(breaks);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class LabelControl : public BreakableControl
|
|
||||||
{
|
|
||||||
RootedAtom label_;
|
|
||||||
|
|
||||||
// The code offset when this was pushed. Used for effectfulness checking.
|
|
||||||
ptrdiff_t startOffset_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
LabelControl(BytecodeEmitter* bce, JSAtom* label, ptrdiff_t startOffset)
|
|
||||||
: BreakableControl(bce, StatementKind::Label),
|
|
||||||
label_(bce->cx, label),
|
|
||||||
startOffset_(startOffset)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
HandleAtom label() const {
|
|
||||||
return label_;
|
|
||||||
}
|
|
||||||
|
|
||||||
ptrdiff_t startOffset() const {
|
|
||||||
return startOffset_;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class LoopControl : public BreakableControl
|
|
||||||
{
|
|
||||||
// Loops' children are emitted in dominance order, so they can always
|
|
||||||
// have a TDZCheckCache.
|
|
||||||
TDZCheckCache tdzCache_;
|
|
||||||
|
|
||||||
// Stack depth when this loop was pushed on the control stack.
|
|
||||||
int32_t stackDepth_;
|
|
||||||
|
|
||||||
// The loop nesting depth. Used as a hint to Ion.
|
|
||||||
uint32_t loopDepth_;
|
|
||||||
|
|
||||||
// Can we OSR into Ion from here? True unless there is non-loop state on the stack.
|
|
||||||
bool canIonOsr_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// The target of continue statement jumps, e.g., the update portion of a
|
|
||||||
// for(;;) loop.
|
|
||||||
JumpTarget continueTarget;
|
|
||||||
|
|
||||||
// Offset of the last continue in the loop.
|
|
||||||
JumpList continues;
|
|
||||||
|
|
||||||
LoopControl(BytecodeEmitter* bce, StatementKind loopKind)
|
|
||||||
: BreakableControl(bce, loopKind),
|
|
||||||
tdzCache_(bce),
|
|
||||||
continueTarget({ -1 })
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(is<LoopControl>());
|
|
||||||
|
|
||||||
LoopControl* enclosingLoop = findNearest<LoopControl>(enclosing());
|
|
||||||
|
|
||||||
stackDepth_ = bce->stackDepth;
|
|
||||||
loopDepth_ = enclosingLoop ? enclosingLoop->loopDepth_ + 1 : 1;
|
|
||||||
|
|
||||||
int loopSlots;
|
|
||||||
if (loopKind == StatementKind::Spread || loopKind == StatementKind::ForOfLoop)
|
|
||||||
loopSlots = 3;
|
|
||||||
else if (loopKind == StatementKind::ForInLoop)
|
|
||||||
loopSlots = 2;
|
|
||||||
else
|
|
||||||
loopSlots = 0;
|
|
||||||
|
|
||||||
MOZ_ASSERT(loopSlots <= stackDepth_);
|
|
||||||
|
|
||||||
if (enclosingLoop) {
|
|
||||||
canIonOsr_ = (enclosingLoop->canIonOsr_ &&
|
|
||||||
stackDepth_ == enclosingLoop->stackDepth_ + loopSlots);
|
|
||||||
} else {
|
|
||||||
canIonOsr_ = stackDepth_ == loopSlots;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t loopDepth() const {
|
|
||||||
return loopDepth_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool canIonOsr() const {
|
|
||||||
return canIonOsr_;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_MUST_USE bool patchBreaksAndContinues(BytecodeEmitter* bce) {
|
|
||||||
MOZ_ASSERT(continueTarget.offset != -1);
|
|
||||||
if (!patchBreaks(bce))
|
|
||||||
return false;
|
|
||||||
bce->patchJumpsToTarget(continues, continueTarget);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class TryFinallyControl : public BytecodeEmitter::NestableControl
|
|
||||||
{
|
|
||||||
bool emittingSubroutine_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// The subroutine when emitting a finally block.
|
|
||||||
JumpList gosubs;
|
|
||||||
|
|
||||||
// Offset of the last catch guard, if any.
|
|
||||||
JumpList guardJump;
|
|
||||||
|
|
||||||
TryFinallyControl(BytecodeEmitter* bce, StatementKind kind)
|
|
||||||
: NestableControl(bce, kind),
|
|
||||||
emittingSubroutine_(false)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(is<TryFinallyControl>());
|
|
||||||
}
|
|
||||||
|
|
||||||
void setEmittingSubroutine() {
|
|
||||||
emittingSubroutine_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool emittingSubroutine() const {
|
|
||||||
return emittingSubroutine_;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class MOZ_STACK_CLASS TryEmitter
|
class MOZ_STACK_CLASS TryEmitter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -898,6 +678,19 @@ class ForOfLoopControl : public LoopControl
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace js {
|
||||||
|
namespace frontend {
|
||||||
|
|
||||||
|
template <>
|
||||||
|
bool
|
||||||
|
NestableControl::is<ForOfLoopControl>() const
|
||||||
|
{
|
||||||
|
return kind_ == StatementKind::ForOfLoop;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace frontend
|
||||||
|
} // namespace js
|
||||||
|
|
||||||
BytecodeEmitter::BytecodeEmitter(BytecodeEmitter* parent,
|
BytecodeEmitter::BytecodeEmitter(BytecodeEmitter* parent,
|
||||||
Parser<FullParseHandler>* parser, SharedContext* sc,
|
Parser<FullParseHandler>* parser, SharedContext* sc,
|
||||||
HandleScript script, Handle<LazyScript*> lazyScript,
|
HandleScript script, Handle<LazyScript*> lazyScript,
|
||||||
|
|
@ -958,13 +751,6 @@ BytecodeEmitter::init()
|
||||||
return atomIndices.acquire(cx);
|
return atomIndices.acquire(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Predicate /* (NestableControl*) -> bool */>
|
|
||||||
BytecodeEmitter::NestableControl*
|
|
||||||
BytecodeEmitter::findInnermostNestableControl(Predicate predicate) const
|
|
||||||
{
|
|
||||||
return NestableControl::findNearest(innermostNestableControl, predicate);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T*
|
T*
|
||||||
BytecodeEmitter::findInnermostNestableControl() const
|
BytecodeEmitter::findInnermostNestableControl() const
|
||||||
|
|
@ -1463,7 +1249,7 @@ class NonLocalExitControl
|
||||||
bce_->stackDepth = savedDepth_;
|
bce_->stackDepth = savedDepth_;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_MUST_USE bool prepareForNonLocalJump(BytecodeEmitter::NestableControl* target);
|
MOZ_MUST_USE bool prepareForNonLocalJump(NestableControl* target);
|
||||||
|
|
||||||
MOZ_MUST_USE bool prepareForNonLocalJumpToOutermost() {
|
MOZ_MUST_USE bool prepareForNonLocalJumpToOutermost() {
|
||||||
return prepareForNonLocalJump(nullptr);
|
return prepareForNonLocalJump(nullptr);
|
||||||
|
|
@ -1494,10 +1280,8 @@ NonLocalExitControl::leaveScope(EmitterScope* es)
|
||||||
* Emit additional bytecode(s) for non-local jumps.
|
* Emit additional bytecode(s) for non-local jumps.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
NonLocalExitControl::prepareForNonLocalJump(BytecodeEmitter::NestableControl* target)
|
NonLocalExitControl::prepareForNonLocalJump(NestableControl* target)
|
||||||
{
|
{
|
||||||
using NestableControl = BytecodeEmitter::NestableControl;
|
|
||||||
|
|
||||||
EmitterScope* es = bce_->innermostEmitterScope();
|
EmitterScope* es = bce_->innermostEmitterScope();
|
||||||
int npops = 0;
|
int npops = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -123,13 +123,12 @@ typedef Vector<jssrcnote, 64> SrcNotesVector;
|
||||||
class CallOrNewEmitter;
|
class CallOrNewEmitter;
|
||||||
class ElemOpEmitter;
|
class ElemOpEmitter;
|
||||||
class EmitterScope;
|
class EmitterScope;
|
||||||
|
class NestableControl;
|
||||||
class PropOpEmitter;
|
class PropOpEmitter;
|
||||||
class TDZCheckCache;
|
class TDZCheckCache;
|
||||||
|
|
||||||
struct MOZ_STACK_CLASS BytecodeEmitter
|
struct MOZ_STACK_CLASS BytecodeEmitter
|
||||||
{
|
{
|
||||||
class NestableControl;
|
|
||||||
|
|
||||||
SharedContext* const sc; /* context shared between parsing and bytecode generation */
|
SharedContext* const sc; /* context shared between parsing and bytecode generation */
|
||||||
|
|
||||||
ExclusiveContext* const cx;
|
ExclusiveContext* const cx;
|
||||||
|
|
@ -257,9 +256,6 @@ struct MOZ_STACK_CLASS BytecodeEmitter
|
||||||
|
|
||||||
MOZ_MUST_USE bool init();
|
MOZ_MUST_USE bool init();
|
||||||
|
|
||||||
template <typename Predicate /* (NestableControl*) -> bool */>
|
|
||||||
NestableControl* findInnermostNestableControl(Predicate predicate) const;
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T* findInnermostNestableControl() const;
|
T* findInnermostNestableControl() const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,7 @@ UNIFIED_SOURCES += [
|
||||||
'ds/LifoAlloc.cpp',
|
'ds/LifoAlloc.cpp',
|
||||||
'ds/MemoryProtectionExceptionHandler.cpp',
|
'ds/MemoryProtectionExceptionHandler.cpp',
|
||||||
'frontend/BytecodeCompiler.cpp',
|
'frontend/BytecodeCompiler.cpp',
|
||||||
|
'frontend/BytecodeControlStructures.cpp',
|
||||||
'frontend/BytecodeEmitter.cpp',
|
'frontend/BytecodeEmitter.cpp',
|
||||||
'frontend/CallOrNewEmitter.cpp',
|
'frontend/CallOrNewEmitter.cpp',
|
||||||
'frontend/ElemOpEmitter.cpp',
|
'frontend/ElemOpEmitter.cpp',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue