JSAtomListElement * js_IndexAtom(JSContext *cx, JSAtom *atom, JSAtomList *al) { JSAtomListElement *ale, *ale2, *next; JSHashEntry **hep; ATOM_LIST_LOOKUP(ale, hep, al, atom); if (!ale) { if (al->count < 10) { /* Few enough for linear search, no hash table needed. */ JS_ASSERT(!al->table); ale = (JSAtomListElement *)js_alloc_temp_entry(cx, atom); if (!ale) return NULL; ALE_SET_ATOM(ale, atom); ALE_SET_NEXT(ale, al->list); al->list = ale; } else { /* We want to hash. Have we already made a hash table? */ if (!al->table) { /* No hash table yet, so hep had better be null! */ JS_ASSERT(!hep); al->table = JS_NewHashTable(al->count + 1, js_hash_atom_ptr, JS_CompareValues, JS_CompareValues, &temp_alloc_ops, cx); if (!al->table) return NULL; /* * Set ht->nentries explicitly, because we are moving entries * from al to ht, not calling JS_HashTable(Raw|)Add. */ al->table->nentries = al->count; /* Insert each ale on al->list into the new hash table. */ for (ale2 = al->list; ale2; ale2 = next) { next = ALE_NEXT(ale2); ale2->entry.keyHash = ALE_ATOM(ale2)->number; hep = JS_HashTableRawLookup(al->table, ale2->entry.keyHash, ale2->entry.key); ALE_SET_NEXT(ale2, *hep); *hep = &ale2->entry; } al->list = NULL; /* Set hep for insertion of atom's ale, immediately below. */ hep = JS_HashTableRawLookup(al->table, atom->number, atom); } /* Finally, add an entry for atom into the hash bucket at hep. */ ale = (JSAtomListElement *) JS_HashTableRawAdd(al->table, hep, atom->number, atom, NULL); if (!ale) return NULL; } ALE_SET_INDEX(ale, al->count++); } return ale; }
static void js_free_temp_entry(void *priv, JSHashEntry *he, uintN flag) { JSCompiler *jsc = (JSCompiler *) priv; JSAtomListElement *ale = (JSAtomListElement *) he; ALE_SET_NEXT(ale, jsc->aleFreeList); jsc->aleFreeList = ale; }