mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-08 12:37:37 +00:00
Bug 1143704 part 6 - Move more functions into BytecodeEmitter. r=efaust
This commit is contained in:
parent
9d8d957e80
commit
71389afa0d
@ -198,18 +198,18 @@ BytecodeEmitter::updateLocalsToFrameSlots()
|
||||
return true;
|
||||
}
|
||||
|
||||
static ptrdiff_t
|
||||
EmitCheck(ExclusiveContext *cx, BytecodeEmitter *bce, ptrdiff_t delta)
|
||||
ptrdiff_t
|
||||
BytecodeEmitter::emitCheck(ptrdiff_t delta)
|
||||
{
|
||||
ptrdiff_t offset = bce->code().length();
|
||||
ptrdiff_t offset = code().length();
|
||||
|
||||
// Start it off moderately large to avoid repeated resizings early on.
|
||||
// ~98% of cases fit within 1024 bytes.
|
||||
if (bce->code().capacity() == 0 && !bce->code().reserve(1024))
|
||||
if (code().capacity() == 0 && !code().reserve(1024))
|
||||
return -1;
|
||||
|
||||
jsbytecode dummy = 0;
|
||||
if (!bce->code().appendN(dummy, delta)) {
|
||||
if (!code().appendN(dummy, delta)) {
|
||||
ReportOutOfMemory(cx);
|
||||
return -1;
|
||||
}
|
||||
@ -260,7 +260,7 @@ bool
|
||||
BytecodeEmitter::emit1(JSOp op)
|
||||
{
|
||||
MOZ_ASSERT(CheckStrictOrSloppy(this, op));
|
||||
ptrdiff_t offset = EmitCheck(cx, this, 1);
|
||||
ptrdiff_t offset = emitCheck(1);
|
||||
if (offset < 0)
|
||||
return false;
|
||||
|
||||
@ -271,52 +271,51 @@ BytecodeEmitter::emit1(JSOp op)
|
||||
}
|
||||
|
||||
bool
|
||||
frontend::Emit2(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op, jsbytecode op1)
|
||||
BytecodeEmitter::emit2(JSOp op, jsbytecode op1)
|
||||
{
|
||||
MOZ_ASSERT(CheckStrictOrSloppy(bce, op));
|
||||
ptrdiff_t offset = EmitCheck(cx, bce, 2);
|
||||
MOZ_ASSERT(CheckStrictOrSloppy(this, op));
|
||||
ptrdiff_t offset = emitCheck(2);
|
||||
if (offset < 0)
|
||||
return false;
|
||||
|
||||
jsbytecode *code = bce->code(offset);
|
||||
jsbytecode *code = this->code(offset);
|
||||
code[0] = jsbytecode(op);
|
||||
code[1] = op1;
|
||||
UpdateDepth(cx, bce, offset);
|
||||
UpdateDepth(cx, this, offset);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
frontend::Emit3(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op, jsbytecode op1,
|
||||
jsbytecode op2)
|
||||
BytecodeEmitter::emit3(JSOp op, jsbytecode op1, jsbytecode op2)
|
||||
{
|
||||
MOZ_ASSERT(CheckStrictOrSloppy(bce, op));
|
||||
MOZ_ASSERT(CheckStrictOrSloppy(this, op));
|
||||
|
||||
/* These should filter through EmitVarOp. */
|
||||
MOZ_ASSERT(!IsArgOp(op));
|
||||
MOZ_ASSERT(!IsLocalOp(op));
|
||||
|
||||
ptrdiff_t offset = EmitCheck(cx, bce, 3);
|
||||
ptrdiff_t offset = emitCheck(3);
|
||||
if (offset < 0)
|
||||
return false;
|
||||
|
||||
jsbytecode *code = bce->code(offset);
|
||||
jsbytecode *code = this->code(offset);
|
||||
code[0] = jsbytecode(op);
|
||||
code[1] = op1;
|
||||
code[2] = op2;
|
||||
UpdateDepth(cx, bce, offset);
|
||||
UpdateDepth(cx, this, offset);
|
||||
return true;
|
||||
}
|
||||
|
||||
ptrdiff_t
|
||||
frontend::EmitN(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op, size_t extra)
|
||||
BytecodeEmitter::emitN(JSOp op, size_t extra)
|
||||
{
|
||||
MOZ_ASSERT(CheckStrictOrSloppy(bce, op));
|
||||
MOZ_ASSERT(CheckStrictOrSloppy(this, op));
|
||||
ptrdiff_t length = 1 + (ptrdiff_t)extra;
|
||||
ptrdiff_t offset = EmitCheck(cx, bce, length);
|
||||
ptrdiff_t offset = emitCheck(length);
|
||||
if (offset < 0)
|
||||
return -1;
|
||||
|
||||
jsbytecode *code = bce->code(offset);
|
||||
jsbytecode *code = this->code(offset);
|
||||
code[0] = jsbytecode(op);
|
||||
/* The remaining |extra| bytes are set by the caller */
|
||||
|
||||
@ -325,31 +324,31 @@ frontend::EmitN(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op, size_t extr
|
||||
* operand yet to be stored in the extra bytes after op.
|
||||
*/
|
||||
if (js_CodeSpec[op].nuses >= 0)
|
||||
UpdateDepth(cx, bce, offset);
|
||||
UpdateDepth(cx, this, offset);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static ptrdiff_t
|
||||
EmitJump(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op, ptrdiff_t off)
|
||||
ptrdiff_t
|
||||
BytecodeEmitter::emitJump(JSOp op, ptrdiff_t off)
|
||||
{
|
||||
ptrdiff_t offset = EmitCheck(cx, bce, 5);
|
||||
ptrdiff_t offset = emitCheck(5);
|
||||
if (offset < 0)
|
||||
return -1;
|
||||
|
||||
jsbytecode *code = bce->code(offset);
|
||||
jsbytecode *code = this->code(offset);
|
||||
code[0] = jsbytecode(op);
|
||||
SET_JUMP_OFFSET(code, off);
|
||||
UpdateDepth(cx, bce, offset);
|
||||
UpdateDepth(cx, this, offset);
|
||||
return offset;
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitCall(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op, uint16_t argc, ParseNode *pn=nullptr)
|
||||
bool
|
||||
BytecodeEmitter::emitCall(JSOp op, uint16_t argc, ParseNode *pn)
|
||||
{
|
||||
if (pn && !UpdateSourceCoordNotes(cx, bce, pn->pn_pos.begin))
|
||||
if (pn && !UpdateSourceCoordNotes(cx, this, pn->pn_pos.begin))
|
||||
return false;
|
||||
return Emit3(cx, bce, op, ARGC_HI(argc), ARGC_LO(argc));
|
||||
return emit3(op, ARGC_HI(argc), ARGC_LO(argc));
|
||||
}
|
||||
|
||||
// Dup the var in operand stack slot "slot". The first item on the operand
|
||||
@ -372,7 +371,7 @@ EmitDupAt(ExclusiveContext *cx, BytecodeEmitter *bce, unsigned slot)
|
||||
bce->reportError(nullptr, JSMSG_TOO_MANY_LOCALS);
|
||||
return false;
|
||||
}
|
||||
ptrdiff_t off = EmitN(cx, bce, JSOP_DUPAT, 3);
|
||||
ptrdiff_t off = bce->emitN(JSOP_DUPAT, 3);
|
||||
if (off < 0)
|
||||
return false;
|
||||
jsbytecode *pc = bce->code(off);
|
||||
@ -433,7 +432,7 @@ EmitBackPatchOp(ExclusiveContext *cx, BytecodeEmitter *bce, ptrdiff_t *lastp)
|
||||
ptrdiff_t delta = offset - *lastp;
|
||||
*lastp = offset;
|
||||
MOZ_ASSERT(delta > 0);
|
||||
return EmitJump(cx, bce, JSOP_BACKPATCH, delta) >= 0;
|
||||
return bce->emitJump(JSOP_BACKPATCH, delta) >= 0;
|
||||
}
|
||||
|
||||
static inline unsigned
|
||||
@ -536,7 +535,7 @@ EmitLoopEntry(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *nextpn)
|
||||
MOZ_ASSERT(loop->loopDepth > 0);
|
||||
|
||||
uint8_t loopDepthAndFlags = PackLoopEntryDepthHintAndFlags(loop->loopDepth, loop->canIonOsr);
|
||||
return Emit2(cx, bce, JSOP_LOOPENTRY, loopDepthAndFlags);
|
||||
return bce->emit2(JSOP_LOOPENTRY, loopDepthAndFlags);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -561,7 +560,7 @@ CheckTypeSet(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op)
|
||||
*/
|
||||
#define EMIT_UINT16_IMM_OP(op, i) \
|
||||
JS_BEGIN_MACRO \
|
||||
if (!Emit3(cx, bce, op, UINT16_HI(i), UINT16_LO(i))) \
|
||||
if (!bce->emit3(op, UINT16_HI(i), UINT16_LO(i))) \
|
||||
return false; \
|
||||
CheckTypeSet(cx, bce, op); \
|
||||
JS_END_MACRO
|
||||
@ -1046,7 +1045,7 @@ EmitIndex32(ExclusiveContext *cx, JSOp op, uint32_t index, BytecodeEmitter *bce)
|
||||
MOZ_ASSERT(CheckStrictOrSloppy(bce, op));
|
||||
const size_t len = 1 + UINT32_INDEX_LEN;
|
||||
MOZ_ASSERT(len == size_t(js_CodeSpec[op].length));
|
||||
ptrdiff_t offset = EmitCheck(cx, bce, len);
|
||||
ptrdiff_t offset = bce->emitCheck(len);
|
||||
if (offset < 0)
|
||||
return false;
|
||||
|
||||
@ -1064,7 +1063,7 @@ EmitIndexOp(ExclusiveContext *cx, JSOp op, uint32_t index, BytecodeEmitter *bce)
|
||||
MOZ_ASSERT(CheckStrictOrSloppy(bce, op));
|
||||
const size_t len = js_CodeSpec[op].length;
|
||||
MOZ_ASSERT(len >= 1 + UINT32_INDEX_LEN);
|
||||
ptrdiff_t offset = EmitCheck(cx, bce, len);
|
||||
ptrdiff_t offset = bce->emitCheck(len);
|
||||
if (offset < 0)
|
||||
return false;
|
||||
|
||||
@ -1134,7 +1133,7 @@ EmitRegExp(ExclusiveContext *cx, uint32_t index, BytecodeEmitter *bce)
|
||||
}
|
||||
|
||||
/*
|
||||
* To catch accidental misuse, EMIT_UINT16_IMM_OP/Emit3 assert that they are
|
||||
* To catch accidental misuse, EMIT_UINT16_IMM_OP/emit3 assert that they are
|
||||
* not used to unconditionally emit JSOP_GETLOCAL. Variable access should
|
||||
* instead be emitted using EmitVarOp. In special cases, when the caller
|
||||
* definitely knows that a given local slot is unaliased, this function may be
|
||||
@ -1146,7 +1145,7 @@ EmitLocalOp(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op, uint32_t slot)
|
||||
MOZ_ASSERT(JOF_OPTYPE(op) != JOF_SCOPECOORD);
|
||||
MOZ_ASSERT(IsLocalOp(op));
|
||||
|
||||
ptrdiff_t off = EmitN(cx, bce, op, LOCALNO_LEN);
|
||||
ptrdiff_t off = bce->emitN(op, LOCALNO_LEN);
|
||||
if (off < 0)
|
||||
return false;
|
||||
|
||||
@ -1177,7 +1176,7 @@ EmitUnaliasedVarOp(ExclusiveContext *cx, JSOp op, uint32_t slot, MaybeCheckLexic
|
||||
}
|
||||
|
||||
MOZ_ASSERT(IsArgOp(op));
|
||||
ptrdiff_t off = EmitN(cx, bce, op, ARGNO_LEN);
|
||||
ptrdiff_t off = bce->emitN(op, ARGNO_LEN);
|
||||
if (off < 0)
|
||||
return false;
|
||||
|
||||
@ -1193,7 +1192,7 @@ EmitScopeCoordOp(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op, ScopeCoord
|
||||
unsigned n = SCOPECOORD_HOPS_LEN + SCOPECOORD_SLOT_LEN;
|
||||
MOZ_ASSERT(int(n) + 1 /* op */ == js_CodeSpec[op].length);
|
||||
|
||||
ptrdiff_t off = EmitN(cx, bce, op, n);
|
||||
ptrdiff_t off = bce->emitN(op, n);
|
||||
if (off < 0)
|
||||
return false;
|
||||
|
||||
@ -2230,7 +2229,7 @@ static bool
|
||||
EmitNewInit(ExclusiveContext *cx, BytecodeEmitter *bce, JSProtoKey key)
|
||||
{
|
||||
const size_t len = 1 + UINT32_INDEX_LEN;
|
||||
ptrdiff_t offset = EmitCheck(cx, bce, len);
|
||||
ptrdiff_t offset = bce->emitCheck(len);
|
||||
if (offset < 0)
|
||||
return false;
|
||||
|
||||
@ -2441,7 +2440,7 @@ EmitPropIncDec(ExclusiveContext *cx, ParseNode *pn, BytecodeEmitter *bce)
|
||||
return false;
|
||||
|
||||
if (post) {
|
||||
if (!Emit2(cx, bce, JSOP_PICK, (jsbytecode)2)) // N? N+1 OBJ
|
||||
if (!bce->emit2(JSOP_PICK, (jsbytecode)2)) // N? N+1 OBJ
|
||||
return false;
|
||||
if (!bce->emit1(JSOP_SWAP)) // N? OBJ N+1
|
||||
return false;
|
||||
@ -2479,7 +2478,7 @@ EmitNameIncDec(ExclusiveContext *cx, ParseNode *pn, BytecodeEmitter *bce)
|
||||
return false;
|
||||
|
||||
if (post) {
|
||||
if (!Emit2(cx, bce, JSOP_PICK, (jsbytecode)2)) // N? N+1 OBJ
|
||||
if (!bce->emit2(JSOP_PICK, (jsbytecode)2)) // N? N+1 OBJ
|
||||
return false;
|
||||
if (!bce->emit1(JSOP_SWAP)) // N? OBJ N+1
|
||||
return false;
|
||||
@ -2510,7 +2509,7 @@ EmitElemOperands(ExclusiveContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *
|
||||
if (!EmitTree(cx, bce, pn->pn_right))
|
||||
return false;
|
||||
bool isSetElem = op == JSOP_SETELEM || op == JSOP_STRICTSETELEM;
|
||||
if (isSetElem && !Emit2(cx, bce, JSOP_PICK, (jsbytecode)2))
|
||||
if (isSetElem && !bce->emit2(JSOP_PICK, (jsbytecode)2))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@ -2562,11 +2561,11 @@ EmitElemIncDec(ExclusiveContext *cx, ParseNode *pn, BytecodeEmitter *bce)
|
||||
return false;
|
||||
|
||||
if (post) {
|
||||
if (!Emit2(cx, bce, JSOP_PICK, (jsbytecode)3)) // KEY N N+1 OBJ
|
||||
if (!bce->emit2(JSOP_PICK, (jsbytecode)3)) // KEY N N+1 OBJ
|
||||
return false;
|
||||
if (!Emit2(cx, bce, JSOP_PICK, (jsbytecode)3)) // N N+1 OBJ KEY
|
||||
if (!bce->emit2(JSOP_PICK, (jsbytecode)3)) // N N+1 OBJ KEY
|
||||
return false;
|
||||
if (!Emit2(cx, bce, JSOP_PICK, (jsbytecode)2)) // N OBJ KEY N+1
|
||||
if (!bce->emit2(JSOP_PICK, (jsbytecode)2)) // N OBJ KEY N+1
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2593,19 +2592,19 @@ EmitNumberOp(ExclusiveContext *cx, double dval, BytecodeEmitter *bce)
|
||||
if (ival == 1)
|
||||
return bce->emit1(JSOP_ONE);
|
||||
if ((int)(int8_t)ival == ival)
|
||||
return Emit2(cx, bce, JSOP_INT8, (jsbytecode)(int8_t)ival);
|
||||
return bce->emit2(JSOP_INT8, (jsbytecode)(int8_t)ival);
|
||||
|
||||
u = (uint32_t)ival;
|
||||
if (u < JS_BIT(16)) {
|
||||
EMIT_UINT16_IMM_OP(JSOP_UINT16, u);
|
||||
} else if (u < JS_BIT(24)) {
|
||||
off = EmitN(cx, bce, JSOP_UINT24, 3);
|
||||
off = bce->emitN(JSOP_UINT24, 3);
|
||||
if (off < 0)
|
||||
return false;
|
||||
pc = bce->code(off);
|
||||
SET_UINT24(pc, u);
|
||||
} else {
|
||||
off = EmitN(cx, bce, JSOP_INT32, 4);
|
||||
off = bce->emitN(JSOP_INT32, 4);
|
||||
if (off < 0)
|
||||
return false;
|
||||
pc = bce->code(off);
|
||||
@ -2855,7 +2854,7 @@ EmitSwitch(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
return false;
|
||||
|
||||
/* Emit switchOp followed by switchSize bytes of jump or lookup table. */
|
||||
if (EmitN(cx, bce, switchOp, switchSize) < 0)
|
||||
if (bce->emitN(switchOp, switchSize) < 0)
|
||||
return false;
|
||||
|
||||
off = -1;
|
||||
@ -2880,7 +2879,7 @@ EmitSwitch(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
caseNoteIndex = NewSrcNote2(cx, bce, SRC_NEXTCASE, 0);
|
||||
if (caseNoteIndex < 0)
|
||||
return false;
|
||||
off = EmitJump(cx, bce, JSOP_CASE, 0);
|
||||
off = bce->emitJump(JSOP_CASE, 0);
|
||||
if (off < 0)
|
||||
return false;
|
||||
pn3->pn_offset = off;
|
||||
@ -2912,7 +2911,7 @@ EmitSwitch(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
}
|
||||
|
||||
/* Emit default even if no explicit default statement. */
|
||||
defaultOffset = EmitJump(cx, bce, JSOP_DEFAULT, 0);
|
||||
defaultOffset = bce->emitJump(JSOP_DEFAULT, 0);
|
||||
if (defaultOffset < 0)
|
||||
return false;
|
||||
} else {
|
||||
@ -3039,7 +3038,7 @@ EmitYieldOp(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op)
|
||||
|
||||
MOZ_ASSERT(op == JSOP_INITIALYIELD || op == JSOP_YIELD);
|
||||
|
||||
ptrdiff_t off = EmitN(cx, bce, op, 3);
|
||||
ptrdiff_t off = bce->emitN(op, 3);
|
||||
if (off < 0)
|
||||
return false;
|
||||
|
||||
@ -3495,7 +3494,7 @@ EmitIteratorNext(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn=nullp
|
||||
return false;
|
||||
if (!bce->emit1(JSOP_SWAP)) // ... NEXT ITER
|
||||
return false;
|
||||
if (!EmitCall(cx, bce, JSOP_CALL, 0, pn)) // ... RESULT
|
||||
if (!bce->emitCall(JSOP_CALL, 0, pn)) // ... RESULT
|
||||
return false;
|
||||
CheckTypeSet(cx, bce, JSOP_CALL);
|
||||
return true;
|
||||
@ -3517,7 +3516,7 @@ EmitDefault(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *defaultExpr)
|
||||
// Emit source note to enable ion compilation.
|
||||
if (NewSrcNote(cx, bce, SRC_IF) < 0)
|
||||
return false;
|
||||
ptrdiff_t jump = EmitJump(cx, bce, JSOP_IFEQ, 0); // VALUE
|
||||
ptrdiff_t jump = bce->emitJump(JSOP_IFEQ, 0); // VALUE
|
||||
if (jump < 0)
|
||||
return false;
|
||||
if (!bce->emit1(JSOP_POP)) // .
|
||||
@ -3563,7 +3562,7 @@ EmitDestructuringOpsArrayHelper(ExclusiveContext *cx, BytecodeEmitter *bce, Pars
|
||||
|
||||
if (elem->isKind(PNK_SPREAD)) {
|
||||
/* Create a new array with the rest of the iterator */
|
||||
ptrdiff_t off = EmitN(cx, bce, JSOP_NEWARRAY, 3); // ... OBJ? ITER ARRAY
|
||||
ptrdiff_t off = bce->emitN(JSOP_NEWARRAY, 3); // ... OBJ? ITER ARRAY
|
||||
if (off < 0)
|
||||
return false;
|
||||
CheckTypeSet(cx, bce, JSOP_NEWARRAY);
|
||||
@ -3593,7 +3592,7 @@ EmitDestructuringOpsArrayHelper(ExclusiveContext *cx, BytecodeEmitter *bce, Pars
|
||||
ptrdiff_t noteIndex = NewSrcNote(cx, bce, SRC_COND);
|
||||
if (noteIndex < 0)
|
||||
return false;
|
||||
ptrdiff_t beq = EmitJump(cx, bce, JSOP_IFEQ, 0);
|
||||
ptrdiff_t beq = bce->emitJump(JSOP_IFEQ, 0);
|
||||
if (beq < 0)
|
||||
return false;
|
||||
|
||||
@ -3603,7 +3602,7 @@ EmitDestructuringOpsArrayHelper(ExclusiveContext *cx, BytecodeEmitter *bce, Pars
|
||||
return false;
|
||||
|
||||
/* Jump around else, fixup the branch, emit else, fixup jump. */
|
||||
ptrdiff_t jmp = EmitJump(cx, bce, JSOP_GOTO, 0);
|
||||
ptrdiff_t jmp = bce->emitJump(JSOP_GOTO, 0);
|
||||
if (jmp < 0)
|
||||
return false;
|
||||
SetJumpOffsetAt(bce, beq);
|
||||
@ -3650,7 +3649,7 @@ EmitDestructuringOpsArrayHelper(ExclusiveContext *cx, BytecodeEmitter *bce, Pars
|
||||
bce->reportError(subpattern, JSMSG_TOO_MANY_LOCALS);
|
||||
return false;
|
||||
}
|
||||
if (!Emit2(cx, bce, JSOP_PICK, (jsbytecode)pickDistance))
|
||||
if (!bce->emit2(JSOP_PICK, (jsbytecode)pickDistance))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -3772,7 +3771,7 @@ EmitDestructuringOpsObjectHelper(ExclusiveContext *cx, BytecodeEmitter *bce, Par
|
||||
bce->reportError(subpattern, JSMSG_TOO_MANY_LOCALS);
|
||||
return false;
|
||||
}
|
||||
if (!Emit2(cx, bce, JSOP_PICK, (jsbytecode)pickDistance))
|
||||
if (!bce->emit2(JSOP_PICK, (jsbytecode)pickDistance))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -4172,7 +4171,7 @@ EmitAssignment(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *lhs, JSOp
|
||||
* the for-of case. If offset == 1, that slot is already at the top of
|
||||
* the stack. Otherwise, rearrange the stack to put that value on top.
|
||||
*/
|
||||
if (offset != 1 && !Emit2(cx, bce, JSOP_PICK, offset - 1))
|
||||
if (offset != 1 && !bce->emit2(JSOP_PICK, offset - 1))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -4469,7 +4468,7 @@ EmitCatch(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
// If the guard expression is false, fall through, pop the block scope,
|
||||
// and jump to the next catch block. Otherwise jump over that code and
|
||||
// pop the dupped exception.
|
||||
ptrdiff_t guardCheck = EmitJump(cx, bce, JSOP_IFNE, 0);
|
||||
ptrdiff_t guardCheck = bce->emitJump(JSOP_IFNE, 0);
|
||||
if (guardCheck < 0)
|
||||
return false;
|
||||
|
||||
@ -4486,7 +4485,7 @@ EmitCatch(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
return false;
|
||||
|
||||
// Jump to the next handler. The jump target is backpatched by EmitTry.
|
||||
ptrdiff_t guardJump = EmitJump(cx, bce, JSOP_GOTO, 0);
|
||||
ptrdiff_t guardJump = bce->emitJump(JSOP_GOTO, 0);
|
||||
if (guardJump < 0)
|
||||
return false;
|
||||
stmt->guardJump() = guardJump;
|
||||
@ -4712,7 +4711,7 @@ EmitIf(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
noteIndex = NewSrcNote(cx, bce, pn3 ? SRC_IF_ELSE : SRC_IF);
|
||||
if (noteIndex < 0)
|
||||
return false;
|
||||
beq = EmitJump(cx, bce, JSOP_IFEQ, 0);
|
||||
beq = bce->emitJump(JSOP_IFEQ, 0);
|
||||
if (beq < 0)
|
||||
return false;
|
||||
|
||||
@ -4869,13 +4868,13 @@ EmitIterator(ExclusiveContext *cx, BytecodeEmitter *bce)
|
||||
// Convert iterable to iterator.
|
||||
if (!bce->emit1(JSOP_DUP)) // OBJ OBJ
|
||||
return false;
|
||||
if (!Emit2(cx, bce, JSOP_SYMBOL, jsbytecode(JS::SymbolCode::iterator))) // OBJ OBJ @@ITERATOR
|
||||
if (!bce->emit2(JSOP_SYMBOL, jsbytecode(JS::SymbolCode::iterator))) // OBJ OBJ @@ITERATOR
|
||||
return false;
|
||||
if (!EmitElemOpBase(cx, bce, JSOP_CALLELEM)) // OBJ ITERFN
|
||||
return false;
|
||||
if (!bce->emit1(JSOP_SWAP)) // ITERFN OBJ
|
||||
return false;
|
||||
if (!EmitCall(cx, bce, JSOP_CALL, 0)) // ITER
|
||||
if (!bce->emitCall(JSOP_CALL, 0)) // ITER
|
||||
return false;
|
||||
CheckTypeSet(cx, bce, JSOP_CALL);
|
||||
return true;
|
||||
@ -4972,7 +4971,7 @@ EmitForOf(ExclusiveContext *cx, BytecodeEmitter *bce, StmtType type, ParseNode *
|
||||
int noteIndex = NewSrcNote(cx, bce, SRC_FOR_OF);
|
||||
if (noteIndex < 0)
|
||||
return false;
|
||||
ptrdiff_t jmp = EmitJump(cx, bce, JSOP_GOTO, 0);
|
||||
ptrdiff_t jmp = bce->emitJump(JSOP_GOTO, 0);
|
||||
if (jmp < 0)
|
||||
return false;
|
||||
|
||||
@ -5043,7 +5042,7 @@ EmitForOf(ExclusiveContext *cx, BytecodeEmitter *bce, StmtType type, ParseNode *
|
||||
if (!EmitAtomOp(cx, cx->names().done, JSOP_GETPROP, bce)) // ... RESULT DONE?
|
||||
return false;
|
||||
|
||||
ptrdiff_t beq = EmitJump(cx, bce, JSOP_IFEQ, top - bce->offset()); // ... RESULT
|
||||
ptrdiff_t beq = bce->emitJump(JSOP_IFEQ, top - bce->offset()); // ... RESULT
|
||||
if (beq < 0)
|
||||
return false;
|
||||
|
||||
@ -5064,7 +5063,7 @@ EmitForOf(ExclusiveContext *cx, BytecodeEmitter *bce, StmtType type, ParseNode *
|
||||
}
|
||||
|
||||
if (type == STMT_SPREAD) {
|
||||
if (!Emit2(cx, bce, JSOP_PICK, (jsbytecode)3)) // ARR I RESULT ITER
|
||||
if (!bce->emit2(JSOP_PICK, (jsbytecode)3)) // ARR I RESULT ITER
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -5095,7 +5094,7 @@ EmitForIn(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t t
|
||||
* destructuring for-in).
|
||||
*/
|
||||
MOZ_ASSERT(pn->isOp(JSOP_ITER));
|
||||
if (!Emit2(cx, bce, JSOP_ITER, (uint8_t) pn->pn_iflags))
|
||||
if (!bce->emit2(JSOP_ITER, (uint8_t) pn->pn_iflags))
|
||||
return false;
|
||||
|
||||
// For-in loops have both the iterator and the value on the stack. Push
|
||||
@ -5124,7 +5123,7 @@ EmitForIn(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t t
|
||||
* Jump down to the loop condition to minimize overhead assuming at
|
||||
* least one iteration, as the other loop forms do.
|
||||
*/
|
||||
ptrdiff_t jmp = EmitJump(cx, bce, JSOP_GOTO, 0);
|
||||
ptrdiff_t jmp = bce->emitJump(JSOP_GOTO, 0);
|
||||
if (jmp < 0)
|
||||
return false;
|
||||
|
||||
@ -5167,7 +5166,7 @@ EmitForIn(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t t
|
||||
return false;
|
||||
if (!bce->emit1(JSOP_ISNOITER))
|
||||
return false;
|
||||
ptrdiff_t beq = EmitJump(cx, bce, JSOP_IFEQ, top - bce->offset());
|
||||
ptrdiff_t beq = bce->emitJump(JSOP_IFEQ, top - bce->offset());
|
||||
if (beq < 0)
|
||||
return false;
|
||||
|
||||
@ -5235,7 +5234,7 @@ EmitNormalFor(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff
|
||||
ptrdiff_t jmp = -1;
|
||||
if (forHead->pn_kid2) {
|
||||
/* Goto the loop condition, which branches back to iterate. */
|
||||
jmp = EmitJump(cx, bce, JSOP_GOTO, 0);
|
||||
jmp = bce->emitJump(JSOP_GOTO, 0);
|
||||
if (jmp < 0)
|
||||
return false;
|
||||
} else {
|
||||
@ -5311,7 +5310,7 @@ EmitNormalFor(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff
|
||||
|
||||
/* If no loop condition, just emit a loop-closing jump. */
|
||||
op = forHead->pn_kid2 ? JSOP_IFNE : JSOP_GOTO;
|
||||
if (EmitJump(cx, bce, op, top - bce->offset()) < 0)
|
||||
if (bce->emitJump(op, top - bce->offset()) < 0)
|
||||
return false;
|
||||
|
||||
if (!bce->tryNoteList.append(JSTRY_LOOP, bce->stackDepth, top, bce->offset()))
|
||||
@ -5523,7 +5522,7 @@ EmitDo(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
if (!EmitTree(cx, bce, pn->pn_right))
|
||||
return false;
|
||||
|
||||
ptrdiff_t beq = EmitJump(cx, bce, JSOP_IFNE, top - bce->offset());
|
||||
ptrdiff_t beq = bce->emitJump(JSOP_IFNE, top - bce->offset());
|
||||
if (beq < 0)
|
||||
return false;
|
||||
|
||||
@ -5568,7 +5567,7 @@ EmitWhile(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t t
|
||||
if (noteIndex < 0)
|
||||
return false;
|
||||
|
||||
ptrdiff_t jmp = EmitJump(cx, bce, JSOP_GOTO, 0);
|
||||
ptrdiff_t jmp = bce->emitJump(JSOP_GOTO, 0);
|
||||
if (jmp < 0)
|
||||
return false;
|
||||
|
||||
@ -5585,7 +5584,7 @@ EmitWhile(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t t
|
||||
if (!EmitTree(cx, bce, pn->pn_left))
|
||||
return false;
|
||||
|
||||
ptrdiff_t beq = EmitJump(cx, bce, JSOP_IFNE, top - bce->offset());
|
||||
ptrdiff_t beq = bce->emitJump(JSOP_IFNE, top - bce->offset());
|
||||
if (beq < 0)
|
||||
return false;
|
||||
|
||||
@ -5841,7 +5840,7 @@ EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter, Parse
|
||||
if (!bce->emit1(JSOP_IN)) // EXCEPTION ITER THROW?
|
||||
return false;
|
||||
// if (THROW?) goto delegate
|
||||
ptrdiff_t checkThrow = EmitJump(cx, bce, JSOP_IFNE, 0); // EXCEPTION ITER
|
||||
ptrdiff_t checkThrow = bce->emitJump(JSOP_IFNE, 0); // EXCEPTION ITER
|
||||
if (checkThrow < 0)
|
||||
return false;
|
||||
if (!bce->emit1(JSOP_POP)) // EXCEPTION
|
||||
@ -5860,9 +5859,9 @@ EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter, Parse
|
||||
return false;
|
||||
if (!bce->emit1(JSOP_SWAP)) // EXCEPTION ITER THROW ITER
|
||||
return false;
|
||||
if (!Emit2(cx, bce, JSOP_PICK, (jsbytecode)3)) // ITER THROW ITER EXCEPTION
|
||||
if (!bce->emit2(JSOP_PICK, (jsbytecode)3)) // ITER THROW ITER EXCEPTION
|
||||
return false;
|
||||
if (!EmitCall(cx, bce, JSOP_CALL, 1, iter)) // ITER RESULT
|
||||
if (!bce->emitCall(JSOP_CALL, 1, iter)) // ITER RESULT
|
||||
return false;
|
||||
CheckTypeSet(cx, bce, JSOP_CALL);
|
||||
MOZ_ASSERT(bce->stackDepth == depth);
|
||||
@ -5897,9 +5896,9 @@ EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter, Parse
|
||||
return false;
|
||||
if (!bce->emit1(JSOP_SWAP)) // RECEIVED ITER NEXT ITER
|
||||
return false;
|
||||
if (!Emit2(cx, bce, JSOP_PICK, (jsbytecode)3)) // ITER NEXT ITER RECEIVED
|
||||
if (!bce->emit2(JSOP_PICK, (jsbytecode)3)) // ITER NEXT ITER RECEIVED
|
||||
return false;
|
||||
if (!EmitCall(cx, bce, JSOP_CALL, 1, iter)) // ITER RESULT
|
||||
if (!bce->emitCall(JSOP_CALL, 1, iter)) // ITER RESULT
|
||||
return false;
|
||||
CheckTypeSet(cx, bce, JSOP_CALL);
|
||||
MOZ_ASSERT(bce->stackDepth == depth);
|
||||
@ -5912,7 +5911,7 @@ EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter, Parse
|
||||
if (!EmitAtomOp(cx, cx->names().done, JSOP_GETPROP, bce)) // ITER RESULT DONE
|
||||
return false;
|
||||
// if (!DONE) goto tryStart;
|
||||
if (EmitJump(cx, bce, JSOP_IFEQ, tryStart - bce->offset()) < 0) // ITER RESULT
|
||||
if (bce->emitJump(JSOP_IFEQ, tryStart - bce->offset()) < 0) // ITER RESULT
|
||||
return false;
|
||||
|
||||
// result.value
|
||||
@ -6136,7 +6135,7 @@ EmitSelfHostedCallFunction(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode
|
||||
bce->emittingForInit = oldEmittingForInit;
|
||||
|
||||
uint32_t argc = pn->pn_count - 3;
|
||||
if (!EmitCall(cx, bce, pn->getOp(), argc))
|
||||
if (!bce->emitCall(pn->getOp(), argc))
|
||||
return false;
|
||||
|
||||
CheckTypeSet(cx, bce, pn->getOp());
|
||||
@ -6167,7 +6166,7 @@ EmitSelfHostedResumeGenerator(ExclusiveContext *cx, BytecodeEmitter *bce, ParseN
|
||||
uint16_t operand = GeneratorObject::getResumeKind(cx, kindNode->pn_atom);
|
||||
MOZ_ASSERT(!kindNode->pn_next);
|
||||
|
||||
if (!EmitCall(cx, bce, JSOP_RESUME, operand))
|
||||
if (!bce->emitCall(JSOP_RESUME, operand))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -6298,7 +6297,7 @@ EmitCallOrNew(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
bce->emittingForInit = oldEmittingForInit;
|
||||
|
||||
if (!spread) {
|
||||
if (!EmitCall(cx, bce, pn->getOp(), argc, pn))
|
||||
if (!bce->emitCall(pn->getOp(), argc, pn))
|
||||
return false;
|
||||
} else {
|
||||
if (!bce->emit1(pn->getOp()))
|
||||
@ -6339,7 +6338,7 @@ EmitLogical(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
ParseNode *pn2 = pn->pn_head;
|
||||
if (!EmitTree(cx, bce, pn2))
|
||||
return false;
|
||||
ptrdiff_t top = EmitJump(cx, bce, JSOP_BACKPATCH, 0);
|
||||
ptrdiff_t top = bce->emitJump(JSOP_BACKPATCH, 0);
|
||||
if (top < 0)
|
||||
return false;
|
||||
if (!bce->emit1(JSOP_POP))
|
||||
@ -6350,7 +6349,7 @@ EmitLogical(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
while ((pn2 = pn2->pn_next)->pn_next) {
|
||||
if (!EmitTree(cx, bce, pn2))
|
||||
return false;
|
||||
ptrdiff_t off = EmitJump(cx, bce, JSOP_BACKPATCH, 0);
|
||||
ptrdiff_t off = bce->emitJump(JSOP_BACKPATCH, 0);
|
||||
if (off < 0)
|
||||
return false;
|
||||
if (!bce->emit1(JSOP_POP))
|
||||
@ -6470,7 +6469,7 @@ EmitLabeledStatement(ExclusiveContext *cx, BytecodeEmitter *bce, const LabeledSt
|
||||
if (!bce->makeAtomIndex(pn->label(), &index))
|
||||
return false;
|
||||
|
||||
ptrdiff_t top = EmitJump(cx, bce, JSOP_LABEL, 0);
|
||||
ptrdiff_t top = bce->emitJump(JSOP_LABEL, 0);
|
||||
if (top < 0)
|
||||
return false;
|
||||
|
||||
@ -6513,12 +6512,12 @@ EmitConditionalExpression(ExclusiveContext *cx, BytecodeEmitter *bce, Conditiona
|
||||
ptrdiff_t noteIndex = NewSrcNote(cx, bce, SRC_COND);
|
||||
if (noteIndex < 0)
|
||||
return false;
|
||||
ptrdiff_t beq = EmitJump(cx, bce, JSOP_IFEQ, 0);
|
||||
ptrdiff_t beq = bce->emitJump(JSOP_IFEQ, 0);
|
||||
if (beq < 0 || !EmitTree(cx, bce, &conditional.thenExpression()))
|
||||
return false;
|
||||
|
||||
/* Jump around else, fixup the branch, emit else, fixup jump. */
|
||||
ptrdiff_t jmp = EmitJump(cx, bce, JSOP_GOTO, 0);
|
||||
ptrdiff_t jmp = bce->emitJump(JSOP_GOTO, 0);
|
||||
if (jmp < 0)
|
||||
return false;
|
||||
SetJumpOffsetAt(bce, beq);
|
||||
@ -6763,7 +6762,7 @@ EmitArray(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, uint32_t co
|
||||
nspread++;
|
||||
}
|
||||
|
||||
ptrdiff_t off = EmitN(cx, bce, JSOP_NEWARRAY, 3); // ARRAY
|
||||
ptrdiff_t off = bce->emitN(JSOP_NEWARRAY, 3); // ARRAY
|
||||
if (off < 0)
|
||||
return false;
|
||||
CheckTypeSet(cx, bce, JSOP_NEWARRAY);
|
||||
@ -6795,9 +6794,9 @@ EmitArray(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, uint32_t co
|
||||
if (pn2->isKind(PNK_SPREAD)) {
|
||||
if (!EmitIterator(cx, bce)) // ARRAY INDEX ITER
|
||||
return false;
|
||||
if (!Emit2(cx, bce, JSOP_PICK, (jsbytecode)2)) // INDEX ITER ARRAY
|
||||
if (!bce->emit2(JSOP_PICK, (jsbytecode)2)) // INDEX ITER ARRAY
|
||||
return false;
|
||||
if (!Emit2(cx, bce, JSOP_PICK, (jsbytecode)2)) // ITER ARRAY INDEX
|
||||
if (!bce->emit2(JSOP_PICK, (jsbytecode)2)) // ITER ARRAY INDEX
|
||||
return false;
|
||||
if (!EmitSpread(cx, bce)) // ARRAY INDEX
|
||||
return false;
|
||||
@ -6805,7 +6804,7 @@ EmitArray(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, uint32_t co
|
||||
if (!bce->emit1(JSOP_INITELEM_INC))
|
||||
return false;
|
||||
} else {
|
||||
off = EmitN(cx, bce, JSOP_INITELEM_ARRAY, 3);
|
||||
off = bce->emitN(JSOP_INITELEM_ARRAY, 3);
|
||||
if (off < 0)
|
||||
return false;
|
||||
SET_UINT24(bce->code(off), atomIndex);
|
||||
@ -6860,7 +6859,7 @@ EmitDefaults(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
// Emit source note to enable ion compilation.
|
||||
if (NewSrcNote(cx, bce, SRC_IF) < 0)
|
||||
return false;
|
||||
ptrdiff_t jump = EmitJump(cx, bce, JSOP_IFEQ, 0);
|
||||
ptrdiff_t jump = bce->emitJump(JSOP_IFEQ, 0);
|
||||
if (jump < 0)
|
||||
return false;
|
||||
if (!EmitTree(cx, bce, arg->expr()))
|
||||
|
@ -255,28 +255,25 @@ struct BytecodeEmitter
|
||||
bool reportStrictWarning(ParseNode *pn, unsigned errorNumber, ...);
|
||||
bool reportStrictModeError(ParseNode *pn, unsigned errorNumber, ...);
|
||||
|
||||
ptrdiff_t emitCheck(ptrdiff_t delta);
|
||||
|
||||
// Emit one bytecode.
|
||||
bool emit1(JSOp op);
|
||||
|
||||
// Emit two bytecodes, an opcode (op) with a byte of immediate operand
|
||||
// (op1).
|
||||
bool emit2(JSOp op, jsbytecode op1);
|
||||
|
||||
// Emit three bytecodes, an opcode with two bytes of immediate operands.
|
||||
bool emit3(JSOp op, jsbytecode op1, jsbytecode op2);
|
||||
|
||||
// Emit (1 + extra) bytecodes, for N bytes of op and its immediate operand.
|
||||
ptrdiff_t emitN(JSOp op, size_t extra);
|
||||
|
||||
ptrdiff_t emitJump(JSOp op, ptrdiff_t off);
|
||||
bool emitCall(JSOp op, uint16_t argc, ParseNode *pn = nullptr);
|
||||
};
|
||||
|
||||
/*
|
||||
* Emit two bytecodes, an opcode (op) with a byte of immediate operand (op1).
|
||||
*/
|
||||
bool
|
||||
Emit2(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op, jsbytecode op1);
|
||||
|
||||
/*
|
||||
* Emit three bytecodes, an opcode with two bytes of immediate operands.
|
||||
*/
|
||||
bool
|
||||
Emit3(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op, jsbytecode op1, jsbytecode op2);
|
||||
|
||||
/*
|
||||
* Emit (1 + extra) bytecodes, for N bytes of op and its immediate operand.
|
||||
*/
|
||||
ptrdiff_t
|
||||
EmitN(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op, size_t extra);
|
||||
|
||||
/*
|
||||
* Emit code into bce for the tree rooted at pn.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user