Bug 366236: cleanup and debug checks for atom indexes. r=brendan

git-svn-id: svn://10.0.0.236/trunk@218238 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
igor.bukanov%gmail.com
2007-01-12 12:10:36 +00:00
parent 553368e2a6
commit 2f1623948d
6 changed files with 66 additions and 93 deletions

View File

@@ -641,7 +641,7 @@ NoSuchMethod(JSContext *cx, JSStackFrame *fp, jsval *vp, uint32 flags,
#if JS_HAS_XML_SUPPORT
case JSOP_GETMETHOD:
#endif
atom = js_GetAtomFromBytecode(cx, fp->script, pc, 0);
atom = js_GetAtomFromBytecode(fp->script, pc, 0);
argc = *argcp;
argsobj = js_NewArrayObject(cx, argc, vp + 2);
if (!argsobj)
@@ -2255,7 +2255,7 @@ js_Interpret(JSContext *cx, jsbytecode *pc, jsval *result)
/* 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))
#define LOAD_ATOM(PCOFF) (atom = GET_ATOM(script, atoms, pc + PCOFF))
/*
* Optimized Get and SetVersion for proper script language versioning.
@@ -3825,7 +3825,6 @@ interrupt:
END_CASE(JSOP_SETPROP)
BEGIN_CASE(JSOP_GETELEM)
BEGIN_CASE(JSOP_GETXELEM)
ELEMENT_OP(-1, ok = OBJ_GET_PROPERTY(cx, obj, id, &rval));
sp--;
STORE_OPND(-1, rval);
@@ -4177,12 +4176,14 @@ interrupt:
BEGIN_CASE(JSOP_ATOMBASE)
atoms += GET_ATOMBASE(pc);
ASSERT_ATOM_INDEX_IN_MAP(script, atoms, 0);
END_CASE(JSOP_ATOMBASE)
BEGIN_CASE(JSOP_ATOMBASE1)
BEGIN_CASE(JSOP_ATOMBASE2)
BEGIN_CASE(JSOP_ATOMBASE3)
atoms += (op - JSOP_ATOMBASE1 + 1) << 16;
ASSERT_ATOM_INDEX_IN_MAP(script, atoms, 0);
END_CASE(JSOP_ATOMBASE3)
BEGIN_CASE(JSOP_RESETBASE0)
@@ -4395,55 +4396,6 @@ interrupt:
}
END_VARLEN_CASE
BEGIN_CASE(JSOP_LOOKUPSWITCH)
lval = POP_OPND();
pc2 = pc;
len = GET_JUMP_OFFSET(pc2);
if (!JSVAL_IS_NUMBER(lval) &&
!JSVAL_IS_STRING(lval) &&
!JSVAL_IS_BOOLEAN(lval)) {
DO_NEXT_OP(len);
}
pc2 += JUMP_OFFSET_LEN;
npairs = (jsint) GET_UINT16(pc2);
pc2 += UINT16_LEN;
#define SEARCH_PAIRS(MATCH_CODE) \
while (npairs) { \
atom = GET_ATOM(cx, atoms, pc2); \
rval = ATOM_KEY(atom); \
MATCH_CODE \
if (match) { \
pc2 += ATOM_INDEX_LEN; \
len = GET_JUMP_OFFSET(pc2); \
DO_NEXT_OP(len); \
} \
pc2 += ATOM_INDEX_LEN + JUMP_OFFSET_LEN; \
npairs--; \
}
if (JSVAL_IS_STRING(lval)) {
str = JSVAL_TO_STRING(lval);
SEARCH_PAIRS(
match = (JSVAL_IS_STRING(rval) &&
((str2 = JSVAL_TO_STRING(rval)) == str ||
js_EqualStrings(str2, str)));
)
} else if (JSVAL_IS_DOUBLE(lval)) {
d = *JSVAL_TO_DOUBLE(lval);
SEARCH_PAIRS(
match = (JSVAL_IS_DOUBLE(rval) &&
*JSVAL_TO_DOUBLE(rval) == d);
)
} else {
SEARCH_PAIRS(
match = (lval == rval);
)
}
#undef SEARCH_PAIRS
END_VARLEN_CASE
BEGIN_CASE(JSOP_TABLESWITCHX)
pc2 = pc;
len = GET_JUMPX_OFFSET(pc2);
@@ -4473,52 +4425,65 @@ interrupt:
END_VARLEN_CASE
BEGIN_CASE(JSOP_LOOKUPSWITCHX)
lval = POP_OPND();
off = JUMPX_OFFSET_LEN;
goto do_lookup_switch;
BEGIN_CASE(JSOP_LOOKUPSWITCH)
off = JUMP_OFFSET_LEN;
do_lookup_switch:
pc2 = pc;
len = GET_JUMPX_OFFSET(pc2);
lval = POP_OPND();
if (!JSVAL_IS_NUMBER(lval) &&
!JSVAL_IS_STRING(lval) &&
!JSVAL_IS_BOOLEAN(lval)) {
DO_NEXT_OP(len);
goto end_lookup_switch;
}
pc2 += JUMPX_OFFSET_LEN;
pc2 += off;
npairs = (jsint) GET_UINT16(pc2);
pc2 += UINT16_LEN;
JS_ASSERT(npairs); /* empty switch uses JSOP_TABLESWITCH */
#define SEARCH_EXTENDED_PAIRS(MATCH_CODE) \
while (npairs) { \
atom = GET_ATOM(cx, atoms, pc2); \
#define SEARCH_PAIRS(MATCH_CODE) \
for (;;) { \
atom = GET_ATOM(script, atoms, pc2); \
rval = ATOM_KEY(atom); \
MATCH_CODE \
if (match) { \
pc2 += ATOM_INDEX_LEN; \
len = GET_JUMPX_OFFSET(pc2); \
DO_NEXT_OP(len); \
pc2 += ATOM_INDEX_LEN; \
if (match) \
break; \
pc2 += off; \
if (--npairs == 0) { \
pc2 = pc; \
break; \
} \
pc2 += ATOM_INDEX_LEN + JUMPX_OFFSET_LEN; \
npairs--; \
}
if (JSVAL_IS_STRING(lval)) {
str = JSVAL_TO_STRING(lval);
SEARCH_EXTENDED_PAIRS(
str = JSVAL_TO_STRING(lval);
SEARCH_PAIRS(
match = (JSVAL_IS_STRING(rval) &&
((str2 = JSVAL_TO_STRING(rval)) == str ||
js_EqualStrings(str2, str)));
)
} else if (JSVAL_IS_DOUBLE(lval)) {
d = *JSVAL_TO_DOUBLE(lval);
SEARCH_EXTENDED_PAIRS(
SEARCH_PAIRS(
match = (JSVAL_IS_DOUBLE(rval) &&
*JSVAL_TO_DOUBLE(rval) == d);
)
} else {
SEARCH_EXTENDED_PAIRS(
SEARCH_PAIRS(
match = (lval == rval);
)
}
#undef SEARCH_EXTENDED_PAIRS
#undef SEARCH_PAIRS
end_lookup_switch:
len = (op == JSOP_LOOKUPSWITCH)
? GET_JUMP_OFFSET(pc2)
: GET_JUMPX_OFFSET(pc2);
END_VARLEN_CASE
EMPTY_CASE(JSOP_CONDSWITCH)
@@ -6100,6 +6065,7 @@ interrupt:
#ifdef JS_THREADED_INTERP
L_JSOP_BACKPATCH:
L_JSOP_BACKPATCH_POP:
L_JSOP_UNUSED197:
#else
default:
#endif

View File

@@ -3121,7 +3121,7 @@ Detecting(JSContext *cx, jsbytecode *pc)
* 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);
atom = js_GetAtomFromBytecode(script, pc, 0);
if (atom == cx->runtime->atomState.typeAtoms[JSTYPE_VOID] &&
(pc += js_CodeSpec[op].length) < endpc) {
op = (JSOp) *pc;
@@ -3529,7 +3529,7 @@ js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
JSString *str;
op = *pc;
if (op == JSOP_GETXPROP || op == JSOP_GETXELEM) {
if (op == JSOP_GETXPROP) {
flags = JSREPORT_ERROR;
} else {
if (!JS_HAS_STRICT_OPTION(cx) ||

View File

@@ -111,8 +111,7 @@ GetJumpOffset(jsbytecode *pc, jsbytecode *pc2)
}
JSAtom *
js_GetAtomFromBytecode(JSContext *cx, JSScript *script, jsbytecode *pc,
ptrdiff_t pcoff)
js_GetAtomFromBytecode(JSScript *script, jsbytecode *pc, ptrdiff_t pcoff)
{
JSOp op;
uintN span, atomBase;
@@ -134,7 +133,8 @@ js_GetAtomFromBytecode(JSContext *cx, JSScript *script, jsbytecode *pc,
atomBase = (pc[-1] - JSOP_ATOMBASE1 + 1) << 16;
}
}
return GET_ATOM(cx, script->atomMap.vector + atomBase, pc + pcoff);
JS_ASSERT(atomBase < script->atomMap.length);
return GET_ATOM(script, script->atomMap.vector + atomBase, pc + pcoff);
}
#ifdef DEBUG
@@ -239,7 +239,7 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
break;
case JOF_CONST:
atom = js_GetAtomFromBytecode(cx, script, pc, 0);
atom = js_GetAtomFromBytecode(script, pc, 0);
bytes = ToDisassemblySource(cx, ATOM_KEY(atom));
if (!bytes)
return 0;
@@ -295,7 +295,7 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
pc2 += UINT16_LEN;
fprintf(fp, " offset %d npairs %u", off, (uintN) npairs);
while (npairs) {
atom = GET_ATOM(cx, script->atomMap.vector, pc2);
atom = GET_ATOM(script, script->atomMap.vector, pc2);
pc2 += ATOM_INDEX_LEN;
off = GetJumpOffset(pc, pc2);
pc2 += jmplen;
@@ -320,7 +320,7 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
case JOF_INDEXCONST:
fprintf(fp, " %u", GET_VARNO(pc));
atom = js_GetAtomFromBytecode(cx, script, pc, VARNO_LEN);
atom = js_GetAtomFromBytecode(script, pc, VARNO_LEN);
bytes = ToDisassemblySource(cx, ATOM_KEY(atom));
if (!bytes)
return 0;
@@ -1222,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 = js_GetAtomFromBytecode(cx, jp->script, pc, 0);
atom = js_GetAtomFromBytecode(jp->script, pc, 0);
else
lval = GetLocal(ss, i, JS_TRUE);
if (atom)
@@ -1347,7 +1347,7 @@ DecompileDestructuring(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc)
case JSOP_UINT24: d = i = GET_UINT24(pc); goto do_getelem;
case JSOP_NUMBER:
atom = js_GetAtomFromBytecode(cx, jp->script, pc, 0);
atom = js_GetAtomFromBytecode(jp->script, pc, 0);
d = *ATOM_TO_DOUBLE(atom);
LOCAL_ASSERT(JSDOUBLE_IS_FINITE(d) && !JSDOUBLE_IS_NEGZERO(d));
i = (jsint)d;
@@ -1379,7 +1379,7 @@ DecompileDestructuring(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc)
case JSOP_GETPROP:
*OFF2STR(&ss->sprinter, head) = '{';
atom = js_GetAtomFromBytecode(cx, jp->script, pc, 0);
atom = js_GetAtomFromBytecode(jp->script, pc, 0);
str = ATOM_TO_STRING(atom);
if (!QuoteString(&ss->sprinter, str,
js_IsIdentifier(str) ? 0 : (jschar)'\'')) {
@@ -1571,7 +1571,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
JS_END_MACRO
#define LOAD_ATOM(PCOFF) \
(atom = js_GetAtomFromBytecode(cx, jp->script, pc, PCOFF))
(atom = js_GetAtomFromBytecode(jp->script, pc, (PCOFF)))
/*
* Get atom from jp->script's atom map, quote/escape its string appropriately
@@ -3360,7 +3360,6 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
/* FALL THROUGH */
case JSOP_GETELEM:
case JSOP_GETXELEM:
op = JSOP_NOP; /* turn off parens */
xval = POP_STR();
op = saveop;
@@ -3607,7 +3606,8 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
} else {
table[k].label = NULL;
}
atom = GET_ATOM(cx, jp->script->atomMap.vector, pc2);
atom = GET_ATOM(jp->script, jp->script->atomMap.vector,
pc2);
pc2 += ATOM_INDEX_LEN;
off2 = GetJumpOffset(pc, pc2);
pc2 += jmplen;
@@ -4721,7 +4721,7 @@ js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v,
JSObject *obj;
JS_ASSERT(ndefs == 0);
atom = js_GetAtomFromBytecode(cx, script, pc, 0);
atom = js_GetAtomFromBytecode(script, pc, 0);
obj = ATOM_TO_OBJECT(atom);
JS_ASSERT(OBJ_BLOCK_DEPTH(cx, obj) == pcdepth);
ndefs = OBJ_BLOCK_COUNT(cx, obj);

View File

@@ -179,7 +179,14 @@ typedef enum JSOpLength {
#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,atoms,pc) ((atoms)[GET_ATOM_INDEX(pc)])
#define ASSERT_ATOM_INDEX_IN_MAP(script,atoms,index) \
JS_ASSERT((size_t)((atoms) - (script)->atomMap.vector) < \
(size_t)(script)->atomMap.length - (size_t)(index))
#define GET_ATOM(script,atoms,pc) \
(ASSERT_ATOM_INDEX_IN_MAP(script,atoms,GET_ATOM_INDEX(pc)), \
(atoms)[GET_ATOM_INDEX(pc)])
#define GET_ATOMBASE(pc) (JS_ASSERT(*(pc) == JSOP_ATOMBASE), \
((uintN)((pc)[1])) << 16)
@@ -264,11 +271,10 @@ 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.
* the atom table segment register itself.
*/
extern JSAtom*
js_GetAtomFromBytecode(JSContext *cx, JSScript *script, jsbytecode *pc,
ptrdiff_t pcoff);
js_GetAtomFromBytecode(JSScript *script, jsbytecode *pc, ptrdiff_t pcoff);
#ifdef DEBUG
/*

View File

@@ -435,11 +435,12 @@ OPDEF(JSOP_SETMETHOD, 194,"setmethod", NULL, 3, 2, 1, 3, JOF_CONST|
OPDEF(JSOP_STOP, 195,"stop", NULL, 1, 0, 0, 0, JOF_BYTE)
/*
* Get an extant property or element value, throwing ReferenceError if the
* identified property does not exist.
* Get an extant property value, throwing ReferenceError if the identified
* property does not exist.
*/
OPDEF(JSOP_GETXPROP, 196,"getxprop", NULL, 3, 1, 1, 18, JOF_CONST|JOF_PROP)
OPDEF(JSOP_GETXELEM, 197,"getxelem", NULL, 1, 2, 1, 18, JOF_BYTE |JOF_ELEM|JOF_LEFTASSOC)
OPDEF(JSOP_UNUSED197, 197,"", NULL, 1, 0, 0, 0, 0)
/*
* Specialized JSOP_TYPEOF to avoid reporting undefined for typeof(0, undef).

View File

@@ -1519,7 +1519,7 @@ js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
if (js_CodeSpec[*pc].format & JOF_ATOMBASE)
pc += js_CodeSpec[*pc].length;
if (*pc == JSOP_DEFFUN) {
atom = js_GetAtomFromBytecode(cx, script, pc, 0);
atom = js_GetAtomFromBytecode(script, pc, 0);
fun = (JSFunction *) JS_GetPrivate(cx, ATOM_TO_OBJECT(atom));
JS_ASSERT(FUN_INTERPRETED(fun));
return fun->u.i.script->lineno;