static JSAtom * js_AtomizeHashedKey(JSContext *cx, jsval key, PRHashNumber keyHash, uintN flags) { PRHashTable *table; PRHashEntry *he, **hep; JSAtom *atom; PR_ASSERT(JS_IS_LOCKED(cx)); table = cx->runtime->atomState.table; hep = PR_HashTableRawLookup(table, keyHash, (void *)key); if ((he = *hep) == NULL) { he = PR_HashTableRawAdd(table, hep, keyHash, (void *)key, NULL); if (!he) { JS_ReportOutOfMemory(cx); return NULL; } } atom = (JSAtom *)he; #ifdef DEBUG_DUPLICATE_ATOMS hep = PR_HashTableRawLookup(table, keyHash, (void *)key); he = *hep; PR_ASSERT(atom == (JSAtom *)he); #endif if (flags & ATOM_NOHOLD) return atom; return js_HoldAtom(cx, atom); }
js_DropAtom(JSContext *cx, JSAtom *atom) { #ifdef DEBUG_DUPLICATE_ATOMS jsval key; PRHashNumber keyHash; PRHashEntry *he, **hep; key = ATOM_KEY(atom); keyHash = js_hash_atom_key((void *)key); hep = PR_HashTableRawLookup(cx->runtime->atomState.table, keyHash, (void*)key); he = *hep; PR_ASSERT(atom == (JSAtom *)he); #endif PR_ASSERT(JS_IS_LOCKED(cx)); PR_ASSERT(atom->nrefs > 0); if (atom->nrefs <= 0) return NULL; if (--atom->nrefs == 0) { PR_HashTableRemove(cx->runtime->atomState.table, atom->entry.key); #ifdef DEBUG_DUPLICATE_ATOMS hep = PR_HashTableRawLookup(cx->runtime->atomState.table, keyHash, (void *)key); he = *hep; PR_ASSERT(he == NULL); #endif atom = NULL; } return atom; }
JSAtom * js_AtomizeDouble(JSContext *cx, jsdouble d, uintN flags) { jsdouble *dp; PRHashTable *table; PRHashNumber keyHash; jsval key; PRHashEntry *he, **hep; JSAtom *atom; #if PR_ALIGN_OF_DOUBLE == 8 dp = &d; #else char alignbuf[16]; dp = (jsdouble *)&alignbuf[8 - ((pruword)&alignbuf & 7)]; *dp = d; #endif PR_ASSERT(JS_IS_LOCKED(cx)); table = cx->runtime->atomState.table; keyHash = HASH_DOUBLE(dp); key = DOUBLE_TO_JSVAL(dp); hep = PR_HashTableRawLookup(table, keyHash, (void *)key); if ((he = *hep) == NULL) { if (!js_NewDoubleValue(cx, d, &key)) return NULL; he = PR_HashTableRawAdd(table, hep, keyHash, (void *)key, NULL); if (!he) { JS_ReportOutOfMemory(cx); return NULL; } } atom = (JSAtom *)he; #ifdef DEBUG_DUPLICATE_ATOMS hep = PR_HashTableRawLookup(table, keyHash, (void *)key); he = *hep; PR_ASSERT(atom == (JSAtom *)he); #endif if (flags & ATOM_NOHOLD) return atom; return js_HoldAtom(cx, atom); }
js_hash_scope_lookup(JSContext *cx, JSScope *scope, jsval id, PRHashNumber hash) { PRHashTable *table = scope->data; PRHashEntry **hep; JSSymbol *sym; hep = PR_HashTableRawLookup(table, hash, (const void *)id); sym = (JSSymbol *) *hep; return sym; }
JSAtom * js_AtomizeString(JSContext *cx, JSString *str, uintN flags) { PRHashTable *table; PRHashNumber keyHash; jsval key; PRHashEntry *he, **hep; JSAtom *atom; PR_ASSERT(JS_IS_LOCKED(cx)); table = cx->runtime->atomState.table; keyHash = js_HashString(str); key = STRING_TO_JSVAL(str); hep = PR_HashTableRawLookup(table, keyHash, (void *)key); if ((he = *hep) == NULL) { if (flags & ATOM_TMPSTR) { if (flags & ATOM_NOCOPY) str = js_NewString(cx, str->chars, str->length, 0); else str = js_NewStringCopyN(cx, str->chars, str->length, 0); if (!str) return NULL; key = STRING_TO_JSVAL(str); } he = PR_HashTableRawAdd(table, hep, keyHash, (void *)key, NULL); if (!he) { JS_ReportOutOfMemory(cx); return NULL; } } atom = (JSAtom *)he; #ifdef DEBUG_DUPLICATE_ATOMS hep = PR_HashTableRawLookup(table, keyHash, (void *)key); he = *hep; PR_ASSERT(atom == (JSAtom *)he); #endif if (flags & ATOM_NOHOLD) return atom; return js_HoldAtom(cx, atom); }
PRHashEntry * js_EnterSharpObject(JSContext *cx, JSObject *obj, jschar **sp) { JSSharpObjectMap *map; PRHashTable *table; PRHashNumber hash; PRHashEntry *he; jsatomid sharpid; char buf[20]; size_t len; map = &cx->sharpObjectMap; table = map->table; if (!table) { table = PR_NewHashTable(8, js_hash_object, PR_CompareValues, PR_CompareValues, NULL, NULL); if (!table) { JS_ReportOutOfMemory(cx); return NULL; } map->table = table; } if (map->depth == 0) { he = MarkSharpObjects(cx, obj); if (!he) return NULL; } else { hash = js_hash_object(obj); he = *PR_HashTableRawLookup(table, hash, obj); PR_ASSERT(he); } sharpid = (jsatomid) he->value; if (sharpid == 0) { *sp = NULL; } else { len = PR_snprintf(buf, sizeof buf, "#%u%c", sharpid >> 1, (sharpid & SHARP_BIT) ? '#' : '='); *sp = js_InflateString(cx, buf, len); if (!*sp) return NULL; } if ((sharpid & SHARP_BIT) == 0) map->depth++; return he; }
/* The hash table is keyed by attribute name, and contains pointers to the * PRCList headers. These in turn, circularly link a set of AttrGetter_s * structures. */ NSAPI_PUBLIC int ACL_AttrGetterRegister(NSErr_t *errp, const char *attr, ACLAttrGetterFn_t fn, ACLMethod_t m, ACLDbType_t d, int position, void *arg) { ACLAttrGetter_t *getter; PRHashEntry **hep; if (position != ACL_AT_FRONT && position != ACL_AT_END) { return -1; } ACL_CritEnter(); hep = PR_HashTableRawLookup(ACLAttrGetterHash, ACLPR_HashCaseString(attr), attr); /* Now, allocate the current entry */ getter = (ACLAttrGetter_t *)CALLOC(sizeof(ACLAttrGetter_t)); if (getter == NULL) { ACL_CritExit(); return -1; } getter->method = m; getter->dbtype = d; getter->fn = fn; getter->arg = arg; if (*hep == 0) { /* New entry */ PR_INIT_CLIST(&getter->list); PR_HashTableAdd(ACLAttrGetterHash, attr, (void *)getter); } else { ACLAttrGetter_t *head = (ACLAttrGetter_t *)((*hep)->value); PR_INSERT_BEFORE(&getter->list, &head->list); if (position == ACL_AT_FRONT) { /* Set new head of list */ (*hep)->value = (void *)getter; } } ACL_CritExit(); return 0; }
js_hash_scope_add(JSContext *cx, JSScope *scope, jsval id, JSProperty *prop) { PRHashTable *table = scope->data; const void *key; PRHashNumber keyHash; PRHashEntry **hep; JSSymbol *sym, **sp; PR_ASSERT(JS_IS_LOCKED(cx)); table->allocPriv = cx; key = (const void *)id; keyHash = js_hash_id(key); hep = PR_HashTableRawLookup(table, keyHash, key); sym = (JSSymbol *) *hep; SCOPE_ADD( sym = (JSSymbol *) PR_HashTableRawAdd(table, hep, keyHash, key, NULL); if (!sym) return NULL; );
JSAtom * js_HoldAtom(JSContext *cx, JSAtom *atom) { #ifdef DEBUG_DUPLICATE_ATOMS jsval key; PRHashNumber keyHash; PRHashEntry *he, **hep; key = ATOM_KEY(atom); keyHash = js_hash_atom_key((void *)key); hep = PR_HashTableRawLookup(cx->runtime->atomState.table, keyHash, (void*)key); he = *hep; PR_ASSERT(atom == (JSAtom *)he); #endif PR_ASSERT(JS_IS_LOCKED(cx)); atom->nrefs++; PR_ASSERT(atom->nrefs > 0); return atom; }
js_hash_scope_add(JSContext *cx, JSScope *scope, jsid id, JSScopeProperty *sprop) { PRHashTable *table = scope->data; const void *key; prhashcode keyHash; PRHashEntry **hep; JSSymbol *sym, **sp; JSScopePrivate *priv; PR_ASSERT(JS_IS_SCOPE_LOCKED(scope)); priv = table->allocPriv; priv->context = cx; key = (const void *)id; keyHash = js_hash_id(key); hep = PR_HashTableRawLookup(table, keyHash, key); sym = (JSSymbol *) *hep; SCOPE_ADD(priv, sym = (JSSymbol *) PR_HashTableRawAdd(table, hep, keyHash, key, NULL); if (!sym) return NULL; );
static PRHashEntry * MarkSharpObjects(JSContext *cx, JSObject *obj) { JSSharpObjectMap *map; PRHashTable *table; PRHashNumber hash; PRHashEntry **hep, *he; jsatomid sharpid; JSProperty *prop; jsval val; map = &cx->sharpObjectMap; table = map->table; hash = js_hash_object(obj); hep = PR_HashTableRawLookup(table, hash, obj); he = *hep; if (!he) { sharpid = 0; he = PR_HashTableRawAdd(table, hep, hash, obj, (void *)sharpid); if (!he) { JS_ReportOutOfMemory(cx); return NULL; } for (prop = obj->map->props; prop; prop = prop->next) { if (!prop->symbols || !(prop->flags & JSPROP_ENUMERATE)) continue; val = prop->object->slots[prop->slot]; if (JSVAL_IS_OBJECT(val) && val != JSVAL_NULL) (void) MarkSharpObjects(cx, JSVAL_TO_OBJECT(val)); } } else { sharpid = (jsatomid) he->value; if (sharpid == 0) { sharpid = ++map->sharpgen << 1; he->value = (void *) sharpid; } } return he; }