/* -*- 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);
}        

