From 2f1623948d43ca06ec82d9114f346665ff10dc90 Mon Sep 17 00:00:00 2001 From: "igor.bukanov%gmail.com" Date: Fri, 12 Jan 2007 12:10:36 +0000 Subject: [PATCH] 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 --- mozilla/js/src/jsinterp.c | 106 ++++++++++++------------------------ mozilla/js/src/jsobj.c | 4 +- mozilla/js/src/jsopcode.c | 26 ++++----- mozilla/js/src/jsopcode.h | 14 +++-- mozilla/js/src/jsopcode.tbl | 7 ++- mozilla/js/src/jsscript.c | 2 +- 6 files changed, 66 insertions(+), 93 deletions(-) diff --git a/mozilla/js/src/jsinterp.c b/mozilla/js/src/jsinterp.c index ad2c121541d..82d2b4b9c8b 100644 --- a/mozilla/js/src/jsinterp.c +++ b/mozilla/js/src/jsinterp.c @@ -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 diff --git a/mozilla/js/src/jsobj.c b/mozilla/js/src/jsobj.c index 9414196d291..63a84ddbe7b 100644 --- a/mozilla/js/src/jsobj.c +++ b/mozilla/js/src/jsobj.c @@ -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) || diff --git a/mozilla/js/src/jsopcode.c b/mozilla/js/src/jsopcode.c index 7755acc4513..3e735cdf9a7 100644 --- a/mozilla/js/src/jsopcode.c +++ b/mozilla/js/src/jsopcode.c @@ -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); diff --git a/mozilla/js/src/jsopcode.h b/mozilla/js/src/jsopcode.h index f2c4dacfda8..52f6fefe08d 100644 --- a/mozilla/js/src/jsopcode.h +++ b/mozilla/js/src/jsopcode.h @@ -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 /* diff --git a/mozilla/js/src/jsopcode.tbl b/mozilla/js/src/jsopcode.tbl index 6a07bec2924..3dc3e431685 100644 --- a/mozilla/js/src/jsopcode.tbl +++ b/mozilla/js/src/jsopcode.tbl @@ -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). diff --git a/mozilla/js/src/jsscript.c b/mozilla/js/src/jsscript.c index 47331d6c4c9..9ea9e0ed27c 100644 --- a/mozilla/js/src/jsscript.c +++ b/mozilla/js/src/jsscript.c @@ -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;