зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1511385 - Re-format the stack comment in BytecodeEmitter and helper classes. r=jorendorff
This commit is contained in:
Родитель
69f9d5002c
Коммит
17371adba7
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -71,7 +71,7 @@ bool CForEmitter::emitBody(Cond cond, const Maybe<uint32_t>& bodyPos) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(JSOP_NOP)) {
|
if (!bce_->emit1(JSOP_NOP)) {
|
||||||
// [stack]
|
// [stack]
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,13 +85,13 @@ bool CForEmitter::emitBody(Cond cond, const Maybe<uint32_t>& bodyPos) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!loopInfo_->emitLoopHead(bce_, bodyPos)) {
|
if (!loopInfo_->emitLoopHead(bce_, bodyPos)) {
|
||||||
// [stack]
|
// [stack]
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond_ == Cond::Missing) {
|
if (cond_ == Cond::Missing) {
|
||||||
if (!loopInfo_->emitLoopEntry(bce_, bodyPos)) {
|
if (!loopInfo_->emitLoopEntry(bce_, bodyPos)) {
|
||||||
// [stack]
|
// [stack]
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,10 +153,10 @@ bool CForEmitter::emitCond(const Maybe<uint32_t>& forPos,
|
||||||
MOZ_ASSERT(state_ == State::Update);
|
MOZ_ASSERT(state_ == State::Update);
|
||||||
|
|
||||||
if (update_ == Update::Present) {
|
if (update_ == Update::Present) {
|
||||||
// [stack] UPDATE
|
// [stack] UPDATE
|
||||||
|
|
||||||
if (!bce_->emit1(JSOP_POP)) {
|
if (!bce_->emit1(JSOP_POP)) {
|
||||||
// [stack]
|
// [stack]
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ bool CForEmitter::emitCond(const Maybe<uint32_t>& forPos,
|
||||||
|
|
||||||
if (cond_ == Cond::Present) {
|
if (cond_ == Cond::Present) {
|
||||||
if (!loopInfo_->emitLoopEntry(bce_, condPos)) {
|
if (!loopInfo_->emitLoopEntry(bce_, condPos)) {
|
||||||
// [stack]
|
// [stack]
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (update_ == Update::Missing) {
|
} else if (update_ == Update::Missing) {
|
||||||
|
@ -217,7 +217,7 @@ bool CForEmitter::emitEnd() {
|
||||||
// If no loop condition, just emit a loop-closing jump.
|
// If no loop condition, just emit a loop-closing jump.
|
||||||
if (!loopInfo_->emitLoopEnd(bce_,
|
if (!loopInfo_->emitLoopEnd(bce_,
|
||||||
cond_ == Cond::Present ? JSOP_IFNE : JSOP_GOTO)) {
|
cond_ == Cond::Present ? JSOP_IFNE : JSOP_GOTO)) {
|
||||||
// [stack]
|
// [stack]
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ bool CForEmitter::emitEnd() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!loopInfo_->patchBreaksAndContinues(bce_)) {
|
if (!loopInfo_->patchBreaksAndContinues(bce_)) {
|
||||||
// [stack]
|
// [stack]
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ bool CallOrNewEmitter::emitNameCallee(JSAtom* name) {
|
||||||
bce_, name,
|
bce_, name,
|
||||||
isCall() ? NameOpEmitter::Kind::Call : NameOpEmitter::Kind::Get);
|
isCall() ? NameOpEmitter::Kind::Call : NameOpEmitter::Kind::Get);
|
||||||
if (!noe.emitGet()) {
|
if (!noe.emitGet()) {
|
||||||
// [stack] CALLEE THIS
|
// [stack] CALLEE THIS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,15 +102,15 @@ bool CallOrNewEmitter::emitSuperCallee() {
|
||||||
MOZ_ASSERT(state_ == State::Start);
|
MOZ_ASSERT(state_ == State::Start);
|
||||||
|
|
||||||
if (!bce_->emitThisEnvironmentCallee()) {
|
if (!bce_->emitThisEnvironmentCallee()) {
|
||||||
// [stack] CALLEE
|
// [stack] CALLEE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(JSOP_SUPERFUN)) {
|
if (!bce_->emit1(JSOP_SUPERFUN)) {
|
||||||
// [stack] CALLEE
|
// [stack] CALLEE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(JSOP_IS_CONSTRUCTING)) {
|
if (!bce_->emit1(JSOP_IS_CONSTRUCTING)) {
|
||||||
// [stack] CALLEE THIS
|
// [stack] CALLEE THIS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,12 +163,12 @@ bool CallOrNewEmitter::emitThis() {
|
||||||
if (needsThis) {
|
if (needsThis) {
|
||||||
if (isNew() || isSuperCall()) {
|
if (isNew() || isSuperCall()) {
|
||||||
if (!bce_->emit1(JSOP_IS_CONSTRUCTING)) {
|
if (!bce_->emit1(JSOP_IS_CONSTRUCTING)) {
|
||||||
// [stack] CALLEE THIS
|
// [stack] CALLEE THIS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!bce_->emit1(JSOP_UNDEFINED)) {
|
if (!bce_->emit1(JSOP_UNDEFINED)) {
|
||||||
// [stack] CALLEE THIS
|
// [stack] CALLEE THIS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,23 +220,23 @@ bool CallOrNewEmitter::emitSpreadArgumentsTest() {
|
||||||
// operation. See the comment in OptimizeSpreadCall in
|
// operation. See the comment in OptimizeSpreadCall in
|
||||||
// Interpreter.cpp for the optimizable conditons.
|
// Interpreter.cpp for the optimizable conditons.
|
||||||
|
|
||||||
// [stack] CALLEE THIS ARG0
|
// [stack] CALLEE THIS ARG0
|
||||||
|
|
||||||
ifNotOptimizable_.emplace(bce_);
|
ifNotOptimizable_.emplace(bce_);
|
||||||
if (!bce_->emit1(JSOP_OPTIMIZE_SPREADCALL)) {
|
if (!bce_->emit1(JSOP_OPTIMIZE_SPREADCALL)) {
|
||||||
// [stack] CALLEE THIS ARG0 OPTIMIZED
|
// [stack] CALLEE THIS ARG0 OPTIMIZED
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(JSOP_NOT)) {
|
if (!bce_->emit1(JSOP_NOT)) {
|
||||||
// [stack] CALLEE THIS ARG0 !OPTIMIZED
|
// [stack] CALLEE THIS ARG0 !OPTIMIZED
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!ifNotOptimizable_->emitThen()) {
|
if (!ifNotOptimizable_->emitThen()) {
|
||||||
// [stack] CALLEE THIS ARG0
|
// [stack] CALLEE THIS ARG0
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(JSOP_POP)) {
|
if (!bce_->emit1(JSOP_POP)) {
|
||||||
// [stack] CALLEE THIS
|
// [stack] CALLEE THIS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,7 @@ bool CallOrNewEmitter::emitEnd(uint32_t argc, const Maybe<uint32_t>& beginPos) {
|
||||||
|
|
||||||
if (isSingleSpreadRest()) {
|
if (isSingleSpreadRest()) {
|
||||||
if (!ifNotOptimizable_->emitEnd()) {
|
if (!ifNotOptimizable_->emitEnd()) {
|
||||||
// [stack] CALLEE THIS ARR
|
// [stack] CALLEE THIS ARR
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,21 +259,21 @@ bool CallOrNewEmitter::emitEnd(uint32_t argc, const Maybe<uint32_t>& beginPos) {
|
||||||
if (isNew() || isSuperCall()) {
|
if (isNew() || isSuperCall()) {
|
||||||
if (isSuperCall()) {
|
if (isSuperCall()) {
|
||||||
if (!bce_->emit1(JSOP_NEWTARGET)) {
|
if (!bce_->emit1(JSOP_NEWTARGET)) {
|
||||||
// [stack] CALLEE THIS ARG.. NEW.TARGET
|
// [stack] CALLEE THIS ARG.. NEW.TARGET
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Repush the callee as new.target
|
// Repush the callee as new.target
|
||||||
uint32_t effectiveArgc = isSpread() ? 1 : argc;
|
uint32_t effectiveArgc = isSpread() ? 1 : argc;
|
||||||
if (!bce_->emitDupAt(effectiveArgc + 1)) {
|
if (!bce_->emitDupAt(effectiveArgc + 1)) {
|
||||||
// [stack] CALLEE THIS ARR CALLEE
|
// [stack] CALLEE THIS ARR CALLEE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!isSpread()) {
|
if (!isSpread()) {
|
||||||
if (!bce_->emitCall(op_, argc, beginPos)) {
|
if (!bce_->emitCall(op_, argc, beginPos)) {
|
||||||
// [stack] RVAL
|
// [stack] RVAL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -283,7 +283,7 @@ bool CallOrNewEmitter::emitEnd(uint32_t argc, const Maybe<uint32_t>& beginPos) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(op_)) {
|
if (!bce_->emit1(op_)) {
|
||||||
// [stack] RVAL
|
// [stack] RVAL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,16 +30,16 @@ bool ElemOpEmitter::prepareForKey() {
|
||||||
|
|
||||||
if (!isSuper() && isIncDec()) {
|
if (!isSuper() && isIncDec()) {
|
||||||
if (!bce_->emit1(JSOP_CHECKOBJCOERCIBLE)) {
|
if (!bce_->emit1(JSOP_CHECKOBJCOERCIBLE)) {
|
||||||
// [stack] OBJ
|
// [stack] OBJ
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isCall()) {
|
if (isCall()) {
|
||||||
if (!bce_->emit1(JSOP_DUP)) {
|
if (!bce_->emit1(JSOP_DUP)) {
|
||||||
// [stack] # if Super
|
// [stack] # if Super
|
||||||
// [stack] THIS THIS
|
// [stack] THIS THIS
|
||||||
// [stack] # otherwise
|
// [stack] # otherwise
|
||||||
// [stack] OBJ OBJ
|
// [stack] OBJ OBJ
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,16 +55,16 @@ bool ElemOpEmitter::emitGet() {
|
||||||
|
|
||||||
if (isIncDec() || isCompoundAssignment()) {
|
if (isIncDec() || isCompoundAssignment()) {
|
||||||
if (!bce_->emit1(JSOP_TOID)) {
|
if (!bce_->emit1(JSOP_TOID)) {
|
||||||
// [stack] # if Super
|
// [stack] # if Super
|
||||||
// [stack] THIS KEY
|
// [stack] THIS KEY
|
||||||
// [stack] # otherwise
|
// [stack] # otherwise
|
||||||
// [stack] OBJ KEY
|
// [stack] OBJ KEY
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isSuper()) {
|
if (isSuper()) {
|
||||||
if (!bce_->emitSuperBase()) {
|
if (!bce_->emitSuperBase()) {
|
||||||
// [stack] THIS? THIS KEY SUPERBASE
|
// [stack] THIS? THIS KEY SUPERBASE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,20 +73,20 @@ bool ElemOpEmitter::emitGet() {
|
||||||
// There's no such thing as JSOP_DUP3, so we have to be creative.
|
// There's no such thing as JSOP_DUP3, so we have to be creative.
|
||||||
// Note that pushing things again is no fewer JSOps.
|
// Note that pushing things again is no fewer JSOps.
|
||||||
if (!bce_->emitDupAt(2)) {
|
if (!bce_->emitDupAt(2)) {
|
||||||
// [stack] THIS KEY SUPERBASE THIS
|
// [stack] THIS KEY SUPERBASE THIS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emitDupAt(2)) {
|
if (!bce_->emitDupAt(2)) {
|
||||||
// [stack] THIS KEY SUPERBASE THIS KEY
|
// [stack] THIS KEY SUPERBASE THIS KEY
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emitDupAt(2)) {
|
if (!bce_->emitDupAt(2)) {
|
||||||
// [stack] THIS KEY SUPERBASE THIS KEY SUPERBASE
|
// [stack] THIS KEY SUPERBASE THIS KEY SUPERBASE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!bce_->emit1(JSOP_DUP2)) {
|
if (!bce_->emit1(JSOP_DUP2)) {
|
||||||
// [stack] OBJ KEY OBJ KEY
|
// [stack] OBJ KEY OBJ KEY
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,19 +101,19 @@ bool ElemOpEmitter::emitGet() {
|
||||||
op = JSOP_GETELEM;
|
op = JSOP_GETELEM;
|
||||||
}
|
}
|
||||||
if (!bce_->emitElemOpBase(op)) {
|
if (!bce_->emitElemOpBase(op)) {
|
||||||
// [stack] # if Get
|
// [stack] # if Get
|
||||||
// [stack] ELEM
|
// [stack] ELEM
|
||||||
// [stack] # if Call
|
// [stack] # if Call
|
||||||
// [stack] THIS ELEM
|
// [stack] THIS ELEM
|
||||||
// [stack] # if Inc/Dec/Assignment, with Super
|
// [stack] # if Inc/Dec/Assignment, with Super
|
||||||
// [stack] THIS KEY SUPERBASE ELEM
|
// [stack] THIS KEY SUPERBASE ELEM
|
||||||
// [stack] # if Inc/Dec/Assignment, other
|
// [stack] # if Inc/Dec/Assignment, other
|
||||||
// [stack] OBJ KEY ELEM
|
// [stack] OBJ KEY ELEM
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (isCall()) {
|
if (isCall()) {
|
||||||
if (!bce_->emit1(JSOP_SWAP)) {
|
if (!bce_->emit1(JSOP_SWAP)) {
|
||||||
// [stack] ELEM THIS
|
// [stack] ELEM THIS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ bool ElemOpEmitter::prepareForRhs() {
|
||||||
// For CompoundAssignment, SUPERBASE is already emitted by emitGet.
|
// For CompoundAssignment, SUPERBASE is already emitted by emitGet.
|
||||||
if (isSuper()) {
|
if (isSuper()) {
|
||||||
if (!bce_->emitSuperBase()) {
|
if (!bce_->emitSuperBase()) {
|
||||||
// [stack] THIS KEY SUPERBASE
|
// [stack] THIS KEY SUPERBASE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,24 +161,24 @@ bool ElemOpEmitter::emitDelete() {
|
||||||
|
|
||||||
if (isSuper()) {
|
if (isSuper()) {
|
||||||
if (!bce_->emit1(JSOP_TOID)) {
|
if (!bce_->emit1(JSOP_TOID)) {
|
||||||
// [stack] THIS KEY
|
// [stack] THIS KEY
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emitSuperBase()) {
|
if (!bce_->emitSuperBase()) {
|
||||||
// [stack] THIS KEY SUPERBASE
|
// [stack] THIS KEY SUPERBASE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unconditionally throw when attempting to delete a super-reference.
|
// Unconditionally throw when attempting to delete a super-reference.
|
||||||
if (!bce_->emitUint16Operand(JSOP_THROWMSG, JSMSG_CANT_DELETE_SUPER)) {
|
if (!bce_->emitUint16Operand(JSOP_THROWMSG, JSMSG_CANT_DELETE_SUPER)) {
|
||||||
// [stack] THIS KEY SUPERBASE
|
// [stack] THIS KEY SUPERBASE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Another wrinkle: Balance the stack from the emitter's point of view.
|
// Another wrinkle: Balance the stack from the emitter's point of view.
|
||||||
// Execution will not reach here, as the last bytecode threw.
|
// Execution will not reach here, as the last bytecode threw.
|
||||||
if (!bce_->emitPopN(2)) {
|
if (!bce_->emitPopN(2)) {
|
||||||
// [stack] THIS
|
// [stack] THIS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -204,7 +204,7 @@ bool ElemOpEmitter::emitAssignment() {
|
||||||
? bce_->sc->strict() ? JSOP_STRICTSETELEM_SUPER : JSOP_SETELEM_SUPER
|
? bce_->sc->strict() ? JSOP_STRICTSETELEM_SUPER : JSOP_SETELEM_SUPER
|
||||||
: bce_->sc->strict() ? JSOP_STRICTSETELEM : JSOP_SETELEM;
|
: bce_->sc->strict() ? JSOP_STRICTSETELEM : JSOP_SETELEM;
|
||||||
if (!bce_->emitElemOpBase(setOp)) {
|
if (!bce_->emitElemOpBase(setOp)) {
|
||||||
// [stack] ELEM
|
// [stack] ELEM
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,7 +219,7 @@ bool ElemOpEmitter::emitIncDec() {
|
||||||
MOZ_ASSERT(isIncDec());
|
MOZ_ASSERT(isIncDec());
|
||||||
|
|
||||||
if (!emitGet()) {
|
if (!emitGet()) {
|
||||||
// [stack] ... ELEM
|
// [stack] ... ELEM
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,56 +227,56 @@ bool ElemOpEmitter::emitIncDec() {
|
||||||
|
|
||||||
JSOp binOp = isInc() ? JSOP_ADD : JSOP_SUB;
|
JSOp binOp = isInc() ? JSOP_ADD : JSOP_SUB;
|
||||||
if (!bce_->emit1(JSOP_POS)) {
|
if (!bce_->emit1(JSOP_POS)) {
|
||||||
// [stack] ... N
|
// [stack] ... N
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (isPostIncDec()) {
|
if (isPostIncDec()) {
|
||||||
if (!bce_->emit1(JSOP_DUP)) {
|
if (!bce_->emit1(JSOP_DUP)) {
|
||||||
// [stack] ... N? N
|
// [stack] ... N? N
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(JSOP_ONE)) {
|
if (!bce_->emit1(JSOP_ONE)) {
|
||||||
// [stack] ... N? N 1
|
// [stack] ... N? N 1
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(binOp)) {
|
if (!bce_->emit1(binOp)) {
|
||||||
// [stack] ... N? N+1
|
// [stack] ... N? N+1
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (isPostIncDec()) {
|
if (isPostIncDec()) {
|
||||||
if (isSuper()) {
|
if (isSuper()) {
|
||||||
// [stack] THIS KEY OBJ N N+1
|
// [stack] THIS KEY OBJ N N+1
|
||||||
|
|
||||||
if (!bce_->emit2(JSOP_PICK, 4)) {
|
if (!bce_->emit2(JSOP_PICK, 4)) {
|
||||||
// [stack] KEY SUPERBASE N N+1 THIS
|
// [stack] KEY SUPERBASE N N+1 THIS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit2(JSOP_PICK, 4)) {
|
if (!bce_->emit2(JSOP_PICK, 4)) {
|
||||||
// [stack] SUPERBASE N N+1 THIS KEY
|
// [stack] SUPERBASE N N+1 THIS KEY
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit2(JSOP_PICK, 4)) {
|
if (!bce_->emit2(JSOP_PICK, 4)) {
|
||||||
// [stack] N N+1 THIS KEY SUPERBASE
|
// [stack] N N+1 THIS KEY SUPERBASE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit2(JSOP_PICK, 3)) {
|
if (!bce_->emit2(JSOP_PICK, 3)) {
|
||||||
// [stack] N THIS KEY SUPERBASE N+1
|
// [stack] N THIS KEY SUPERBASE N+1
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// [stack] OBJ KEY N N+1
|
// [stack] OBJ KEY N N+1
|
||||||
|
|
||||||
if (!bce_->emit2(JSOP_PICK, 3)) {
|
if (!bce_->emit2(JSOP_PICK, 3)) {
|
||||||
// [stack] KEY N N+1 OBJ
|
// [stack] KEY N N+1 OBJ
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit2(JSOP_PICK, 3)) {
|
if (!bce_->emit2(JSOP_PICK, 3)) {
|
||||||
// [stack] N N+1 OBJ KEY
|
// [stack] N N+1 OBJ KEY
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit2(JSOP_PICK, 2)) {
|
if (!bce_->emit2(JSOP_PICK, 2)) {
|
||||||
// [stack] N OBJ KEY N+1
|
// [stack] N OBJ KEY N+1
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -287,12 +287,12 @@ bool ElemOpEmitter::emitIncDec() {
|
||||||
? (bce_->sc->strict() ? JSOP_STRICTSETELEM_SUPER : JSOP_SETELEM_SUPER)
|
? (bce_->sc->strict() ? JSOP_STRICTSETELEM_SUPER : JSOP_SETELEM_SUPER)
|
||||||
: (bce_->sc->strict() ? JSOP_STRICTSETELEM : JSOP_SETELEM);
|
: (bce_->sc->strict() ? JSOP_STRICTSETELEM : JSOP_SETELEM);
|
||||||
if (!bce_->emitElemOpBase(setOp)) {
|
if (!bce_->emitElemOpBase(setOp)) {
|
||||||
// [stack] N? N+1
|
// [stack] N? N+1
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (isPostIncDec()) {
|
if (isPostIncDec()) {
|
||||||
if (!bce_->emit1(JSOP_POP)) {
|
if (!bce_->emit1(JSOP_POP)) {
|
||||||
// [stack] N
|
// [stack] N
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,14 +39,14 @@ bool ExpressionStatementEmitter::emitEnd() {
|
||||||
MOZ_ASSERT(state_ == State::Expr);
|
MOZ_ASSERT(state_ == State::Expr);
|
||||||
MOZ_ASSERT(bce_->stackDepth == depth_ + 1);
|
MOZ_ASSERT(bce_->stackDepth == depth_ + 1);
|
||||||
|
|
||||||
// [stack] VAL
|
// [stack] VAL
|
||||||
|
|
||||||
JSOp op = valueUsage_ == ValueUsage::WantValue ? JSOP_SETRVAL : JSOP_POP;
|
JSOp op = valueUsage_ == ValueUsage::WantValue ? JSOP_SETRVAL : JSOP_POP;
|
||||||
if (!bce_->emit1(op)) {
|
if (!bce_->emit1(op)) {
|
||||||
// [stack] # if WantValue
|
// [stack] # if WantValue
|
||||||
// [stack] VAL
|
// [stack] VAL
|
||||||
// [stack] # otherwise
|
// [stack] # otherwise
|
||||||
// [stack]
|
// [stack]
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,14 +37,14 @@ bool ForInEmitter::emitInitialize() {
|
||||||
tdzCacheForIteratedValue_.reset();
|
tdzCacheForIteratedValue_.reset();
|
||||||
|
|
||||||
if (!bce_->emit1(JSOP_ITER)) {
|
if (!bce_->emit1(JSOP_ITER)) {
|
||||||
// [stack] ITER
|
// [stack] ITER
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For-in loops have both the iterator and the value on the stack. Push
|
// For-in loops have both the iterator and the value on the stack. Push
|
||||||
// undefined to balance the stack.
|
// undefined to balance the stack.
|
||||||
if (!bce_->emit1(JSOP_UNDEFINED)) {
|
if (!bce_->emit1(JSOP_UNDEFINED)) {
|
||||||
// [stack] ITER ITERVAL
|
// [stack] ITER ITERVAL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,12 +58,12 @@ bool ForInEmitter::emitInitialize() {
|
||||||
// Jump down to the loop condition to minimize overhead (assuming at
|
// Jump down to the loop condition to minimize overhead (assuming at
|
||||||
// least one iteration, just like the other loop forms).
|
// least one iteration, just like the other loop forms).
|
||||||
if (!loopInfo_->emitEntryJump(bce_)) {
|
if (!loopInfo_->emitEntryJump(bce_)) {
|
||||||
// [stack] ITER ITERVAL
|
// [stack] ITER ITERVAL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!loopInfo_->emitLoopHead(bce_, Nothing())) {
|
if (!loopInfo_->emitLoopHead(bce_, Nothing())) {
|
||||||
// [stack] ITER ITERVAL
|
// [stack] ITER ITERVAL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ bool ForInEmitter::emitInitialize() {
|
||||||
|
|
||||||
if (headLexicalEmitterScope_->hasEnvironment()) {
|
if (headLexicalEmitterScope_->hasEnvironment()) {
|
||||||
if (!bce_->emit1(JSOP_RECREATELEXICALENV)) {
|
if (!bce_->emit1(JSOP_RECREATELEXICALENV)) {
|
||||||
// [stack] ITER ITERVAL
|
// [stack] ITER ITERVAL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ bool ForInEmitter::emitInitialize() {
|
||||||
MOZ_ASSERT(loopDepth_ >= 2);
|
MOZ_ASSERT(loopDepth_ >= 2);
|
||||||
|
|
||||||
if (!bce_->emit1(JSOP_ITERNEXT)) {
|
if (!bce_->emit1(JSOP_ITERNEXT)) {
|
||||||
// [stack] ITER ITERVAL
|
// [stack] ITER ITERVAL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,24 +134,24 @@ bool ForInEmitter::emitEnd(const Maybe<uint32_t>& forPos) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!loopInfo_->emitLoopEntry(bce_, Nothing())) {
|
if (!loopInfo_->emitLoopEntry(bce_, Nothing())) {
|
||||||
// [stack] ITER ITERVAL
|
// [stack] ITER ITERVAL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(JSOP_POP)) {
|
if (!bce_->emit1(JSOP_POP)) {
|
||||||
// [stack] ITER
|
// [stack] ITER
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(JSOP_MOREITER)) {
|
if (!bce_->emit1(JSOP_MOREITER)) {
|
||||||
// [stack] ITER NEXTITERVAL?
|
// [stack] ITER NEXTITERVAL?
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(JSOP_ISNOITER)) {
|
if (!bce_->emit1(JSOP_ISNOITER)) {
|
||||||
// [stack] ITER NEXTITERVAL? ISNOITER
|
// [stack] ITER NEXTITERVAL? ISNOITER
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!loopInfo_->emitLoopEnd(bce_, JSOP_IFEQ)) {
|
if (!loopInfo_->emitLoopEnd(bce_, JSOP_IFEQ)) {
|
||||||
// [stack] ITER NEXTITERVAL
|
// [stack] ITER NEXTITERVAL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ bool ForInEmitter::emitEnd(const Maybe<uint32_t>& forPos) {
|
||||||
|
|
||||||
// Pop the enumeration value.
|
// Pop the enumeration value.
|
||||||
if (!bce_->emit1(JSOP_POP)) {
|
if (!bce_->emit1(JSOP_POP)) {
|
||||||
// [stack] ITER
|
// [stack] ITER
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ bool ForInEmitter::emitEnd(const Maybe<uint32_t>& forPos) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bce_->emit1(JSOP_ENDITER)) {
|
if (!bce_->emit1(JSOP_ENDITER)) {
|
||||||
// [stack]
|
// [stack]
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,12 +48,12 @@ bool ForOfEmitter::emitInitialize(const Maybe<uint32_t>& forPos) {
|
||||||
|
|
||||||
if (iterKind_ == IteratorKind::Async) {
|
if (iterKind_ == IteratorKind::Async) {
|
||||||
if (!bce_->emitAsyncIterator()) {
|
if (!bce_->emitAsyncIterator()) {
|
||||||
// [stack] NEXT ITER
|
// [stack] NEXT ITER
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!bce_->emitIterator()) {
|
if (!bce_->emitIterator()) {
|
||||||
// [stack] NEXT ITER
|
// [stack] NEXT ITER
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ bool ForOfEmitter::emitInitialize(const Maybe<uint32_t>& forPos) {
|
||||||
// the result.value on the stack.
|
// the result.value on the stack.
|
||||||
// Push an undefined to balance the stack.
|
// Push an undefined to balance the stack.
|
||||||
if (!bce_->emit1(JSOP_UNDEFINED)) {
|
if (!bce_->emit1(JSOP_UNDEFINED)) {
|
||||||
// [stack] NEXT ITER UNDEF
|
// [stack] NEXT ITER UNDEF
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,12 +76,12 @@ bool ForOfEmitter::emitInitialize(const Maybe<uint32_t>& forPos) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!loopInfo_->emitEntryJump(bce_)) {
|
if (!loopInfo_->emitEntryJump(bce_)) {
|
||||||
// [stack] NEXT ITER UNDEF
|
// [stack] NEXT ITER UNDEF
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!loopInfo_->emitLoopHead(bce_, Nothing())) {
|
if (!loopInfo_->emitLoopHead(bce_, Nothing())) {
|
||||||
// [stack] NEXT ITER UNDEF
|
// [stack] NEXT ITER UNDEF
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ bool ForOfEmitter::emitInitialize(const Maybe<uint32_t>& forPos) {
|
||||||
|
|
||||||
if (headLexicalEmitterScope_->hasEnvironment()) {
|
if (headLexicalEmitterScope_->hasEnvironment()) {
|
||||||
if (!bce_->emit1(JSOP_RECREATELEXICALENV)) {
|
if (!bce_->emit1(JSOP_RECREATELEXICALENV)) {
|
||||||
// [stack] NEXT ITER UNDEF
|
// [stack] NEXT ITER UNDEF
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,54 +122,54 @@ bool ForOfEmitter::emitInitialize(const Maybe<uint32_t>& forPos) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bce_->emit1(JSOP_POP)) {
|
if (!bce_->emit1(JSOP_POP)) {
|
||||||
// [stack] NEXT ITER
|
// [stack] NEXT ITER
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(JSOP_DUP2)) {
|
if (!bce_->emit1(JSOP_DUP2)) {
|
||||||
// [stack] NEXT ITER NEXT ITER
|
// [stack] NEXT ITER NEXT ITER
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bce_->emitIteratorNext(forPos, iterKind_, allowSelfHostedIter_)) {
|
if (!bce_->emitIteratorNext(forPos, iterKind_, allowSelfHostedIter_)) {
|
||||||
// [stack] NEXT ITER RESULT
|
// [stack] NEXT ITER RESULT
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bce_->emit1(JSOP_DUP)) {
|
if (!bce_->emit1(JSOP_DUP)) {
|
||||||
// [stack] NEXT ITER RESULT RESULT
|
// [stack] NEXT ITER RESULT RESULT
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emitAtomOp(bce_->cx->names().done, JSOP_GETPROP)) {
|
if (!bce_->emitAtomOp(bce_->cx->names().done, JSOP_GETPROP)) {
|
||||||
// [stack] NEXT ITER RESULT DONE
|
// [stack] NEXT ITER RESULT DONE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
InternalIfEmitter ifDone(bce_);
|
InternalIfEmitter ifDone(bce_);
|
||||||
|
|
||||||
if (!ifDone.emitThen()) {
|
if (!ifDone.emitThen()) {
|
||||||
// [stack] NEXT ITER RESULT
|
// [stack] NEXT ITER RESULT
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove RESULT from the stack to release it.
|
// Remove RESULT from the stack to release it.
|
||||||
if (!bce_->emit1(JSOP_POP)) {
|
if (!bce_->emit1(JSOP_POP)) {
|
||||||
// [stack] NEXT ITER
|
// [stack] NEXT ITER
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(JSOP_UNDEFINED)) {
|
if (!bce_->emit1(JSOP_UNDEFINED)) {
|
||||||
// [stack] NEXT ITER UNDEF
|
// [stack] NEXT ITER UNDEF
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the iteration is done, leave loop here, instead of the branch at
|
// If the iteration is done, leave loop here, instead of the branch at
|
||||||
// the end of the loop.
|
// the end of the loop.
|
||||||
if (!loopInfo_->emitSpecialBreakForDone(bce_)) {
|
if (!loopInfo_->emitSpecialBreakForDone(bce_)) {
|
||||||
// [stack] NEXT ITER UNDEF
|
// [stack] NEXT ITER UNDEF
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ifDone.emitEnd()) {
|
if (!ifDone.emitEnd()) {
|
||||||
// [stack] NEXT ITER RESULT
|
// [stack] NEXT ITER RESULT
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ bool ForOfEmitter::emitInitialize(const Maybe<uint32_t>& forPos) {
|
||||||
// Note that ES 13.7.5.13, step 5.c says getting result.value does not
|
// Note that ES 13.7.5.13, step 5.c says getting result.value does not
|
||||||
// call IteratorClose, so start JSTRY_ITERCLOSE after the GETPROP.
|
// call IteratorClose, so start JSTRY_ITERCLOSE after the GETPROP.
|
||||||
if (!bce_->emitAtomOp(bce_->cx->names().value, JSOP_GETPROP)) {
|
if (!bce_->emitAtomOp(bce_->cx->names().value, JSOP_GETPROP)) {
|
||||||
// [stack] NEXT ITER VALUE
|
// [stack] NEXT ITER VALUE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,11 +201,11 @@ bool ForOfEmitter::emitBody() {
|
||||||
|
|
||||||
// Remove VALUE from the stack to release it.
|
// Remove VALUE from the stack to release it.
|
||||||
if (!bce_->emit1(JSOP_POP)) {
|
if (!bce_->emit1(JSOP_POP)) {
|
||||||
// [stack] NEXT ITER
|
// [stack] NEXT ITER
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(JSOP_UNDEFINED)) {
|
if (!bce_->emit1(JSOP_UNDEFINED)) {
|
||||||
// [stack] NEXT ITER UNDEF
|
// [stack] NEXT ITER UNDEF
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,11 +236,11 @@ bool ForOfEmitter::emitEnd(const Maybe<uint32_t>& iteratedPos) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bce_->emit1(JSOP_FALSE)) {
|
if (!bce_->emit1(JSOP_FALSE)) {
|
||||||
// [stack] NEXT ITER UNDEF FALSE
|
// [stack] NEXT ITER UNDEF FALSE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!loopInfo_->emitLoopEnd(bce_, JSOP_IFEQ)) {
|
if (!loopInfo_->emitLoopEnd(bce_, JSOP_IFEQ)) {
|
||||||
// [stack] NEXT ITER UNDEF
|
// [stack] NEXT ITER UNDEF
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +262,7 @@ bool ForOfEmitter::emitEnd(const Maybe<uint32_t>& iteratedPos) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bce_->emitPopN(3)) {
|
if (!bce_->emitPopN(3)) {
|
||||||
// [stack]
|
// [stack]
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,17 +37,17 @@ bool ForOfLoopControl::emitBeginCodeNeedingIteratorClose(BytecodeEmitter* bce) {
|
||||||
|
|
||||||
bool ForOfLoopControl::emitEndCodeNeedingIteratorClose(BytecodeEmitter* bce) {
|
bool ForOfLoopControl::emitEndCodeNeedingIteratorClose(BytecodeEmitter* bce) {
|
||||||
if (!tryCatch_->emitCatch()) {
|
if (!tryCatch_->emitCatch()) {
|
||||||
// [stack] ITER ...
|
// [stack] ITER ...
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bce->emit1(JSOP_EXCEPTION)) {
|
if (!bce->emit1(JSOP_EXCEPTION)) {
|
||||||
// [stack] ITER ... EXCEPTION
|
// [stack] ITER ... EXCEPTION
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
unsigned slotFromTop = bce->stackDepth - iterDepth_;
|
unsigned slotFromTop = bce->stackDepth - iterDepth_;
|
||||||
if (!bce->emitDupAt(slotFromTop)) {
|
if (!bce->emitDupAt(slotFromTop)) {
|
||||||
// [stack] ITER ... EXCEPTION ITER
|
// [stack] ITER ... EXCEPTION ITER
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,23 +55,23 @@ bool ForOfLoopControl::emitEndCodeNeedingIteratorClose(BytecodeEmitter* bce) {
|
||||||
// IteratorClose for non-local jump, and we should't perform
|
// IteratorClose for non-local jump, and we should't perform
|
||||||
// IteratorClose again here.
|
// IteratorClose again here.
|
||||||
if (!bce->emit1(JSOP_UNDEFINED)) {
|
if (!bce->emit1(JSOP_UNDEFINED)) {
|
||||||
// [stack] ITER ... EXCEPTION ITER UNDEF
|
// [stack] ITER ... EXCEPTION ITER UNDEF
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce->emit1(JSOP_STRICTNE)) {
|
if (!bce->emit1(JSOP_STRICTNE)) {
|
||||||
// [stack] ITER ... EXCEPTION NE
|
// [stack] ITER ... EXCEPTION NE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
InternalIfEmitter ifIteratorIsNotClosed(bce);
|
InternalIfEmitter ifIteratorIsNotClosed(bce);
|
||||||
if (!ifIteratorIsNotClosed.emitThen()) {
|
if (!ifIteratorIsNotClosed.emitThen()) {
|
||||||
// [stack] ITER ... EXCEPTION
|
// [stack] ITER ... EXCEPTION
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(slotFromTop == unsigned(bce->stackDepth - iterDepth_));
|
MOZ_ASSERT(slotFromTop == unsigned(bce->stackDepth - iterDepth_));
|
||||||
if (!bce->emitDupAt(slotFromTop)) {
|
if (!bce->emitDupAt(slotFromTop)) {
|
||||||
// [stack] ITER ... EXCEPTION ITER
|
// [stack] ITER ... EXCEPTION ITER
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!emitIteratorCloseInInnermostScope(bce, CompletionKind::Throw)) {
|
if (!emitIteratorCloseInInnermostScope(bce, CompletionKind::Throw)) {
|
||||||
|
@ -79,12 +79,12 @@ bool ForOfLoopControl::emitEndCodeNeedingIteratorClose(BytecodeEmitter* bce) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ifIteratorIsNotClosed.emitEnd()) {
|
if (!ifIteratorIsNotClosed.emitEnd()) {
|
||||||
// [stack] ITER ... EXCEPTION
|
// [stack] ITER ... EXCEPTION
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bce->emit1(JSOP_THROW)) {
|
if (!bce->emit1(JSOP_THROW)) {
|
||||||
// [stack] ITER ...
|
// [stack] ITER ...
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,23 +99,23 @@ bool ForOfLoopControl::emitEndCodeNeedingIteratorClose(BytecodeEmitter* bce) {
|
||||||
|
|
||||||
InternalIfEmitter ifGeneratorClosing(bce);
|
InternalIfEmitter ifGeneratorClosing(bce);
|
||||||
if (!bce->emit1(JSOP_ISGENCLOSING)) {
|
if (!bce->emit1(JSOP_ISGENCLOSING)) {
|
||||||
// [stack] ITER ... FTYPE FVALUE CLOSING
|
// [stack] ITER ... FTYPE FVALUE CLOSING
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!ifGeneratorClosing.emitThen()) {
|
if (!ifGeneratorClosing.emitThen()) {
|
||||||
// [stack] ITER ... FTYPE FVALUE
|
// [stack] ITER ... FTYPE FVALUE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce->emitDupAt(slotFromTop + 1)) {
|
if (!bce->emitDupAt(slotFromTop + 1)) {
|
||||||
// [stack] ITER ... FTYPE FVALUE ITER
|
// [stack] ITER ... FTYPE FVALUE ITER
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!emitIteratorCloseInInnermostScope(bce, CompletionKind::Normal)) {
|
if (!emitIteratorCloseInInnermostScope(bce, CompletionKind::Normal)) {
|
||||||
// [stack] ITER ... FTYPE FVALUE
|
// [stack] ITER ... FTYPE FVALUE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!ifGeneratorClosing.emitEnd()) {
|
if (!ifGeneratorClosing.emitEnd()) {
|
||||||
// [stack] ITER ... FTYPE FVALUE
|
// [stack] ITER ... FTYPE FVALUE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,33 +165,33 @@ bool ForOfLoopControl::emitPrepareForNonLocalJumpFromScope(
|
||||||
// reach the depth for try-catch, and effectively re-enter the
|
// reach the depth for try-catch, and effectively re-enter the
|
||||||
// try-catch block.
|
// try-catch block.
|
||||||
if (!bce->emit1(JSOP_POP)) {
|
if (!bce->emit1(JSOP_POP)) {
|
||||||
// [stack] NEXT ITER
|
// [stack] NEXT ITER
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pop the iterator's next method.
|
// Pop the iterator's next method.
|
||||||
if (!bce->emit1(JSOP_SWAP)) {
|
if (!bce->emit1(JSOP_SWAP)) {
|
||||||
// [stack] ITER NEXT
|
// [stack] ITER NEXT
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce->emit1(JSOP_POP)) {
|
if (!bce->emit1(JSOP_POP)) {
|
||||||
// [stack] ITER
|
// [stack] ITER
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear ITER slot on the stack to tell catch block to avoid performing
|
// Clear ITER slot on the stack to tell catch block to avoid performing
|
||||||
// IteratorClose again.
|
// IteratorClose again.
|
||||||
if (!bce->emit1(JSOP_UNDEFINED)) {
|
if (!bce->emit1(JSOP_UNDEFINED)) {
|
||||||
// [stack] ITER UNDEF
|
// [stack] ITER UNDEF
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce->emit1(JSOP_SWAP)) {
|
if (!bce->emit1(JSOP_SWAP)) {
|
||||||
// [stack] UNDEF ITER
|
// [stack] UNDEF ITER
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!emitIteratorCloseInScope(bce, currentScope, CompletionKind::Normal)) {
|
if (!emitIteratorCloseInScope(bce, currentScope, CompletionKind::Normal)) {
|
||||||
// [stack] UNDEF
|
// [stack] UNDEF
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,16 +200,16 @@ bool ForOfLoopControl::emitPrepareForNonLocalJumpFromScope(
|
||||||
// loop that will pop the next method, the iterator, and the
|
// loop that will pop the next method, the iterator, and the
|
||||||
// value, so push two undefineds to balance the stack.
|
// value, so push two undefineds to balance the stack.
|
||||||
if (!bce->emit1(JSOP_UNDEFINED)) {
|
if (!bce->emit1(JSOP_UNDEFINED)) {
|
||||||
// [stack] UNDEF UNDEF
|
// [stack] UNDEF UNDEF
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce->emit1(JSOP_UNDEFINED)) {
|
if (!bce->emit1(JSOP_UNDEFINED)) {
|
||||||
// [stack] UNDEF UNDEF UNDEF
|
// [stack] UNDEF UNDEF UNDEF
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!bce->emit1(JSOP_POP)) {
|
if (!bce->emit1(JSOP_POP)) {
|
||||||
// [stack]
|
// [stack]
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,37 +32,37 @@ bool NameOpEmitter::emitGet() {
|
||||||
switch (loc_.kind()) {
|
switch (loc_.kind()) {
|
||||||
case NameLocation::Kind::Dynamic:
|
case NameLocation::Kind::Dynamic:
|
||||||
if (!bce_->emitAtomOp(name_, JSOP_GETNAME)) {
|
if (!bce_->emitAtomOp(name_, JSOP_GETNAME)) {
|
||||||
// [stack] VAL
|
// [stack] VAL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NameLocation::Kind::Global:
|
case NameLocation::Kind::Global:
|
||||||
if (!bce_->emitAtomOp(name_, JSOP_GETGNAME)) {
|
if (!bce_->emitAtomOp(name_, JSOP_GETGNAME)) {
|
||||||
// [stack] VAL
|
// [stack] VAL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NameLocation::Kind::Intrinsic:
|
case NameLocation::Kind::Intrinsic:
|
||||||
if (!bce_->emitAtomOp(name_, JSOP_GETINTRINSIC)) {
|
if (!bce_->emitAtomOp(name_, JSOP_GETINTRINSIC)) {
|
||||||
// [stack] VAL
|
// [stack] VAL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NameLocation::Kind::NamedLambdaCallee:
|
case NameLocation::Kind::NamedLambdaCallee:
|
||||||
if (!bce_->emit1(JSOP_CALLEE)) {
|
if (!bce_->emit1(JSOP_CALLEE)) {
|
||||||
// [stack] VAL
|
// [stack] VAL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NameLocation::Kind::Import:
|
case NameLocation::Kind::Import:
|
||||||
if (!bce_->emitAtomOp(name_, JSOP_GETIMPORT)) {
|
if (!bce_->emitAtomOp(name_, JSOP_GETIMPORT)) {
|
||||||
// [stack] VAL
|
// [stack] VAL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NameLocation::Kind::ArgumentSlot:
|
case NameLocation::Kind::ArgumentSlot:
|
||||||
if (!bce_->emitArgOp(JSOP_GETARG, loc_.argumentSlot())) {
|
if (!bce_->emitArgOp(JSOP_GETARG, loc_.argumentSlot())) {
|
||||||
// [stack] VAL
|
// [stack] VAL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -73,7 +73,7 @@ bool NameOpEmitter::emitGet() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!bce_->emitLocalOp(JSOP_GETLOCAL, loc_.frameSlot())) {
|
if (!bce_->emitLocalOp(JSOP_GETLOCAL, loc_.frameSlot())) {
|
||||||
// [stack] VAL
|
// [stack] VAL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -85,7 +85,7 @@ bool NameOpEmitter::emitGet() {
|
||||||
}
|
}
|
||||||
if (!bce_->emitEnvCoordOp(JSOP_GETALIASEDVAR,
|
if (!bce_->emitEnvCoordOp(JSOP_GETALIASEDVAR,
|
||||||
loc_.environmentCoordinate())) {
|
loc_.environmentCoordinate())) {
|
||||||
// [stack] VAL
|
// [stack] VAL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -101,14 +101,14 @@ bool NameOpEmitter::emitGet() {
|
||||||
JSOp thisOp =
|
JSOp thisOp =
|
||||||
bce_->needsImplicitThis() ? JSOP_IMPLICITTHIS : JSOP_GIMPLICITTHIS;
|
bce_->needsImplicitThis() ? JSOP_IMPLICITTHIS : JSOP_GIMPLICITTHIS;
|
||||||
if (!bce_->emitAtomOp(name_, thisOp)) {
|
if (!bce_->emitAtomOp(name_, thisOp)) {
|
||||||
// [stack] CALLEE THIS
|
// [stack] CALLEE THIS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NameLocation::Kind::Global:
|
case NameLocation::Kind::Global:
|
||||||
if (!bce_->emitAtomOp(name_, JSOP_GIMPLICITTHIS)) {
|
if (!bce_->emitAtomOp(name_, JSOP_GIMPLICITTHIS)) {
|
||||||
// [stack] CALLEE THIS
|
// [stack] CALLEE THIS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -119,7 +119,7 @@ bool NameOpEmitter::emitGet() {
|
||||||
case NameLocation::Kind::FrameSlot:
|
case NameLocation::Kind::FrameSlot:
|
||||||
case NameLocation::Kind::EnvironmentCoordinate:
|
case NameLocation::Kind::EnvironmentCoordinate:
|
||||||
if (!bce_->emit1(JSOP_UNDEFINED)) {
|
if (!bce_->emit1(JSOP_UNDEFINED)) {
|
||||||
// [stack] CALLEE UNDEF
|
// [stack] CALLEE UNDEF
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -151,12 +151,12 @@ bool NameOpEmitter::prepareForRhs() {
|
||||||
// even if lexical environments in between contain same-named
|
// even if lexical environments in between contain same-named
|
||||||
// bindings.
|
// bindings.
|
||||||
if (!bce_->emit1(JSOP_BINDVAR)) {
|
if (!bce_->emit1(JSOP_BINDVAR)) {
|
||||||
// [stack] ENV
|
// [stack] ENV
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!bce_->emitIndexOp(JSOP_BINDNAME, atomIndex_)) {
|
if (!bce_->emitIndexOp(JSOP_BINDNAME, atomIndex_)) {
|
||||||
// [stack] ENV
|
// [stack] ENV
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,7 +172,7 @@ bool NameOpEmitter::prepareForRhs() {
|
||||||
MOZ_ASSERT(bce_->innermostScope()->is<GlobalScope>());
|
MOZ_ASSERT(bce_->innermostScope()->is<GlobalScope>());
|
||||||
} else {
|
} else {
|
||||||
if (!bce_->emitIndexOp(JSOP_BINDGNAME, atomIndex_)) {
|
if (!bce_->emitIndexOp(JSOP_BINDGNAME, atomIndex_)) {
|
||||||
// [stack] ENV
|
// [stack] ENV
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
emittedBindOp_ = true;
|
emittedBindOp_ = true;
|
||||||
|
@ -214,16 +214,16 @@ bool NameOpEmitter::prepareForRhs() {
|
||||||
// GETBOUNDNAME uses the environment already pushed on the stack
|
// GETBOUNDNAME uses the environment already pushed on the stack
|
||||||
// from the earlier BINDNAME.
|
// from the earlier BINDNAME.
|
||||||
if (!bce_->emit1(JSOP_DUP)) {
|
if (!bce_->emit1(JSOP_DUP)) {
|
||||||
// [stack] ENV ENV
|
// [stack] ENV ENV
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emitAtomOp(name_, JSOP_GETBOUNDNAME)) {
|
if (!bce_->emitAtomOp(name_, JSOP_GETBOUNDNAME)) {
|
||||||
// [stack] ENV V
|
// [stack] ENV V
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!emitGet()) {
|
if (!emitGet()) {
|
||||||
// [stack] ENV? V
|
// [stack] ENV? V
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -354,44 +354,44 @@ bool NameOpEmitter::emitIncDec() {
|
||||||
|
|
||||||
JSOp binOp = isInc() ? JSOP_ADD : JSOP_SUB;
|
JSOp binOp = isInc() ? JSOP_ADD : JSOP_SUB;
|
||||||
if (!prepareForRhs()) {
|
if (!prepareForRhs()) {
|
||||||
// [stack] ENV? V
|
// [stack] ENV? V
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(JSOP_POS)) {
|
if (!bce_->emit1(JSOP_POS)) {
|
||||||
// [stack] ENV? N
|
// [stack] ENV? N
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (isPostIncDec()) {
|
if (isPostIncDec()) {
|
||||||
if (!bce_->emit1(JSOP_DUP)) {
|
if (!bce_->emit1(JSOP_DUP)) {
|
||||||
// [stack] ENV? N? N
|
// [stack] ENV? N? N
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(JSOP_ONE)) {
|
if (!bce_->emit1(JSOP_ONE)) {
|
||||||
// [stack] ENV? N? N 1
|
// [stack] ENV? N? N 1
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(binOp)) {
|
if (!bce_->emit1(binOp)) {
|
||||||
// [stack] ENV? N? N+1
|
// [stack] ENV? N? N+1
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (isPostIncDec() && emittedBindOp()) {
|
if (isPostIncDec() && emittedBindOp()) {
|
||||||
if (!bce_->emit2(JSOP_PICK, 2)) {
|
if (!bce_->emit2(JSOP_PICK, 2)) {
|
||||||
// [stack] N? N+1 ENV?
|
// [stack] N? N+1 ENV?
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(JSOP_SWAP)) {
|
if (!bce_->emit1(JSOP_SWAP)) {
|
||||||
// [stack] N? ENV? N+1
|
// [stack] N? ENV? N+1
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!emitAssignment()) {
|
if (!emitAssignment()) {
|
||||||
// [stack] N? N+1
|
// [stack] N? N+1
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (isPostIncDec()) {
|
if (isPostIncDec()) {
|
||||||
if (!bce_->emit1(JSOP_POP)) {
|
if (!bce_->emit1(JSOP_POP)) {
|
||||||
// [stack] N
|
// [stack] N
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,28 +43,28 @@ bool PropOpEmitter::emitGet(JSAtom* prop) {
|
||||||
}
|
}
|
||||||
if (isCall()) {
|
if (isCall()) {
|
||||||
if (!bce_->emit1(JSOP_DUP)) {
|
if (!bce_->emit1(JSOP_DUP)) {
|
||||||
// [stack] # if Super
|
// [stack] # if Super
|
||||||
// [stack] THIS THIS
|
// [stack] THIS THIS
|
||||||
// [stack] # otherwise
|
// [stack] # otherwise
|
||||||
// [stack] OBJ OBJ
|
// [stack] OBJ OBJ
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isSuper()) {
|
if (isSuper()) {
|
||||||
if (!bce_->emitSuperBase()) {
|
if (!bce_->emitSuperBase()) {
|
||||||
// [stack] THIS? THIS SUPERBASE
|
// [stack] THIS? THIS SUPERBASE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isIncDec() || isCompoundAssignment()) {
|
if (isIncDec() || isCompoundAssignment()) {
|
||||||
if (isSuper()) {
|
if (isSuper()) {
|
||||||
if (!bce_->emit1(JSOP_DUP2)) {
|
if (!bce_->emit1(JSOP_DUP2)) {
|
||||||
// [stack] THIS SUPERBASE THIS SUPERBASE
|
// [stack] THIS SUPERBASE THIS SUPERBASE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!bce_->emit1(JSOP_DUP)) {
|
if (!bce_->emit1(JSOP_DUP)) {
|
||||||
// [stack] OBJ OBJ
|
// [stack] OBJ OBJ
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,19 +79,19 @@ bool PropOpEmitter::emitGet(JSAtom* prop) {
|
||||||
op = isLength_ ? JSOP_LENGTH : JSOP_GETPROP;
|
op = isLength_ ? JSOP_LENGTH : JSOP_GETPROP;
|
||||||
}
|
}
|
||||||
if (!bce_->emitAtomOp(propAtomIndex_, op)) {
|
if (!bce_->emitAtomOp(propAtomIndex_, op)) {
|
||||||
// [stack] # if Get
|
// [stack] # if Get
|
||||||
// [stack] PROP
|
// [stack] PROP
|
||||||
// [stack] # if Call
|
// [stack] # if Call
|
||||||
// [stack] THIS PROP
|
// [stack] THIS PROP
|
||||||
// [stack] # if Inc/Dec/Compound, Super]
|
// [stack] # if Inc/Dec/Compound, Super]
|
||||||
// [stack] THIS SUPERBASE PROP
|
// [stack] THIS SUPERBASE PROP
|
||||||
// [stack] # if Inc/Dec/Compound, other
|
// [stack] # if Inc/Dec/Compound, other
|
||||||
// [stack] OBJ PROP
|
// [stack] OBJ PROP
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (isCall()) {
|
if (isCall()) {
|
||||||
if (!bce_->emit1(JSOP_SWAP)) {
|
if (!bce_->emit1(JSOP_SWAP)) {
|
||||||
// [stack] PROP THIS
|
// [stack] PROP THIS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ bool PropOpEmitter::prepareForRhs() {
|
||||||
// For CompoundAssignment, SUPERBASE is already emitted by emitGet.
|
// For CompoundAssignment, SUPERBASE is already emitted by emitGet.
|
||||||
if (isSuper()) {
|
if (isSuper()) {
|
||||||
if (!bce_->emitSuperBase()) {
|
if (!bce_->emitSuperBase()) {
|
||||||
// [stack] THIS SUPERBASE
|
// [stack] THIS SUPERBASE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,26 +143,26 @@ bool PropOpEmitter::emitDelete(JSAtom* prop) {
|
||||||
}
|
}
|
||||||
if (isSuper()) {
|
if (isSuper()) {
|
||||||
if (!bce_->emitSuperBase()) {
|
if (!bce_->emitSuperBase()) {
|
||||||
// [stack] THIS SUPERBASE
|
// [stack] THIS SUPERBASE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unconditionally throw when attempting to delete a super-reference.
|
// Unconditionally throw when attempting to delete a super-reference.
|
||||||
if (!bce_->emitUint16Operand(JSOP_THROWMSG, JSMSG_CANT_DELETE_SUPER)) {
|
if (!bce_->emitUint16Operand(JSOP_THROWMSG, JSMSG_CANT_DELETE_SUPER)) {
|
||||||
// [stack] THIS SUPERBASE
|
// [stack] THIS SUPERBASE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Another wrinkle: Balance the stack from the emitter's point of view.
|
// Another wrinkle: Balance the stack from the emitter's point of view.
|
||||||
// Execution will not reach here, as the last bytecode threw.
|
// Execution will not reach here, as the last bytecode threw.
|
||||||
if (!bce_->emit1(JSOP_POP)) {
|
if (!bce_->emit1(JSOP_POP)) {
|
||||||
// [stack] THIS
|
// [stack] THIS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
JSOp op = bce_->sc->strict() ? JSOP_STRICTDELPROP : JSOP_DELPROP;
|
JSOp op = bce_->sc->strict() ? JSOP_STRICTDELPROP : JSOP_DELPROP;
|
||||||
if (!bce_->emitAtomOp(propAtomIndex_, op)) {
|
if (!bce_->emitAtomOp(propAtomIndex_, op)) {
|
||||||
// [stack] SUCCEEDED
|
// [stack] SUCCEEDED
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,7 @@ bool PropOpEmitter::emitAssignment(JSAtom* prop) {
|
||||||
? bce_->sc->strict() ? JSOP_STRICTSETPROP_SUPER : JSOP_SETPROP_SUPER
|
? bce_->sc->strict() ? JSOP_STRICTSETPROP_SUPER : JSOP_SETPROP_SUPER
|
||||||
: bce_->sc->strict() ? JSOP_STRICTSETPROP : JSOP_SETPROP;
|
: bce_->sc->strict() ? JSOP_STRICTSETPROP : JSOP_SETPROP;
|
||||||
if (!bce_->emitAtomOp(propAtomIndex_, setOp)) {
|
if (!bce_->emitAtomOp(propAtomIndex_, setOp)) {
|
||||||
// [stack] VAL
|
// [stack] VAL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,50 +211,50 @@ bool PropOpEmitter::emitIncDec(JSAtom* prop) {
|
||||||
JSOp binOp = isInc() ? JSOP_ADD : JSOP_SUB;
|
JSOp binOp = isInc() ? JSOP_ADD : JSOP_SUB;
|
||||||
|
|
||||||
if (!bce_->emit1(JSOP_POS)) {
|
if (!bce_->emit1(JSOP_POS)) {
|
||||||
// [stack] ... N
|
// [stack] ... N
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (isPostIncDec()) {
|
if (isPostIncDec()) {
|
||||||
if (!bce_->emit1(JSOP_DUP)) {
|
if (!bce_->emit1(JSOP_DUP)) {
|
||||||
// [stack] .. N N
|
// [stack] .. N N
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(JSOP_ONE)) {
|
if (!bce_->emit1(JSOP_ONE)) {
|
||||||
// [stack] ... N? N 1
|
// [stack] ... N? N 1
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(binOp)) {
|
if (!bce_->emit1(binOp)) {
|
||||||
// [stack] ... N? N+1
|
// [stack] ... N? N+1
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (isPostIncDec()) {
|
if (isPostIncDec()) {
|
||||||
if (isSuper()) {
|
if (isSuper()) {
|
||||||
// [stack] THIS OBJ N N+1
|
// [stack] THIS OBJ N N+1
|
||||||
if (!bce_->emit2(JSOP_PICK, 3)) {
|
if (!bce_->emit2(JSOP_PICK, 3)) {
|
||||||
// [stack] OBJ N N+1 THIS
|
// [stack] OBJ N N+1 THIS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(JSOP_SWAP)) {
|
if (!bce_->emit1(JSOP_SWAP)) {
|
||||||
// [stack] OBJ N THIS N+1
|
// [stack] OBJ N THIS N+1
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit2(JSOP_PICK, 3)) {
|
if (!bce_->emit2(JSOP_PICK, 3)) {
|
||||||
// [stack] N THIS N+1 OBJ
|
// [stack] N THIS N+1 OBJ
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(JSOP_SWAP)) {
|
if (!bce_->emit1(JSOP_SWAP)) {
|
||||||
// [stack] N THIS OBJ N+1
|
// [stack] N THIS OBJ N+1
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// [stack] OBJ N N+1
|
// [stack] OBJ N N+1
|
||||||
if (!bce_->emit2(JSOP_PICK, 2)) {
|
if (!bce_->emit2(JSOP_PICK, 2)) {
|
||||||
// [stack] N N+1 OBJ
|
// [stack] N N+1 OBJ
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bce_->emit1(JSOP_SWAP)) {
|
if (!bce_->emit1(JSOP_SWAP)) {
|
||||||
// [stack] N OBJ N+1
|
// [stack] N OBJ N+1
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -265,12 +265,12 @@ bool PropOpEmitter::emitIncDec(JSAtom* prop) {
|
||||||
? bce_->sc->strict() ? JSOP_STRICTSETPROP_SUPER : JSOP_SETPROP_SUPER
|
? bce_->sc->strict() ? JSOP_STRICTSETPROP_SUPER : JSOP_SETPROP_SUPER
|
||||||
: bce_->sc->strict() ? JSOP_STRICTSETPROP : JSOP_SETPROP;
|
: bce_->sc->strict() ? JSOP_STRICTSETPROP : JSOP_SETPROP;
|
||||||
if (!bce_->emitAtomOp(propAtomIndex_, setOp)) {
|
if (!bce_->emitAtomOp(propAtomIndex_, setOp)) {
|
||||||
// [stack] N? N+1
|
// [stack] N? N+1
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (isPostIncDec()) {
|
if (isPostIncDec()) {
|
||||||
if (!bce_->emit1(JSOP_POP)) {
|
if (!bce_->emit1(JSOP_POP)) {
|
||||||
// [stack] N
|
// [stack] N
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
# The column index of '[' of '[stack]'
|
# The column index of '[' of '[stack]'
|
||||||
ALIGNMENT_COLUMN = 30
|
ALIGNMENT_COLUMN = 20
|
||||||
|
|
||||||
# The maximum column for comment
|
# The maximum column for comment
|
||||||
MAX_CHARS_PER_LINE = 80
|
MAX_CHARS_PER_LINE = 80
|
||||||
|
|
Загрузка…
Ссылка в новой задаче