mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-05 00:25:27 +00:00
Igor's patch for simpler extended atom indexing (365608, tweaks and r=me).
This commit is contained in:
parent
2296397878
commit
5535f707ed
@ -928,7 +928,7 @@ GetSwitchTableBounds(JSScript *script, uintN offset,
|
||||
pc += jmplen;
|
||||
n = GET_ATOM_INDEX(pc);
|
||||
pc += ATOM_INDEX_LEN;
|
||||
jmplen += ATOM_INDEX_LEN;
|
||||
jmplen += JUMP_OFFSET_LEN;
|
||||
break;
|
||||
}
|
||||
|
||||
|
130
js/src/jsemit.c
130
js/src/jsemit.c
@ -595,8 +595,8 @@ BuildSpanDepTable(JSContext *cx, JSCodeGenerator *cg)
|
||||
if (!AddSpanDep(cx, cg, pc, pc2, off))
|
||||
return JS_FALSE;
|
||||
pc2 += JUMP_OFFSET_LEN;
|
||||
npairs = (jsint) GET_ATOM_INDEX(pc2);
|
||||
pc2 += ATOM_INDEX_LEN;
|
||||
npairs = (jsint) GET_UINT16(pc2);
|
||||
pc2 += UINT16_LEN;
|
||||
while (npairs) {
|
||||
pc2 += ATOM_INDEX_LEN;
|
||||
off = GET_JUMP_OFFSET(pc2);
|
||||
@ -1734,76 +1734,42 @@ IndexRegExpClone(JSContext *cx, JSParseNode *pn, JSAtomListElement *ale,
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static int
|
||||
EmitBigIndexPrefix(JSContext *cx, JSCodeGenerator *cg, jsatomid atomIndex)
|
||||
{
|
||||
if (atomIndex < JS_BIT(16))
|
||||
return JSOP_NOP;
|
||||
atomIndex >>= 16;
|
||||
if (atomIndex <= JSOP_ATOMBASE3 - JSOP_ATOMBASE1 + 1) {
|
||||
if (js_Emit1(cx, cg, JSOP_ATOMBASE1 + atomIndex - 1) < 0)
|
||||
return -1;
|
||||
return JSOP_RESETBASE0;
|
||||
}
|
||||
if (js_Emit2(cx, cg, JSOP_ATOMBASE, atomIndex) < 0)
|
||||
return -1;
|
||||
return JSOP_RESETBASE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Emit a bytecode and its 2-byte constant (atom) index immediate operand.
|
||||
* If the atomIndex requires more than 2 bytes, emit a prefix op whose 24-bit
|
||||
* immediate operand indexes the atom in script->atomMap.
|
||||
* If the atomIndex requires more than 2 bytes, emit a prefix op whose 8-bit
|
||||
* immediate operand effectively extends the 16-bit immediate of the prefixed
|
||||
* opcode, by changing atom "segment" within script->atomMap (see jsinterp.c).
|
||||
* We optimize segments 1-3 with single-byte JSOP_ATOMBASE[123] codes.
|
||||
*
|
||||
* If op has JOF_NAME mode, emit JSOP_FINDNAME to find and push the object in
|
||||
* the scope chain in which the literal name was found, followed by the name
|
||||
* as a string. This enables us to use the JOF_ELEM counterpart to op.
|
||||
*
|
||||
* Otherwise, if op has JOF_PROP mode, emit JSOP_LITERAL before op, to push
|
||||
* the atom's value key. For JOF_PROP ops, the object being operated on has
|
||||
* already been pushed, and JSOP_LITERAL will push the id, leaving the stack
|
||||
* in the proper state for a JOF_ELEM counterpart.
|
||||
*
|
||||
* Otherwise, emit JSOP_LITOPX to push the atom index, then perform a special
|
||||
* dispatch on op, but getting op's atom index from the stack instead of from
|
||||
* an unsigned 16-bit immediate operand.
|
||||
* Such prefixing currently requires a suffix to restore the "zero segment"
|
||||
* register setting, but this could be optimized further.
|
||||
*/
|
||||
static JSBool
|
||||
EmitAtomIndexOp(JSContext *cx, JSOp op, jsatomid atomIndex, JSCodeGenerator *cg)
|
||||
{
|
||||
uint32 mode;
|
||||
JSOp prefixOp;
|
||||
ptrdiff_t off;
|
||||
jsbytecode *pc;
|
||||
|
||||
if (atomIndex >= JS_BIT(16)) {
|
||||
mode = (js_CodeSpec[op].format & JOF_MODEMASK);
|
||||
if (op != JSOP_SETNAME) {
|
||||
prefixOp = (mode == JOF_NAME)
|
||||
? JSOP_FINDNAME
|
||||
: (mode == JOF_PROP)
|
||||
? JSOP_LITERAL
|
||||
: JSOP_LITOPX;
|
||||
off = js_EmitN(cx, cg, prefixOp, 3);
|
||||
if (off < 0)
|
||||
return JS_FALSE;
|
||||
pc = CG_CODE(cg, off);
|
||||
SET_LITERAL_INDEX(pc, atomIndex);
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case JSOP_DECNAME: op = JSOP_DECELEM; break;
|
||||
case JSOP_DECPROP: op = JSOP_DECELEM; break;
|
||||
case JSOP_DELNAME: op = JSOP_DELELEM; break;
|
||||
case JSOP_DELPROP: op = JSOP_DELELEM; break;
|
||||
case JSOP_FORNAME: op = JSOP_FORELEM; break;
|
||||
case JSOP_FORPROP: op = JSOP_FORELEM; break;
|
||||
case JSOP_GETPROP: op = JSOP_GETELEM; break;
|
||||
case JSOP_GETXPROP: op = JSOP_GETXELEM; break;
|
||||
case JSOP_IMPORTPROP: op = JSOP_IMPORTELEM; break;
|
||||
case JSOP_INCNAME: op = JSOP_INCELEM; break;
|
||||
case JSOP_INCPROP: op = JSOP_INCELEM; break;
|
||||
case JSOP_INITPROP: op = JSOP_INITELEM; break;
|
||||
case JSOP_NAME: op = JSOP_GETELEM; break;
|
||||
case JSOP_NAMEDEC: op = JSOP_ELEMDEC; break;
|
||||
case JSOP_NAMEINC: op = JSOP_ELEMINC; break;
|
||||
case JSOP_PROPDEC: op = JSOP_ELEMDEC; break;
|
||||
case JSOP_PROPINC: op = JSOP_ELEMINC; break;
|
||||
case JSOP_BINDNAME: return JS_TRUE;
|
||||
case JSOP_SETNAME: op = JSOP_SETELEM; break;
|
||||
case JSOP_SETPROP: op = JSOP_SETELEM; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return js_Emit1(cx, cg, op) >= 0;
|
||||
}
|
||||
int bigSuffix;
|
||||
|
||||
bigSuffix = EmitBigIndexPrefix(cx, cg, atomIndex);
|
||||
if (bigSuffix < 0)
|
||||
return JS_FALSE;
|
||||
EMIT_UINT16_IMM_OP(op, atomIndex);
|
||||
return JS_TRUE;
|
||||
return bigSuffix == JSOP_NOP || js_Emit1(cx, cg, bigSuffix) >= 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1844,31 +1810,23 @@ static JSBool
|
||||
EmitIndexConstOp(JSContext *cx, JSOp op, uintN slot, jsatomid atomIndex,
|
||||
JSCodeGenerator *cg)
|
||||
{
|
||||
int bigSuffix;
|
||||
ptrdiff_t off;
|
||||
jsbytecode *pc;
|
||||
|
||||
if (atomIndex >= JS_BIT(16)) {
|
||||
/*
|
||||
* Lots of literals in the outer function, so we have to emit
|
||||
* [JSOP_LITOPX, atomIndex, op, slot].
|
||||
*/
|
||||
off = js_EmitN(cx, cg, JSOP_LITOPX, 3);
|
||||
if (off < 0)
|
||||
return JS_FALSE;
|
||||
pc = CG_CODE(cg, off);
|
||||
SET_LITERAL_INDEX(pc, atomIndex);
|
||||
EMIT_UINT16_IMM_OP(op, slot);
|
||||
} else {
|
||||
/* Emit [op, slot, atomIndex]. */
|
||||
off = js_EmitN(cx, cg, op, 2 + ATOM_INDEX_LEN);
|
||||
if (off < 0)
|
||||
return JS_FALSE;
|
||||
pc = CG_CODE(cg, off);
|
||||
SET_UINT16(pc, slot);
|
||||
pc += 2;
|
||||
SET_ATOM_INDEX(pc, atomIndex);
|
||||
}
|
||||
return JS_TRUE;
|
||||
bigSuffix = EmitBigIndexPrefix(cx, cg, atomIndex);
|
||||
if (bigSuffix < 0)
|
||||
return JS_FALSE;
|
||||
|
||||
/* Emit [op, slot, atomIndex]. */
|
||||
off = js_EmitN(cx, cg, op, 2 + ATOM_INDEX_LEN);
|
||||
if (off < 0)
|
||||
return JS_FALSE;
|
||||
pc = CG_CODE(cg, off);
|
||||
SET_UINT16(pc, slot);
|
||||
pc += 2;
|
||||
SET_ATOM_INDEX(pc, atomIndex);
|
||||
return bigSuffix == 0 || js_Emit1(cx, cg, bigSuffix) >= 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2590,7 +2548,7 @@ EmitNumberOp(JSContext *cx, jsdouble dval, JSCodeGenerator *cg)
|
||||
if (off < 0)
|
||||
return JS_FALSE;
|
||||
pc = CG_CODE(cg, off);
|
||||
SET_LITERAL_INDEX(pc, atomIndex);
|
||||
SET_UINT24(pc, atomIndex);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -632,7 +632,6 @@ NoSuchMethod(JSContext *cx, JSStackFrame *fp, jsval *vp, uint32 flags,
|
||||
JSObject *thisp, *argsobj;
|
||||
jsid id;
|
||||
jsbytecode *pc;
|
||||
jsatomid atomIndex;
|
||||
JSAtom *atom;
|
||||
uintN argc;
|
||||
JSArena *a;
|
||||
@ -691,8 +690,7 @@ NoSuchMethod(JSContext *cx, JSStackFrame *fp, jsval *vp, uint32 flags,
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
case JSOP_GETMETHOD:
|
||||
#endif
|
||||
atomIndex = GET_ATOM_INDEX(pc);
|
||||
atom = js_GetAtom(cx, &fp->script->atomMap, atomIndex);
|
||||
atom = js_GetAtomFromBytecode(cx, fp->script, pc, 0);
|
||||
argc = *argcp;
|
||||
argsobj = js_NewArrayObject(cx, argc, vp + 2);
|
||||
if (!argsobj)
|
||||
@ -760,7 +758,7 @@ typedef struct CallKey {
|
||||
/* Compensate for typeof null == "object" brain damage. */
|
||||
#define JSTYPE_NULL JSTYPE_LIMIT
|
||||
#define TYPEOF(cx,v) (JSVAL_IS_NULL(v) ? JSTYPE_NULL : JS_TypeOfValue(cx,v))
|
||||
#define TYPENAME(t) (((t) == JSTYPE_NULL) ? js_null_str : js_type_str[t])
|
||||
#define TYPENAME(t) (((t) == JSTYPE_NULL) ? js_null_str : js_type_strs[t])
|
||||
#define NTYPEHIST (JSTYPE_LIMIT + 1)
|
||||
|
||||
typedef struct CallValue {
|
||||
@ -907,7 +905,8 @@ CallTableDumper(JSHashEntry *he, intN k, void *arg)
|
||||
argval = avc->value;
|
||||
fprintf(fp, " %9u: %8lu %.*s (%#lx)\n",
|
||||
n, (unsigned long) avc->count,
|
||||
sizeof avc->strbuf, avc->strbuf, argval);
|
||||
(int) sizeof avc->strbuf, avc->strbuf,
|
||||
argval);
|
||||
++n;
|
||||
}
|
||||
}
|
||||
@ -1032,13 +1031,13 @@ LogCall(JSContext *cx, jsval callee, uintN argc, jsval *argv)
|
||||
cstr = "";
|
||||
switch (TYPEOF(cx, argval)) {
|
||||
case JSTYPE_VOID:
|
||||
cstr = js_type_str[JSTYPE_VOID];
|
||||
cstr = js_type_strs[JSTYPE_VOID];
|
||||
break;
|
||||
case JSTYPE_NULL:
|
||||
cstr = js_null_str;
|
||||
break;
|
||||
case JSTYPE_BOOLEAN:
|
||||
cstr = js_boolean_str[JSVAL_TO_BOOLEAN(argval)];
|
||||
cstr = js_boolean_strs[JSVAL_TO_BOOLEAN(argval)];
|
||||
break;
|
||||
case JSTYPE_NUMBER:
|
||||
if (JSVAL_IS_INT(argval)) {
|
||||
@ -2196,6 +2195,7 @@ js_Interpret(JSContext *cx, jsbytecode *pc, jsval *result)
|
||||
JSStackFrame *fp;
|
||||
JSScript *script;
|
||||
uintN inlineCallCount;
|
||||
JSAtom **atoms;
|
||||
JSObject *obj, *obj2, *parent;
|
||||
JSVersion currentVersion, originalVersion;
|
||||
JSBranchCallback onbranch;
|
||||
@ -2289,6 +2289,11 @@ js_Interpret(JSContext *cx, jsbytecode *pc, jsval *result)
|
||||
/* Count of JS function calls that nest in this C js_Interpret frame. */
|
||||
inlineCallCount = 0;
|
||||
|
||||
/* Load the atom base register used by LOAD_ATOM and inline equivalents. */
|
||||
atoms = script->atomMap.vector;
|
||||
|
||||
#define LOAD_ATOM(PCOFF) (atom = GET_ATOM(cx, atoms, pc + PCOFF))
|
||||
|
||||
/*
|
||||
* Optimized Get and SetVersion for proper script language versioning.
|
||||
*
|
||||
@ -2629,6 +2634,7 @@ interrupt:
|
||||
/* Restore the calling script's interpreter registers. */
|
||||
script = fp->script;
|
||||
depth = (jsint) script->depth;
|
||||
atoms = script->atomMap.vector;
|
||||
pc = fp->pc;
|
||||
#ifndef JS_THREADED_INTERP
|
||||
endpc = script->code + script->length;
|
||||
@ -2813,14 +2819,14 @@ interrupt:
|
||||
* Handle JSOP_FORPROP first, so the cost of the goto do_forinloop
|
||||
* is not paid for the more common cases.
|
||||
*/
|
||||
lval = FETCH_OPND(-1);
|
||||
atom = GET_ATOM(cx, script, pc);
|
||||
LOAD_ATOM(0);
|
||||
id = ATOM_TO_JSID(atom);
|
||||
lval = FETCH_OPND(-1);
|
||||
i = -2;
|
||||
goto do_forinloop;
|
||||
|
||||
BEGIN_CASE(JSOP_FORNAME)
|
||||
atom = GET_ATOM(cx, script, pc);
|
||||
LOAD_ATOM(0);
|
||||
id = ATOM_TO_JSID(atom);
|
||||
|
||||
/*
|
||||
@ -3050,17 +3056,9 @@ interrupt:
|
||||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
#define BEGIN_LITOPX_CASE(OP,PCOFF) \
|
||||
BEGIN_CASE(OP) \
|
||||
pc2 = pc; \
|
||||
atomIndex = GET_ATOM_INDEX(pc + PCOFF); \
|
||||
do_##OP: \
|
||||
atom = js_GetAtom(cx, &script->atomMap, atomIndex);
|
||||
|
||||
#define END_LITOPX_CASE(OP) \
|
||||
END_CASE(OP)
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_SETCONST, 0)
|
||||
BEGIN_CASE(JSOP_SETCONST)
|
||||
LOAD_ATOM(0);
|
||||
obj = fp->varobj;
|
||||
rval = FETCH_OPND(-1);
|
||||
SAVE_SP_AND_PC(fp);
|
||||
@ -3072,7 +3070,7 @@ interrupt:
|
||||
if (!ok)
|
||||
goto out;
|
||||
STORE_OPND(-1, rval);
|
||||
END_LITOPX_CASE(JSOP_SETCONST)
|
||||
END_CASE(JSOP_SETCONST)
|
||||
|
||||
#if JS_HAS_DESTRUCTURING
|
||||
BEGIN_CASE(JSOP_ENUMCONSTELEM)
|
||||
@ -3091,18 +3089,20 @@ interrupt:
|
||||
END_CASE(JSOP_ENUMCONSTELEM)
|
||||
#endif
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_BINDNAME, 0)
|
||||
BEGIN_CASE(JSOP_BINDNAME)
|
||||
LOAD_ATOM(0);
|
||||
id = ATOM_TO_JSID(atom);
|
||||
SAVE_SP_AND_PC(fp);
|
||||
obj = js_FindIdentifierBase(cx, ATOM_TO_JSID(atom));
|
||||
obj = js_FindIdentifierBase(cx, id);
|
||||
if (!obj) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
PUSH_OPND(OBJECT_TO_JSVAL(obj));
|
||||
END_LITOPX_CASE(JSOP_BINDNAME)
|
||||
END_CASE(JSOP_BINDNAME)
|
||||
|
||||
BEGIN_CASE(JSOP_SETNAME)
|
||||
atom = GET_ATOM(cx, script, pc);
|
||||
LOAD_ATOM(0);
|
||||
id = ATOM_TO_JSID(atom);
|
||||
rval = FETCH_OPND(-1);
|
||||
lval = FETCH_OPND(-2);
|
||||
@ -3558,7 +3558,7 @@ interrupt:
|
||||
DO_NEXT_OP(len);
|
||||
|
||||
BEGIN_CASE(JSOP_DELNAME)
|
||||
atom = GET_ATOM(cx, script, pc);
|
||||
LOAD_ATOM(0);
|
||||
id = ATOM_TO_JSID(atom);
|
||||
|
||||
SAVE_SP_AND_PC(fp);
|
||||
@ -3578,7 +3578,7 @@ interrupt:
|
||||
END_CASE(JSOP_DELNAME)
|
||||
|
||||
BEGIN_CASE(JSOP_DELPROP)
|
||||
atom = GET_ATOM(cx, script, pc);
|
||||
LOAD_ATOM(0);
|
||||
id = ATOM_TO_JSID(atom);
|
||||
PROPERTY_OP(-1, ok = OBJ_DELETE_PROPERTY(cx, obj, id, &rval));
|
||||
STORE_OPND(-1, rval);
|
||||
@ -3608,7 +3608,7 @@ interrupt:
|
||||
BEGIN_CASE(JSOP_DECNAME)
|
||||
BEGIN_CASE(JSOP_NAMEINC)
|
||||
BEGIN_CASE(JSOP_NAMEDEC)
|
||||
atom = GET_ATOM(cx, script, pc);
|
||||
LOAD_ATOM(0);
|
||||
id = ATOM_TO_JSID(atom);
|
||||
|
||||
SAVE_SP_AND_PC(fp);
|
||||
@ -3627,7 +3627,7 @@ interrupt:
|
||||
BEGIN_CASE(JSOP_DECPROP)
|
||||
BEGIN_CASE(JSOP_PROPINC)
|
||||
BEGIN_CASE(JSOP_PROPDEC)
|
||||
atom = GET_ATOM(cx, script, pc);
|
||||
LOAD_ATOM(0);
|
||||
id = ATOM_TO_JSID(atom);
|
||||
lval = FETCH_OPND(-1);
|
||||
i = -1;
|
||||
@ -3830,7 +3830,8 @@ interrupt:
|
||||
DO_NEXT_OP(len);
|
||||
}
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_GETTHISPROP, 0)
|
||||
BEGIN_CASE(JSOP_GETTHISPROP)
|
||||
LOAD_ATOM(0);
|
||||
id = ATOM_TO_JSID(atom);
|
||||
obj = fp->thisp;
|
||||
SAVE_SP_AND_PC(fp);
|
||||
@ -3838,23 +3839,26 @@ interrupt:
|
||||
if (!ok)
|
||||
goto out;
|
||||
PUSH_OPND(rval);
|
||||
END_LITOPX_CASE(JSOP_GETTHISPROP)
|
||||
END_CASE(JSOP_GETTHISPROP)
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_GETARGPROP, ARGNO_LEN)
|
||||
BEGIN_CASE(JSOP_GETARGPROP)
|
||||
LOAD_ATOM(ARGNO_LEN);
|
||||
slot = GET_ARGNO(pc);
|
||||
JS_ASSERT(slot < fp->fun->nargs);
|
||||
PUSH_OPND(fp->argv[slot]);
|
||||
len = JSOP_GETARGPROP_LENGTH;
|
||||
goto do_getprop_body;
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_GETVARPROP, VARNO_LEN)
|
||||
BEGIN_CASE(JSOP_GETVARPROP)
|
||||
LOAD_ATOM(VARNO_LEN);
|
||||
slot = GET_VARNO(pc);
|
||||
JS_ASSERT(slot < fp->fun->u.i.nvars);
|
||||
PUSH_OPND(fp->vars[slot]);
|
||||
len = JSOP_GETVARPROP_LENGTH;
|
||||
goto do_getprop_body;
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_GETLOCALPROP, 2)
|
||||
BEGIN_CASE(JSOP_GETLOCALPROP)
|
||||
LOAD_ATOM(2);
|
||||
slot = GET_UINT16(pc);
|
||||
JS_ASSERT(slot < (uintN)depth);
|
||||
PUSH_OPND(fp->spbase[slot]);
|
||||
@ -3864,7 +3868,7 @@ interrupt:
|
||||
BEGIN_CASE(JSOP_GETPROP)
|
||||
BEGIN_CASE(JSOP_GETXPROP)
|
||||
/* Get an immediate atom naming the property. */
|
||||
atom = GET_ATOM(cx, script, pc);
|
||||
LOAD_ATOM(0);
|
||||
len = JSOP_GETPROP_LENGTH;
|
||||
|
||||
do_getprop_body:
|
||||
@ -3886,12 +3890,12 @@ interrupt:
|
||||
END_VARLEN_CASE
|
||||
|
||||
BEGIN_CASE(JSOP_SETPROP)
|
||||
/* Get an immediate atom naming the property. */
|
||||
LOAD_ATOM(0);
|
||||
id = ATOM_TO_JSID(atom);
|
||||
|
||||
/* Pop the right-hand side into rval for OBJ_SET_PROPERTY. */
|
||||
rval = FETCH_OPND(-1);
|
||||
|
||||
/* Get an immediate atom naming the property. */
|
||||
atom = GET_ATOM(cx, script, pc);
|
||||
id = ATOM_TO_JSID(atom);
|
||||
PROPERTY_OP(-2, CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval)));
|
||||
sp--;
|
||||
STORE_OPND(-1, rval);
|
||||
@ -3988,6 +3992,7 @@ interrupt:
|
||||
nvars = fun->u.i.nvars;
|
||||
script = fun->u.i.script;
|
||||
depth = (jsint) script->depth;
|
||||
atoms = script->atomMap.vector;
|
||||
nslots = nframeslots + nvars + 2 * depth;
|
||||
|
||||
/* Allocate missing expected args adjacent to actual args. */
|
||||
@ -4136,6 +4141,7 @@ interrupt:
|
||||
bad_inline_call:
|
||||
script = fp->script;
|
||||
depth = (jsint) script->depth;
|
||||
atoms = script->atomMap.vector;
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
@ -4197,7 +4203,7 @@ interrupt:
|
||||
#endif
|
||||
|
||||
BEGIN_CASE(JSOP_NAME)
|
||||
atom = GET_ATOM(cx, script, pc);
|
||||
LOAD_ATOM(0);
|
||||
id = ATOM_TO_JSID(atom);
|
||||
|
||||
SAVE_SP_AND_PC(fp);
|
||||
@ -4235,112 +4241,42 @@ interrupt:
|
||||
END_CASE(JSOP_NAME)
|
||||
|
||||
BEGIN_CASE(JSOP_UINT16)
|
||||
i = (jsint) GET_ATOM_INDEX(pc);
|
||||
i = (jsint) GET_UINT16(pc);
|
||||
rval = INT_TO_JSVAL(i);
|
||||
PUSH_OPND(rval);
|
||||
obj = NULL;
|
||||
END_CASE(JSOP_UINT16)
|
||||
|
||||
BEGIN_CASE(JSOP_UINT24)
|
||||
i = (jsint) GET_LITERAL_INDEX(pc);
|
||||
i = (jsint) GET_UINT24(pc);
|
||||
rval = INT_TO_JSVAL(i);
|
||||
PUSH_OPND(rval);
|
||||
END_CASE(JSOP_UINT24)
|
||||
|
||||
BEGIN_CASE(JSOP_LITERAL)
|
||||
atomIndex = GET_LITERAL_INDEX(pc);
|
||||
atom = js_GetAtom(cx, &script->atomMap, atomIndex);
|
||||
PUSH_OPND(ATOM_KEY(atom));
|
||||
obj = NULL;
|
||||
END_CASE(JSOP_LITERAL)
|
||||
BEGIN_CASE(JSOP_ATOMBASE)
|
||||
atoms += GET_ATOMBASE(pc);
|
||||
END_CASE(JSOP_ATOMBASE)
|
||||
|
||||
BEGIN_CASE(JSOP_FINDNAME)
|
||||
atomIndex = GET_LITERAL_INDEX(pc);
|
||||
atom = js_GetAtom(cx, &script->atomMap, atomIndex);
|
||||
SAVE_SP_AND_PC(fp);
|
||||
obj = js_FindIdentifierBase(cx, ATOM_TO_JSID(atom));
|
||||
if (!obj) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
PUSH_OPND(OBJECT_TO_JSVAL(obj));
|
||||
PUSH_OPND(ATOM_KEY(atom));
|
||||
END_CASE(JSOP_FINDNAME)
|
||||
BEGIN_CASE(JSOP_ATOMBASE1)
|
||||
BEGIN_CASE(JSOP_ATOMBASE2)
|
||||
BEGIN_CASE(JSOP_ATOMBASE3)
|
||||
atoms += (op - JSOP_ATOMBASE1 + 1) << 16;
|
||||
END_CASE(JSOP_ATOMBASE3)
|
||||
|
||||
BEGIN_CASE(JSOP_LITOPX)
|
||||
/*
|
||||
* Load atomIndex, which is used by code at each do_JSOP_* label.
|
||||
*
|
||||
* Also set pc2 to point at the bytecode extended by this prefix
|
||||
* to have a leading 24 bit atomIndex, instead of the unextended
|
||||
* 16-bit atomIndex that normally comes after op. This enables
|
||||
* JOF_INDEXCONST format ops (which have multiple immediates) to
|
||||
* collect their other immediate via GET_VARNO(pc2) or similar.
|
||||
*
|
||||
* Finally, load op and, if threading, adjust pc so that it will
|
||||
* be advanced properly at the end of op's case by DO_NEXT_OP.
|
||||
*/
|
||||
atomIndex = GET_LITERAL_INDEX(pc);
|
||||
pc2 = pc + 1 + LITERAL_INDEX_LEN;
|
||||
op = *pc2;
|
||||
pc += JSOP_LITOPX_LENGTH - (1 + ATOM_INDEX_LEN);
|
||||
#ifndef JS_THREADED_INTERP
|
||||
len = js_CodeSpec[op].length;
|
||||
#endif
|
||||
switch (op) {
|
||||
case JSOP_ANONFUNOBJ: goto do_JSOP_ANONFUNOBJ;
|
||||
case JSOP_BINDNAME: goto do_JSOP_BINDNAME;
|
||||
case JSOP_CLOSURE: goto do_JSOP_CLOSURE;
|
||||
case JSOP_DEFCONST: goto do_JSOP_DEFCONST;
|
||||
case JSOP_DEFFUN: goto do_JSOP_DEFFUN;
|
||||
case JSOP_DEFLOCALFUN: goto do_JSOP_DEFLOCALFUN;
|
||||
case JSOP_DEFVAR: goto do_JSOP_DEFVAR;
|
||||
#if JS_HAS_EXPORT_IMPORT
|
||||
case JSOP_EXPORTNAME: goto do_JSOP_EXPORTNAME;
|
||||
#endif
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
case JSOP_GETMETHOD: goto do_JSOP_GETMETHOD;
|
||||
case JSOP_SETMETHOD: goto do_JSOP_SETMETHOD;
|
||||
#endif
|
||||
case JSOP_NAMEDFUNOBJ: goto do_JSOP_NAMEDFUNOBJ;
|
||||
case JSOP_NUMBER: goto do_JSOP_NUMBER;
|
||||
case JSOP_OBJECT: goto do_JSOP_OBJECT;
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
case JSOP_QNAMECONST: goto do_JSOP_QNAMECONST;
|
||||
case JSOP_QNAMEPART: goto do_JSOP_QNAMEPART;
|
||||
#endif
|
||||
case JSOP_REGEXP: goto do_JSOP_REGEXP;
|
||||
case JSOP_SETCONST: goto do_JSOP_SETCONST;
|
||||
case JSOP_STRING: goto do_JSOP_STRING;
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
case JSOP_XMLCDATA: goto do_JSOP_XMLCDATA;
|
||||
case JSOP_XMLCOMMENT: goto do_JSOP_XMLCOMMENT;
|
||||
case JSOP_XMLOBJECT: goto do_JSOP_XMLOBJECT;
|
||||
case JSOP_XMLPI: goto do_JSOP_XMLPI;
|
||||
#endif
|
||||
case JSOP_ENTERBLOCK: goto do_JSOP_ENTERBLOCK;
|
||||
case JSOP_GETTHISPROP: goto do_JSOP_GETTHISPROP;
|
||||
case JSOP_GETARGPROP: goto do_JSOP_GETARGPROP;
|
||||
case JSOP_GETVARPROP: goto do_JSOP_GETVARPROP;
|
||||
case JSOP_GETLOCALPROP: goto do_JSOP_GETLOCALPROP;
|
||||
default: JS_ASSERT(0);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
BEGIN_CASE(JSOP_RESETBASE0)
|
||||
BEGIN_CASE(JSOP_RESETBASE)
|
||||
atoms = script->atomMap.vector;
|
||||
END_CASE(JSOP_RESETBASE)
|
||||
|
||||
BEGIN_CASE(JSOP_NUMBER)
|
||||
BEGIN_CASE(JSOP_STRING)
|
||||
BEGIN_CASE(JSOP_OBJECT)
|
||||
atomIndex = GET_ATOM_INDEX(pc);
|
||||
|
||||
do_JSOP_NUMBER:
|
||||
do_JSOP_STRING:
|
||||
do_JSOP_OBJECT:
|
||||
atom = js_GetAtom(cx, &script->atomMap, atomIndex);
|
||||
LOAD_ATOM(0);
|
||||
PUSH_OPND(ATOM_KEY(atom));
|
||||
obj = NULL;
|
||||
END_CASE(JSOP_NUMBER)
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_REGEXP, 0)
|
||||
BEGIN_CASE(JSOP_REGEXP)
|
||||
{
|
||||
JSRegExp *re;
|
||||
JSObject *funobj;
|
||||
@ -4369,6 +4305,7 @@ interrupt:
|
||||
* need a similar op for other kinds of object literals, we should
|
||||
* push cloning down under JSObjectOps and reuse code here.
|
||||
*/
|
||||
LOAD_ATOM(0);
|
||||
JS_ASSERT(ATOM_IS_OBJECT(atom));
|
||||
obj = ATOM_TO_OBJECT(atom);
|
||||
JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_RegExpClass);
|
||||
@ -4461,7 +4398,7 @@ interrupt:
|
||||
PUSH_OPND(rval);
|
||||
obj = NULL;
|
||||
}
|
||||
END_LITOPX_CASE(JSOP_REGEXP)
|
||||
END_CASE(JSOP_REGEXP)
|
||||
|
||||
BEGIN_CASE(JSOP_ZERO)
|
||||
PUSH_OPND(JSVAL_ZERO);
|
||||
@ -4548,12 +4485,12 @@ interrupt:
|
||||
}
|
||||
|
||||
pc2 += JUMP_OFFSET_LEN;
|
||||
npairs = (jsint) GET_ATOM_INDEX(pc2);
|
||||
pc2 += ATOM_INDEX_LEN;
|
||||
npairs = (jsint) GET_UINT16(pc2);
|
||||
pc2 += UINT16_LEN;
|
||||
|
||||
#define SEARCH_PAIRS(MATCH_CODE) \
|
||||
while (npairs) { \
|
||||
atom = GET_ATOM(cx, script, pc2); \
|
||||
atom = GET_ATOM(cx, atoms, pc2); \
|
||||
rval = ATOM_KEY(atom); \
|
||||
MATCH_CODE \
|
||||
if (match) { \
|
||||
@ -4625,12 +4562,12 @@ interrupt:
|
||||
}
|
||||
|
||||
pc2 += JUMPX_OFFSET_LEN;
|
||||
npairs = (jsint) GET_ATOM_INDEX(pc2);
|
||||
pc2 += ATOM_INDEX_LEN;
|
||||
npairs = (jsint) GET_UINT16(pc2);
|
||||
pc2 += UINT16_LEN;
|
||||
|
||||
#define SEARCH_EXTENDED_PAIRS(MATCH_CODE) \
|
||||
while (npairs) { \
|
||||
atom = GET_ATOM(cx, script, pc2); \
|
||||
atom = GET_ATOM(cx, atoms, pc2); \
|
||||
rval = ATOM_KEY(atom); \
|
||||
MATCH_CODE \
|
||||
if (match) { \
|
||||
@ -4692,7 +4629,8 @@ interrupt:
|
||||
}
|
||||
END_CASE(JSOP_EXPORTALL)
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_EXPORTNAME, 0)
|
||||
BEGIN_CASE(JSOP_EXPORTNAME)
|
||||
LOAD_ATOM(0);
|
||||
id = ATOM_TO_JSID(atom);
|
||||
obj = fp->varobj;
|
||||
SAVE_SP_AND_PC(fp);
|
||||
@ -4712,7 +4650,7 @@ interrupt:
|
||||
}
|
||||
if (!ok)
|
||||
goto out;
|
||||
END_LITOPX_CASE(JSOP_EXPORTNAME)
|
||||
END_CASE(JSOP_EXPORTNAME)
|
||||
|
||||
BEGIN_CASE(JSOP_IMPORTALL)
|
||||
id = (jsid) JSVAL_VOID;
|
||||
@ -4722,7 +4660,7 @@ interrupt:
|
||||
|
||||
BEGIN_CASE(JSOP_IMPORTPROP)
|
||||
/* Get an immediate atom naming the property. */
|
||||
atom = GET_ATOM(cx, script, pc);
|
||||
LOAD_ATOM(0);
|
||||
id = ATOM_TO_JSID(atom);
|
||||
PROPERTY_OP(-1, ok = ImportProperty(cx, obj, id));
|
||||
sp--;
|
||||
@ -4863,7 +4801,7 @@ interrupt:
|
||||
* JSOP_SETGVAR has arity 1: [rval], not arity 2: [obj, rval]
|
||||
* as JSOP_SETNAME does, where [obj] is due to JSOP_BINDNAME.
|
||||
*/
|
||||
atom = GET_ATOM(cx, script, pc);
|
||||
LOAD_ATOM(0);
|
||||
id = ATOM_TO_JSID(atom);
|
||||
SAVE_SP_AND_PC(fp);
|
||||
CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval));
|
||||
@ -4881,10 +4819,7 @@ interrupt:
|
||||
BEGIN_CASE(JSOP_DEFCONST)
|
||||
BEGIN_CASE(JSOP_DEFVAR)
|
||||
atomIndex = GET_ATOM_INDEX(pc);
|
||||
|
||||
do_JSOP_DEFCONST:
|
||||
do_JSOP_DEFVAR:
|
||||
atom = js_GetAtom(cx, &script->atomMap, atomIndex);
|
||||
atom = atoms[atomIndex];
|
||||
obj = fp->varobj;
|
||||
attrs = JSPROP_ENUMERATE;
|
||||
if (!(fp->flags & JSFRAME_EVAL))
|
||||
@ -4936,7 +4871,9 @@ interrupt:
|
||||
OBJ_DROP_PROPERTY(cx, obj2, prop);
|
||||
END_CASE(JSOP_DEFVAR)
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_DEFFUN, 0)
|
||||
BEGIN_CASE(JSOP_DEFFUN)
|
||||
atomIndex = GET_ATOM_INDEX(pc);
|
||||
atom = atoms[atomIndex];
|
||||
obj = ATOM_TO_OBJECT(atom);
|
||||
fun = (JSFunction *) JS_GetPrivate(cx, obj);
|
||||
id = ATOM_TO_JSID(fun->atom);
|
||||
@ -5048,9 +4985,10 @@ interrupt:
|
||||
}
|
||||
#endif
|
||||
OBJ_DROP_PROPERTY(cx, parent, prop);
|
||||
END_LITOPX_CASE(JSOP_DEFFUN)
|
||||
END_CASE(JSOP_DEFFUN)
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_DEFLOCALFUN, VARNO_LEN)
|
||||
BEGIN_CASE(JSOP_DEFLOCALFUN)
|
||||
LOAD_ATOM(VARNO_LEN);
|
||||
/*
|
||||
* Define a local function (i.e., one nested at the top level of
|
||||
* another function), parented by the current scope chain, and
|
||||
@ -5058,7 +4996,7 @@ interrupt:
|
||||
* This is an optimization over JSOP_DEFFUN that avoids requiring
|
||||
* a call object for the outer function's activation.
|
||||
*/
|
||||
slot = GET_VARNO(pc2);
|
||||
slot = GET_VARNO(pc);
|
||||
obj = ATOM_TO_OBJECT(atom);
|
||||
|
||||
/*
|
||||
@ -5097,10 +5035,11 @@ interrupt:
|
||||
if (!ok)
|
||||
goto out;
|
||||
fp->vars[slot] = OBJECT_TO_JSVAL(obj);
|
||||
END_LITOPX_CASE(JSOP_DEFLOCALFUN)
|
||||
END_CASE(JSOP_DEFLOCALFUN)
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_ANONFUNOBJ, 0)
|
||||
BEGIN_CASE(JSOP_ANONFUNOBJ)
|
||||
/* Push the specified function object literal. */
|
||||
LOAD_ATOM(0);
|
||||
obj = ATOM_TO_OBJECT(atom);
|
||||
|
||||
/* If re-parenting, push a clone of the function object. */
|
||||
@ -5119,10 +5058,11 @@ interrupt:
|
||||
}
|
||||
PUSH_OPND(OBJECT_TO_JSVAL(obj));
|
||||
obj = NULL;
|
||||
END_LITOPX_CASE(JSOP_ANONFUNOBJ)
|
||||
END_CASE(JSOP_ANONFUNOBJ)
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_NAMEDFUNOBJ, 0)
|
||||
BEGIN_CASE(JSOP_NAMEDFUNOBJ)
|
||||
/* ECMA ed. 3 FunctionExpression: function Identifier [etc.]. */
|
||||
LOAD_ATOM(0);
|
||||
rval = ATOM_KEY(atom);
|
||||
JS_ASSERT(VALUE_IS_FUNCTION(cx, rval));
|
||||
|
||||
@ -5211,9 +5151,12 @@ interrupt:
|
||||
*/
|
||||
PUSH_OPND(OBJECT_TO_JSVAL(obj));
|
||||
obj = NULL;
|
||||
END_LITOPX_CASE(JSOP_NAMEDFUNOBJ)
|
||||
END_CASE(JSOP_NAMEDFUNOBJ)
|
||||
|
||||
BEGIN_CASE(JSOP_CLOSURE)
|
||||
atomIndex = GET_ATOM_INDEX(pc);
|
||||
atom = atoms[atomIndex];
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_CLOSURE, 0)
|
||||
/*
|
||||
* ECMA ed. 3 extension: a named function expression in a compound
|
||||
* statement (not at the top statement level of global code, or at
|
||||
@ -5296,16 +5239,27 @@ interrupt:
|
||||
}
|
||||
#endif
|
||||
OBJ_DROP_PROPERTY(cx, parent, prop);
|
||||
END_LITOPX_CASE(JSOP_CLOSURE)
|
||||
END_CASE(JSOP_CLOSURE)
|
||||
|
||||
#if JS_HAS_GETTER_SETTER
|
||||
BEGIN_CASE(JSOP_GETTER)
|
||||
BEGIN_CASE(JSOP_SETTER)
|
||||
do_getter_setter:
|
||||
op2 = (JSOp) *++pc;
|
||||
switch (op2) {
|
||||
case JSOP_ATOMBASE:
|
||||
atoms += GET_ATOMBASE(pc);
|
||||
pc += JSOP_ATOMBASE_LENGTH - 1;
|
||||
goto do_getter_setter;
|
||||
case JSOP_ATOMBASE1:
|
||||
case JSOP_ATOMBASE2:
|
||||
case JSOP_ATOMBASE3:
|
||||
atoms += (op2 - JSOP_ATOMBASE1 + 1) << 16;
|
||||
goto do_getter_setter;
|
||||
|
||||
case JSOP_SETNAME:
|
||||
case JSOP_SETPROP:
|
||||
atom = GET_ATOM(cx, script, pc);
|
||||
LOAD_ATOM(0);
|
||||
id = ATOM_TO_JSID(atom);
|
||||
rval = FETCH_OPND(-1);
|
||||
i = -1;
|
||||
@ -5323,7 +5277,7 @@ interrupt:
|
||||
JS_ASSERT(sp - fp->spbase >= 2);
|
||||
rval = FETCH_OPND(-1);
|
||||
i = -1;
|
||||
atom = GET_ATOM(cx, script, pc);
|
||||
LOAD_ATOM(0);
|
||||
id = ATOM_TO_JSID(atom);
|
||||
goto gs_get_lval;
|
||||
|
||||
@ -5410,13 +5364,13 @@ interrupt:
|
||||
END_CASE(JSOP_ENDINIT)
|
||||
|
||||
BEGIN_CASE(JSOP_INITPROP)
|
||||
/* Get the immediate property name into id. */
|
||||
LOAD_ATOM(0);
|
||||
id = ATOM_TO_JSID(atom);
|
||||
/* Pop the property's value into rval. */
|
||||
JS_ASSERT(sp - fp->spbase >= 2);
|
||||
rval = FETCH_OPND(-1);
|
||||
|
||||
/* Get the immediate property name into id. */
|
||||
atom = GET_ATOM(cx, script, pc);
|
||||
id = ATOM_TO_JSID(atom);
|
||||
i = -1;
|
||||
goto do_init;
|
||||
|
||||
@ -5459,7 +5413,7 @@ interrupt:
|
||||
}
|
||||
fp->sharpArray = obj;
|
||||
}
|
||||
i = (jsint) GET_ATOM_INDEX(pc);
|
||||
i = (jsint) GET_UINT16(pc);
|
||||
id = INT_TO_JSID(i);
|
||||
rval = FETCH_OPND(-1);
|
||||
if (JSVAL_IS_PRIMITIVE(rval)) {
|
||||
@ -5476,7 +5430,7 @@ interrupt:
|
||||
END_CASE(JSOP_DEFSHARP)
|
||||
|
||||
BEGIN_CASE(JSOP_USESHARP)
|
||||
i = (jsint) GET_ATOM_INDEX(pc);
|
||||
i = (jsint) GET_UINT16(pc);
|
||||
id = INT_TO_JSID(i);
|
||||
obj = fp->sharpArray;
|
||||
if (!obj) {
|
||||
@ -5505,8 +5459,7 @@ interrupt:
|
||||
|
||||
/* Reset the stack to the given depth. */
|
||||
BEGIN_CASE(JSOP_SETSP)
|
||||
i = (jsint) GET_ATOM_INDEX(pc);
|
||||
JS_ASSERT(i >= 0);
|
||||
i = (jsint) GET_UINT16(pc);
|
||||
|
||||
for (obj = fp->blockChain; obj; obj = OBJ_GET_PARENT(cx, obj)) {
|
||||
JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_BlockClass);
|
||||
@ -5682,11 +5635,13 @@ interrupt:
|
||||
PUSH_OPND(rval);
|
||||
END_CASE(JSOP_ANYNAME)
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_QNAMEPART, 0)
|
||||
BEGIN_CASE(JSOP_QNAMEPART)
|
||||
LOAD_ATOM(0);
|
||||
PUSH_OPND(ATOM_KEY(atom));
|
||||
END_LITOPX_CASE(JSOP_QNAMEPART)
|
||||
END_CASE(JSOP_QNAMEPART)
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_QNAMECONST, 0)
|
||||
BEGIN_CASE(JSOP_QNAMECONST)
|
||||
LOAD_ATOM(0);
|
||||
rval = ATOM_KEY(atom);
|
||||
lval = FETCH_OPND(-1);
|
||||
SAVE_SP_AND_PC(fp);
|
||||
@ -5696,7 +5651,7 @@ interrupt:
|
||||
goto out;
|
||||
}
|
||||
STORE_OPND(-1, OBJECT_TO_JSVAL(obj));
|
||||
END_LITOPX_CASE(JSOP_QNAMECONST)
|
||||
END_CASE(JSOP_QNAMECONST)
|
||||
|
||||
BEGIN_CASE(JSOP_QNAME)
|
||||
rval = FETCH_OPND(-1);
|
||||
@ -5872,7 +5827,8 @@ interrupt:
|
||||
STORE_OPND(-1, STRING_TO_JSVAL(str));
|
||||
END_CASE(JSOP_XMLELTEXPR)
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_XMLOBJECT, 0)
|
||||
BEGIN_CASE(JSOP_XMLOBJECT)
|
||||
LOAD_ATOM(0);
|
||||
SAVE_SP_AND_PC(fp);
|
||||
obj = js_CloneXMLObject(cx, ATOM_TO_OBJECT(atom));
|
||||
if (!obj) {
|
||||
@ -5881,9 +5837,10 @@ interrupt:
|
||||
}
|
||||
PUSH_OPND(OBJECT_TO_JSVAL(obj));
|
||||
obj = NULL;
|
||||
END_LITOPX_CASE(JSOP_XMLOBJECT)
|
||||
END_CASE(JSOP_XMLOBJECT)
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_XMLCDATA, 0)
|
||||
BEGIN_CASE(JSOP_XMLCDATA)
|
||||
LOAD_ATOM(0);
|
||||
str = ATOM_TO_STRING(atom);
|
||||
obj = js_NewXMLSpecialObject(cx, JSXML_CLASS_TEXT, NULL, str);
|
||||
if (!obj) {
|
||||
@ -5891,9 +5848,10 @@ interrupt:
|
||||
goto out;
|
||||
}
|
||||
PUSH_OPND(OBJECT_TO_JSVAL(obj));
|
||||
END_LITOPX_CASE(JSOP_XMLCDATA)
|
||||
END_CASE(JSOP_XMLCDATA)
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_XMLCOMMENT, 0)
|
||||
BEGIN_CASE(JSOP_XMLCOMMENT)
|
||||
LOAD_ATOM(0);
|
||||
str = ATOM_TO_STRING(atom);
|
||||
obj = js_NewXMLSpecialObject(cx, JSXML_CLASS_COMMENT, NULL, str);
|
||||
if (!obj) {
|
||||
@ -5901,9 +5859,10 @@ interrupt:
|
||||
goto out;
|
||||
}
|
||||
PUSH_OPND(OBJECT_TO_JSVAL(obj));
|
||||
END_LITOPX_CASE(JSOP_XMLCOMMENT)
|
||||
END_CASE(JSOP_XMLCOMMENT)
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_XMLPI, 0)
|
||||
BEGIN_CASE(JSOP_XMLPI)
|
||||
LOAD_ATOM(0);
|
||||
str = ATOM_TO_STRING(atom);
|
||||
rval = FETCH_OPND(-1);
|
||||
str2 = JSVAL_TO_STRING(rval);
|
||||
@ -5916,10 +5875,11 @@ interrupt:
|
||||
goto out;
|
||||
}
|
||||
STORE_OPND(-1, OBJECT_TO_JSVAL(obj));
|
||||
END_LITOPX_CASE(JSOP_XMLPI)
|
||||
END_CASE(JSOP_XMLPI)
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_GETMETHOD, 0)
|
||||
BEGIN_CASE(JSOP_GETMETHOD)
|
||||
/* Get an immediate atom naming the property. */
|
||||
LOAD_ATOM(0);
|
||||
id = ATOM_TO_JSID(atom);
|
||||
lval = FETCH_OPND(-1);
|
||||
SAVE_SP_AND_PC(fp);
|
||||
@ -5968,10 +5928,11 @@ interrupt:
|
||||
if (!ok)
|
||||
goto out;
|
||||
STORE_OPND(-1, rval);
|
||||
END_LITOPX_CASE(JSOP_GETMETHOD)
|
||||
END_CASE(JSOP_GETMETHOD)
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_SETMETHOD, 0)
|
||||
BEGIN_CASE(JSOP_SETMETHOD)
|
||||
/* Get an immediate atom naming the property. */
|
||||
LOAD_ATOM(0);
|
||||
id = ATOM_TO_JSID(atom);
|
||||
rval = FETCH_OPND(-1);
|
||||
FETCH_OBJECT(cx, -2, lval, obj);
|
||||
@ -5991,7 +5952,7 @@ interrupt:
|
||||
--sp;
|
||||
STORE_OPND(-1, rval);
|
||||
obj = NULL;
|
||||
END_LITOPX_CASE(JSOP_SETMETHOD)
|
||||
END_CASE(JSOP_SETMETHOD)
|
||||
|
||||
BEGIN_CASE(JSOP_GETFUNNS)
|
||||
ok = js_GetFunctionNamespace(cx, &rval);
|
||||
@ -6001,7 +5962,8 @@ interrupt:
|
||||
END_CASE(JSOP_GETFUNNS)
|
||||
#endif /* JS_HAS_XML_SUPPORT */
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_ENTERBLOCK, 0)
|
||||
BEGIN_CASE(JSOP_ENTERBLOCK)
|
||||
LOAD_ATOM(0);
|
||||
obj = ATOM_TO_OBJECT(atom);
|
||||
JS_ASSERT(fp->spbase + OBJ_BLOCK_DEPTH(cx, obj) == sp);
|
||||
vp = sp + OBJ_BLOCK_COUNT(cx, obj);
|
||||
@ -6033,7 +5995,7 @@ interrupt:
|
||||
OBJ_GET_PARENT(cx, obj) == fp->blockChain);
|
||||
fp->blockChain = obj;
|
||||
}
|
||||
END_LITOPX_CASE(JSOP_ENTERBLOCK)
|
||||
END_CASE(JSOP_ENTERBLOCK)
|
||||
|
||||
BEGIN_CASE(JSOP_LEAVEBLOCKEXPR)
|
||||
BEGIN_CASE(JSOP_LEAVEBLOCK)
|
||||
|
@ -63,11 +63,11 @@
|
||||
#include "jslock.h"
|
||||
#include "jsnum.h"
|
||||
#include "jsobj.h"
|
||||
#include "jsopcode.h"
|
||||
#include "jsscan.h"
|
||||
#include "jsscope.h"
|
||||
#include "jsscript.h"
|
||||
#include "jsstr.h"
|
||||
#include "jsopcode.h"
|
||||
|
||||
#include "jsdbgapi.h" /* whether or not JS_HAS_OBJ_WATCHPOINT */
|
||||
|
||||
@ -787,7 +787,9 @@ js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
size_t classnchars = strlen(classname);
|
||||
static const char classpropid[] = "C";
|
||||
const char *cp;
|
||||
#ifdef DEBUG
|
||||
size_t onchars = nchars;
|
||||
#endif
|
||||
|
||||
/* 2 for ': ', 2 quotes around classname, 2 for ', ' after. */
|
||||
classnchars += sizeof classpropid - 1 + 2 + 2;
|
||||
@ -3100,41 +3102,51 @@ Detecting(JSContext *cx, jsbytecode *pc)
|
||||
if (!cx->fp)
|
||||
return JS_FALSE;
|
||||
script = cx->fp->script;
|
||||
for (endpc = script->code + script->length; pc < endpc; pc++) {
|
||||
for (endpc = script->code + script->length;
|
||||
pc < endpc;
|
||||
pc += js_CodeSpec[op].length) {
|
||||
/* General case: a branch or equality op follows the access. */
|
||||
op = (JSOp) *pc;
|
||||
if (js_CodeSpec[op].format & JOF_DETECTING)
|
||||
return JS_TRUE;
|
||||
|
||||
/*
|
||||
* Special case #1: handle (document.all == null). Don't sweat about
|
||||
* JS1.2's revision of the equality operators here.
|
||||
*/
|
||||
if (op == JSOP_NULL) {
|
||||
switch (op) {
|
||||
case JSOP_NULL:
|
||||
/*
|
||||
* Special case #1: handle (document.all == null). Don't sweat
|
||||
* about JS1.2's revision of the equality operators here.
|
||||
*/
|
||||
if (++pc < endpc)
|
||||
return *pc == JSOP_EQ || *pc == JSOP_NE;
|
||||
break;
|
||||
}
|
||||
return JS_FALSE;
|
||||
|
||||
/*
|
||||
* Special case #2: handle (document.all == undefined). Don't worry
|
||||
* about someone redefining undefined, which was added by Edition 3,
|
||||
* so is read/write for backward compatibility.
|
||||
*/
|
||||
if (op == JSOP_NAME) {
|
||||
atom = GET_ATOM(cx, script, pc);
|
||||
case JSOP_NAME:
|
||||
/*
|
||||
* Special case #2: handle (document.all == undefined). Don't
|
||||
* worry about someone redefining undefined, which was added by
|
||||
* Edition 3, so is read/write for backward compatibility.
|
||||
*/
|
||||
atom = js_GetAtomFromBytecode(cx, script, pc, 0);
|
||||
if (atom == cx->runtime->atomState.typeAtoms[JSTYPE_VOID] &&
|
||||
(pc += js_CodeSpec[op].length) < endpc) {
|
||||
op = (JSOp) *pc;
|
||||
return op == JSOP_EQ || op == JSOP_NE ||
|
||||
op == JSOP_STRICTEQ || op == JSOP_STRICTNE;
|
||||
}
|
||||
return JS_FALSE;
|
||||
|
||||
case JSOP_GROUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* At this point, anything but grouping means we're not detecting
|
||||
* unless we see an extended atom index prefix.
|
||||
*/
|
||||
if (js_CodeSpec[op].format & JOF_ATOMBASE)
|
||||
return JS_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* At this point, anything but grouping means we're not detecting. */
|
||||
if (op != JSOP_GROUP)
|
||||
break;
|
||||
}
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
@ -110,6 +110,33 @@ GetJumpOffset(jsbytecode *pc, jsbytecode *pc2)
|
||||
return GET_JUMP_OFFSET(pc2);
|
||||
}
|
||||
|
||||
JSAtom *
|
||||
js_GetAtomFromBytecode(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
ptrdiff_t pcoff)
|
||||
{
|
||||
JSOp op;
|
||||
uintN span, atomBase;
|
||||
|
||||
op = (JSOp)*pc;
|
||||
JS_ASSERT(js_CodeSpec[op].length >= 1 + pcoff + ATOM_INDEX_LEN);
|
||||
|
||||
/*
|
||||
* We need to detect atom base prefix. It presents when resetbase
|
||||
* follows the bytecode.
|
||||
*/
|
||||
span = js_CodeSpec[op].length;
|
||||
atomBase = 0;
|
||||
if (pc - script->code + span < script->length) {
|
||||
if (pc[span] == JSOP_RESETBASE) {
|
||||
atomBase = GET_ATOMBASE(pc - JSOP_ATOMBASE_LENGTH);
|
||||
} else if (pc[span] == JSOP_RESETBASE0) {
|
||||
JS_ASSERT(JSOP_ATOMBASE1 <= pc[-1] || pc[-1] <= JSOP_ATOMBASE3);
|
||||
atomBase = (pc[-1] - JSOP_ATOMBASE1 + 1) << 16;
|
||||
}
|
||||
}
|
||||
return GET_ATOM(cx, script->atomMap.vector + atomBase, pc + pcoff);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
@ -169,8 +196,8 @@ ToDisassemblySource(JSContext *cx, jsval v)
|
||||
}
|
||||
|
||||
JS_FRIEND_API(uintN)
|
||||
js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc,
|
||||
JSBool lines, FILE *fp)
|
||||
js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
uintN loc, JSBool lines, FILE *fp)
|
||||
{
|
||||
JSOp op;
|
||||
const JSCodeSpec *cs;
|
||||
@ -212,7 +239,7 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc,
|
||||
break;
|
||||
|
||||
case JOF_CONST:
|
||||
atom = GET_ATOM(cx, script, pc);
|
||||
atom = js_GetAtomFromBytecode(cx, script, pc, 0);
|
||||
bytes = ToDisassemblySource(cx, ATOM_KEY(atom));
|
||||
if (!bytes)
|
||||
return 0;
|
||||
@ -224,6 +251,10 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc,
|
||||
fprintf(fp, " %u", GET_UINT16(pc));
|
||||
break;
|
||||
|
||||
case JOF_2BYTE:
|
||||
fprintf(fp, " %u", (uintN)pc[1]);
|
||||
break;
|
||||
|
||||
case JOF_TABLESWITCH:
|
||||
case JOF_TABLESWITCHX:
|
||||
{
|
||||
@ -260,11 +291,11 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc,
|
||||
pc2 = pc;
|
||||
off = GetJumpOffset(pc, pc2);
|
||||
pc2 += jmplen;
|
||||
npairs = GET_ATOM_INDEX(pc2);
|
||||
pc2 += ATOM_INDEX_LEN;
|
||||
npairs = GET_UINT16(pc2);
|
||||
pc2 += UINT16_LEN;
|
||||
fprintf(fp, " offset %d npairs %u", off, (uintN) npairs);
|
||||
while (npairs) {
|
||||
atom = GET_ATOM(cx, script, pc2);
|
||||
atom = GET_ATOM(cx, script->atomMap.vector, pc2);
|
||||
pc2 += ATOM_INDEX_LEN;
|
||||
off = GetJumpOffset(pc, pc2);
|
||||
pc2 += jmplen;
|
||||
@ -289,8 +320,7 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc,
|
||||
|
||||
case JOF_INDEXCONST:
|
||||
fprintf(fp, " %u", GET_VARNO(pc));
|
||||
pc += VARNO_LEN;
|
||||
atom = GET_ATOM(cx, script, pc);
|
||||
atom = js_GetAtomFromBytecode(cx, script, pc, VARNO_LEN);
|
||||
bytes = ToDisassemblySource(cx, ATOM_KEY(atom));
|
||||
if (!bytes)
|
||||
return 0;
|
||||
@ -298,45 +328,10 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc,
|
||||
break;
|
||||
|
||||
case JOF_UINT24:
|
||||
if (op == JSOP_FINDNAME) {
|
||||
/* Special case to avoid a JOF_FINDNAME just for this op. */
|
||||
atom = js_GetAtom(cx, &script->atomMap, GET_UINT24(pc));
|
||||
bytes = ToDisassemblySource(cx, ATOM_KEY(atom));
|
||||
if (!bytes)
|
||||
return 0;
|
||||
fprintf(fp, " %s", bytes);
|
||||
break;
|
||||
}
|
||||
|
||||
JS_ASSERT(op == JSOP_UINT24 || op == JSOP_LITERAL);
|
||||
JS_ASSERT(op == JSOP_UINT24);
|
||||
fprintf(fp, " %u", GET_UINT24(pc));
|
||||
break;
|
||||
|
||||
case JOF_LITOPX:
|
||||
atom = js_GetAtom(cx, &script->atomMap, GET_LITERAL_INDEX(pc));
|
||||
bytes = ToDisassemblySource(cx, ATOM_KEY(atom));
|
||||
if (!bytes)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Bytecode: JSOP_LITOPX <uint24> op [<varno> if JSOP_DEFLOCALFUN].
|
||||
* Advance pc to point at op.
|
||||
*/
|
||||
pc += 1 + LITERAL_INDEX_LEN;
|
||||
op = *pc;
|
||||
cs = &js_CodeSpec[op];
|
||||
fprintf(fp, " %s op %s", bytes, cs->name);
|
||||
if ((cs->format & JOF_TYPEMASK) == JOF_INDEXCONST)
|
||||
fprintf(fp, " %u", GET_VARNO(pc));
|
||||
|
||||
/*
|
||||
* Adjust len to advance pc to skip op and any other immediates
|
||||
* (namely, <varno> if JSOP_DEFLOCALFUN).
|
||||
*/
|
||||
JS_ASSERT(cs->length > ATOM_INDEX_LEN);
|
||||
len += cs->length - (1 + ATOM_INDEX_LEN);
|
||||
break;
|
||||
|
||||
default: {
|
||||
char numBuf[12];
|
||||
JS_snprintf(numBuf, sizeof numBuf, "%lx", (unsigned long) cs->format);
|
||||
@ -1227,7 +1222,7 @@ DecompileDestructuringLHS(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc,
|
||||
else if (op == JSOP_SETVAR)
|
||||
atom = GetSlotAtom(jp, js_GetLocalVariable, i);
|
||||
else if (op == JSOP_SETGVAR)
|
||||
atom = GET_ATOM(cx, jp->script, pc);
|
||||
atom = js_GetAtomFromBytecode(cx, jp->script, pc, 0);
|
||||
else
|
||||
lval = GetLocal(ss, i, JS_TRUE);
|
||||
if (atom)
|
||||
@ -1312,8 +1307,6 @@ DecompileDestructuring(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc)
|
||||
jsint i, lasti;
|
||||
jsdouble d;
|
||||
const char *lval;
|
||||
jsbytecode *pc2;
|
||||
jsatomid atomIndex;
|
||||
JSAtom *atom;
|
||||
jssrcnote *sn;
|
||||
JSString *str;
|
||||
@ -1353,19 +1346,8 @@ DecompileDestructuring(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc)
|
||||
case JSOP_UINT16: d = i = GET_UINT16(pc); goto do_getelem;
|
||||
case JSOP_UINT24: d = i = GET_UINT24(pc); goto do_getelem;
|
||||
|
||||
/* Handle the extended literal form of JSOP_NUMBER. */
|
||||
case JSOP_LITOPX:
|
||||
atomIndex = GET_LITERAL_INDEX(pc);
|
||||
pc2 = pc + 1 + LITERAL_INDEX_LEN;
|
||||
op = *pc2;
|
||||
LOCAL_ASSERT(op == JSOP_NUMBER);
|
||||
goto do_getatom;
|
||||
|
||||
case JSOP_NUMBER:
|
||||
atomIndex = GET_ATOM_INDEX(pc);
|
||||
|
||||
do_getatom:
|
||||
atom = js_GetAtom(cx, &jp->script->atomMap, atomIndex);
|
||||
atom = js_GetAtomFromBytecode(cx, jp->script, pc, 0);
|
||||
d = *ATOM_TO_DOUBLE(atom);
|
||||
LOCAL_ASSERT(JSDOUBLE_IS_FINITE(d) && !JSDOUBLE_IS_NEGZERO(d));
|
||||
i = (jsint)d;
|
||||
@ -1379,8 +1361,7 @@ DecompileDestructuring(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc)
|
||||
LOCAL_ASSERT(op == JSOP_GETELEM);
|
||||
|
||||
/* Distinguish object from array by opcode or source note. */
|
||||
if (saveop == JSOP_LITERAL ||
|
||||
(sn && SN_TYPE(sn) == SRC_INITPROP)) {
|
||||
if (sn && SN_TYPE(sn) == SRC_INITPROP) {
|
||||
*OFF2STR(&ss->sprinter, head) = '{';
|
||||
if (Sprint(&ss->sprinter, "%g: ", d) < 0)
|
||||
return NULL;
|
||||
@ -1396,13 +1377,9 @@ DecompileDestructuring(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc)
|
||||
}
|
||||
break;
|
||||
|
||||
case JSOP_LITERAL:
|
||||
atomIndex = GET_LITERAL_INDEX(pc);
|
||||
goto do_getatom;
|
||||
|
||||
case JSOP_GETPROP:
|
||||
*OFF2STR(&ss->sprinter, head) = '{';
|
||||
atom = GET_ATOM(cx, jp->script, pc);
|
||||
atom = js_GetAtomFromBytecode(cx, jp->script, pc, 0);
|
||||
str = ATOM_TO_STRING(atom);
|
||||
if (!QuoteString(&ss->sprinter, str,
|
||||
js_IsIdentifier(str) ? 0 : (jschar)'\'')) {
|
||||
@ -1535,7 +1512,6 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
const char *lval, *rval, *xval, *fmt;
|
||||
jsint i, argc;
|
||||
char **argv;
|
||||
jsatomid atomIndex;
|
||||
JSAtom *atom;
|
||||
JSObject *obj;
|
||||
JSFunction *fun;
|
||||
@ -1594,13 +1570,16 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
return NULL; \
|
||||
JS_END_MACRO
|
||||
|
||||
#define LOAD_ATOM(PCOFF) \
|
||||
(atom = js_GetAtomFromBytecode(cx, jp->script, pc, PCOFF))
|
||||
|
||||
/*
|
||||
* Get atom from jp->script's atom map, quote/escape its string appropriately
|
||||
* into rval, and select fmt from the quoted and unquoted alternatives.
|
||||
*/
|
||||
#define GET_ATOM_QUOTE_AND_FMT(qfmt, ufmt, rval) \
|
||||
JS_BEGIN_MACRO \
|
||||
atom = GET_ATOM(cx, jp->script, pc); \
|
||||
LOAD_ATOM(0); \
|
||||
GET_QUOTE_AND_FMT(qfmt, ufmt, rval); \
|
||||
JS_END_MACRO
|
||||
|
||||
@ -1632,8 +1611,21 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
* set to nop or otherwise mutated to suppress auto-parens.
|
||||
*/
|
||||
lastop = saveop;
|
||||
op = saveop = (JSOp) *pc;
|
||||
cs = &js_CodeSpec[saveop];
|
||||
op = (JSOp) *pc;
|
||||
cs = &js_CodeSpec[op];
|
||||
if (cs->format & JOF_ATOMBASE) {
|
||||
/*
|
||||
* The decompiler uses js_GetAtomFromBytecode to get atoms and
|
||||
* ignores these suffix/prefix bytecodes, thus simplifying code
|
||||
* that must process JSOP_GETTER/JSOP_SETTER prefixes.
|
||||
*/
|
||||
pc += cs->length;
|
||||
if (pc >= endpc)
|
||||
break;
|
||||
op = (JSOp) *pc;
|
||||
cs = &js_CodeSpec[op];
|
||||
}
|
||||
saveop = op;
|
||||
len = oplen = cs->length;
|
||||
|
||||
if (nb < 0 && -(nb + 1) == (intN)ss->top - cs->nuses + cs->ndefs)
|
||||
@ -1784,10 +1776,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
switch (op) {
|
||||
#define BEGIN_LITOPX_CASE(OP,PCOFF) \
|
||||
case OP: \
|
||||
pc2 = pc; \
|
||||
atomIndex = GET_ATOM_INDEX(pc + PCOFF); \
|
||||
do_##OP: \
|
||||
atom = js_GetAtom(cx, &jp->script->atomMap, atomIndex);
|
||||
LOAD_ATOM(PCOFF);
|
||||
|
||||
#define END_LITOPX_CASE \
|
||||
break;
|
||||
@ -1972,7 +1961,6 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
|
||||
case JSOP_PUSHOBJ:
|
||||
case JSOP_BINDNAME:
|
||||
do_JSOP_BINDNAME:
|
||||
todo = Sprint(&ss->sprinter, "");
|
||||
break;
|
||||
|
||||
@ -2776,7 +2764,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
goto do_fornameinloop;
|
||||
|
||||
case JSOP_FORNAME:
|
||||
atom = GET_ATOM(cx, jp->script, pc);
|
||||
LOAD_ATOM(0);
|
||||
|
||||
do_fornameinloop:
|
||||
lval = "";
|
||||
@ -2787,7 +2775,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
|
||||
case JSOP_FORPROP:
|
||||
xval = NULL;
|
||||
atom = GET_ATOM(cx, jp->script, pc);
|
||||
LOAD_ATOM(0);
|
||||
if (!ATOM_IS_IDENTIFIER(atom)) {
|
||||
xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
|
||||
(jschar)'\'');
|
||||
@ -3004,10 +2992,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
case JSOP_SETCONST:
|
||||
case JSOP_SETNAME:
|
||||
case JSOP_SETGVAR:
|
||||
atomIndex = GET_ATOM_INDEX(pc);
|
||||
|
||||
do_JSOP_SETCONST:
|
||||
atom = js_GetAtom(cx, &jp->script->atomMap, atomIndex);
|
||||
LOAD_ATOM(0);
|
||||
|
||||
do_setname:
|
||||
lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
|
||||
@ -3115,7 +3100,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
break;
|
||||
|
||||
case JSOP_DELNAME:
|
||||
atom = GET_ATOM(cx, jp->script, pc);
|
||||
LOAD_ATOM(0);
|
||||
lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
|
||||
if (!lval)
|
||||
return NULL;
|
||||
@ -3176,7 +3161,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
case JSOP_DECNAME:
|
||||
case JSOP_INCGVAR:
|
||||
case JSOP_DECGVAR:
|
||||
atom = GET_ATOM(cx, jp->script, pc);
|
||||
LOAD_ATOM(0);
|
||||
do_incatom:
|
||||
lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
|
||||
if (!lval)
|
||||
@ -3238,7 +3223,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
case JSOP_NAMEDEC:
|
||||
case JSOP_GVARINC:
|
||||
case JSOP_GVARDEC:
|
||||
atom = GET_ATOM(cx, jp->script, pc);
|
||||
LOAD_ATOM(0);
|
||||
do_atominc:
|
||||
lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
|
||||
if (!lval)
|
||||
@ -3290,7 +3275,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
|
||||
case JSOP_GETPROP:
|
||||
case JSOP_GETXPROP:
|
||||
atom = GET_ATOM(cx, jp->script, pc);
|
||||
LOAD_ATOM(0);
|
||||
|
||||
do_getprop:
|
||||
GET_QUOTE_AND_FMT(index_format, dot_format, rval);
|
||||
@ -3342,7 +3327,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
#endif
|
||||
|
||||
case JSOP_SETPROP:
|
||||
atom = GET_ATOM(cx, jp->script, pc);
|
||||
LOAD_ATOM(0);
|
||||
|
||||
do_setprop:
|
||||
GET_QUOTE_AND_FMT("%s[%s] %s= %s", "%s.%s %s= %s", xval);
|
||||
@ -3418,7 +3403,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
break;
|
||||
|
||||
case JSOP_ARGSUB:
|
||||
i = (jsint) GET_ATOM_INDEX(pc);
|
||||
i = (jsint) GET_ARGNO(pc);
|
||||
todo = Sprint(&ss->sprinter, "%s[%d]",
|
||||
js_arguments_str, (int) i);
|
||||
break;
|
||||
@ -3448,7 +3433,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
|
||||
case JSOP_NAME:
|
||||
case JSOP_GETGVAR:
|
||||
atom = GET_ATOM(cx, jp->script, pc);
|
||||
LOAD_ATOM(0);
|
||||
do_name:
|
||||
lval = "";
|
||||
do_qname:
|
||||
@ -3462,7 +3447,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
break;
|
||||
|
||||
case JSOP_UINT16:
|
||||
i = (jsint) GET_ATOM_INDEX(pc);
|
||||
i = (jsint) GET_UINT16(pc);
|
||||
goto do_sprint_int;
|
||||
|
||||
case JSOP_UINT24:
|
||||
@ -3471,62 +3456,6 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
todo = Sprint(&ss->sprinter, "%u", (unsigned) i);
|
||||
break;
|
||||
|
||||
case JSOP_LITERAL:
|
||||
atomIndex = GET_LITERAL_INDEX(pc);
|
||||
goto do_JSOP_STRING;
|
||||
|
||||
case JSOP_FINDNAME:
|
||||
atomIndex = GET_LITERAL_INDEX(pc);
|
||||
todo = Sprint(&ss->sprinter, "");
|
||||
if (todo < 0 || !PushOff(ss, todo, op))
|
||||
return NULL;
|
||||
atom = js_GetAtom(cx, &jp->script->atomMap, atomIndex);
|
||||
goto do_name;
|
||||
|
||||
case JSOP_LITOPX:
|
||||
atomIndex = GET_LITERAL_INDEX(pc);
|
||||
pc2 = pc + 1 + LITERAL_INDEX_LEN;
|
||||
op = saveop = *pc2;
|
||||
pc += len - (1 + ATOM_INDEX_LEN);
|
||||
cs = &js_CodeSpec[op];
|
||||
len = cs->length;
|
||||
switch (op) {
|
||||
case JSOP_ANONFUNOBJ: goto do_JSOP_ANONFUNOBJ;
|
||||
case JSOP_BINDNAME: goto do_JSOP_BINDNAME;
|
||||
case JSOP_CLOSURE: goto do_JSOP_CLOSURE;
|
||||
#if JS_HAS_EXPORT_IMPORT
|
||||
case JSOP_EXPORTNAME: goto do_JSOP_EXPORTNAME;
|
||||
#endif
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
case JSOP_GETMETHOD: goto do_JSOP_GETMETHOD;
|
||||
case JSOP_SETMETHOD: goto do_JSOP_SETMETHOD;
|
||||
#endif
|
||||
case JSOP_NAMEDFUNOBJ: goto do_JSOP_NAMEDFUNOBJ;
|
||||
case JSOP_NUMBER: goto do_JSOP_NUMBER;
|
||||
case JSOP_OBJECT: goto do_JSOP_OBJECT;
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
case JSOP_QNAMECONST: goto do_JSOP_QNAMECONST;
|
||||
case JSOP_QNAMEPART: goto do_JSOP_QNAMEPART;
|
||||
#endif
|
||||
case JSOP_REGEXP: goto do_JSOP_REGEXP;
|
||||
case JSOP_SETCONST: goto do_JSOP_SETCONST;
|
||||
case JSOP_STRING: goto do_JSOP_STRING;
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
case JSOP_XMLCDATA: goto do_JSOP_XMLCDATA;
|
||||
case JSOP_XMLCOMMENT: goto do_JSOP_XMLCOMMENT;
|
||||
case JSOP_XMLOBJECT: goto do_JSOP_XMLOBJECT;
|
||||
case JSOP_XMLPI: goto do_JSOP_XMLPI;
|
||||
#endif
|
||||
case JSOP_ENTERBLOCK: goto do_JSOP_ENTERBLOCK;
|
||||
case JSOP_GETTHISPROP: goto do_JSOP_GETTHISPROP;
|
||||
case JSOP_GETARGPROP: goto do_JSOP_GETARGPROP;
|
||||
case JSOP_GETVARPROP: goto do_JSOP_GETVARPROP;
|
||||
case JSOP_GETLOCALPROP: goto do_JSOP_GETLOCALPROP;
|
||||
default: LOCAL_ASSERT(0);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
break;
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_NUMBER, 0)
|
||||
val = ATOM_KEY(atom);
|
||||
if (JSVAL_IS_INT(val)) {
|
||||
@ -3556,13 +3485,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
case JSOP_REGEXP:
|
||||
case JSOP_ANONFUNOBJ:
|
||||
case JSOP_NAMEDFUNOBJ:
|
||||
atomIndex = GET_ATOM_INDEX(pc);
|
||||
|
||||
do_JSOP_OBJECT:
|
||||
do_JSOP_REGEXP:
|
||||
do_JSOP_ANONFUNOBJ:
|
||||
do_JSOP_NAMEDFUNOBJ:
|
||||
atom = js_GetAtom(cx, &jp->script->atomMap, atomIndex);
|
||||
LOAD_ATOM(0);
|
||||
if (op == JSOP_OBJECT || op == JSOP_REGEXP) {
|
||||
if (!js_regexp_toString(cx, ATOM_TO_OBJECT(atom), 0, NULL,
|
||||
&val)) {
|
||||
@ -3667,8 +3590,8 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
pc2 = pc;
|
||||
off = GetJumpOffset(pc, pc2);
|
||||
pc2 += jmplen;
|
||||
npairs = GET_ATOM_INDEX(pc2);
|
||||
pc2 += ATOM_INDEX_LEN;
|
||||
npairs = GET_UINT16(pc2);
|
||||
pc2 += UINT16_LEN;
|
||||
|
||||
table = (TableEntry *)
|
||||
JS_malloc(cx, (size_t)npairs * sizeof *table);
|
||||
@ -3684,7 +3607,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
} else {
|
||||
table[k].label = NULL;
|
||||
}
|
||||
atom = GET_ATOM(cx, jp->script, pc2);
|
||||
atom = GET_ATOM(cx, jp->script->atomMap.vector, pc2);
|
||||
pc2 += ATOM_INDEX_LEN;
|
||||
off2 = GetJumpOffset(pc, pc2);
|
||||
pc2 += jmplen;
|
||||
@ -3866,7 +3789,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
pc += len;
|
||||
cs = &js_CodeSpec[op];
|
||||
len = cs->length;
|
||||
i = (jsint) GET_ATOM_INDEX(pc);
|
||||
i = (jsint) GET_UINT16(pc);
|
||||
if (Sprint(&ss->sprinter, "#%u=", (unsigned) i) < 0)
|
||||
return NULL;
|
||||
}
|
||||
@ -3894,7 +3817,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
break;
|
||||
|
||||
case JSOP_INITPROP:
|
||||
atom = GET_ATOM(cx, jp->script, pc);
|
||||
LOAD_ATOM(0);
|
||||
xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
|
||||
(jschar)
|
||||
(ATOM_IS_IDENTIFIER(atom) ? 0 : '\''));
|
||||
@ -3962,13 +3885,13 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
|
||||
#if JS_HAS_SHARP_VARS
|
||||
case JSOP_DEFSHARP:
|
||||
i = (jsint) GET_ATOM_INDEX(pc);
|
||||
i = (jsint) GET_UINT16(pc);
|
||||
rval = POP_STR();
|
||||
todo = Sprint(&ss->sprinter, "#%u=%s", (unsigned) i, rval);
|
||||
break;
|
||||
|
||||
case JSOP_USESHARP:
|
||||
i = (jsint) GET_ATOM_INDEX(pc);
|
||||
i = (jsint) GET_UINT16(pc);
|
||||
todo = Sprint(&ss->sprinter, "#%u#", (unsigned) i);
|
||||
break;
|
||||
#endif /* JS_HAS_SHARP_VARS */
|
||||
@ -4677,12 +4600,9 @@ js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v,
|
||||
*/
|
||||
pcdepth = 0;
|
||||
for (pc = script->main; pc < begin; pc += oplen) {
|
||||
jsbytecode *pc2;
|
||||
uint32 type;
|
||||
intN nuses, ndefs;
|
||||
|
||||
/* Let pc2 be non-null only for JSOP_LITOPX. */
|
||||
pc2 = NULL;
|
||||
op = (JSOp) *pc;
|
||||
if (op == JSOP_TRAP)
|
||||
op = JS_GetTrapOpcode(cx, script, pc);
|
||||
@ -4732,6 +4652,7 @@ js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v,
|
||||
case JOF_TABLESWITCHX:
|
||||
{
|
||||
jsint jmplen, i, low, high;
|
||||
jsbytecode *pc2;
|
||||
|
||||
jmplen = (type == JOF_TABLESWITCH) ? JUMP_OFFSET_LEN
|
||||
: JUMPX_OFFSET_LEN;
|
||||
@ -4758,7 +4679,7 @@ js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v,
|
||||
: JUMPX_OFFSET_LEN;
|
||||
pc2 = pc;
|
||||
pc2 += jmplen;
|
||||
npairs = GET_ATOM_INDEX(pc2);
|
||||
npairs = GET_UINT16(pc2);
|
||||
pc2 += ATOM_INDEX_LEN;
|
||||
while (npairs) {
|
||||
pc2 += ATOM_INDEX_LEN;
|
||||
@ -4769,14 +4690,6 @@ js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v,
|
||||
break;
|
||||
}
|
||||
|
||||
case JOF_LITOPX:
|
||||
pc2 = pc + 1 + LITERAL_INDEX_LEN;
|
||||
op = *pc2;
|
||||
cs = &js_CodeSpec[op];
|
||||
JS_ASSERT(cs->length > ATOM_INDEX_LEN);
|
||||
oplen += cs->length - (1 + ATOM_INDEX_LEN);
|
||||
break;
|
||||
|
||||
default:;
|
||||
}
|
||||
|
||||
@ -4804,13 +4717,11 @@ js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v,
|
||||
JS_ASSERT(ndefs == 0);
|
||||
ndefs = 2;
|
||||
} else if (op == JSOP_ENTERBLOCK) {
|
||||
jsatomid atomIndex;
|
||||
JSAtom *atom;
|
||||
JSObject *obj;
|
||||
|
||||
JS_ASSERT(ndefs == 0);
|
||||
atomIndex = pc2 ? GET_LITERAL_INDEX(pc) : GET_ATOM_INDEX(pc);
|
||||
atom = js_GetAtom(cx, &script->atomMap, atomIndex);
|
||||
atom = js_GetAtomFromBytecode(cx, script, pc, 0);
|
||||
obj = ATOM_TO_OBJECT(atom);
|
||||
JS_ASSERT(OBJ_BLOCK_DEPTH(cx, obj) == pcdepth);
|
||||
ndefs = OBJ_BLOCK_COUNT(cx, obj);
|
||||
|
@ -84,9 +84,8 @@ typedef enum JSOpLength {
|
||||
#define JOF_TABLESWITCHX 10 /* extended (32-bit offset) table switch */
|
||||
#define JOF_LOOKUPSWITCHX 11 /* extended (32-bit offset) lookup switch */
|
||||
#define JOF_UINT24 12 /* extended unsigned 24-bit literal (index) */
|
||||
#define JOF_LITOPX 13 /* JOF_UINT24 followed by op being extended,
|
||||
where op if JOF_CONST has no unsigned 16-
|
||||
bit immediate operand */
|
||||
#define JOF_2BYTE 13 /* 2-byte opcode, e.g., upper 8 bits of 24-bit
|
||||
atom index */
|
||||
#define JOF_LOCAL 14 /* block-local operand stack variable */
|
||||
#define JOF_TYPEMASK 0x000f /* mask for above immediate types */
|
||||
#define JOF_NAME 0x0010 /* name operation */
|
||||
@ -109,6 +108,7 @@ typedef enum JSOpLength {
|
||||
#define JOF_BACKPATCH 0x8000 /* backpatch placeholder during codegen */
|
||||
#define JOF_LEFTASSOC 0x10000 /* left-associative operator */
|
||||
#define JOF_DECLARING 0x20000 /* var, const, or function declaration op */
|
||||
#define JOF_ATOMBASE 0x40000 /* atom segment base setting prefix op */
|
||||
|
||||
#define JOF_TYPE_IS_EXTENDED_JUMP(t) \
|
||||
((unsigned)((t) - JOF_JUMPX) <= (unsigned)(JOF_LOOKUPSWITCHX - JOF_JUMPX))
|
||||
@ -117,11 +117,19 @@ typedef enum JSOpLength {
|
||||
* Immediate operand getters, setters, and bounds.
|
||||
*/
|
||||
|
||||
/* Common uint16 immediate format helpers. */
|
||||
#define UINT16_LEN 2
|
||||
#define UINT16_HI(i) ((jsbytecode)((i) >> 8))
|
||||
#define UINT16_LO(i) ((jsbytecode)(i))
|
||||
#define GET_UINT16(pc) ((uintN)(((pc)[1] << 8) | (pc)[2]))
|
||||
#define SET_UINT16(pc,i) ((pc)[1] = UINT16_HI(i), (pc)[2] = UINT16_LO(i))
|
||||
#define UINT16_LIMIT ((uintN)1 << 16)
|
||||
|
||||
/* Short (2-byte signed offset) relative jump macros. */
|
||||
#define JUMP_OFFSET_LEN 2
|
||||
#define JUMP_OFFSET_HI(off) ((jsbytecode)((off) >> 8))
|
||||
#define JUMP_OFFSET_LO(off) ((jsbytecode)(off))
|
||||
#define GET_JUMP_OFFSET(pc) ((int16)(((pc)[1] << 8) | (pc)[2]))
|
||||
#define GET_JUMP_OFFSET(pc) ((int16)GET_UINT16(pc))
|
||||
#define SET_JUMP_OFFSET(pc,off) ((pc)[1] = JUMP_OFFSET_HI(off), \
|
||||
(pc)[2] = JUMP_OFFSET_LO(off))
|
||||
#define JUMP_OFFSET_MIN ((int16)0x8000)
|
||||
@ -138,7 +146,7 @@ typedef enum JSOpLength {
|
||||
* found (via binary search) by its "before span-dependency optimization" pc
|
||||
* offset (from script main entry point).
|
||||
*/
|
||||
#define GET_SPANDEP_INDEX(pc) ((uint16)(((pc)[1] << 8) | (pc)[2]))
|
||||
#define GET_SPANDEP_INDEX(pc) ((uint16)GET_UINT16(pc))
|
||||
#define SET_SPANDEP_INDEX(pc,i) ((pc)[1] = JUMP_OFFSET_HI(i), \
|
||||
(pc)[2] = JUMP_OFFSET_LO(i))
|
||||
#define SPANDEP_INDEX_MAX ((uint16)0xfffe)
|
||||
@ -162,18 +170,20 @@ typedef enum JSOpLength {
|
||||
/*
|
||||
* A literal is indexed by a per-script atom map. Most scripts have relatively
|
||||
* few literals, so the standard JOF_CONST format specifies a fixed 16 bits of
|
||||
* immediate operand index. A script with more than 64K literals must push all
|
||||
* high-indexed literals on the stack using JSOP_LITERAL, then use JOF_ELEM ops
|
||||
* instead of JOF_PROP, etc.
|
||||
* immediate operand index. A script with more than 64K literals must wrap the
|
||||
* bytecode into JSOP_ATOMBASE and JSOP_RESETBASE pair.
|
||||
*/
|
||||
#define ATOM_INDEX_LEN 2
|
||||
#define ATOM_INDEX_HI(i) ((jsbytecode)((i) >> 8))
|
||||
#define ATOM_INDEX_LO(i) ((jsbytecode)(i))
|
||||
#define GET_ATOM_INDEX(pc) ((jsatomid)(((pc)[1] << 8) | (pc)[2]))
|
||||
#define GET_ATOM_INDEX(pc) GET_UINT16(pc)
|
||||
#define SET_ATOM_INDEX(pc,i) ((pc)[1] = ATOM_INDEX_HI(i), \
|
||||
(pc)[2] = ATOM_INDEX_LO(i))
|
||||
#define GET_ATOM(cx,script,pc) js_GetAtom((cx), &(script)->atomMap, \
|
||||
GET_ATOM_INDEX(pc))
|
||||
#define GET_ATOM(cx,atoms,pc) ((atoms)[GET_ATOM_INDEX(pc)])
|
||||
|
||||
#define GET_ATOMBASE(pc) (JS_ASSERT(*(pc) == JSOP_ATOMBASE), \
|
||||
((uintN)((pc)[1])) << 16)
|
||||
#define ATOMBASE_LEN 1
|
||||
|
||||
/* A full atom index for JSOP_UINT24 uses 24 bits of immediate operand. */
|
||||
#define UINT24_HI(i) ((jsbytecode)((i) >> 16))
|
||||
@ -186,14 +196,6 @@ typedef enum JSOpLength {
|
||||
(pc)[2] = UINT24_MID(i), \
|
||||
(pc)[3] = UINT24_LO(i))
|
||||
|
||||
/* Same format for JSOP_LITERAL, etc., but future-proof with different names. */
|
||||
#define LITERAL_INDEX_LEN 3
|
||||
#define LITERAL_INDEX_HI(i) UINT24_HI(i)
|
||||
#define LITERAL_INDEX_MID(i) UINT24_MID(i)
|
||||
#define LITERAL_INDEX_LO(i) UINT24_LO(i)
|
||||
#define GET_LITERAL_INDEX(pc) GET_UINT24(pc)
|
||||
#define SET_LITERAL_INDEX(pc,i) SET_UINT24(pc,i)
|
||||
|
||||
/* Atom index limit is determined by SN_3BYTE_OFFSET_FLAG, see jsemit.h. */
|
||||
#define ATOM_INDEX_LIMIT_LOG2 23
|
||||
#define ATOM_INDEX_LIMIT ((uint32)1 << ATOM_INDEX_LIMIT_LOG2)
|
||||
@ -201,13 +203,6 @@ typedef enum JSOpLength {
|
||||
JS_STATIC_ASSERT(sizeof(jsatomid) * JS_BITS_PER_BYTE >=
|
||||
ATOM_INDEX_LIMIT_LOG2 + 1);
|
||||
|
||||
/* Common uint16 immediate format helpers. */
|
||||
#define UINT16_HI(i) ((jsbytecode)((i) >> 8))
|
||||
#define UINT16_LO(i) ((jsbytecode)(i))
|
||||
#define GET_UINT16(pc) ((uintN)(((pc)[1] << 8) | (pc)[2]))
|
||||
#define SET_UINT16(pc,i) ((pc)[1] = UINT16_HI(i), (pc)[2] = UINT16_LO(i))
|
||||
#define UINT16_LIMIT ((uintN)1 << 16)
|
||||
|
||||
/* Actual argument count operand format helpers. */
|
||||
#define ARGC_HI(argc) UINT16_HI(argc)
|
||||
#define ARGC_LO(argc) UINT16_LO(argc)
|
||||
@ -267,6 +262,14 @@ js_printf(JSPrinter *jp, const char *format, ...);
|
||||
extern JSBool
|
||||
js_puts(JSPrinter *jp, const char *s);
|
||||
|
||||
/*
|
||||
* A slower version of GET_ATOM when the caller does not want to maintain
|
||||
* atoms table offset itself.
|
||||
*/
|
||||
extern JSAtom*
|
||||
js_GetAtomFromBytecode(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
ptrdiff_t pcoff);
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* Disassemblers, for debugging only.
|
||||
|
@ -407,15 +407,19 @@ OPDEF(JSOP_FOREACH, 186,"foreach", NULL, 1, 1, 1, 0, JOF_BYTE)
|
||||
OPDEF(JSOP_DELDESC, 187,"deldesc", NULL, 1, 2, 1, 17, JOF_BYTE |JOF_ELEM|JOF_DEL)
|
||||
|
||||
/*
|
||||
* Opcodes for extended literal addressing, using unsigned 24-bit immediate
|
||||
* operands to hold integer operands (JSOP_UINT24), extended atom indexes in
|
||||
* script->atomMap (JSOP_LITERAL, JSOP_FINDNAME), and ops prefixed by such
|
||||
* atom index immediates (JSOP_LITOPX). See jsemit.c, EmitAtomIndexOp.
|
||||
* Opcode to hold 24-bit immediate integer operands.
|
||||
*/
|
||||
OPDEF(JSOP_UINT24, 188,"uint24", NULL, 4, 0, 1, 16, JOF_UINT24)
|
||||
OPDEF(JSOP_LITERAL, 189,"literal", NULL, 4, 0, 1, 19, JOF_UINT24)
|
||||
OPDEF(JSOP_FINDNAME, 190,"findname", NULL, 4, 0, 2, 0, JOF_UINT24)
|
||||
OPDEF(JSOP_LITOPX, 191,"litopx", NULL, 5, 0, 0, 0, JOF_LITOPX)
|
||||
|
||||
/*
|
||||
* Opcodes to allow 24-bit atom indexes. Whenever an atom index exceeds the
|
||||
* 16-bit limit, the atom-indexing bytecode must be bracketed by JSOP_ATOMBASE
|
||||
* and JSOP_RESETBASE to provide the upper bits of the index. See jsemit.c,
|
||||
* EmitAtomIndexOp.
|
||||
*/
|
||||
OPDEF(JSOP_ATOMBASE, 189,"atombase", NULL, 2, 0, 0, 0, JOF_2BYTE|JOF_ATOMBASE)
|
||||
OPDEF(JSOP_RESETBASE, 190,"resetbase", NULL, 1, 0, 0, 0, JOF_BYTE)
|
||||
OPDEF(JSOP_RESETBASE0, 191,"resetbase0", NULL, 1, 0, 0, 0, JOF_BYTE)
|
||||
|
||||
/*
|
||||
* Opcodes to help the decompiler deal with XML.
|
||||
@ -484,3 +488,11 @@ OPDEF(JSOP_GETTHISPROP, 216,"getthisprop", NULL, 3, 0, 1, 18, JOF_CONST)
|
||||
OPDEF(JSOP_GETARGPROP, 217,"getargprop", NULL, 5, 0, 1, 18, JOF_INDEXCONST|JOF_VARPROP)
|
||||
OPDEF(JSOP_GETVARPROP, 218,"getvarprop", NULL, 5, 0, 1, 18, JOF_INDEXCONST|JOF_VARPROP)
|
||||
OPDEF(JSOP_GETLOCALPROP, 219,"getlocalprop", NULL, 5, 0, 1, 18, JOF_INDEXCONST|JOF_VARPROP)
|
||||
|
||||
/*
|
||||
* Optimize atom segments 1-3. These must be followed by JSOP_RESETBASE0 after
|
||||
* the opcode that they prefix.
|
||||
*/
|
||||
OPDEF(JSOP_ATOMBASE1, 220,"atombase1", NULL, 1, 0, 0, 0, JOF_BYTE |JOF_ATOMBASE)
|
||||
OPDEF(JSOP_ATOMBASE2, 221,"atombase2", NULL, 1, 0, 0, 0, JOF_BYTE |JOF_ATOMBASE)
|
||||
OPDEF(JSOP_ATOMBASE3, 222,"atombase3", NULL, 1, 0, 0, 0, JOF_BYTE |JOF_ATOMBASE)
|
||||
|
@ -1515,12 +1515,10 @@ js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
|
||||
* Special case: function definition needs no line number note because
|
||||
* the function's script contains its starting line number.
|
||||
*/
|
||||
if (*pc == JSOP_DEFFUN ||
|
||||
(*pc == JSOP_LITOPX && pc[1 + LITERAL_INDEX_LEN] == JSOP_DEFFUN)) {
|
||||
atom = js_GetAtom(cx, &script->atomMap,
|
||||
(*pc == JSOP_DEFFUN)
|
||||
? GET_ATOM_INDEX(pc)
|
||||
: GET_LITERAL_INDEX(pc));
|
||||
if (js_CodeSpec[*pc].format & JOF_ATOMBASE)
|
||||
pc += js_CodeSpec[*pc].length;
|
||||
if (*pc == JSOP_DEFFUN) {
|
||||
atom = js_GetAtomFromBytecode(cx, script, pc, 0);
|
||||
fun = (JSFunction *) JS_GetPrivate(cx, ATOM_TO_OBJECT(atom));
|
||||
JS_ASSERT(FUN_INTERPRETED(fun));
|
||||
return fun->u.i.script->lineno;
|
||||
|
Loading…
Reference in New Issue
Block a user