зеркало из https://github.com/mozilla/pjs.git
Bug 386885: JSAtom.number is removed in favour of using atoms itself for hashing. r=brendan
This commit is contained in:
Родитель
11d0936e48
Коммит
740c486981
|
@ -1277,8 +1277,7 @@ DumpAtom(JSHashEntry *he, int i, void *arg)
|
|||
FILE *fp = args->fp;
|
||||
JSAtom *atom = (JSAtom *)he;
|
||||
|
||||
fprintf(fp, "%3d %08x %5lu ",
|
||||
i, (uintN)he->keyHash, (unsigned long)atom->number);
|
||||
fprintf(fp, "%3d %08x ", i, (uintN)he->keyHash);
|
||||
if (ATOM_IS_STRING(atom))
|
||||
fprintf(fp, "\"%s\"\n", js_AtomToPrintableString(args->cx, atom));
|
||||
else if (ATOM_IS_INT(atom))
|
||||
|
|
|
@ -155,10 +155,7 @@ const char js_ExecutionContext_str[] = "ExecutionContext";
|
|||
const char js_current_str[] = "current";
|
||||
#endif
|
||||
|
||||
#define HASH_OBJECT(o) (JS_PTR_TO_UINT32(o) >> JSVAL_TAGBITS)
|
||||
#define HASH_INT(i) ((JSHashNumber)(i))
|
||||
#define HASH_DOUBLE(dp) ((JSDOUBLE_HI32(*dp) ^ JSDOUBLE_LO32(*dp)))
|
||||
#define HASH_BOOLEAN(b) ((JSHashNumber)(b))
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(JSHashNumber)
|
||||
js_hash_atom_key(const void *key)
|
||||
|
@ -166,20 +163,15 @@ js_hash_atom_key(const void *key)
|
|||
jsval v;
|
||||
jsdouble *dp;
|
||||
|
||||
/* Order JSVAL_IS_* tests by likelihood of success. */
|
||||
v = (jsval)key;
|
||||
if (JSVAL_IS_STRING(v))
|
||||
return js_HashString(JSVAL_TO_STRING(v));
|
||||
if (JSVAL_IS_INT(v))
|
||||
return HASH_INT(JSVAL_TO_INT(v));
|
||||
if (JSVAL_IS_DOUBLE(v)) {
|
||||
dp = JSVAL_TO_DOUBLE(v);
|
||||
return HASH_DOUBLE(dp);
|
||||
}
|
||||
if (JSVAL_IS_OBJECT(v))
|
||||
return HASH_OBJECT(JSVAL_TO_OBJECT(v));
|
||||
if (JSVAL_IS_BOOLEAN(v))
|
||||
return HASH_BOOLEAN(JSVAL_TO_BOOLEAN(v));
|
||||
JS_ASSERT(JSVAL_IS_INT(v) || v == JSVAL_TRUE || v == JSVAL_FALSE ||
|
||||
v == JSVAL_NULL || v == JSVAL_VOID);
|
||||
return (JSHashNumber)v;
|
||||
}
|
||||
|
||||
|
@ -228,8 +220,10 @@ js_free_table_space(void *priv, void *item)
|
|||
JS_STATIC_DLL_CALLBACK(JSHashEntry *)
|
||||
js_alloc_atom(void *priv, const void *key)
|
||||
{
|
||||
JSAtomState *state = (JSAtomState *) priv;
|
||||
JSAtom *atom;
|
||||
#ifdef JS_THREADSAFE
|
||||
JSAtomState *state = (JSAtomState *) priv;
|
||||
#endif
|
||||
|
||||
atom = (JSAtom *) malloc(sizeof(JSAtom));
|
||||
if (!atom)
|
||||
|
@ -240,7 +234,6 @@ js_alloc_atom(void *priv, const void *key)
|
|||
atom->entry.key = key;
|
||||
atom->entry.value = NULL;
|
||||
atom->flags = 0;
|
||||
atom->number = state->number++;
|
||||
return &atom->entry;
|
||||
}
|
||||
|
||||
|
@ -502,7 +495,7 @@ js_UnpinPinnedAtoms(JSAtomState *state)
|
|||
}
|
||||
|
||||
static JSAtom *
|
||||
js_AtomizeHashedKey(JSContext *cx, jsval key, JSHashNumber keyHash, uintN flags)
|
||||
js_AtomizeHashedKey(JSContext *cx, jsval key, JSHashNumber keyHash)
|
||||
{
|
||||
JSAtomState *state;
|
||||
JSHashTable *table;
|
||||
|
@ -523,41 +516,18 @@ js_AtomizeHashedKey(JSContext *cx, jsval key, JSHashNumber keyHash, uintN flags)
|
|||
}
|
||||
|
||||
atom = (JSAtom *)he;
|
||||
atom->flags |= flags;
|
||||
cx->weakRoots.lastAtom = atom;
|
||||
out:
|
||||
JS_UNLOCK(&state->lock,cx);
|
||||
return atom;
|
||||
}
|
||||
|
||||
JSAtom *
|
||||
js_AtomizeBoolean(JSContext *cx, JSBool b, uintN flags)
|
||||
{
|
||||
jsval key;
|
||||
JSHashNumber keyHash;
|
||||
|
||||
key = BOOLEAN_TO_JSVAL(b);
|
||||
keyHash = HASH_BOOLEAN(b);
|
||||
return js_AtomizeHashedKey(cx, key, keyHash, flags);
|
||||
}
|
||||
|
||||
JSAtom *
|
||||
js_AtomizeInt(JSContext *cx, jsint i, uintN flags)
|
||||
{
|
||||
jsval key;
|
||||
JSHashNumber keyHash;
|
||||
|
||||
key = INT_TO_JSVAL(i);
|
||||
keyHash = HASH_INT(i);
|
||||
return js_AtomizeHashedKey(cx, key, keyHash, flags);
|
||||
}
|
||||
|
||||
/* Worst-case alignment grain and aligning macro for 2x-sized buffer. */
|
||||
#define ALIGNMENT(t) JS_MAX(JSVAL_ALIGN, sizeof(t))
|
||||
#define ALIGN(b,t) ((t*) &(b)[ALIGNMENT(t) - (jsuword)(b) % ALIGNMENT(t)])
|
||||
|
||||
JSAtom *
|
||||
js_AtomizeDouble(JSContext *cx, jsdouble d, uintN flags)
|
||||
js_AtomizeDouble(JSContext *cx, jsdouble d)
|
||||
{
|
||||
jsdouble *dp;
|
||||
JSHashNumber keyHash;
|
||||
|
@ -602,7 +572,6 @@ js_AtomizeDouble(JSContext *cx, jsdouble d, uintN flags)
|
|||
}
|
||||
|
||||
atom = (JSAtom *)he;
|
||||
atom->flags |= flags;
|
||||
cx->weakRoots.lastAtom = atom;
|
||||
out:
|
||||
JS_UNLOCK(&state->lock,cx);
|
||||
|
@ -760,18 +729,15 @@ js_GetExistingStringAtom(JSContext *cx, const jschar *chars, size_t length)
|
|||
}
|
||||
|
||||
JSAtom *
|
||||
js_AtomizePrimitiveValue(JSContext *cx, jsval value, uintN flags)
|
||||
js_AtomizePrimitiveValue(JSContext *cx, jsval v)
|
||||
{
|
||||
if (JSVAL_IS_STRING(value))
|
||||
return js_AtomizeString(cx, JSVAL_TO_STRING(value), flags);
|
||||
if (JSVAL_IS_INT(value))
|
||||
return js_AtomizeInt(cx, JSVAL_TO_INT(value), flags);
|
||||
if (JSVAL_IS_DOUBLE(value))
|
||||
return js_AtomizeDouble(cx, *JSVAL_TO_DOUBLE(value), flags);
|
||||
if (JSVAL_IS_BOOLEAN(value))
|
||||
return js_AtomizeBoolean(cx, JSVAL_TO_BOOLEAN(value), flags);
|
||||
JS_ASSERT(value == JSVAL_NULL || value == JSVAL_VOID);
|
||||
return js_AtomizeHashedKey(cx, value, (JSHashNumber)value, flags);
|
||||
if (JSVAL_IS_STRING(v))
|
||||
return js_AtomizeString(cx, JSVAL_TO_STRING(v), 0);
|
||||
if (JSVAL_IS_DOUBLE(v))
|
||||
return js_AtomizeDouble(cx, *JSVAL_TO_DOUBLE(v));
|
||||
JS_ASSERT(JSVAL_IS_INT(v) || v == JSVAL_TRUE || v == JSVAL_FALSE ||
|
||||
v == JSVAL_NULL || v == JSVAL_VOID);
|
||||
return js_AtomizeHashedKey(cx, v, (JSHashNumber)v);
|
||||
}
|
||||
|
||||
JSAtom *
|
||||
|
@ -789,7 +755,7 @@ JS_STATIC_DLL_CALLBACK(JSHashNumber)
|
|||
js_hash_atom_ptr(const void *key)
|
||||
{
|
||||
const JSAtom *atom = (const JSAtom *) key;
|
||||
return atom->number;
|
||||
return ATOM_HASH(atom);
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(void *)
|
||||
|
@ -870,7 +836,7 @@ js_IndexAtom(JSContext *cx, JSAtom *atom, JSAtomList *al)
|
|||
/* Insert each ale on al->list into the new hash table. */
|
||||
for (ale2 = (JSAtomListElement *)al->list; ale2; ale2 = next) {
|
||||
next = ALE_NEXT(ale2);
|
||||
ale2->entry.keyHash = ALE_ATOM(ale2)->number;
|
||||
ale2->entry.keyHash = ATOM_HASH(ALE_ATOM(ale2));
|
||||
hep = JS_HashTableRawLookup(al->table, ale2->entry.keyHash,
|
||||
ale2->entry.key);
|
||||
ale2->entry.next = *hep;
|
||||
|
@ -879,12 +845,13 @@ js_IndexAtom(JSContext *cx, JSAtom *atom, JSAtomList *al)
|
|||
al->list = NULL;
|
||||
|
||||
/* Set hep for insertion of atom's ale, immediately below. */
|
||||
hep = JS_HashTableRawLookup(al->table, atom->number, atom);
|
||||
hep = JS_HashTableRawLookup(al->table, ATOM_HASH(atom), atom);
|
||||
}
|
||||
|
||||
/* Finally, add an entry for atom into the hash bucket at hep. */
|
||||
ale = (JSAtomListElement *)
|
||||
JS_HashTableRawAdd(al->table, hep, atom->number, atom, NULL);
|
||||
JS_HashTableRawAdd(al->table, hep, ATOM_HASH(atom), atom,
|
||||
NULL);
|
||||
if (!ale)
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -66,7 +66,6 @@ struct JSAtom {
|
|||
JSHashEntry entry; /* key is jsval or unhidden atom
|
||||
if ATOM_HIDDEN */
|
||||
uint32 flags; /* pinned, interned, and mark flags */
|
||||
jsatomid number; /* atom serial number and hash code */
|
||||
};
|
||||
|
||||
#define ATOM_KEY(atom) ((jsval)(atom)->entry.key)
|
||||
|
@ -79,6 +78,18 @@ struct JSAtom {
|
|||
#define ATOM_IS_BOOLEAN(atom) JSVAL_IS_BOOLEAN(ATOM_KEY(atom))
|
||||
#define ATOM_TO_BOOLEAN(atom) JSVAL_TO_BOOLEAN(ATOM_KEY(atom))
|
||||
|
||||
JS_STATIC_ASSERT(sizeof(JSHashNumber) == 4);
|
||||
JS_STATIC_ASSERT(sizeof(JSAtom *) == JS_BYTES_PER_WORD);
|
||||
|
||||
#if JS_BYTES_PER_WORD == 4
|
||||
# define ATOM_HASH(atom) ((JSHashNumber)(atom) >> 2)
|
||||
#elif JS_BYTES_PER_WORD == 8
|
||||
# define ATOM_HASH(atom) (((JSHashNumber)(atom) >> 3) ^ \
|
||||
(JSHashNumber)((jsuword)(atom) >> 32))
|
||||
#else
|
||||
# error "Unsupported configuration"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Return a printable, lossless char[] representation of a string-type atom.
|
||||
* The lifetime of the result extends at least until the next GC activation,
|
||||
|
@ -119,7 +130,8 @@ struct JSAtomList {
|
|||
#define ATOM_LIST_LOOKUP(_ale,_hep,_al,_atom) \
|
||||
JS_BEGIN_MACRO \
|
||||
if ((_al)->table) { \
|
||||
_hep = JS_HashTableRawLookup((_al)->table, _atom->number, _atom); \
|
||||
_hep = JS_HashTableRawLookup((_al)->table, ATOM_HASH(_atom), \
|
||||
_atom); \
|
||||
_ale = *_hep ? (JSAtomListElement *) *_hep : NULL; \
|
||||
} else { \
|
||||
JSHashEntry **_alep = &(_al)->list; \
|
||||
|
@ -145,7 +157,6 @@ struct JSAtomMap {
|
|||
struct JSAtomState {
|
||||
JSRuntime *runtime; /* runtime that owns us */
|
||||
JSHashTable *table; /* hash table containing all atoms */
|
||||
jsatomid number; /* one beyond greatest atom number */
|
||||
jsatomid liveAtoms; /* number of live atoms after last GC */
|
||||
|
||||
/* The rt->emptyString atom, see jsstr.c's js_InitRuntimeStringState. */
|
||||
|
@ -365,29 +376,15 @@ extern void
|
|||
js_UnpinPinnedAtoms(JSAtomState *state);
|
||||
|
||||
/*
|
||||
* Find or create the atom for a Boolean value. If we create a new atom, give
|
||||
* it the type indicated in flags. Return 0 on failure to allocate memory.
|
||||
* Find or create the atom for a double value. Return null on failure to
|
||||
* allocate memory.
|
||||
*/
|
||||
extern JSAtom *
|
||||
js_AtomizeBoolean(JSContext *cx, JSBool b, uintN flags);
|
||||
js_AtomizeDouble(JSContext *cx, jsdouble d);
|
||||
|
||||
/*
|
||||
* Find or create the atom for an integer value. If we create a new atom, give
|
||||
* it the type indicated in flags. Return 0 on failure to allocate memory.
|
||||
*/
|
||||
extern JSAtom *
|
||||
js_AtomizeInt(JSContext *cx, jsint i, uintN flags);
|
||||
|
||||
/*
|
||||
* Find or create the atom for a double value. If we create a new atom, give
|
||||
* it the type indicated in flags. Return 0 on failure to allocate memory.
|
||||
*/
|
||||
extern JSAtom *
|
||||
js_AtomizeDouble(JSContext *cx, jsdouble d, uintN flags);
|
||||
|
||||
/*
|
||||
* Find or create the atom for a string. If we create a new atom, give it the
|
||||
* type indicated in flags. Return 0 on failure to allocate memory.
|
||||
* Find or create the atom for a string. Return null on failure to allocate
|
||||
* memory.
|
||||
*/
|
||||
extern JSAtom *
|
||||
js_AtomizeString(JSContext *cx, JSString *str, uintN flags);
|
||||
|
@ -409,7 +406,7 @@ js_GetExistingStringAtom(JSContext *cx, const jschar *chars, size_t length);
|
|||
* This variant handles all primitive values.
|
||||
*/
|
||||
extern JSAtom *
|
||||
js_AtomizePrimitiveValue(JSContext *cx, jsval value, uintN flags);
|
||||
js_AtomizePrimitiveValue(JSContext *cx, jsval v);
|
||||
|
||||
/*
|
||||
* Convert v to an atomized string.
|
||||
|
|
|
@ -1527,20 +1527,29 @@ js_DefineCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom,
|
|||
jsdouble dval;
|
||||
jsint ival;
|
||||
JSAtom *valueAtom;
|
||||
jsval v;
|
||||
JSAtomListElement *ale;
|
||||
|
||||
/* XXX just do numbers for now */
|
||||
if (pn->pn_type == TOK_NUMBER) {
|
||||
dval = pn->pn_dval;
|
||||
valueAtom = (JSDOUBLE_IS_INT(dval, ival) && INT_FITS_IN_JSVAL(ival))
|
||||
? js_AtomizeInt(cx, ival, 0)
|
||||
: js_AtomizeDouble(cx, dval, 0);
|
||||
if (!valueAtom)
|
||||
return JS_FALSE;
|
||||
if (JSDOUBLE_IS_INT(dval, ival) && INT_FITS_IN_JSVAL(ival)) {
|
||||
v = INT_TO_JSVAL(ival);
|
||||
} else {
|
||||
/*
|
||||
* We atomize double to root a jsdouble instance that we wrap as
|
||||
* jsval and store in cg->constList. This works because atoms are
|
||||
* protected from GC during compilation.
|
||||
*/
|
||||
valueAtom = js_AtomizeDouble(cx, dval);
|
||||
if (!valueAtom)
|
||||
return JS_FALSE;
|
||||
v = ATOM_KEY(valueAtom);
|
||||
}
|
||||
ale = js_IndexAtom(cx, atom, &cg->constList);
|
||||
if (!ale)
|
||||
return JS_FALSE;
|
||||
ale->entry.value = (void *)ATOM_KEY(valueAtom);
|
||||
ale->entry.value = (void *)v;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -2578,7 +2587,7 @@ static JSBool
|
|||
EmitNumberOp(JSContext *cx, jsdouble dval, JSCodeGenerator *cg)
|
||||
{
|
||||
jsint ival;
|
||||
jsatomid atomIndex;
|
||||
uint32 u;
|
||||
ptrdiff_t off;
|
||||
jsbytecode *pc;
|
||||
JSAtom *atom;
|
||||
|
@ -2589,33 +2598,36 @@ EmitNumberOp(JSContext *cx, jsdouble dval, JSCodeGenerator *cg)
|
|||
return js_Emit1(cx, cg, JSOP_ZERO) >= 0;
|
||||
if (ival == 1)
|
||||
return js_Emit1(cx, cg, JSOP_ONE) >= 0;
|
||||
if ((jsint)(int8)ival == ival)
|
||||
return js_Emit2(cx, cg, JSOP_INT8, (jsbytecode)(int8)ival) >= 0;
|
||||
|
||||
atomIndex = (jsatomid)ival;
|
||||
if (atomIndex < JS_BIT(16)) {
|
||||
EMIT_UINT16_IMM_OP(JSOP_UINT16, atomIndex);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
if (atomIndex < JS_BIT(24)) {
|
||||
u = (uint32)ival;
|
||||
if (u < JS_BIT(16)) {
|
||||
EMIT_UINT16_IMM_OP(JSOP_UINT16, u);
|
||||
} else if (u < JS_BIT(24)) {
|
||||
off = js_EmitN(cx, cg, JSOP_UINT24, 3);
|
||||
if (off < 0)
|
||||
return JS_FALSE;
|
||||
pc = CG_CODE(cg, off);
|
||||
SET_UINT24(pc, atomIndex);
|
||||
return JS_TRUE;
|
||||
SET_UINT24(pc, u);
|
||||
} else {
|
||||
off = js_EmitN(cx, cg, JSOP_INT32, 4);
|
||||
if (off < 0)
|
||||
return JS_FALSE;
|
||||
pc = CG_CODE(cg, off);
|
||||
SET_INT32(pc, ival);
|
||||
}
|
||||
|
||||
atom = js_AtomizeInt(cx, ival, 0);
|
||||
} else {
|
||||
atom = js_AtomizeDouble(cx, dval, 0);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
atom = js_AtomizeDouble(cx, dval);
|
||||
if (!atom)
|
||||
return JS_FALSE;
|
||||
|
||||
ale = js_IndexAtom(cx, atom, &cg->atomList);
|
||||
if (!ale)
|
||||
return JS_FALSE;
|
||||
return EmitIndexOp(cx, JSOP_NUMBER, ALE_INDEX(ale), cg);
|
||||
return EmitIndexOp(cx, JSOP_DOUBLE, ALE_INDEX(ale), cg);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
@ -2759,7 +2771,7 @@ EmitSwitch(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
|
|||
if (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i)) {
|
||||
pn3->pn_val = INT_TO_JSVAL(i);
|
||||
} else {
|
||||
atom = js_AtomizeDouble(cx, d, 0);
|
||||
atom = js_AtomizeDouble(cx, d);
|
||||
if (!atom) {
|
||||
ok = JS_FALSE;
|
||||
goto release;
|
||||
|
@ -3134,7 +3146,7 @@ EmitSwitch(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
|
|||
for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
|
||||
if (pn3->pn_type == TOK_DEFAULT)
|
||||
continue;
|
||||
atom = js_AtomizePrimitiveValue(cx, pn3->pn_val, 0);
|
||||
atom = js_AtomizePrimitiveValue(cx, pn3->pn_val);
|
||||
if (!atom)
|
||||
goto bad;
|
||||
ale = js_IndexAtom(cx, atom, &cg->atomList);
|
||||
|
|
|
@ -4126,6 +4126,18 @@ interrupt:
|
|||
PUSH_OPND(rval);
|
||||
END_CASE(JSOP_UINT24)
|
||||
|
||||
BEGIN_CASE(JSOP_INT8)
|
||||
i = GET_INT8(pc);
|
||||
rval = INT_TO_JSVAL(i);
|
||||
PUSH_OPND(rval);
|
||||
END_CASE(JSOP_INT8)
|
||||
|
||||
BEGIN_CASE(JSOP_INT32)
|
||||
i = GET_INT32(pc);
|
||||
rval = INT_TO_JSVAL(i);
|
||||
PUSH_OPND(rval);
|
||||
END_CASE(JSOP_INT32)
|
||||
|
||||
BEGIN_CASE(JSOP_INDEXBASE)
|
||||
/*
|
||||
* Here atoms can exceed script->atomMap.length as we use atoms
|
||||
|
@ -4145,11 +4157,11 @@ interrupt:
|
|||
atoms = script->atomMap.vector;
|
||||
END_CASE(JSOP_RESETBASE)
|
||||
|
||||
BEGIN_CASE(JSOP_NUMBER)
|
||||
BEGIN_CASE(JSOP_DOUBLE)
|
||||
BEGIN_CASE(JSOP_STRING)
|
||||
LOAD_ATOM(0);
|
||||
PUSH_OPND(ATOM_KEY(atom));
|
||||
END_CASE(JSOP_NUMBER)
|
||||
END_CASE(JSOP_DOUBLE)
|
||||
|
||||
BEGIN_CASE(JSOP_OBJECT)
|
||||
LOAD_OBJECT(0);
|
||||
|
|
|
@ -219,6 +219,7 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
|
|||
JSObject *obj;
|
||||
jsval v;
|
||||
const char *bytes;
|
||||
jsint i;
|
||||
|
||||
op = (JSOp)*pc;
|
||||
if (op >= JSOP_LIMIT) {
|
||||
|
@ -274,8 +275,8 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
|
|||
|
||||
case JOF_UINT16:
|
||||
case JOF_LOCAL:
|
||||
fprintf(fp, " %u", GET_UINT16(pc));
|
||||
break;
|
||||
i = (jsint)GET_UINT16(pc);
|
||||
goto print_int;
|
||||
|
||||
case JOF_2BYTE:
|
||||
fprintf(fp, " %u", (uintN)pc[1]);
|
||||
|
@ -363,7 +364,19 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
|
|||
|
||||
case JOF_UINT24:
|
||||
JS_ASSERT(op == JSOP_UINT24);
|
||||
fprintf(fp, " %u", GET_UINT24(pc));
|
||||
i = (jsint)GET_UINT24(pc);
|
||||
goto print_int;
|
||||
|
||||
case JOF_INT8:
|
||||
JS_ASSERT(op == JSOP_INT8);
|
||||
i = GET_INT8(pc);
|
||||
goto print_int;
|
||||
|
||||
case JOF_INT32:
|
||||
JS_ASSERT(op == JSOP_INT32);
|
||||
i = GET_INT32(pc);
|
||||
print_int:
|
||||
fprintf(fp, " %d", i);
|
||||
break;
|
||||
|
||||
default: {
|
||||
|
@ -1475,8 +1488,10 @@ DecompileDestructuring(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc)
|
|||
case JSOP_ONE: d = i = 1; goto do_getelem;
|
||||
case JSOP_UINT16: d = i = GET_UINT16(pc); goto do_getelem;
|
||||
case JSOP_UINT24: d = i = GET_UINT24(pc); goto do_getelem;
|
||||
case JSOP_INT8: d = i = GET_INT8(pc); goto do_getelem;
|
||||
case JSOP_INT32: d = i = GET_INT32(pc); goto do_getelem;
|
||||
|
||||
case JSOP_NUMBER:
|
||||
case JSOP_DOUBLE:
|
||||
GET_ATOM_FROM_BYTECODE(jp->script, pc, 0, atom);
|
||||
d = *ATOM_TO_DOUBLE(atom);
|
||||
LOCAL_ASSERT(JSDOUBLE_IS_FINITE(d) && !JSDOUBLE_IS_NEGZERO(d));
|
||||
|
@ -3772,15 +3787,22 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
|
||||
case JSOP_UINT24:
|
||||
i = (jsint) GET_UINT24(pc);
|
||||
goto do_sprint_int;
|
||||
|
||||
case JSOP_INT8:
|
||||
i = GET_INT8(pc);
|
||||
goto do_sprint_int;
|
||||
|
||||
case JSOP_INT32:
|
||||
i = GET_INT32(pc);
|
||||
do_sprint_int:
|
||||
todo = Sprint(&ss->sprinter, "%u", (unsigned) i);
|
||||
todo = Sprint(&ss->sprinter, "%d", i);
|
||||
break;
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_NUMBER, 0)
|
||||
BEGIN_LITOPX_CASE(JSOP_DOUBLE, 0)
|
||||
val = ATOM_KEY(atom);
|
||||
todo = JSVAL_IS_INT(val)
|
||||
? Sprint(&ss->sprinter, "%ld", (long) JSVAL_TO_INT(val))
|
||||
: SprintDoubleValue(&ss->sprinter, val, &saveop);
|
||||
JS_ASSERT(JSVAL_IS_DOUBLE(val));
|
||||
todo = SprintDoubleValue(&ss->sprinter, val, &saveop);
|
||||
END_LITOPX_CASE
|
||||
|
||||
BEGIN_LITOPX_CASE(JSOP_STRING, 0)
|
||||
|
|
|
@ -90,7 +90,10 @@ typedef enum JSOpLength {
|
|||
#define JOF_OBJECT 15 /* unsigned 16-bit object pool index */
|
||||
#define JOF_INDEXOBJECT 16 /* uint16 slot index + object pool index */
|
||||
#define JOF_REGEXP 17 /* unsigned 16-bit regexp pool index */
|
||||
#define JOF_INT8 18 /* int8 immediate operand */
|
||||
#define JOF_INT32 19 /* int32 immediate operand */
|
||||
#define JOF_TYPEMASK 0x001f /* mask for above immediate types */
|
||||
|
||||
#define JOF_NAME (1U<<5) /* name operation */
|
||||
#define JOF_PROP (2U<<5) /* obj.prop operation */
|
||||
#define JOF_ELEM (3U<<5) /* obj[index] operation */
|
||||
|
@ -209,6 +212,17 @@ typedef enum JSOpLength {
|
|||
(pc)[2] = UINT24_MID(i), \
|
||||
(pc)[3] = UINT24_LO(i))
|
||||
|
||||
#define GET_INT8(pc) ((jsint)(int8)(pc)[1])
|
||||
|
||||
#define GET_INT32(pc) ((jsint)(((uint32)((pc)[1]) << 24) | \
|
||||
((uint32)((pc)[2]) << 16) | \
|
||||
((uint32)((pc)[3]) << 8) | \
|
||||
(uint32)(pc)[4]))
|
||||
#define SET_INT32(pc,i) ((pc)[1] = (jsbytecode)((uint32)(i) >> 24), \
|
||||
(pc)[2] = (jsbytecode)((uint32)(i) >> 16), \
|
||||
(pc)[3] = (jsbytecode)((uint32)(i) >> 8), \
|
||||
(pc)[4] = (jsbytecode)(uint32)(i))
|
||||
|
||||
/* Index limit is determined by SN_3BYTE_OFFSET_FLAG, see jsemit.h. */
|
||||
#define INDEX_LIMIT_LOG2 23
|
||||
#define INDEX_LIMIT ((uint32)1 << INDEX_LIMIT_LOG2)
|
||||
|
|
|
@ -79,12 +79,12 @@
|
|||
* 13 +, -, etc. JSOP_ADD, JSOP_SUB, etc.
|
||||
* 14 *, /, % JSOP_MUL, JSOP_DIV, JSOP_MOD
|
||||
* 15 !, ~, etc. JSOP_NOT, JSOP_BITNOT, etc.
|
||||
* 16 3.14, 0, etc. JSOP_NUMBER, JSOP_ZERO, etc.
|
||||
* 16 3.14, 0, etc. JSOP_DOUBLE, JSOP_ZERO, etc.
|
||||
* 17 delete, new JSOP_DEL*, JSOP_NEW
|
||||
* 18 x.y, f(), etc. JSOP_GETPROP, JSOP_CALL, etc.
|
||||
* 19 x, null, etc. JSOP_NAME, JSOP_NULL, etc.
|
||||
*
|
||||
* The push-numeric-constant operators, JSOP_ZERO, JSOP_NUMBER, etc., have
|
||||
* The push-numeric-constant operators, JSOP_ZERO, JSOP_DOUBLE, etc., have
|
||||
* lower precedence than the member operators emitted for the . operator, to
|
||||
* cause the decompiler to parenthesize the . left operand, e.g. (0).foo.
|
||||
* Otherwise the . could be taken as a decimal point. We use the same level
|
||||
|
@ -163,7 +163,7 @@ OPDEF(JSOP_SETELEM, 56, "setelem", NULL, 1, 3, 1, 3, JOF_BYTE |
|
|||
OPDEF(JSOP_CALLNAME, 57, "callname", NULL, 3, 0, 2, 19, JOF_CONST|JOF_NAME|JOF_CALLOP)
|
||||
OPDEF(JSOP_CALL, 58, "call", NULL, 3, -1, 1, 18, JOF_UINT16|JOF_INVOKE)
|
||||
OPDEF(JSOP_NAME, 59, "name", NULL, 3, 0, 1, 19, JOF_CONST|JOF_NAME)
|
||||
OPDEF(JSOP_NUMBER, 60, "number", NULL, 3, 0, 1, 16, JOF_CONST)
|
||||
OPDEF(JSOP_DOUBLE, 60, "double", NULL, 3, 0, 1, 16, JOF_CONST)
|
||||
OPDEF(JSOP_STRING, 61, "string", NULL, 3, 0, 1, 19, JOF_CONST)
|
||||
OPDEF(JSOP_ZERO, 62, "zero", "0", 1, 0, 1, 16, JOF_BYTE)
|
||||
OPDEF(JSOP_ONE, 63, "one", "1", 1, 0, 1, 16, JOF_BYTE)
|
||||
|
@ -503,3 +503,9 @@ OPDEF(JSOP_CALLGVAR, 223, "callgvar", NULL, 3, 0, 2, 19, JOF_CONST|
|
|||
OPDEF(JSOP_CALLVAR, 224, "callvar", NULL, 3, 0, 2, 19, JOF_QVAR |JOF_NAME|JOF_CALLOP)
|
||||
OPDEF(JSOP_CALLARG, 225, "callarg", NULL, 3, 0, 2, 19, JOF_QARG |JOF_NAME|JOF_CALLOP)
|
||||
OPDEF(JSOP_CALLLOCAL, 226, "calllocal", NULL, 3, 0, 2, 19, JOF_LOCAL|JOF_NAME|JOF_CALLOP)
|
||||
|
||||
/*
|
||||
* Opcodes to hold 8-bit and 32-bit immediate integer operands.
|
||||
*/
|
||||
OPDEF(JSOP_INT8, 227, "int8", NULL, 2, 0, 1, 16, JOF_INT8)
|
||||
OPDEF(JSOP_INT32, 228, "int32", NULL, 5, 0, 1, 16, JOF_INT32)
|
||||
|
|
|
@ -2088,7 +2088,7 @@ HashFindPropValKey(JSDHashTable *table, const void *key)
|
|||
return (pnkey->pn_type == TOK_NUMBER)
|
||||
? (JSDHashNumber) (JSDOUBLE_HI32(pnkey->pn_dval) ^
|
||||
JSDOUBLE_LO32(pnkey->pn_dval))
|
||||
: (JSDHashNumber) pnkey->pn_atom->number;
|
||||
: ATOM_HASH(pnkey->pn_atom);
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||
|
@ -6100,7 +6100,7 @@ FoldType(JSContext *cx, JSParseNode *pn, JSTokenType type)
|
|||
return JS_FALSE;
|
||||
pn->pn_dval = d;
|
||||
pn->pn_type = TOK_NUMBER;
|
||||
pn->pn_op = JSOP_NUMBER;
|
||||
pn->pn_op = JSOP_DOUBLE;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -6211,7 +6211,7 @@ FoldBinaryNumeric(JSContext *cx, JSOp op, JSParseNode *pn1, JSParseNode *pn2,
|
|||
if (pn2 != pn)
|
||||
RecycleTree(pn2, tc);
|
||||
pn->pn_type = TOK_NUMBER;
|
||||
pn->pn_op = JSOP_NUMBER;
|
||||
pn->pn_op = JSOP_DOUBLE;
|
||||
pn->pn_arity = PN_NULLARY;
|
||||
pn->pn_dval = d;
|
||||
return JS_TRUE;
|
||||
|
@ -6795,7 +6795,7 @@ js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc)
|
|||
return JS_TRUE;
|
||||
}
|
||||
pn->pn_type = TOK_NUMBER;
|
||||
pn->pn_op = JSOP_NUMBER;
|
||||
pn->pn_op = JSOP_DOUBLE;
|
||||
pn->pn_arity = PN_NULLARY;
|
||||
pn->pn_dval = d;
|
||||
RecycleTree(pn1, tc);
|
||||
|
|
|
@ -229,13 +229,22 @@ JS_FRIEND_DATA(JSScopeStats) js_scope_stats;
|
|||
# define METER(x) /* nothing */
|
||||
#endif
|
||||
|
||||
JS_STATIC_ASSERT(sizeof(JSHashNumber) == 4);
|
||||
JS_STATIC_ASSERT(sizeof(jsid) == JS_BYTES_PER_WORD);
|
||||
|
||||
#if JS_BYTES_PER_WORD == 4
|
||||
# define HASH_ID(id) ((JSHashNumber)(id))
|
||||
#elif JS_BYTES_PER_WORD == 8
|
||||
# define HASH_ID(id) ((JSHashNumber)(id) ^ (JSHashNumber)((id) >> 32))
|
||||
#else
|
||||
# error "Unsupported configuration"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Double hashing needs the second hash code to be relatively prime to table
|
||||
* size, so we simply make hash2 odd. The inputs to multiplicative hash are
|
||||
* the golden ratio, expressed as a fixed-point 32 bit fraction, and the int
|
||||
* property index or named property's atom number (observe that most objects
|
||||
* have either no indexed properties, or almost all indexed and a few names,
|
||||
* so collisions between index and atom number are unlikely).
|
||||
* the golden ratio, expressed as a fixed-point 32 bit fraction, and the id
|
||||
* itself.
|
||||
*/
|
||||
#define SCOPE_HASH0(id) (HASH_ID(id) * JS_GOLDEN_RATIO)
|
||||
#define SCOPE_HASH1(hash0,shift) ((hash0) >> (shift))
|
||||
|
|
|
@ -351,9 +351,6 @@ js_DestroyScope(JSContext *cx, JSScope *scope);
|
|||
#define ID_TO_VALUE(id) (JSID_IS_ATOM(id) ? ATOM_JSID_TO_JSVAL(id) : \
|
||||
JSID_IS_OBJECT(id) ? OBJECT_JSID_TO_JSVAL(id) : \
|
||||
(jsval)(id))
|
||||
#define HASH_ID(id) (JSID_IS_ATOM(id) ? JSID_TO_ATOM(id)->number : \
|
||||
JSID_IS_OBJECT(id) ? (jsatomid) JSID_CLRTAG(id) : \
|
||||
(jsatomid) JSID_TO_INT(id))
|
||||
|
||||
extern JS_FRIEND_API(JSScopeProperty **)
|
||||
js_SearchScope(JSScope *scope, jsid id, JSBool adding);
|
||||
|
|
|
@ -630,11 +630,11 @@ js_XDRAtom(JSXDRState *xdr, JSAtom **atomp)
|
|||
if (type == JSVAL_DOUBLE) {
|
||||
if (!XDRDoubleValue(xdr, &d))
|
||||
return JS_FALSE;
|
||||
atom = js_AtomizeDouble(xdr->cx, d, 0);
|
||||
atom = js_AtomizeDouble(xdr->cx, d);
|
||||
} else {
|
||||
if (!XDRValueBody(xdr, type, &v))
|
||||
return JS_FALSE;
|
||||
atom = js_AtomizePrimitiveValue(xdr->cx, v, 0);
|
||||
atom = js_AtomizePrimitiveValue(xdr->cx, v);
|
||||
}
|
||||
|
||||
if (!atom)
|
||||
|
|
|
@ -201,7 +201,7 @@ JS_XDRFindClassById(JSXDRState *xdr, uint32 id);
|
|||
* before deserialization of bytecode. If the saved version does not match
|
||||
* the current version, abort deserialization and invalidate the file.
|
||||
*/
|
||||
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 13)
|
||||
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 14)
|
||||
|
||||
/*
|
||||
* Library-private functions.
|
||||
|
|
Загрузка…
Ссылка в новой задаче