зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1662559 - Part 18: Remove all support for private members from ElemOpEmitter. r=arai
Depends on D108299 Differential Revision: https://phabricator.services.mozilla.com/D108300
This commit is contained in:
Родитель
13e102bcd2
Коммит
37b6d0f84c
|
@ -2049,8 +2049,7 @@ bool BytecodeEmitter::emitElemIncDec(UnaryNode* incDec) {
|
|||
ParseNodeKind kind = incDec->getKind();
|
||||
ElemOpEmitter eoe(
|
||||
this, ConvertIncDecKind(kind),
|
||||
isSuper ? ElemOpEmitter::ObjKind::Super : ElemOpEmitter::ObjKind::Other,
|
||||
NameVisibility::Public);
|
||||
isSuper ? ElemOpEmitter::ObjKind::Super : ElemOpEmitter::ObjKind::Other);
|
||||
if (!emitElemObjAndKey(elemExpr, isSuper, eoe)) {
|
||||
// [stack] # if Super
|
||||
// [stack] THIS KEY
|
||||
|
@ -2824,8 +2823,7 @@ bool BytecodeEmitter::emitDestructuringLHSRef(ParseNode* target,
|
|||
MOZ_ASSERT(!elem->key().isKind(ParseNodeKind::PrivateName));
|
||||
ElemOpEmitter eoe(this, ElemOpEmitter::Kind::SimpleAssignment,
|
||||
isSuper ? ElemOpEmitter::ObjKind::Super
|
||||
: ElemOpEmitter::ObjKind::Other,
|
||||
NameVisibility::Public);
|
||||
: ElemOpEmitter::ObjKind::Other);
|
||||
if (!emitElemObjAndKey(elem, isSuper, eoe)) {
|
||||
// [stack] # if Super
|
||||
// [stack] THIS KEY
|
||||
|
@ -2984,8 +2982,7 @@ bool BytecodeEmitter::emitSetOrInitializeDestructuring(
|
|||
MOZ_ASSERT(!elem->key().isKind(ParseNodeKind::PrivateName));
|
||||
ElemOpEmitter eoe(this, ElemOpEmitter::Kind::SimpleAssignment,
|
||||
isSuper ? ElemOpEmitter::ObjKind::Super
|
||||
: ElemOpEmitter::ObjKind::Other,
|
||||
NameVisibility::Public);
|
||||
: ElemOpEmitter::ObjKind::Other);
|
||||
if (!eoe.skipObjAndKeyAndRhs()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -4427,8 +4424,7 @@ bool BytecodeEmitter::emitAssignmentOrInit(ParseNodeKind kind, ParseNode* lhs,
|
|||
: isInit ? ElemOpEmitter::Kind::PropInit
|
||||
: ElemOpEmitter::Kind::SimpleAssignment,
|
||||
isSuper ? ElemOpEmitter::ObjKind::Super
|
||||
: ElemOpEmitter::ObjKind::Other,
|
||||
NameVisibility::Public);
|
||||
: ElemOpEmitter::ObjKind::Other);
|
||||
if (!emitElemObjAndKey(elem, isSuper, *eoe)) {
|
||||
// [stack] # if Super
|
||||
// [stack] THIS KEY
|
||||
|
@ -4739,8 +4735,7 @@ bool BytecodeEmitter::emitShortCircuitAssignment(AssignmentNode* node) {
|
|||
MOZ_ASSERT(!elem->key().isKind(ParseNodeKind::PrivateName));
|
||||
eoe.emplace(this, ElemOpEmitter::Kind::CompoundAssignment,
|
||||
isSuper ? ElemOpEmitter::ObjKind::Super
|
||||
: ElemOpEmitter::ObjKind::Other,
|
||||
NameVisibility::Public);
|
||||
: ElemOpEmitter::ObjKind::Other);
|
||||
|
||||
if (!emitElemObjAndKey(elem, isSuper, *eoe)) {
|
||||
// [stack] # if Super
|
||||
|
@ -7136,8 +7131,7 @@ bool BytecodeEmitter::emitDeleteElement(UnaryNode* deleteNode) {
|
|||
MOZ_ASSERT(!isPrivate);
|
||||
ElemOpEmitter eoe(
|
||||
this, ElemOpEmitter::Kind::Delete,
|
||||
isSuper ? ElemOpEmitter::ObjKind::Super : ElemOpEmitter::ObjKind::Other,
|
||||
NameVisibility::Public); // Can't delete a private name.
|
||||
isSuper ? ElemOpEmitter::ObjKind::Super : ElemOpEmitter::ObjKind::Other);
|
||||
if (isSuper) {
|
||||
// The expression |delete super[foo];| has to evaluate |super[foo]|,
|
||||
// which could throw if |this| hasn't yet been set by a |super(...)|
|
||||
|
@ -7288,7 +7282,7 @@ bool BytecodeEmitter::emitDeleteElementInOptChain(PropertyByValueBase* elemExpr,
|
|||
MOZ_ASSERT_IF(elemExpr->is<PropertyByValue>(),
|
||||
!elemExpr->as<PropertyByValue>().isSuper());
|
||||
ElemOpEmitter eoe(this, ElemOpEmitter::Kind::Delete,
|
||||
ElemOpEmitter::ObjKind::Other, NameVisibility::Public);
|
||||
ElemOpEmitter::ObjKind::Other);
|
||||
|
||||
if (!eoe.prepareForObj()) {
|
||||
// [stack]
|
||||
|
@ -8359,7 +8353,7 @@ bool BytecodeEmitter::emitOptionalTree(
|
|||
bool isSuper = false;
|
||||
MOZ_ASSERT(!elem->key().isKind(ParseNodeKind::PrivateName));
|
||||
ElemOpEmitter eoe(this, ElemOpEmitter::Kind::Get,
|
||||
ElemOpEmitter::ObjKind::Other, NameVisibility::Public);
|
||||
ElemOpEmitter::ObjKind::Other);
|
||||
|
||||
if (!emitOptionalElemExpression(elem, eoe, isSuper, oe)) {
|
||||
return false;
|
||||
|
@ -8372,8 +8366,7 @@ bool BytecodeEmitter::emitOptionalTree(
|
|||
MOZ_ASSERT(!elem->key().isKind(ParseNodeKind::PrivateName));
|
||||
ElemOpEmitter eoe(this, ElemOpEmitter::Kind::Get,
|
||||
isSuper ? ElemOpEmitter::ObjKind::Super
|
||||
: ElemOpEmitter::ObjKind::Other,
|
||||
NameVisibility::Public);
|
||||
: ElemOpEmitter::ObjKind::Other);
|
||||
|
||||
if (!emitOptionalElemExpression(elem, eoe, isSuper, oe)) {
|
||||
return false;
|
||||
|
@ -11297,8 +11290,7 @@ bool BytecodeEmitter::emitTree(
|
|||
MOZ_ASSERT(!elem->key().isKind(ParseNodeKind::PrivateName));
|
||||
ElemOpEmitter eoe(this, ElemOpEmitter::Kind::Get,
|
||||
isSuper ? ElemOpEmitter::ObjKind::Super
|
||||
: ElemOpEmitter::ObjKind::Other,
|
||||
NameVisibility::Public);
|
||||
: ElemOpEmitter::ObjKind::Other);
|
||||
if (!emitElemObjAndKey(elem, isSuper, eoe)) {
|
||||
// [stack] # if Super
|
||||
// [stack] THIS KEY
|
||||
|
|
|
@ -754,7 +754,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
|
|||
PropOpEmitter& poe, bool isSuper,
|
||||
OptionalEmitter& oe);
|
||||
[[nodiscard]] bool emitOptionalElemExpression(PropertyByValueBase* elem,
|
||||
ElemOpEmitter& poe,
|
||||
ElemOpEmitter& eoe,
|
||||
bool isSuper,
|
||||
OptionalEmitter& oe);
|
||||
[[nodiscard]] bool emitOptionalPrivateExpression(
|
||||
|
|
|
@ -63,8 +63,7 @@ bool CallOrNewEmitter::emitNameCallee(TaggedParserAtomIndex name) {
|
|||
eoe_.emplace(bce_,
|
||||
isCall() ? ElemOpEmitter::Kind::Call : ElemOpEmitter::Kind::Get,
|
||||
isSuperElem ? ElemOpEmitter::ObjKind::Super
|
||||
: ElemOpEmitter::ObjKind::Other,
|
||||
NameVisibility::Public);
|
||||
: ElemOpEmitter::ObjKind::Other);
|
||||
|
||||
state_ = State::ElemCallee;
|
||||
return *eoe_;
|
||||
|
|
|
@ -14,13 +14,8 @@
|
|||
using namespace js;
|
||||
using namespace js::frontend;
|
||||
|
||||
ElemOpEmitter::ElemOpEmitter(BytecodeEmitter* bce, Kind kind, ObjKind objKind,
|
||||
NameVisibility visibility)
|
||||
: bce_(bce), kind_(kind), objKind_(objKind), visibility_(visibility) {
|
||||
// Can't access private names of super!
|
||||
MOZ_ASSERT_IF(visibility == NameVisibility::Private,
|
||||
objKind != ObjKind::Super);
|
||||
}
|
||||
ElemOpEmitter::ElemOpEmitter(BytecodeEmitter* bce, Kind kind, ObjKind objKind)
|
||||
: bce_(bce), kind_(kind), objKind_(objKind) {}
|
||||
|
||||
bool ElemOpEmitter::prepareForObj() {
|
||||
MOZ_ASSERT(state_ == State::Start);
|
||||
|
@ -56,66 +51,12 @@ bool ElemOpEmitter::prepareForKey() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ElemOpEmitter::emitPrivateGuard() {
|
||||
MOZ_ASSERT(state_ == State::Key || state_ == State::Rhs);
|
||||
|
||||
if (!isPrivate()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isPropInit()) {
|
||||
// [stack] OBJ KEY
|
||||
if (!bce_->emitCheckPrivateField(ThrowCondition::ThrowHas,
|
||||
ThrowMsgKind::PrivateDoubleInit)) {
|
||||
// [stack] OBJ KEY BOOL
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!bce_->emitCheckPrivateField(ThrowCondition::ThrowHasNot,
|
||||
isPrivateGet()
|
||||
? ThrowMsgKind::MissingPrivateOnGet
|
||||
: ThrowMsgKind::MissingPrivateOnSet)) {
|
||||
// [stack] OBJ KEY BOOL
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// CheckPrivate leaves the result of the HasOwnCheck on the stack. Pop it off.
|
||||
return bce_->emit1(JSOp::Pop);
|
||||
// [stack] OBJ KEY
|
||||
}
|
||||
|
||||
bool ElemOpEmitter::emitPrivateGuardForAssignment() {
|
||||
if (!isPrivate()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// [stack] OBJ KEY RHS
|
||||
if (!bce_->emitUnpickN(2)) {
|
||||
// [stack] RHS OBJ KEY
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!emitPrivateGuard()) {
|
||||
// [stack] RHS OBJ KEY
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!bce_->emitPickN(2)) {
|
||||
// [stack] OBJ KEY RHS
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ElemOpEmitter::emitGet() {
|
||||
MOZ_ASSERT(state_ == State::Key);
|
||||
|
||||
// Inc/dec and compound assignment use the KEY twice, but if it's an object,
|
||||
// it must be converted ToPropertyKey only once, per spec. But for a private
|
||||
// field, KEY is always a symbol and ToPropertyKey would be a no-op.
|
||||
if ((isIncDec() || isCompoundAssignment()) && !isPrivate()) {
|
||||
// it must be converted ToPropertyKey only once, per spec.
|
||||
if (isIncDec() || isCompoundAssignment()) {
|
||||
if (!bce_->emit1(JSOp::ToPropertyKey)) {
|
||||
// [stack] # if Super
|
||||
// [stack] THIS KEY
|
||||
|
@ -125,10 +66,6 @@ bool ElemOpEmitter::emitGet() {
|
|||
}
|
||||
}
|
||||
|
||||
if (!emitPrivateGuard()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isSuper()) {
|
||||
if (!bce_->emitSuperBase()) {
|
||||
// [stack] THIS? THIS KEY SUPERBASE
|
||||
|
@ -213,7 +150,6 @@ bool ElemOpEmitter::skipObjAndKeyAndRhs() {
|
|||
bool ElemOpEmitter::emitDelete() {
|
||||
MOZ_ASSERT(state_ == State::Key);
|
||||
MOZ_ASSERT(isDelete());
|
||||
MOZ_ASSERT(!isPrivate());
|
||||
|
||||
if (isSuper()) {
|
||||
if (!bce_->emit1(JSOp::ToPropertyKey)) {
|
||||
|
@ -238,7 +174,6 @@ bool ElemOpEmitter::emitDelete() {
|
|||
return false;
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(!isPrivate());
|
||||
JSOp op = bce_->sc->strict() ? JSOp::StrictDelElem : JSOp::DelElem;
|
||||
if (!bce_->emitElemOpBase(op)) {
|
||||
// SUCCEEDED
|
||||
|
@ -258,16 +193,6 @@ bool ElemOpEmitter::emitAssignment() {
|
|||
|
||||
MOZ_ASSERT_IF(isPropInit(), !isSuper());
|
||||
|
||||
if (!isCompoundAssignment()) {
|
||||
// For compound assignment, we call emitGet(), then emitAssignment(). So
|
||||
// we already went through emitGet() and emitted a guard for this object
|
||||
// and key. There's no point checking again--a private field can't be
|
||||
// removed from an object.
|
||||
if (!emitPrivateGuardForAssignment()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
JSOp setOp = isPropInit() ? JSOp::InitElem
|
||||
: isSuper() ? bce_->sc->strict() ? JSOp::StrictSetElemSuper
|
||||
: JSOp::SetElemSuper
|
||||
|
|
|
@ -139,7 +139,6 @@ class MOZ_STACK_CLASS ElemOpEmitter {
|
|||
|
||||
Kind kind_;
|
||||
ObjKind objKind_;
|
||||
NameVisibility visibility_ = NameVisibility::Public;
|
||||
|
||||
#ifdef DEBUG
|
||||
// The state of this emitter.
|
||||
|
@ -212,8 +211,7 @@ class MOZ_STACK_CLASS ElemOpEmitter {
|
|||
#endif
|
||||
|
||||
public:
|
||||
ElemOpEmitter(BytecodeEmitter* bce, Kind kind, ObjKind objKind,
|
||||
NameVisibility visibility);
|
||||
ElemOpEmitter(BytecodeEmitter* bce, Kind kind, ObjKind objKind);
|
||||
|
||||
private:
|
||||
[[nodiscard]] bool isCall() const { return kind_ == Kind::Call; }
|
||||
|
@ -222,14 +220,8 @@ class MOZ_STACK_CLASS ElemOpEmitter {
|
|||
return kind_ == Kind::SimpleAssignment;
|
||||
}
|
||||
|
||||
bool isPrivate() { return visibility_ == NameVisibility::Private; }
|
||||
|
||||
[[nodiscard]] bool isPropInit() const { return kind_ == Kind::PropInit; }
|
||||
|
||||
[[nodiscard]] bool isPrivateGet() const {
|
||||
return visibility_ == NameVisibility::Private && kind_ == Kind::Get;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isDelete() const { return kind_ == Kind::Delete; }
|
||||
|
||||
[[nodiscard]] bool isCompoundAssignment() const {
|
||||
|
@ -268,12 +260,6 @@ class MOZ_STACK_CLASS ElemOpEmitter {
|
|||
[[nodiscard]] bool emitAssignment();
|
||||
|
||||
[[nodiscard]] bool emitIncDec();
|
||||
|
||||
private:
|
||||
// When we have private names, we may need to emit a CheckPrivateField
|
||||
// op to potentially throw errors where required.
|
||||
[[nodiscard]] bool emitPrivateGuard();
|
||||
[[nodiscard]] bool emitPrivateGuardForAssignment();
|
||||
};
|
||||
|
||||
} /* namespace frontend */
|
||||
|
|
Загрузка…
Ссылка в новой задаче