Bug 386885: JSAtom.number is removed in favour of using atoms itself for hashing. r=brendan

This commit is contained in:
igor%mir2.org 2007-07-11 09:25:45 +00:00
Родитель 11d0936e48
Коммит 740c486981
13 изменённых файлов: 164 добавлений и 129 удалений

Просмотреть файл

@ -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.