| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
| * vim: set ts=8 sts=4 et sw=4 tw=99: |
| * This Source Code Form is subject to the terms of the Mozilla Public |
| * License, v. 2.0. If a copy of the MPL was not distributed with this |
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| |
| /* |
| * JavaScript Debugging support - Atom support |
| */ |
| |
| #include "jsd.h" |
| |
| /* #define TEST_ATOMS 1 */ |
| |
| #ifdef TEST_ATOMS |
| static void |
| _testAtoms(JSDContext*jsdc) |
| { |
| JSDAtom* atom0 = jsd_AddAtom(jsdc, "foo"); |
| JSDAtom* atom1 = jsd_AddAtom(jsdc, "foo"); |
| JSDAtom* atom2 = jsd_AddAtom(jsdc, "bar"); |
| JSDAtom* atom3 = jsd_CloneAtom(jsdc, atom1); |
| JSDAtom* atom4 = jsd_CloneAtom(jsdc, atom2); |
| |
| const char* c0 = JSD_ATOM_TO_STRING(atom0); |
| const char* c1 = JSD_ATOM_TO_STRING(atom1); |
| const char* c2 = JSD_ATOM_TO_STRING(atom2); |
| const char* c3 = JSD_ATOM_TO_STRING(atom3); |
| const char* c4 = JSD_ATOM_TO_STRING(atom4); |
| |
| jsd_DropAtom(jsdc, atom0); |
| jsd_DropAtom(jsdc, atom1); |
| jsd_DropAtom(jsdc, atom2); |
| jsd_DropAtom(jsdc, atom3); |
| jsd_DropAtom(jsdc, atom4); |
| } |
| #endif |
| |
| static int |
| _atom_smasher(JSHashEntry *he, int i, void *arg) |
| { |
| JS_ASSERT(he); |
| JS_ASSERT(he->value); |
| JS_ASSERT(((JSDAtom*)(he->value))->str); |
| |
| free(((JSDAtom*)(he->value))->str); |
| free(he->value); |
| he->value = NULL; |
| he->key = NULL; |
| return HT_ENUMERATE_NEXT; |
| } |
| |
| static int |
| _compareAtomKeys(const void *v1, const void *v2) |
| { |
| return 0 == strcmp((const char*)v1, (const char*)v2); |
| } |
| |
| static int |
| _compareAtoms(const void *v1, const void *v2) |
| { |
| return 0 == strcmp(((JSDAtom*)v1)->str, ((JSDAtom*)v2)->str); |
| } |
| |
| |
| JSBool |
| jsd_CreateAtomTable(JSDContext* jsdc) |
| { |
| jsdc->atoms = JS_NewHashTable(256, JS_HashString, |
| _compareAtomKeys, _compareAtoms, |
| NULL, NULL); |
| #ifdef TEST_ATOMS |
| _testAtoms(jsdc); |
| #endif |
| return !!jsdc->atoms; |
| } |
| |
| void |
| jsd_DestroyAtomTable(JSDContext* jsdc) |
| { |
| if( jsdc->atoms ) |
| { |
| JS_HashTableEnumerateEntries(jsdc->atoms, _atom_smasher, NULL); |
| JS_HashTableDestroy(jsdc->atoms); |
| jsdc->atoms = NULL; |
| } |
| } |
| |
| JSDAtom* |
| jsd_AddAtom(JSDContext* jsdc, const char* str) |
| { |
| JSDAtom* atom; |
| |
| if(!str) |
| { |
| JS_ASSERT(0); |
| return NULL; |
| } |
| |
| JSD_LOCK_ATOMS(jsdc); |
| |
| atom = (JSDAtom*) JS_HashTableLookup(jsdc->atoms, str); |
| |
| if( atom ) |
| atom->refcount++; |
| else |
| { |
| atom = (JSDAtom*) malloc(sizeof(JSDAtom)); |
| if( atom ) |
| { |
| atom->str = strdup(str); |
| atom->refcount = 1; |
| if(!JS_HashTableAdd(jsdc->atoms, atom->str, atom)) |
| { |
| free(atom->str); |
| free(atom); |
| atom = NULL; |
| } |
| } |
| } |
| |
| JSD_UNLOCK_ATOMS(jsdc); |
| return atom; |
| } |
| |
| JSDAtom* |
| jsd_CloneAtom(JSDContext* jsdc, JSDAtom* atom) |
| { |
| JSD_LOCK_ATOMS(jsdc); |
| atom->refcount++; |
| JSD_UNLOCK_ATOMS(jsdc); |
| return atom; |
| } |
| |
| void |
| jsd_DropAtom(JSDContext* jsdc, JSDAtom* atom) |
| { |
| JSD_LOCK_ATOMS(jsdc); |
| if(! --atom->refcount) |
| { |
| JS_HashTableRemove(jsdc->atoms, atom->str); |
| free(atom->str); |
| free(atom); |
| } |
| JSD_UNLOCK_ATOMS(jsdc); |
| } |
| |