JS_UNLOCK(&state->lock, cx); str = (JSString*)(((flags & ATOM_NOCOPY) ? js_NewString : js_NewStringCopyN) (cx, str->chars, str->length, 0));
JS_UNLOCK(&state->lock,cx); if (flags & ATOM_NOCOPY) { str = js_NewString(cx, str->chars, str->length, 0); } else { str = js_NewStringCopyN(cx, str->chars, str->length, 0); }
js_AtomizeString(JSContext *cx, JSString *str, uintN flags){    JSHashNumber keyHash;    jsval key;    JSAtomState *state;    JSHashTable *table;    JSHashEntry *he, **hep;    JSAtom *atom;    keyHash = js_HashString(str);    key = STRING_TO_JSVAL(str);    state = &cx->runtime->atomState;    JS_LOCK(&state->lock, cx);    table = state->table;    hep = JS_HashTableRawLookup(table, keyHash, (void *)key);    if ((he = *hep) == NULL) {	if (flags & ATOM_TMPSTR) {#ifdef JS_THREADSAFE	    uint32 gen = state->tablegen;#endif	    JS_UNLOCK(&state->lock, cx);            str = (JSString*)(((flags & ATOM_NOCOPY) ? js_NewString : js_NewStringCopyN)                   (cx, str->chars, str->length, 0));	    if (!str)		return NULL;	    key = STRING_TO_JSVAL(str);	    JS_LOCK(&state->lock, cx);#ifdef JS_THREADSAFE	    if (state->tablegen != gen) {		hep = JS_HashTableRawLookup(table, keyHash, (void *)key);		if ((he = *hep) != NULL) {		    atom = (JSAtom *)he;		    if (flags & ATOM_NOCOPY)			str->chars = NULL;		    goto out;		}	    }#endif	}	he = JS_HashTableRawAdd(table, hep, keyHash, (void *)key, NULL);	if (!he) {	    JS_ReportOutOfMemory(cx);	    atom = NULL;	    goto out;	}    }    atom = (JSAtom *)he;    atom->flags |= flags & ATOM_PINNED;out:    JS_UNLOCK(&state->lock,cx);    return atom;}