Bug 1147216 part 1 - Give JSOP_LINENO a 4-byte instead of 2-byte operand. r=luke

This commit is contained in:
Jan de Mooij 2015-04-10 11:38:50 +02:00
parent db3b77867f
commit 00300d588d
8 changed files with 61 additions and 17 deletions

View File

@ -523,15 +523,26 @@ BytecodeEmitter::checkTypeSet(JSOp op)
} }
bool bool
BytecodeEmitter::emitUint16Operand(JSOp op, uint32_t i) BytecodeEmitter::emitUint16Operand(JSOp op, uint32_t operand)
{ {
MOZ_ASSERT(i <= UINT16_MAX); MOZ_ASSERT(operand <= UINT16_MAX);
if (!emit3(op, UINT16_HI(i), UINT16_LO(i))) if (!emit3(op, UINT16_HI(operand), UINT16_LO(operand)))
return false; return false;
checkTypeSet(op); checkTypeSet(op);
return true; return true;
} }
bool
BytecodeEmitter::emitUint32Operand(JSOp op, uint32_t operand)
{
ptrdiff_t off;
if (!emitN(op, 4, &off))
return false;
SET_UINT32(code(off), operand);
checkTypeSet(op);
return true;
}
bool bool
BytecodeEmitter::flushPops(int* npops) BytecodeEmitter::flushPops(int* npops)
{ {
@ -6426,7 +6437,7 @@ BytecodeEmitter::emitCallOrNew(ParseNode* pn)
pn->isOp(JSOP_STRICTSPREADEVAL)) pn->isOp(JSOP_STRICTSPREADEVAL))
{ {
uint32_t lineNum = parser->tokenStream.srcCoords.lineNum(pn->pn_pos.begin); uint32_t lineNum = parser->tokenStream.srcCoords.lineNum(pn->pn_pos.begin);
if (!emitUint16Operand(JSOP_LINENO, lineNum)) if (!emitUint32Operand(JSOP_LINENO, lineNum))
return false; return false;
} }
if (pn->pn_xflags & PNX_SETCALL) { if (pn->pn_xflags & PNX_SETCALL) {

View File

@ -397,7 +397,10 @@ struct BytecodeEmitter
// Emit a bytecode followed by an uint16 immediate operand stored in // Emit a bytecode followed by an uint16 immediate operand stored in
// big-endian order. // big-endian order.
bool emitUint16Operand(JSOp op, uint32_t i); bool emitUint16Operand(JSOp op, uint32_t operand);
// Emit a bytecode followed by an uint32 immediate operand.
bool emitUint32Operand(JSOp op, uint32_t operand);
// Emit (1 + extra) bytecodes, for N bytes of op and its immediate operand. // Emit (1 + extra) bytecodes, for N bytes of op and its immediate operand.
bool emitN(JSOp op, size_t extra, ptrdiff_t* offset = nullptr); bool emitN(JSOp op, size_t extra, ptrdiff_t* offset = nullptr);

View File

@ -0,0 +1,14 @@
// Ensure JSOP_LINENO (emitted after JSOP_EVAL) handles big line
// numbers correctly.
function f() {
var s = "";
var stack;
for (var i=0; i<66002; i++) {
s += "\n";
if (i === 66000)
s += "eval('stack = Error().stack');";
}
eval(s);
assertEq(stack.indexOf("line 66002") > 0, true);
}
f();

View File

@ -1041,6 +1041,10 @@ js::Disassemble1(JSContext* cx, HandleScript script, jsbytecode* pc,
Sprint(sp, " %u", GET_LOCALNO(pc)); Sprint(sp, " %u", GET_LOCALNO(pc));
break; break;
case JOF_UINT32:
Sprint(sp, " %u", GET_UINT32(pc));
break;
{ {
int i; int i;

View File

@ -48,8 +48,8 @@ enum {
JOF_UINT8 = 13, /* uint8_t immediate, e.g. top 8 bits of 24-bit JOF_UINT8 = 13, /* uint8_t immediate, e.g. top 8 bits of 24-bit
atom index */ atom index */
JOF_INT32 = 14, /* int32_t immediate operand */ JOF_INT32 = 14, /* int32_t immediate operand */
JOF_OBJECT = 15, /* unsigned 16-bit object index */ JOF_UINT32 = 15, /* uint32_t immediate operand */
/* 16 is unused */ JOF_OBJECT = 16, /* unsigned 16-bit object index */
JOF_REGEXP = 17, /* unsigned 32-bit regexp index */ JOF_REGEXP = 17, /* unsigned 32-bit regexp index */
JOF_INT8 = 18, /* int8_t immediate operand */ JOF_INT8 = 18, /* int8_t immediate operand */
JOF_ATOMOBJECT = 19, /* uint16_t constant index + object index */ JOF_ATOMOBJECT = 19, /* uint16_t constant index + object index */
@ -222,8 +222,8 @@ GET_INT8(const jsbytecode* pc)
return int8_t(pc[1]); return int8_t(pc[1]);
} }
static MOZ_ALWAYS_INLINE int32_t static MOZ_ALWAYS_INLINE uint32_t
GET_INT32(const jsbytecode* pc) GET_UINT32(const jsbytecode* pc)
{ {
return (uint32_t(pc[1]) << 24) | return (uint32_t(pc[1]) << 24) |
(uint32_t(pc[2]) << 16) | (uint32_t(pc[2]) << 16) |
@ -232,12 +232,24 @@ GET_INT32(const jsbytecode* pc)
} }
static MOZ_ALWAYS_INLINE void static MOZ_ALWAYS_INLINE void
SET_INT32(jsbytecode* pc, uint32_t i) SET_UINT32(jsbytecode* pc, uint32_t u)
{ {
pc[1] = jsbytecode(uint32_t(i) >> 24); pc[1] = jsbytecode(u >> 24);
pc[2] = jsbytecode(uint32_t(i) >> 16); pc[2] = jsbytecode(u >> 16);
pc[3] = jsbytecode(uint32_t(i) >> 8); pc[3] = jsbytecode(u >> 8);
pc[4] = jsbytecode(uint32_t(i)); pc[4] = jsbytecode(u);
}
static MOZ_ALWAYS_INLINE int32_t
GET_INT32(const jsbytecode* pc)
{
return static_cast<int32_t>(GET_UINT32(pc));
}
static MOZ_ALWAYS_INLINE void
SET_INT32(jsbytecode* pc, int32_t i)
{
SET_UINT32(pc, static_cast<uint32_t>(i));
} }
/* Index limit is determined by SN_4BYTE_OFFSET_FLAG, see frontend/BytecodeEmitter.h. */ /* Index limit is determined by SN_4BYTE_OFFSET_FLAG, see frontend/BytecodeEmitter.h. */

View File

@ -2928,7 +2928,7 @@ js::DescribeScriptedCallerForCompilation(JSContext* cx, MutableHandleScript mayb
JSOp(*pc) == JSOP_STRICTSPREADEVAL; JSOp(*pc) == JSOP_STRICTSPREADEVAL;
MOZ_ASSERT(*(pc + (isSpread ? JSOP_SPREADEVAL_LENGTH : JSOP_EVAL_LENGTH)) == JSOP_LINENO); MOZ_ASSERT(*(pc + (isSpread ? JSOP_SPREADEVAL_LENGTH : JSOP_EVAL_LENGTH)) == JSOP_LINENO);
*file = maybeScript->filename(); *file = maybeScript->filename();
*linenop = GET_UINT16(pc + (JSOp(*pc) == JSOP_EVAL ? JSOP_EVAL_LENGTH *linenop = GET_UINT32(pc + (JSOp(*pc) == JSOP_EVAL ? JSOP_EVAL_LENGTH
: JSOP_SPREADEVAL_LENGTH)); : JSOP_SPREADEVAL_LENGTH));
*pcOffset = pc - maybeScript->code(); *pcOffset = pc - maybeScript->code();
*mutedErrors = maybeScript->mutedErrors(); *mutedErrors = maybeScript->mutedErrors();

View File

@ -1166,7 +1166,7 @@
* Operands: uint32_t lineno * Operands: uint32_t lineno
* Stack: => * Stack: =>
*/ \ */ \
macro(JSOP_LINENO, 119,"lineno", NULL, 3, 0, 0, JOF_UINT16) \ macro(JSOP_LINENO, 119,"lineno", NULL, 5, 0, 0, JOF_UINT32) \
\ \
/* /*
* This no-op appears after the bytecode for EXPR in 'switch (EXPR) {...}' * This no-op appears after the bytecode for EXPR in 'switch (EXPR) {...}'

View File

@ -29,7 +29,7 @@ namespace js {
* *
* https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode * https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode
*/ */
static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 275; static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 276;
static const uint32_t XDR_BYTECODE_VERSION = static const uint32_t XDR_BYTECODE_VERSION =
uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND); uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND);