Bug 720316 - Convert the various object and function indexes into uint32_t. r=jorendorff

--HG--
extra : rebase_source : 179deea8ca29b157b88658ccde6eabd6df48fab2
This commit is contained in:
Jeff Walden 2012-01-19 17:15:33 -08:00
parent d9caec48a5
commit 2261405ba1
15 changed files with 151 additions and 176 deletions

View File

@ -565,7 +565,7 @@ CheckTypeSet(JSContext *cx, BytecodeEmitter *bce, JSOp op)
ptrdiff_t off_ = EmitN(cx, bce, op, 2 * UINT16_LEN); \
if (off_ < 0) \
return JS_FALSE; \
jsbytecode *pc_ = bce->code(off_); \
jsbytecode *pc_ = bce->code(off_); \
SET_UINT16(pc_, i); \
pc_ += UINT16_LEN; \
SET_UINT16(pc_, j); \
@ -573,9 +573,18 @@ CheckTypeSet(JSContext *cx, BytecodeEmitter *bce, JSOp op)
#define EMIT_UINT16_IN_PLACE(offset, op, i) \
JS_BEGIN_MACRO \
bce->code(offset)[0] = op; \
bce->code(offset)[1] = UINT16_HI(i); \
bce->code(offset)[2] = UINT16_LO(i); \
bce->code(offset)[0] = op; \
bce->code(offset)[1] = UINT16_HI(i); \
bce->code(offset)[2] = UINT16_LO(i); \
JS_END_MACRO
#define EMIT_UINT32_IN_PLACE(offset, op, i) \
JS_BEGIN_MACRO \
bce->code(offset)[0] = op; \
bce->code(offset)[1] = jsbytecode(i >> 24); \
bce->code(offset)[2] = jsbytecode(i >> 16); \
bce->code(offset)[3] = jsbytecode(i >> 8); \
bce->code(offset)[4] = jsbytecode(i); \
JS_END_MACRO
static JSBool
@ -970,17 +979,11 @@ EmitAtomOp(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce, JSOp *ps
return EmitAtomOp(cx, pn->pn_atom, op, bce, psuffix);
}
static JSBool
EmitObjectOp(JSContext *cx, ObjectBox *objbox, JSOp op, BytecodeEmitter *bce)
{
JS_ASSERT(JOF_OPTYPE(op) == JOF_OBJECT);
return EmitIndexOp(cx, op, bce->objectList.index(objbox), bce);
}
static bool
EmitIndex32(JSContext *cx, JSOp op, uint32_t index, BytecodeEmitter *bce)
{
const size_t len = 1 + UINT32_INDEX_LEN;
JS_ASSERT(js_CodeSpec[op].length == len);
ptrdiff_t offset = EmitCheck(cx, bce, len);
if (offset < 0)
return false;
@ -994,43 +997,39 @@ EmitIndex32(JSContext *cx, JSOp op, uint32_t index, BytecodeEmitter *bce)
return true;
}
static bool
EmitFunctionOp(JSContext *cx, JSOp op, uint32_t index, BytecodeEmitter *bce)
{
return EmitIndex32(cx, op, index, bce);
}
static bool
EmitObjectOp(JSContext *cx, ObjectBox *objbox, JSOp op, BytecodeEmitter *bce)
{
JS_ASSERT(JOF_OPTYPE(op) == JOF_OBJECT);
return EmitIndex32(cx, op, bce->objectList.index(objbox), bce);
}
static bool
EmitRegExp(JSContext *cx, uint32_t index, BytecodeEmitter *bce)
{
return EmitIndex32(cx, JSOP_REGEXP, index, bce);
}
/*
* What good are ARGNO_LEN and SLOTNO_LEN, you ask? The answer is that, apart
* from EmitSlotIndexOp, they abstract out the detail that both are 2, and in
* other parts of the code there's no necessary relationship between the two.
* The abstraction cracks here in order to share EmitSlotIndexOp code among
* the JSOP_DEFLOCALFUN and JSOP_GET{ARG,VAR,LOCAL}PROP cases.
*/
JS_STATIC_ASSERT(ARGNO_LEN == 2);
JS_STATIC_ASSERT(SLOTNO_LEN == 2);
static JSBool
EmitSlotIndexOp(JSContext *cx, JSOp op, uintN slot, uintN index, BytecodeEmitter *bce)
static bool
EmitSlotObjectOp(JSContext *cx, JSOp op, uintN slot, uint32_t index, BytecodeEmitter *bce)
{
JSOp bigSuffix;
ptrdiff_t off;
jsbytecode *pc;
JS_ASSERT(JOF_OPTYPE(op) == JOF_SLOTOBJECT);
bigSuffix = EmitBigIndexPrefix(cx, bce, index);
if (bigSuffix == JSOP_FALSE)
return JS_FALSE;
/* Emit [op, slot, index]. */
off = EmitN(cx, bce, op, 2 + INDEX_LEN);
ptrdiff_t off = EmitN(cx, bce, op, SLOTNO_LEN + UINT32_INDEX_LEN);
if (off < 0)
return JS_FALSE;
pc = bce->code(off);
return false;
jsbytecode *pc = bce->code(off);
SET_UINT16(pc, slot);
pc += 2;
SET_INDEX(pc, index);
return bigSuffix == JSOP_NOP || Emit1(cx, bce, bigSuffix) >= 0;
pc += SLOTNO_LEN;
SET_UINT32_INDEX(pc, index);
return true;
}
bool
@ -3910,8 +3909,19 @@ EmitFunctionDefNop(JSContext *cx, BytecodeEmitter *bce, uintN index)
static bool
EmitNewInit(JSContext *cx, BytecodeEmitter *bce, JSProtoKey key, ParseNode *pn)
{
if (Emit3(cx, bce, JSOP_NEWINIT, (jsbytecode) key, 0) < 0)
const size_t len = 1 + UINT32_INDEX_LEN;
ptrdiff_t offset = EmitCheck(cx, bce, len);
if (offset < 0)
return false;
jsbytecode *next = bce->next();
next[0] = JSOP_NEWINIT;
next[1] = jsbytecode(key);
next[2] = 0;
next[3] = 0;
next[4] = 0;
bce->current->next = next + len;
UpdateDepth(cx, bce, offset);
CheckTypeSet(cx, bce, JSOP_NEWINIT);
return true;
}
@ -5109,8 +5119,8 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
{
return false;
}
EMIT_INDEX_OP(pn->getOp(), index);
return true;
return EmitFunctionOp(cx, pn->getOp(), index, bce);
}
/*
@ -5129,7 +5139,8 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
if (pn->pn_cookie.isFree()) {
bce->switchToProlog();
JSOp op = fun->isFlatClosure() ? JSOP_DEFFUN_FC : JSOP_DEFFUN;
EMIT_INDEX_OP(op, index);
if (!EmitFunctionOp(cx, op, index, bce))
return false;
bce->switchToMain();
}
@ -5149,7 +5160,7 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
{
return false;
}
return EmitSlotIndexOp(cx, op, slot, index, bce);
return EmitSlotObjectOp(cx, op, slot, index, bce);
}
return true;
@ -6046,8 +6057,11 @@ EmitObject(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
if (!objbox)
return false;
uintN index = bce->objectList.index(objbox);
if (FitsWithoutBigIndex(index))
EMIT_UINT16_IN_PLACE(offset, JSOP_NEWOBJECT, uint16_t(index));
if (FitsWithoutBigIndex(index)) {
MOZ_STATIC_ASSERT(JSOP_NEWINIT_LENGTH == JSOP_NEWOBJECT_LENGTH,
"newinit and newobject must have equal length to edit in-place");
EMIT_UINT32_IN_PLACE(offset, JSOP_NEWOBJECT, uint32_t(index));
}
}
return true;

View File

@ -0,0 +1,9 @@
try { }
catch (e) { }
try { throw 2; }
catch (e)
{
try { throw 3; }
catch (e2) { }
}

View File

@ -3,7 +3,7 @@ setDebug(true);
x = "notset";
function main() {
/* The JSOP_STOP in main. */
a = { valueOf: function () { trap(main, 34, "success()"); } };
a = { valueOf: function () { trap(main, 39, "success()"); } };
a + "";
x = "failure";
}

View File

@ -3,7 +3,7 @@ setDebug(true);
x = "notset";
function main() {
/* The JSOP_STOP in main. */
a = { valueOf: function () { trap(main, 55, "success()"); } };
a = { valueOf: function () { trap(main, 60, "success()"); } };
b = "";
eval();
a + b;

View File

@ -119,7 +119,7 @@ ScriptAnalysis::checkAliasedName(JSContext *cx, jsbytecode *pc)
JSAtom *atom;
if (JSOp(*pc) == JSOP_DEFFUN) {
JSFunction *fun = script->getFunction(js_GetIndexFromBytecode(script, pc, 0));
JSFunction *fun = script->getFunction(GET_UINT32_INDEX(pc));
atom = fun->atom;
} else {
JS_ASSERT(JOF_TYPE(js_CodeSpec[*pc].format) == JOF_ATOM);

View File

@ -2026,7 +2026,7 @@ TypeCompartment::newAllocationSiteTypeObject(JSContext *cx, const AllocationSite
* observed by other code before all properties have been added. Mark
* all the properties as definite properties of the object.
*/
JSObject *baseobj = key.script->getObject(GET_SLOTNO(pc));
JSObject *baseobj = key.script->getObject(GET_UINT32_INDEX(pc));
if (!res->addDefiniteProperties(cx, baseobj))
return NULL;
@ -2047,13 +2047,6 @@ GetAtomId(JSContext *cx, JSScript *script, const jsbytecode *pc, unsigned offset
return MakeTypeId(cx, ATOM_TO_JSID(script->getAtom(index)));
}
static inline JSObject *
GetScriptObject(JSContext *cx, JSScript *script, const jsbytecode *pc, unsigned offset)
{
unsigned index = js_GetIndexFromBytecode(script, (jsbytecode*) pc, offset);
return script->getObject(index);
}
static inline const Value &
GetScriptConst(JSContext *cx, JSScript *script, const jsbytecode *pc)
{
@ -3528,7 +3521,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset,
break;
case JSOP_OBJECT: {
JSObject *obj = GetScriptObject(cx, script, pc, 0);
JSObject *obj = script->getObject(GET_UINT32_INDEX(pc));
pushed[0].addType(cx, Type::ObjectType(obj));
break;
}
@ -3833,7 +3826,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset,
case JSOP_DEFLOCALFUN:
case JSOP_DEFLOCALFUN_FC: {
unsigned off = (op == JSOP_DEFLOCALFUN || op == JSOP_DEFLOCALFUN_FC) ? SLOTNO_LEN : 0;
JSObject *obj = GetScriptObject(cx, script, pc, off);
JSObject *obj = script->getObject(GET_UINT32_INDEX(pc + off));
TypeSet *res = NULL;
if (op == JSOP_LAMBDA || op == JSOP_LAMBDA_FC) {

View File

@ -1435,12 +1435,6 @@ js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode)
#define GET_FULL_INDEX(PCOFF) \
(atoms - script->atoms + GET_INDEX(regs.pc + (PCOFF)))
#define LOAD_OBJECT(PCOFF, obj) \
(obj = script->getObject(GET_FULL_INDEX(PCOFF)))
#define LOAD_FUNCTION(PCOFF) \
(fun = script->getFunction(GET_FULL_INDEX(PCOFF)))
#define LOAD_DOUBLE(PCOFF, dbl) \
(dbl = script->getConst(GET_FULL_INDEX(PCOFF)).toDouble())
@ -2941,9 +2935,7 @@ END_CASE(JSOP_STRING)
BEGIN_CASE(JSOP_OBJECT)
{
JSObject *obj;
LOAD_OBJECT(0, obj);
PUSH_OBJECT(*obj);
PUSH_OBJECT(*script->getObject(GET_UINT32_INDEX(regs.pc)));
}
END_CASE(JSOP_OBJECT)
@ -3222,8 +3214,7 @@ BEGIN_CASE(JSOP_DEFFUN)
* a compound statement (not at the top statement level of global code, or
* at the top level of a function body).
*/
JSFunction *fun;
LOAD_FUNCTION(0);
JSFunction *fun = script->getFunction(GET_UINT32_INDEX(regs.pc));
JSObject *obj = fun;
JSObject *obj2;
@ -3332,8 +3323,7 @@ END_CASE(JSOP_DEFFUN)
BEGIN_CASE(JSOP_DEFFUN_FC)
{
JSFunction *fun;
LOAD_FUNCTION(0);
JSFunction *fun = script->getFunction(GET_UINT32_INDEX(regs.pc));
JSObject *obj = js_NewFlatClosure(cx, fun);
if (!obj)
@ -3369,8 +3359,7 @@ BEGIN_CASE(JSOP_DEFLOCALFUN)
* JSOP_DEFFUN that avoids requiring a call object for the outer function's
* activation.
*/
JSFunction *fun;
LOAD_FUNCTION(SLOTNO_LEN);
JSFunction *fun = script->getFunction(GET_UINT32_INDEX(regs.pc + SLOTNO_LEN));
JS_ASSERT(fun->isInterpreted());
JS_ASSERT(!fun->isFlatClosure());
@ -3395,8 +3384,7 @@ END_CASE(JSOP_DEFLOCALFUN)
BEGIN_CASE(JSOP_DEFLOCALFUN_FC)
{
JSFunction *fun;
LOAD_FUNCTION(SLOTNO_LEN);
JSFunction *fun = script->getFunction(GET_UINT32_INDEX(regs.pc + SLOTNO_LEN));
JSObject *obj = js_NewFlatClosure(cx, fun);
if (!obj)
@ -3410,8 +3398,7 @@ END_CASE(JSOP_DEFLOCALFUN_FC)
BEGIN_CASE(JSOP_LAMBDA)
{
/* Load the specified function object literal. */
JSFunction *fun;
LOAD_FUNCTION(0);
JSFunction *fun = script->getFunction(GET_UINT32_INDEX(regs.pc));
JSObject *obj = fun;
/* do-while(0) so we can break instead of using a goto. */
@ -3504,8 +3491,7 @@ END_CASE(JSOP_LAMBDA)
BEGIN_CASE(JSOP_LAMBDA_FC)
{
JSFunction *fun;
LOAD_FUNCTION(0);
JSFunction *fun = script->getFunction(GET_UINT32_INDEX(regs.pc));
JSObject *obj = js_NewFlatClosure(cx, fun);
if (!obj)
@ -3682,8 +3668,7 @@ END_CASE(JSOP_NEWARRAY)
BEGIN_CASE(JSOP_NEWOBJECT)
{
JSObject *baseobj;
LOAD_OBJECT(0, baseobj);
JSObject *baseobj = script->getObject(GET_UINT32_INDEX(regs.pc));
TypeObject *type = TypeScript::InitObject(cx, script, regs.pc, JSProto_Object);
if (!type)
@ -4229,9 +4214,7 @@ BEGIN_CASE(JSOP_ENTERBLOCK)
BEGIN_CASE(JSOP_ENTERLET0)
BEGIN_CASE(JSOP_ENTERLET1)
{
JSObject *obj;
LOAD_OBJECT(0, obj);
StaticBlockObject &blockObj = obj->asStaticBlock();
StaticBlockObject &blockObj = script->getObject(GET_UINT32_INDEX(regs.pc))->asStaticBlock();
JS_ASSERT(regs.fp()->maybeBlockChain() == blockObj.enclosingBlock());
if (op == JSOP_ENTERBLOCK) {

View File

@ -149,6 +149,7 @@ js_GetIndexFromBytecode(JSScript *script, jsbytecode *pc, ptrdiff_t pcoff)
{
JSOp op = JSOp(*pc);
JS_ASSERT(js_CodeSpec[op].length >= 1 + pcoff + UINT16_LEN);
JS_ASSERT(js_CodeSpec[op].format & JOF_ATOM);
/*
* We need to detect index base prefix. It presents when resetbase
@ -204,9 +205,7 @@ NumBlockSlots(JSScript *script, jsbytecode *pc)
JS_STATIC_ASSERT(JSOP_ENTERBLOCK_LENGTH == JSOP_ENTERLET0_LENGTH);
JS_STATIC_ASSERT(JSOP_ENTERBLOCK_LENGTH == JSOP_ENTERLET1_LENGTH);
JSObject *obj = NULL;
GET_OBJECT_FROM_BYTECODE(script, pc, 0, obj);
return obj->asStaticBlock().slotCount();
return script->getObject(GET_UINT32_INDEX(pc))->asStaticBlock().slotCount();
}
uintN
@ -541,7 +540,7 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
Sprint(sp, "%4u", JS_PCToLineNumber(cx, script, pc));
Sprint(sp, " %s", js_CodeName[op]);
switch (uint32_t type = JOF_TYPE(cs->format)) {
switch (JOF_TYPE(cs->format)) {
case JOF_BYTE:
// Scan the trynotes to find the associated catch block
// and make the try opcode look like a jump instruction
@ -568,28 +567,14 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
break;
}
case JOF_ATOM:
case JOF_OBJECT: {
case JOF_ATOM: {
uintN index = js_GetIndexFromBytecode(script, pc, 0);
jsval v;
if (type == JOF_ATOM) {
if (op == JSOP_DOUBLE) {
v = script->getConst(index);
} else {
JSAtom *atom = script->getAtom(index);
v = STRING_TO_JSVAL(atom);
}
if (op == JSOP_DOUBLE) {
v = script->getConst(index);
} else {
JS_ASSERT(type == JOF_OBJECT);
/* Don't call obj.toSource if analysis/inference is active. */
if (cx->compartment->activeAnalysis) {
Sprint(sp, " object");
break;
}
JSObject *obj = script->getObject(index);
v = OBJECT_TO_JSVAL(obj);
JSAtom *atom = script->getAtom(index);
v = STRING_TO_JSVAL(atom);
}
{
JSAutoByteString bytes;
@ -600,6 +585,23 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
break;
}
case JOF_OBJECT: {
/* Don't call obj.toSource if analysis/inference is active. */
if (cx->compartment->activeAnalysis) {
Sprint(sp, " object");
break;
}
JSObject *obj = script->getObject(GET_UINT32_INDEX(pc));
{
JSAutoByteString bytes;
if (!ToDisassemblySource(cx, ObjectValue(*obj), &bytes))
return 0;
Sprint(sp, " %s", bytes.ptr());
}
break;
}
case JOF_REGEXP: {
JSObject *obj = script->getRegExp(GET_UINT32_INDEX(pc));
JSAutoByteString bytes;
@ -664,10 +666,9 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
case JOF_SLOTOBJECT: {
Sprint(sp, " %u", GET_SLOTNO(pc));
uintN index = js_GetIndexFromBytecode(script, pc, SLOTNO_LEN);
jsval v = OBJECT_TO_JSVAL(script->getObject(index));
JSObject *obj = script->getObject(GET_UINT32_INDEX(pc + SLOTNO_LEN));
JSAutoByteString bytes;
if (!ToDisassemblySource(cx, v, &bytes))
if (!ToDisassemblySource(cx, ObjectValue(*obj), &bytes))
return 0;
Sprint(sp, " %s", bytes.ptr());
break;
@ -1857,8 +1858,7 @@ GetLocal(SprintStack *ss, jsint i)
JS_ASSERT(pc < (ss->printer->script->code + ss->printer->script->length));
if (JSOP_ENTERBLOCK == (JSOp)*pc) {
jsatomid j = js_GetIndexFromBytecode(ss->printer->script, pc, 0);
JSObject *obj = script->getObject(j);
JSObject *obj = script->getObject(GET_UINT32_INDEX(pc));
if (obj->isBlock()) {
uint32_t depth = obj->asBlock().stackDepth();
@ -2660,12 +2660,6 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
return NULL; \
JS_END_MACRO
#define LOAD_OBJECT(PCOFF) \
GET_OBJECT_FROM_BYTECODE(jp->script, pc, PCOFF, obj)
#define LOAD_FUNCTION(PCOFF) \
GET_FUNCTION_FROM_BYTECODE(jp->script, pc, PCOFF, fun)
#define GET_SOURCE_NOTE_ATOM(sn, atom) \
JS_BEGIN_MACRO \
jsatomid atomIndex_ = (jsatomid) js_GetSrcNoteOffset((sn), 0); \
@ -2736,9 +2730,8 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
if (cs->format & JOF_INDEXBASE) {
/*
* The decompiler uses js_GetIndexFromBytecode to get atoms and
* objects and ignores these suffix/prefix bytecodes, thus
* simplifying code that must process JSOP_GETTER/JSOP_SETTER
* prefixes.
* ignores these suffix/prefix bytecodes, thus simplifying code
* that must process JSOP_GETTER/JSOP_SETTER prefixes.
*/
pc += cs->length;
if (pc >= endpc)
@ -3292,7 +3285,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
case JSOP_ENTERBLOCK:
{
LOAD_OBJECT(0);
obj = jp->script->getObject(GET_UINT32_INDEX(pc));
AtomVector atoms(cx);
StaticBlockObject &blockObj = obj->asStaticBlock();
@ -3435,7 +3428,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
case JSOP_ENTERLET0:
{
LOAD_OBJECT(0);
obj = jp->script->getObject(GET_UINT32_INDEX(pc));
StaticBlockObject &blockObj = obj->asStaticBlock();
AtomVector atoms(cx);
@ -3554,7 +3547,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
*/
case JSOP_ENTERLET1:
{
LOAD_OBJECT(0);
obj = jp->script->getObject(GET_UINT32_INDEX(pc));
StaticBlockObject &blockObj = obj->asStaticBlock();
AtomVector atoms(cx);
@ -4229,7 +4222,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
ptrdiff_t offsetToLet = js_GetSrcNoteOffset(sn, 0);
LOCAL_ASSERT(*(pc + offsetToLet) == JSOP_ENTERLET0);
GET_OBJECT_FROM_BYTECODE(jp->script, pc + offsetToLet, 0, obj);
obj = jp->script->getObject(GET_UINT32_INDEX(pc + offsetToLet));
StaticBlockObject &blockObj = obj->asStaticBlock();
uint32_t blockDepth = blockObj.stackDepth();
@ -4776,7 +4769,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
SprintStack ss2(cx);
JSFunction *outerfun;
LOAD_FUNCTION(0);
fun = jp->script->getFunction(GET_UINT32_INDEX(pc));
/*
* All allocation when decompiling is LIFO, using malloc or,
@ -4902,7 +4895,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
#endif /* JS_HAS_GENERATOR_EXPRS */
/* FALL THROUGH */
LOAD_FUNCTION(0);
fun = jp->script->getFunction(GET_UINT32_INDEX(pc));
{
/*
* Always parenthesize expression closures. We can't force
@ -4928,7 +4921,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
break;
case JSOP_OBJECT:
LOAD_OBJECT(0);
obj = jp->script->getObject(GET_UINT32_INDEX(pc));
str = js_ValueToSource(cx, ObjectValue(*obj));
if (!str)
return NULL;
@ -5132,7 +5125,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
case JSOP_DEFFUN:
case JSOP_DEFFUN_FC:
LOAD_FUNCTION(0);
fun = jp->script->getFunction(GET_UINT32_INDEX(pc));
todo = -2;
goto do_function;
break;

View File

@ -207,11 +207,10 @@ SET_UINT32_INDEX(jsbytecode *pc, uint32_t index)
}
/*
* A literal is indexed by a per-script atom or object maps. Most scripts
* have relatively few literals, so the standard JOF_ATOM and JOF_OBJECT
* format specifies a fixed 16 bits of immediate operand index.
* A script with more than 64K literals must wrap the bytecode into
* JSOP_INDEXBASE and JSOP_RESETBASE pair.
* A literal is indexed by a per-script atom map. Most scripts have relatively
* few literals, so the standard JOF_ATOM format specifies a fixed 16 bits of
* immediate operand index. A script with more than 64K literals must wrap the
* bytecode into an JSOP_INDEXBASE and JSOP_RESETBASE pair.
*/
#define INDEX_LEN 2
#define INDEX_HI(i) ((jsbytecode)((i) >> 8))
@ -360,18 +359,6 @@ js_GetIndexFromBytecode(JSScript *script, jsbytecode *pc, ptrdiff_t pcoff);
(dbl) = (script)->getConst(index_).toDouble(); \
JS_END_MACRO
#define GET_OBJECT_FROM_BYTECODE(script, pc, pcoff, obj) \
JS_BEGIN_MACRO \
uintN index_ = js_GetIndexFromBytecode((script), (pc), (pcoff)); \
obj = (script)->getObject(index_); \
JS_END_MACRO
#define GET_FUNCTION_FROM_BYTECODE(script, pc, pcoff, fun) \
JS_BEGIN_MACRO \
uintN index_ = js_GetIndexFromBytecode((script), (pc), (pcoff)); \
fun = (script)->getFunction(index_); \
JS_END_MACRO
#ifdef __cplusplus
namespace js {

View File

@ -224,7 +224,7 @@ OPDEF(JSOP_ENDITER, 78, "enditer", NULL, 1, 1, 0, 0, JOF_BYTE)
OPDEF(JSOP_FUNAPPLY, 79, "funapply", NULL, 3, -1, 1, 18, JOF_UINT16|JOF_INVOKE|JOF_TYPESET)
/* Push object literal: either an XML object or initialiser object. */
OPDEF(JSOP_OBJECT, 80, "object", NULL, 3, 0, 1, 19, JOF_OBJECT)
OPDEF(JSOP_OBJECT, 80, "object", NULL, 5, 0, 1, 19, JOF_OBJECT)
/* Pop value and discard it. */
OPDEF(JSOP_POP, 81, "pop", NULL, 1, 1, 0, 2, JOF_BYTE)
@ -251,9 +251,9 @@ OPDEF(JSOP_UINT16, 88, "uint16", NULL, 3, 0, 1, 16, JOF_UINT16
* shape, which can be set at the start and slots then filled in directly.
* NEWINIT has an extra byte so it can be exchanged with NEWOBJECT during emit.
*/
OPDEF(JSOP_NEWINIT, 89, "newinit", NULL, 3, 0, 1, 19, JOF_UINT8|JOF_TYPESET)
OPDEF(JSOP_NEWINIT, 89, "newinit", NULL, 5, 0, 1, 19, JOF_UINT8|JOF_TYPESET)
OPDEF(JSOP_NEWARRAY, 90, "newarray", NULL, 4, 0, 1, 19, JOF_UINT24|JOF_TYPESET)
OPDEF(JSOP_NEWOBJECT, 91, "newobject", NULL, 3, 0, 1, 19, JOF_OBJECT|JOF_TYPESET)
OPDEF(JSOP_NEWOBJECT, 91, "newobject", NULL, 5, 0, 1, 19, JOF_OBJECT|JOF_TYPESET)
OPDEF(JSOP_ENDINIT, 92, "endinit", NULL, 1, 0, 0, 19, JOF_BYTE)
OPDEF(JSOP_INITPROP, 93, "initprop", NULL, 3, 2, 1, 3, JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING)
OPDEF(JSOP_INITELEM, 94, "initelem", NULL, 1, 3, 1, 3, JOF_BYTE|JOF_ELEM|JOF_SET|JOF_DETECTING)
@ -338,12 +338,12 @@ OPDEF(JSOP_SETTER, 126,js_setter_str,NULL, 1, 0, 0, 0, JOF_BYTE)
/*
* Prolog bytecodes for defining function, var, and const names.
*/
OPDEF(JSOP_DEFFUN, 127,"deffun", NULL, 3, 0, 0, 0, JOF_OBJECT|JOF_DECLARING)
OPDEF(JSOP_DEFFUN, 127,"deffun", NULL, 5, 0, 0, 0, JOF_OBJECT|JOF_DECLARING)
OPDEF(JSOP_DEFCONST, 128,"defconst", NULL, 3, 0, 0, 0, JOF_ATOM|JOF_DECLARING)
OPDEF(JSOP_DEFVAR, 129,"defvar", NULL, 3, 0, 0, 0, JOF_ATOM|JOF_DECLARING)
/* Push a closure for a named or anonymous function expression. */
OPDEF(JSOP_LAMBDA, 130, "lambda", NULL, 3, 0, 1, 19, JOF_OBJECT)
OPDEF(JSOP_LAMBDA, 130, "lambda", NULL, 5, 0, 1, 19, JOF_OBJECT)
/* Used for named function expression self-naming, if lightweight. */
OPDEF(JSOP_CALLEE, 131, "callee", NULL, 1, 0, 1, 19, JOF_BYTE)
@ -377,7 +377,7 @@ OPDEF(JSOP_CALLFCSLOT, 137,"callfcslot", NULL, 3, 0, 1, 19, JOF_UINT16
* The local variable's slot number is the first immediate two-byte operand.
* The function object's atom index is the second immediate operand.
*/
OPDEF(JSOP_DEFLOCALFUN, 138,"deflocalfun",NULL, 5, 0, 0, 0, JOF_SLOTOBJECT|JOF_DECLARING|JOF_TMPSLOT)
OPDEF(JSOP_DEFLOCALFUN, 138,"deflocalfun",NULL, 7, 0, 0, 0, JOF_SLOTOBJECT|JOF_DECLARING|JOF_TMPSLOT)
/* Extended jumps. */
OPDEF(JSOP_UNUSED4, 139,"unused4", NULL, 1, 0, 0, 0, JOF_BYTE)
@ -441,10 +441,10 @@ OPDEF(JSOP_DELDESC, 183,"deldesc", NULL, 1, 2, 1, 15, JOF_BYTE|J
OPDEF(JSOP_CALLPROP, 184,"callprop", NULL, 3, 1, 1, 18, JOF_ATOM|JOF_PROP|JOF_TYPESET|JOF_TMPSLOT3)
/* Enter a let block/expr whose slots are at the top of the stack. */
OPDEF(JSOP_ENTERLET0, 185,"enterlet0", NULL, 3, -1, -1, 0, JOF_OBJECT)
OPDEF(JSOP_ENTERLET0, 185,"enterlet0", NULL, 5, -1, -1, 0, JOF_OBJECT)
/* Enter a let block/expr whose slots are 1 below the top of the stack. */
OPDEF(JSOP_ENTERLET1, 186,"enterlet1", NULL, 3, -1, -1, 0, JOF_OBJECT)
OPDEF(JSOP_ENTERLET1, 186,"enterlet1", NULL, 5, -1, -1, 0, JOF_OBJECT)
/*
* Opcode to hold 24-bit immediate integer operands.
@ -491,7 +491,7 @@ OPDEF(JSOP_TYPEOFEXPR, 197,"typeofexpr", NULL, 1, 1, 1, 15, JOF_BYTE|J
/*
* Block-local scope support.
*/
OPDEF(JSOP_ENTERBLOCK, 198,"enterblock", NULL, 3, 0, -1, 0, JOF_OBJECT)
OPDEF(JSOP_ENTERBLOCK, 198,"enterblock", NULL, 5, 0, -1, 0, JOF_OBJECT)
OPDEF(JSOP_LEAVEBLOCK, 199,"leaveblock", NULL, 3, -1, 0, 0, JOF_UINT16)
@ -555,9 +555,9 @@ OPDEF(JSOP_HOLE, 218, "hole", NULL, 1, 0, 1, 0, JOF_BYTE)
/*
* Variants of JSOP_{DEF{,LOCAL}FUN,LAMBDA} optimized for the flat closure case.
*/
OPDEF(JSOP_DEFFUN_FC, 219,"deffun_fc", NULL, 3, 0, 0, 0, JOF_OBJECT|JOF_DECLARING)
OPDEF(JSOP_DEFLOCALFUN_FC,220,"deflocalfun_fc",NULL, 5, 0, 0, 0, JOF_SLOTOBJECT|JOF_DECLARING|JOF_TMPSLOT)
OPDEF(JSOP_LAMBDA_FC, 221,"lambda_fc", NULL, 3, 0, 1, 19, JOF_OBJECT)
OPDEF(JSOP_DEFFUN_FC, 219,"deffun_fc", NULL, 5, 0, 0, 0, JOF_OBJECT|JOF_DECLARING)
OPDEF(JSOP_DEFLOCALFUN_FC,220,"deflocalfun_fc",NULL, 7, 0, 0, 0, JOF_SLOTOBJECT|JOF_DECLARING|JOF_TMPSLOT)
OPDEF(JSOP_LAMBDA_FC, 221,"lambda_fc", NULL, 5, 0, 1, 19, JOF_OBJECT)
/*
* Joined function object as method optimization support.

View File

@ -1459,11 +1459,8 @@ js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
JSOp op = JSOp(*pc);
if (js_CodeSpec[op].format & JOF_INDEXBASE)
pc += js_CodeSpec[op].length;
if (*pc == JSOP_DEFFUN) {
JSFunction *fun;
GET_FUNCTION_FROM_BYTECODE(script, pc, 0, fun);
return fun->script()->lineno;
}
if (*pc == JSOP_DEFFUN)
return script->getFunction(GET_UINT32_INDEX(pc))->script()->lineno;
/*
* General case: walk through source notes accumulating their deltas,

View File

@ -226,7 +226,7 @@ JS_XDRFindClassById(JSXDRState *xdr, uint32_t id);
* and saved versions. If deserialization fails, the data should be
* invalidated if possible.
*/
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 105)
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 106)
/*
* Library-private functions.

View File

@ -3019,8 +3019,7 @@ mjit::Compiler::generateMethod()
BEGIN_CASE(JSOP_DEFFUN)
{
uint32_t index = fullAtomIndex(PC);
JSFunction *innerFun = script->getFunction(index);
JSFunction *innerFun = script->getFunction(GET_UINT32_INDEX(PC));
prepareStubCall(Uses(0));
masm.move(ImmPtr(innerFun), Registers::ArgReg1);
@ -3054,7 +3053,7 @@ mjit::Compiler::generateMethod()
BEGIN_CASE(JSOP_DEFLOCALFUN_FC)
{
uint32_t slot = GET_SLOTNO(PC);
JSFunction *fun = script->getFunction(fullAtomIndex(&PC[SLOTNO_LEN]));
JSFunction *fun = script->getFunction(GET_UINT32_INDEX(PC + SLOTNO_LEN));
prepareStubCall(Uses(frame.frameSlots()));
masm.move(ImmPtr(fun), Registers::ArgReg1);
INLINE_STUBCALL(stubs::DefLocalFun_FC, REJOIN_DEFLOCALFUN);
@ -3068,7 +3067,7 @@ mjit::Compiler::generateMethod()
BEGIN_CASE(JSOP_LAMBDA)
{
JSFunction *fun = script->getFunction(fullAtomIndex(PC));
JSFunction *fun = script->getFunction(GET_UINT32_INDEX(PC));
JSObjStubFun stub = stubs::Lambda;
uint32_t uses = 0;
@ -3134,7 +3133,7 @@ mjit::Compiler::generateMethod()
BEGIN_CASE(JSOP_DEFLOCALFUN)
{
uint32_t slot = GET_SLOTNO(PC);
JSFunction *fun = script->getFunction(fullAtomIndex(&PC[SLOTNO_LEN]));
JSFunction *fun = script->getFunction(GET_UINT32_INDEX(PC + SLOTNO_LEN));
prepareStubCall(Uses(0));
masm.move(ImmPtr(fun), Registers::ArgReg1);
INLINE_STUBCALL(stubs::DefLocalFun, REJOIN_DEFLOCALFUN);
@ -3175,7 +3174,7 @@ mjit::Compiler::generateMethod()
BEGIN_CASE(JSOP_OBJECT)
{
JSObject *object = script->getObject(fullAtomIndex(PC));
JSObject *object = script->getObject(GET_UINT32_INDEX(PC));
RegisterID reg = frame.allocReg();
masm.move(ImmPtr(object), reg);
frame.pushTypedPayload(JSVAL_TYPE_OBJECT, reg);
@ -3201,7 +3200,7 @@ mjit::Compiler::generateMethod()
BEGIN_CASE(JSOP_ENTERBLOCK)
BEGIN_CASE(JSOP_ENTERLET0)
BEGIN_CASE(JSOP_ENTERLET1)
enterBlock(script->getObject(fullAtomIndex(PC)));
enterBlock(&script->getObject(GET_UINT32_INDEX(PC))->asStaticBlock());
END_CASE(JSOP_ENTERBLOCK);
BEGIN_CASE(JSOP_LEAVEBLOCK)
@ -3222,7 +3221,7 @@ mjit::Compiler::generateMethod()
BEGIN_CASE(JSOP_LAMBDA_FC)
{
JSFunction *fun = script->getFunction(fullAtomIndex(PC));
JSFunction *fun = script->getFunction(GET_UINT32_INDEX(PC));
prepareStubCall(Uses(frame.frameSlots()));
masm.move(ImmPtr(fun), Registers::ArgReg1);
INLINE_STUBCALL(stubs::FlatLambda, REJOIN_PUSH_OBJECT);
@ -6798,7 +6797,7 @@ mjit::Compiler::jsop_newinit()
* actually a global object). This should only happen in chrome code.
*/
isArray = false;
baseobj = globalObj ? script->getObject(fullAtomIndex(PC)) : NULL;
baseobj = globalObj ? script->getObject(GET_UINT32_INDEX(PC)) : NULL;
break;
default:
JS_NOT_REACHED("Bad op");
@ -7215,11 +7214,11 @@ mjit::Compiler::jumpAndRun(Jump j, jsbytecode *target, Jump *slow, bool *trampol
}
void
mjit::Compiler::enterBlock(JSObject *obj)
mjit::Compiler::enterBlock(StaticBlockObject *block)
{
/* For now, don't bother doing anything for this opcode. */
frame.syncAndForgetEverything();
masm.move(ImmPtr(obj), Registers::ArgReg1);
masm.move(ImmPtr(block), Registers::ArgReg1);
INLINE_STUBCALL(stubs::EnterBlock, REJOIN_NONE);
if (*PC == JSOP_ENTERBLOCK)
frame.enterBlock(StackDefs(script, PC));

View File

@ -683,7 +683,7 @@ private:
bool jsop_instanceof();
void jsop_name(PropertyName *name, JSValueType type);
bool jsop_xname(PropertyName *name);
void enterBlock(JSObject *obj);
void enterBlock(StaticBlockObject *block);
void leaveBlock();
void emitEval(uint32_t argc);
void jsop_arguments(RejoinState rejoin);

View File

@ -626,7 +626,7 @@ js_InternalThrow(VMFrame &f)
*/
if (cx->isExceptionPending()) {
JS_ASSERT(JSOp(*pc) == JSOP_ENTERBLOCK);
StaticBlockObject &blockObj = script->getObject(GET_SLOTNO(pc))->asStaticBlock();
StaticBlockObject &blockObj = script->getObject(GET_UINT32_INDEX(pc))->asStaticBlock();
Value *vp = cx->regs().sp + blockObj.slotCount();
SetValueRangeToUndefined(cx->regs().sp, vp);
cx->regs().sp = vp;