mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 654301: Better interned string API. (r=Waldo)
This commit is contained in:
parent
c226d4cca1
commit
36481bff9a
@ -3427,7 +3427,7 @@ nsresult nsScriptSecurityManager::Init()
|
||||
|
||||
::JS_BeginRequest(cx);
|
||||
if (sEnabledID == JSID_VOID)
|
||||
sEnabledID = INTERNED_STRING_TO_JSID(::JS_InternString(cx, "enabled"));
|
||||
sEnabledID = INTERNED_STRING_TO_JSID(cx, ::JS_InternString(cx, "enabled"));
|
||||
::JS_EndRequest(cx);
|
||||
|
||||
InitPrefs();
|
||||
|
@ -908,7 +908,7 @@ nsEventListenerManager::RegisterScriptEventListener(nsIScriptContext *aContext,
|
||||
if (sAddListenerID == JSID_VOID) {
|
||||
JSAutoRequest ar(cx);
|
||||
sAddListenerID =
|
||||
INTERNED_STRING_TO_JSID(::JS_InternString(cx, "addEventListener"));
|
||||
INTERNED_STRING_TO_JSID(cx, ::JS_InternString(cx, "addEventListener"));
|
||||
}
|
||||
|
||||
if (aContext->GetScriptTypeID() == nsIProgrammingLanguage::JAVASCRIPT) {
|
||||
|
@ -3322,7 +3322,7 @@ nsHTMLDocument::DoClipboardSecurityCheck(PRBool aPaste)
|
||||
if (aPaste) {
|
||||
if (nsHTMLDocument::sPasteInternal_id == JSID_VOID) {
|
||||
nsHTMLDocument::sPasteInternal_id =
|
||||
INTERNED_STRING_TO_JSID(::JS_InternString(cx, "paste"));
|
||||
INTERNED_STRING_TO_JSID(cx, ::JS_InternString(cx, "paste"));
|
||||
}
|
||||
rv = secMan->CheckPropertyAccess(cx, nsnull, classNameStr.get(),
|
||||
nsHTMLDocument::sPasteInternal_id,
|
||||
@ -3330,7 +3330,7 @@ nsHTMLDocument::DoClipboardSecurityCheck(PRBool aPaste)
|
||||
} else {
|
||||
if (nsHTMLDocument::sCutCopyInternal_id == JSID_VOID) {
|
||||
nsHTMLDocument::sCutCopyInternal_id =
|
||||
INTERNED_STRING_TO_JSID(::JS_InternString(cx, "cutcopy"));
|
||||
INTERNED_STRING_TO_JSID(cx, ::JS_InternString(cx, "cutcopy"));
|
||||
}
|
||||
rv = secMan->CheckPropertyAccess(cx, nsnull, classNameStr.get(),
|
||||
nsHTMLDocument::sCutCopyInternal_id,
|
||||
|
@ -985,7 +985,7 @@ nsJSObjWrapper::NP_Enumerate(NPObject *npobj, NPIdentifier **idarray,
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
id = StringToNPIdentifier(str);
|
||||
id = StringToNPIdentifier(cx, str);
|
||||
} else {
|
||||
NS_ASSERTION(JSVAL_IS_INT(v),
|
||||
"The element in ida must be either string or int!\n");
|
||||
@ -1473,8 +1473,8 @@ CallNPMethodInternal(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
|
||||
if (npobj->_class->invoke) {
|
||||
JSFunction *fun = (JSFunction *)::JS_GetPrivate(cx, funobj);
|
||||
JSString *name = ::JS_GetFunctionId(fun);
|
||||
NPIdentifier id = StringToNPIdentifier(name);
|
||||
JSString *name = ::JS_InternJSString(cx, ::JS_GetFunctionId(fun));
|
||||
NPIdentifier id = StringToNPIdentifier(cx, name);
|
||||
|
||||
ok = npobj->_class->invoke(npobj, id, npargs, argc, &v);
|
||||
} else {
|
||||
|
@ -144,9 +144,9 @@ NPIdentifierToString(NPIdentifier id)
|
||||
}
|
||||
|
||||
static inline NPIdentifier
|
||||
StringToNPIdentifier(JSString *str)
|
||||
StringToNPIdentifier(JSContext *cx, JSString *str)
|
||||
{
|
||||
return JSIdToNPIdentifier(INTERNED_STRING_TO_JSID(str));
|
||||
return JSIdToNPIdentifier(INTERNED_STRING_TO_JSID(cx, str));
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
@ -63,6 +63,7 @@ CPPSRCS = \
|
||||
testGCChunkAlloc.cpp \
|
||||
testGetPropertyDefault.cpp \
|
||||
testIntString.cpp \
|
||||
testIntern.cpp \
|
||||
testLookup.cpp \
|
||||
testLooselyEqual.cpp \
|
||||
testNewObject.cpp \
|
||||
|
40
js/src/jsapi-tests/testIntern.cpp
Normal file
40
js/src/jsapi-tests/testIntern.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
#include "tests.h"
|
||||
#include "jsatom.h"
|
||||
|
||||
BEGIN_TEST(testAtomizedIsNotInterned)
|
||||
{
|
||||
/* Try to pick a string that won't be interned by other tests in this runtime. */
|
||||
static const char someChars[] = "blah blah blah? blah blah blah";
|
||||
JSAtom *atom = js_Atomize(cx, someChars, JS_ARRAY_LENGTH(someChars));
|
||||
CHECK(!JS_StringHasBeenInterned(cx, atom));
|
||||
CHECK(JS_InternJSString(cx, atom));
|
||||
CHECK(JS_StringHasBeenInterned(cx, atom));
|
||||
return true;
|
||||
}
|
||||
END_TEST(testAtomizedIsNotInterned)
|
||||
|
||||
struct StringWrapper
|
||||
{
|
||||
JSString *str;
|
||||
bool strOk;
|
||||
} sw;
|
||||
|
||||
JSBool
|
||||
GCCallback(JSContext *cx, JSGCStatus status)
|
||||
{
|
||||
if (status == JSGC_MARK_END)
|
||||
sw.strOk = !JS_IsAboutToBeFinalized(cx, sw.str);
|
||||
return true;
|
||||
}
|
||||
|
||||
BEGIN_TEST(testInternAcrossGC)
|
||||
{
|
||||
sw.str = JS_InternString(cx, "wrapped chars that another test shouldn't be using");
|
||||
sw.strOk = false;
|
||||
CHECK(sw.str);
|
||||
JS_SetGCCallback(cx, GCCallback);
|
||||
JS_GC(cx);
|
||||
CHECK(sw.strOk);
|
||||
return true;
|
||||
}
|
||||
END_TEST(testInternAcrossGC)
|
@ -14,7 +14,7 @@ BEGIN_TEST(testStringBuffer_finishString)
|
||||
JSString *str = JS_NewStringCopyZ(cx, "foopy");
|
||||
CHECK(str);
|
||||
|
||||
JSAtom *atom = js_AtomizeString(cx, str, 0);
|
||||
JSAtom *atom = js_AtomizeString(cx, str);
|
||||
CHECK(atom);
|
||||
|
||||
js::StringBuffer buffer(cx);
|
||||
|
@ -1574,7 +1574,7 @@ StdNameToAtom(JSContext *cx, JSStdName *stdn)
|
||||
if (!atom) {
|
||||
name = stdn->name;
|
||||
if (name) {
|
||||
atom = js_Atomize(cx, name, strlen(name), ATOM_PINNED);
|
||||
atom = js_Atomize(cx, name, strlen(name), InternAtom);
|
||||
OFFSET_TO_ATOM(cx->runtime, offset) = atom;
|
||||
}
|
||||
}
|
||||
@ -3236,14 +3236,14 @@ JS_LookupElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp)
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_LookupProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp)
|
||||
{
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
return atom && JS_LookupPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_LookupUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, jsval *vp)
|
||||
{
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
|
||||
return atom && JS_LookupPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
|
||||
}
|
||||
|
||||
@ -3266,7 +3266,7 @@ JS_PUBLIC_API(JSBool)
|
||||
JS_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, const char *name, uintN flags, jsval *vp)
|
||||
{
|
||||
JSObject *obj2;
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
return atom && JS_LookupPropertyWithFlagsById(cx, obj, ATOM_TO_JSID(atom), flags, &obj2, vp);
|
||||
}
|
||||
|
||||
@ -3290,14 +3290,14 @@ JS_HasElement(JSContext *cx, JSObject *obj, jsint index, JSBool *foundp)
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_HasProperty(JSContext *cx, JSObject *obj, const char *name, JSBool *foundp)
|
||||
{
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
return atom && JS_HasPropertyById(cx, obj, ATOM_TO_JSID(atom), foundp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_HasUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, JSBool *foundp)
|
||||
{
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
|
||||
return atom && JS_HasPropertyById(cx, obj, ATOM_TO_JSID(atom), foundp);
|
||||
}
|
||||
|
||||
@ -3332,7 +3332,7 @@ JS_AlreadyHasOwnElement(JSContext *cx, JSObject *obj, jsint index, JSBool *found
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_AlreadyHasOwnProperty(JSContext *cx, JSObject *obj, const char *name, JSBool *foundp)
|
||||
{
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
return atom && JS_AlreadyHasOwnPropertyById(cx, obj, ATOM_TO_JSID(atom), foundp);
|
||||
}
|
||||
|
||||
@ -3340,7 +3340,7 @@ JS_PUBLIC_API(JSBool)
|
||||
JS_AlreadyHasOwnUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen,
|
||||
JSBool *foundp)
|
||||
{
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
|
||||
return atom && JS_AlreadyHasOwnPropertyById(cx, obj, ATOM_TO_JSID(atom), foundp);
|
||||
}
|
||||
|
||||
@ -3395,7 +3395,7 @@ DefineProperty(JSContext *cx, JSObject *obj, const char *name, const Value &valu
|
||||
atom = NULL;
|
||||
attrs &= ~JSPROP_INDEX;
|
||||
} else {
|
||||
atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
atom = js_Atomize(cx, name, strlen(name));
|
||||
if (!atom)
|
||||
return JS_FALSE;
|
||||
id = ATOM_TO_JSID(atom);
|
||||
@ -3424,7 +3424,7 @@ DefineUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namele
|
||||
const Value &value, PropertyOp getter, StrictPropertyOp setter, uintN attrs,
|
||||
uintN flags, intN tinyid)
|
||||
{
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
|
||||
return atom && DefinePropertyById(cx, obj, ATOM_TO_JSID(atom), value, getter, setter, attrs,
|
||||
flags, tinyid);
|
||||
}
|
||||
@ -3522,7 +3522,7 @@ JS_AliasProperty(JSContext *cx, JSObject *obj, const char *name, const char *ali
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj);
|
||||
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
if (!atom)
|
||||
return JS_FALSE;
|
||||
if (!LookupPropertyById(cx, obj, ATOM_TO_JSID(atom), JSRESOLVE_QUALIFIED, &obj2, &prop))
|
||||
@ -3536,7 +3536,7 @@ JS_AliasProperty(JSContext *cx, JSObject *obj, const char *name, const char *ali
|
||||
alias, name, obj2->getClass()->name);
|
||||
return JS_FALSE;
|
||||
}
|
||||
atom = js_Atomize(cx, alias, strlen(alias), 0);
|
||||
atom = js_Atomize(cx, alias, strlen(alias));
|
||||
if (!atom) {
|
||||
ok = JS_FALSE;
|
||||
} else {
|
||||
@ -3560,7 +3560,7 @@ JS_AliasElement(JSContext *cx, JSObject *obj, const char *name, jsint alias)
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj);
|
||||
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
if (!atom)
|
||||
return JS_FALSE;
|
||||
if (!LookupPropertyById(cx, obj, ATOM_TO_JSID(atom), JSRESOLVE_QUALIFIED, &obj2, &prop))
|
||||
@ -3665,7 +3665,7 @@ JS_PUBLIC_API(JSBool)
|
||||
JS_GetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
|
||||
uintN *attrsp, JSBool *foundp)
|
||||
{
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, ATOM_TO_JSID(atom),
|
||||
attrsp, foundp, NULL, NULL);
|
||||
}
|
||||
@ -3674,7 +3674,7 @@ JS_PUBLIC_API(JSBool)
|
||||
JS_GetUCPropertyAttributes(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen,
|
||||
uintN *attrsp, JSBool *foundp)
|
||||
{
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
|
||||
return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, ATOM_TO_JSID(atom),
|
||||
attrsp, foundp, NULL, NULL);
|
||||
}
|
||||
@ -3684,7 +3684,7 @@ JS_GetPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj, const char *nam
|
||||
uintN *attrsp, JSBool *foundp,
|
||||
JSPropertyOp *getterp, JSStrictPropertyOp *setterp)
|
||||
{
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, ATOM_TO_JSID(atom),
|
||||
attrsp, foundp, getterp, setterp);
|
||||
}
|
||||
@ -3695,7 +3695,7 @@ JS_GetUCPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj,
|
||||
uintN *attrsp, JSBool *foundp,
|
||||
JSPropertyOp *getterp, JSStrictPropertyOp *setterp)
|
||||
{
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
|
||||
return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, ATOM_TO_JSID(atom),
|
||||
attrsp, foundp, getterp, setterp);
|
||||
}
|
||||
@ -3731,7 +3731,7 @@ JS_PUBLIC_API(JSBool)
|
||||
JS_SetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
|
||||
uintN attrs, JSBool *foundp)
|
||||
{
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
return atom && SetPropertyAttributesById(cx, obj, ATOM_TO_JSID(atom), attrs, foundp);
|
||||
}
|
||||
|
||||
@ -3739,7 +3739,7 @@ JS_PUBLIC_API(JSBool)
|
||||
JS_SetUCPropertyAttributes(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen,
|
||||
uintN attrs, JSBool *foundp)
|
||||
{
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
|
||||
return atom && SetPropertyAttributesById(cx, obj, ATOM_TO_JSID(atom), attrs, foundp);
|
||||
}
|
||||
|
||||
@ -3767,21 +3767,21 @@ JS_GetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp)
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_GetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp)
|
||||
{
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
return atom && JS_GetPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_GetPropertyDefault(JSContext *cx, JSObject *obj, const char *name, jsval def, jsval *vp)
|
||||
{
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
return atom && JS_GetPropertyByIdDefault(cx, obj, ATOM_TO_JSID(atom), def, vp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_GetUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, jsval *vp)
|
||||
{
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
|
||||
return atom && JS_GetPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
|
||||
}
|
||||
|
||||
@ -3800,7 +3800,7 @@ JS_GetMethodById(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, jsval *
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_GetMethod(JSContext *cx, JSObject *obj, const char *name, JSObject **objp, jsval *vp)
|
||||
{
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
return atom && JS_GetMethodById(cx, obj, ATOM_TO_JSID(atom), objp, vp);
|
||||
}
|
||||
|
||||
@ -3822,14 +3822,14 @@ JS_SetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp)
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_SetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp)
|
||||
{
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
return atom && JS_SetPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_SetUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, jsval *vp)
|
||||
{
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
|
||||
return atom && JS_SetPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
|
||||
}
|
||||
|
||||
@ -3851,14 +3851,14 @@ JS_DeleteElement2(JSContext *cx, JSObject *obj, jsint index, jsval *rval)
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_DeleteProperty2(JSContext *cx, JSObject *obj, const char *name, jsval *rval)
|
||||
{
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
return atom && JS_DeletePropertyById2(cx, obj, ATOM_TO_JSID(atom), rval);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_DeleteUCProperty2(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, jsval *rval)
|
||||
{
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
|
||||
return atom && JS_DeletePropertyById2(cx, obj, ATOM_TO_JSID(atom), rval);
|
||||
}
|
||||
|
||||
@ -4188,7 +4188,7 @@ JS_NewFunction(JSContext *cx, JSNative native, uintN nargs, uintN flags,
|
||||
if (!name) {
|
||||
atom = NULL;
|
||||
} else {
|
||||
atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
atom = js_Atomize(cx, name, strlen(name));
|
||||
if (!atom)
|
||||
return NULL;
|
||||
}
|
||||
@ -4397,7 +4397,7 @@ JS_DefineFunction(JSContext *cx, JSObject *obj, const char *name, JSNative call,
|
||||
JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj);
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
if (!atom)
|
||||
return NULL;
|
||||
return js_DefineFunction(cx, obj, ATOM_TO_JSID(atom), Valueify(call), nargs, attrs);
|
||||
@ -4411,7 +4411,7 @@ JS_DefineUCFunction(JSContext *cx, JSObject *obj,
|
||||
JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj);
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
|
||||
if (!atom)
|
||||
return NULL;
|
||||
return js_DefineFunction(cx, obj, ATOM_TO_JSID(atom), Valueify(call), nargs, attrs);
|
||||
@ -4737,7 +4737,7 @@ CompileUCFunctionForPrincipalsCommon(JSContext *cx, JSObject *obj,
|
||||
if (!name) {
|
||||
funAtom = NULL;
|
||||
} else {
|
||||
funAtom = js_Atomize(cx, name, strlen(name), 0);
|
||||
funAtom = js_Atomize(cx, name, strlen(name));
|
||||
if (!funAtom) {
|
||||
fun = NULL;
|
||||
goto out2;
|
||||
@ -4762,7 +4762,7 @@ CompileUCFunctionForPrincipalsCommon(JSContext *cx, JSObject *obj,
|
||||
Bindings bindings(cx, emptyCallShape);
|
||||
AutoBindingsRooter root(cx, bindings);
|
||||
for (i = 0; i < nargs; i++) {
|
||||
argAtom = js_Atomize(cx, argnames[i], strlen(argnames[i]), 0);
|
||||
argAtom = js_Atomize(cx, argnames[i], strlen(argnames[i]));
|
||||
if (!argAtom) {
|
||||
fun = NULL;
|
||||
goto out2;
|
||||
@ -5059,7 +5059,7 @@ JS_CallFunctionName(JSContext *cx, JSObject *obj, const char *name, uintN argc,
|
||||
assertSameCompartment(cx, obj, JSValueArray(argv, argc));
|
||||
|
||||
AutoValueRooter tvr(cx);
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
JSBool ok =
|
||||
atom &&
|
||||
js_GetMethod(cx, obj, ATOM_TO_JSID(atom), JSGET_NO_METHOD_BARRIER, tvr.addr()) &&
|
||||
@ -5245,23 +5245,32 @@ JS_NewStringCopyZ(JSContext *cx, const char *s)
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_StringHasBeenInterned(JSString *str)
|
||||
JS_StringHasBeenInterned(JSContext *cx, JSString *str)
|
||||
{
|
||||
return str->isAtom();
|
||||
CHECK_REQUEST(cx);
|
||||
|
||||
if (!str->isAtom())
|
||||
return false;
|
||||
|
||||
return AtomIsInterned(cx, &str->asAtom());
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSString *)
|
||||
JS_InternJSString(JSContext *cx, JSString *str)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return js_AtomizeString(cx, str, 0);
|
||||
JSAtom *atom = js_AtomizeString(cx, str, InternAtom);
|
||||
JS_ASSERT_IF(atom, JS_StringHasBeenInterned(cx, atom));
|
||||
return atom;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSString *)
|
||||
JS_InternString(JSContext *cx, const char *s)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return js_Atomize(cx, s, strlen(s), ATOM_INTERNED);
|
||||
JSAtom *atom = js_Atomize(cx, s, strlen(s), InternAtom);
|
||||
JS_ASSERT_IF(atom, JS_StringHasBeenInterned(cx, atom));
|
||||
return atom;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSString *)
|
||||
@ -5291,7 +5300,9 @@ JS_PUBLIC_API(JSString *)
|
||||
JS_InternUCStringN(JSContext *cx, const jschar *s, size_t length)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return js_AtomizeChars(cx, s, length, ATOM_INTERNED);
|
||||
JSAtom *atom = js_AtomizeChars(cx, s, length, InternAtom);
|
||||
JS_ASSERT_IF(atom, JS_StringHasBeenInterned(cx, atom));
|
||||
return atom;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSString *)
|
||||
|
@ -333,16 +333,22 @@ JSID_IS_ZERO(jsid id)
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_StringHasBeenInterned(JSString *str);
|
||||
JS_StringHasBeenInterned(JSContext *cx, JSString *str);
|
||||
|
||||
/* A jsid may only hold an interned JSString. */
|
||||
/*
|
||||
* Only JSStrings that have been interned via the JSAPI can be turned into
|
||||
* jsids by API clients.
|
||||
*
|
||||
* N.B. if a jsid is backed by a string which has not been interned, that
|
||||
* string must be appropriately rooted to avoid being collected by the GC.
|
||||
*/
|
||||
static JS_ALWAYS_INLINE jsid
|
||||
INTERNED_STRING_TO_JSID(JSString *str)
|
||||
INTERNED_STRING_TO_JSID(JSContext *cx, JSString *str)
|
||||
{
|
||||
jsid id;
|
||||
JS_ASSERT(str);
|
||||
JS_ASSERT(JS_StringHasBeenInterned(str));
|
||||
JS_ASSERT(((size_t)str & JSID_TYPE_MASK) == 0);
|
||||
JS_ASSERT(JS_StringHasBeenInterned(cx, str));
|
||||
JSID_BITS(id) = (size_t)str;
|
||||
return id;
|
||||
}
|
||||
|
@ -164,7 +164,6 @@ struct JSArenaPool {
|
||||
(JS_UPTRDIFF(mark, (a)->base) <= JS_UPTRDIFF((a)->avail, (a)->base))
|
||||
|
||||
#ifdef DEBUG
|
||||
#define JS_FREE_PATTERN 0xDA
|
||||
#define JS_CLEAR_UNUSED(a) (JS_ASSERT((a)->avail <= (a)->limit), \
|
||||
memset((void*)(a)->avail, JS_FREE_PATTERN, \
|
||||
(a)->limit - (a)->avail))
|
||||
|
@ -278,7 +278,7 @@ BigIndexToId(JSContext *cx, JSObject *obj, jsuint index, JSBool createAtom,
|
||||
return JS_TRUE;
|
||||
}
|
||||
} else {
|
||||
atom = js_AtomizeChars(cx, start, JS_ARRAY_END(buf) - start, 0);
|
||||
atom = js_AtomizeChars(cx, start, JS_ARRAY_END(buf) - start);
|
||||
if (!atom)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
@ -67,28 +67,15 @@
|
||||
using namespace js;
|
||||
using namespace js::gc;
|
||||
|
||||
const size_t JSAtomState::commonAtomsOffset = offsetof(JSAtomState, emptyAtom);
|
||||
const size_t JSAtomState::lazyAtomsOffset = offsetof(JSAtomState, lazy);
|
||||
|
||||
/*
|
||||
* ATOM_HASH assumes that JSHashNumber is 32-bit even on 64-bit systems.
|
||||
*/
|
||||
JS_STATIC_ASSERT(sizeof(JSHashNumber) == 4);
|
||||
JS_STATIC_ASSERT(sizeof(JSAtom *) == JS_BYTES_PER_WORD);
|
||||
|
||||
/*
|
||||
* Start and limit offsets for atom pointers in JSAtomState must be aligned
|
||||
* on the word boundary.
|
||||
*/
|
||||
JS_STATIC_ASSERT(ATOM_OFFSET_START % sizeof(JSAtom *) == 0);
|
||||
JS_STATIC_ASSERT(ATOM_OFFSET_LIMIT % sizeof(JSAtom *) == 0);
|
||||
|
||||
/*
|
||||
* JS_BOOLEAN_STR and JS_TYPE_STR assume that boolean names starts from the
|
||||
* index 1 and type name starts from the index 1+2 atoms in JSAtomState.
|
||||
*/
|
||||
JS_STATIC_ASSERT(1 * sizeof(JSAtom *) ==
|
||||
offsetof(JSAtomState, booleanAtoms) - ATOM_OFFSET_START);
|
||||
JS_STATIC_ASSERT((1 + 2) * sizeof(JSAtom *) ==
|
||||
offsetof(JSAtomState, typeAtoms) - ATOM_OFFSET_START);
|
||||
|
||||
const char *
|
||||
js_AtomToPrintableString(JSContext *cx, JSAtom *atom, JSAutoByteString *bytes)
|
||||
{
|
||||
@ -217,8 +204,28 @@ const char *const js_common_atom_names[] = {
|
||||
"WeakMap" /* WeakMapAtom */
|
||||
};
|
||||
|
||||
JS_STATIC_ASSERT(JS_ARRAY_LENGTH(js_common_atom_names) * sizeof(JSAtom *) ==
|
||||
LAZY_ATOM_OFFSET_START - ATOM_OFFSET_START);
|
||||
void
|
||||
JSAtomState::checkStaticInvariants()
|
||||
{
|
||||
/*
|
||||
* Start and limit offsets for atom pointers in JSAtomState must be aligned
|
||||
* on the word boundary.
|
||||
*/
|
||||
JS_STATIC_ASSERT(commonAtomsOffset % sizeof(JSAtom *) == 0);
|
||||
JS_STATIC_ASSERT(sizeof(*this) % sizeof(JSAtom *) == 0);
|
||||
|
||||
/*
|
||||
* JS_BOOLEAN_STR and JS_TYPE_STR assume that boolean names starts from the
|
||||
* index 1 and type name starts from the index 1+2 atoms in JSAtomState.
|
||||
*/
|
||||
JS_STATIC_ASSERT(1 * sizeof(JSAtom *) ==
|
||||
offsetof(JSAtomState, booleanAtoms) - commonAtomsOffset);
|
||||
JS_STATIC_ASSERT((1 + 2) * sizeof(JSAtom *) ==
|
||||
offsetof(JSAtomState, typeAtoms) - commonAtomsOffset);
|
||||
|
||||
JS_STATIC_ASSERT(JS_ARRAY_LENGTH(js_common_atom_names) * sizeof(JSAtom *) ==
|
||||
lazyAtomsOffset - commonAtomsOffset);
|
||||
}
|
||||
|
||||
/*
|
||||
* Interpreter macros called by the trace recorder assume common atom indexes
|
||||
@ -295,40 +302,6 @@ const char js_close_str[] = "close";
|
||||
const char js_send_str[] = "send";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Helper macros to access and modify JSAtomHashEntry.
|
||||
*/
|
||||
|
||||
inline AtomEntryType
|
||||
StringToInitialAtomEntry(JSString *str)
|
||||
{
|
||||
return (AtomEntryType) str;
|
||||
}
|
||||
|
||||
inline uintN
|
||||
AtomEntryFlags(AtomEntryType entry)
|
||||
{
|
||||
return (uintN) (entry & ATOM_ENTRY_FLAG_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Conceptually, we have compressed a HashMap<JSAtom *, uint> into a
|
||||
* HashMap<size_t>. Here, we promise that we are only changing the "value" of
|
||||
* the HashMap entry, so the const_cast is safe.
|
||||
*/
|
||||
|
||||
inline void
|
||||
AddAtomEntryFlags(const AtomEntryType &entry, uintN flags)
|
||||
{
|
||||
const_cast<AtomEntryType &>(entry) |= AtomEntryType(flags);
|
||||
}
|
||||
|
||||
inline void
|
||||
ClearAtomEntryFlags(const AtomEntryType &entry, uintN flags)
|
||||
{
|
||||
const_cast<AtomEntryType &>(entry) &= ~AtomEntryType(flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* For a browser build from 2007-08-09 after the browser starts up there are
|
||||
* just 55 double atoms, but over 15000 string atoms. Not to penalize more
|
||||
@ -367,47 +340,35 @@ js_FinishAtomState(JSRuntime *rt)
|
||||
}
|
||||
|
||||
for (AtomSet::Range r = state->atoms.all(); !r.empty(); r.popFront())
|
||||
AtomEntryToKey(r.front())->finalize(rt);
|
||||
r.front().toAtom()->finalize(rt);
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
js_FinishLock(&state->lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
JSBool
|
||||
bool
|
||||
js_InitCommonAtoms(JSContext *cx)
|
||||
{
|
||||
JSAtomState *state = &cx->runtime->atomState;
|
||||
uintN i;
|
||||
JSAtom **atoms;
|
||||
|
||||
atoms = COMMON_ATOMS_START(state);
|
||||
for (i = 0; i < JS_ARRAY_LENGTH(js_common_atom_names); i++, atoms++) {
|
||||
*atoms = js_Atomize(cx, js_common_atom_names[i],
|
||||
strlen(js_common_atom_names[i]), ATOM_PINNED);
|
||||
JSAtom **atoms = state->commonAtomsStart();
|
||||
for (size_t i = 0; i < JS_ARRAY_LENGTH(js_common_atom_names); i++, atoms++) {
|
||||
*atoms = js_Atomize(cx, js_common_atom_names[i], strlen(js_common_atom_names[i]),
|
||||
InternAtom);
|
||||
if (!*atoms)
|
||||
return JS_FALSE;
|
||||
return false;
|
||||
}
|
||||
JS_ASSERT((uint8 *)atoms - (uint8 *)state == LAZY_ATOM_OFFSET_START);
|
||||
memset(atoms, 0, ATOM_OFFSET_LIMIT - LAZY_ATOM_OFFSET_START);
|
||||
|
||||
state->clearLazyAtoms();
|
||||
cx->runtime->emptyString = state->emptyAtom;
|
||||
return JS_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
js_FinishCommonAtoms(JSContext *cx)
|
||||
{
|
||||
cx->runtime->emptyString = NULL;
|
||||
JSAtomState *state = &cx->runtime->atomState;
|
||||
|
||||
for (AtomSet::Range r = state->atoms.all(); !r.empty(); r.popFront())
|
||||
ClearAtomEntryFlags(r.front(), ATOM_PINNED);
|
||||
|
||||
#ifdef DEBUG
|
||||
memset(COMMON_ATOMS_START(state), JS_FREE_PATTERN,
|
||||
ATOM_OFFSET_LIMIT - ATOM_OFFSET_START);
|
||||
#endif
|
||||
cx->runtime->atomState.junkAtoms();
|
||||
}
|
||||
|
||||
void
|
||||
@ -423,20 +384,16 @@ js_TraceAtomState(JSTracer *trc)
|
||||
if (rt->gcKeepAtoms) {
|
||||
for (AtomSet::Range r = state->atoms.all(); !r.empty(); r.popFront()) {
|
||||
JS_SET_TRACING_INDEX(trc, "locked_atom", number++);
|
||||
MarkString(trc, AtomEntryToKey(r.front()));
|
||||
MarkString(trc, r.front().toAtom());
|
||||
}
|
||||
} else {
|
||||
for (AtomSet::Range r = state->atoms.all(); !r.empty(); r.popFront()) {
|
||||
AtomEntryType entry = r.front();
|
||||
uintN flags = AtomEntryFlags(entry);
|
||||
if (flags & (ATOM_PINNED | ATOM_INTERNED)) {
|
||||
JS_SET_TRACING_INDEX(trc,
|
||||
flags & ATOM_PINNED
|
||||
? "pinned_atom"
|
||||
: "interned_atom",
|
||||
number++);
|
||||
MarkString(trc, AtomEntryToKey(entry));
|
||||
}
|
||||
AtomStateEntry entry = r.front();
|
||||
if (!entry.isInterned())
|
||||
continue;
|
||||
|
||||
JS_SET_TRACING_INDEX(trc, "interned_atom", number++);
|
||||
MarkString(trc, entry.toAtom());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -447,26 +404,66 @@ js_SweepAtomState(JSContext *cx)
|
||||
JSAtomState *state = &cx->runtime->atomState;
|
||||
|
||||
for (AtomSet::Enum e(state->atoms); !e.empty(); e.popFront()) {
|
||||
AtomEntryType entry = e.front();
|
||||
if (AtomEntryFlags(entry) & (ATOM_PINNED | ATOM_INTERNED)) {
|
||||
AtomStateEntry entry = e.front();
|
||||
|
||||
if (entry.isInterned()) {
|
||||
/* Pinned or interned key cannot be finalized. */
|
||||
JS_ASSERT(!IsAboutToBeFinalized(cx, AtomEntryToKey(entry)));
|
||||
} else if (IsAboutToBeFinalized(cx, AtomEntryToKey(entry))) {
|
||||
e.removeFront();
|
||||
JS_ASSERT(!IsAboutToBeFinalized(cx, entry.toAtom()));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IsAboutToBeFinalized(cx, entry.toAtom()))
|
||||
e.removeFront();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AtomIsInterned(JSContext *cx, JSAtom *atom)
|
||||
{
|
||||
if (atom->isStaticAtom())
|
||||
return true;
|
||||
|
||||
AutoLockAtomsCompartment lock(cx);
|
||||
AtomSet::Ptr p = cx->runtime->atomState.atoms.lookup(atom);
|
||||
if (!p)
|
||||
return false;
|
||||
|
||||
return p->isInterned();
|
||||
}
|
||||
|
||||
/*
|
||||
* Callers passing ATOM_NOCOPY have freshly allocated *pchars and thus this
|
||||
* This call takes ownership of 'chars' if ATOM_NOCOPY is set.
|
||||
* Non-branching code sequence to put the intern flag on |entryRef| if
|
||||
* |intern| is true.
|
||||
*
|
||||
* Conceptually, we have compressed a HashMap<JSAtom *, uint> into a
|
||||
* HashMap<size_t>. Here, we promise that we are only changing the "value" of
|
||||
* the HashMap entry, so the const_cast is safe.
|
||||
*/
|
||||
static void
|
||||
MakeInterned(const AutoLockAtomsCompartment &, const AtomStateEntry &entryRef, InternBehavior ib)
|
||||
{
|
||||
AtomStateEntry *entry = const_cast<AtomStateEntry *>(&entryRef);
|
||||
AtomStateEntry::makeInterned(entry, ib);
|
||||
JS_ASSERT(entryRef.isInterned() >= ib);
|
||||
}
|
||||
|
||||
enum OwnCharsBehavior
|
||||
{
|
||||
CopyChars, /* in other words, do not take ownership */
|
||||
TakeCharOwnership
|
||||
};
|
||||
|
||||
/*
|
||||
* Callers passing OwnChars have freshly allocated *pchars and thus this
|
||||
* memory can be used as a new JSAtom's buffer without copying. When this flag
|
||||
* is set, the contract is that callers will free *pchars iff *pchars == NULL.
|
||||
*/
|
||||
static JSAtom *
|
||||
Atomize(JSContext *cx, const jschar **pchars, size_t length, uintN flags)
|
||||
Atomize(JSContext *cx, const jschar **pchars, size_t length,
|
||||
InternBehavior ib, OwnCharsBehavior ocb = CopyChars)
|
||||
{
|
||||
const jschar *chars = *pchars;
|
||||
JS_ASSERT(!(flags & ~(ATOM_PINNED|ATOM_INTERNED|ATOM_NOCOPY)));
|
||||
|
||||
if (JSAtom *s = JSAtom::lookupStatic(chars, length))
|
||||
return s;
|
||||
@ -476,45 +473,65 @@ Atomize(JSContext *cx, const jschar **pchars, size_t length, uintN flags)
|
||||
AtomSet &atoms = cx->runtime->atomState.atoms;
|
||||
AtomSet::AddPtr p = atoms.lookupForAdd(AtomHasher::Lookup(chars, length));
|
||||
|
||||
JSAtom *atom;
|
||||
if (p) {
|
||||
atom = AtomEntryToKey(*p);
|
||||
} else {
|
||||
SwitchToCompartment sc(cx, cx->runtime->atomsCompartment);
|
||||
|
||||
JSFixedString *key;
|
||||
if (flags & ATOM_NOCOPY) {
|
||||
key = js_NewString(cx, const_cast<jschar *>(chars), length);
|
||||
if (!key)
|
||||
return NULL;
|
||||
*pchars = NULL; /* Caller should not free *pchars. */
|
||||
} else {
|
||||
key = js_NewStringCopyN(cx, chars, length);
|
||||
if (!key)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* We have to relookup the key as the last ditch GC invoked from the
|
||||
* string allocation or OOM handling may unlock the atomsCompartment.
|
||||
*/
|
||||
AtomHasher::Lookup lookup(chars, length);
|
||||
if (!atoms.relookupOrAdd(p, lookup, StringToInitialAtomEntry(key))) {
|
||||
JS_ReportOutOfMemory(cx); /* SystemAllocPolicy does not report */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
atom = key->morphInternedStringIntoAtom();
|
||||
JSAtom *atom = p->toAtom();
|
||||
MakeInterned(lock, *p, ib);
|
||||
return atom;
|
||||
}
|
||||
|
||||
AddAtomEntryFlags(*p, flags & (ATOM_PINNED | ATOM_INTERNED));
|
||||
return atom;
|
||||
SwitchToCompartment sc(cx, cx->runtime->atomsCompartment);
|
||||
|
||||
JSFixedString *key;
|
||||
|
||||
if (ocb == TakeCharOwnership) {
|
||||
key = js_NewString(cx, const_cast<jschar *>(chars), length);
|
||||
if (!key)
|
||||
return NULL;
|
||||
*pchars = NULL; /* Called should not free *pchars. */
|
||||
} else {
|
||||
JS_ASSERT(ocb == CopyChars);
|
||||
key = js_NewStringCopyN(cx, chars, length);
|
||||
if (!key)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* We have to relookup the key as the last ditch GC invoked from the
|
||||
* string allocation or OOM handling may unlock the atomsCompartment.
|
||||
*
|
||||
* N.B. this avoids recomputing the hash but still has a potential
|
||||
* (# collisions * # chars) comparison cost in the case of a hash
|
||||
* collision!
|
||||
*/
|
||||
AtomHasher::Lookup lookup(chars, length);
|
||||
if (!atoms.relookupOrAdd(p, lookup, AtomStateEntry(key, ib))) {
|
||||
JS_ReportOutOfMemory(cx); /* SystemAllocPolicy does not report */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return key->morphAtomizedStringIntoAtom();
|
||||
}
|
||||
|
||||
JSAtom *
|
||||
js_AtomizeString(JSContext *cx, JSString *str, uintN flags)
|
||||
js_AtomizeString(JSContext *cx, JSString *str, InternBehavior ib)
|
||||
{
|
||||
JS_ASSERT(!(flags & ATOM_NOCOPY));
|
||||
if (str->isAtom()) {
|
||||
JSAtom &atom = str->asAtom();
|
||||
/* N.B. static atoms are effectively always interned. */
|
||||
if (ib != InternAtom || atom.isStaticAtom())
|
||||
return &atom;
|
||||
|
||||
/* Here we have to check whether the atom is already interned. */
|
||||
AutoLockAtomsCompartment lock(cx);
|
||||
|
||||
AtomSet &atoms = cx->runtime->atomState.atoms;
|
||||
AtomSet::Ptr p = atoms.lookup(AtomHasher::Lookup(&atom));
|
||||
JS_ASSERT(p); /* Non-static atom must exist in atom state set. */
|
||||
JS_ASSERT(p->toAtom() == &atom);
|
||||
JS_ASSERT(ib == Intern);
|
||||
MakeInterned(lock, *p, ib);
|
||||
return &atom;
|
||||
}
|
||||
|
||||
if (str->isAtom())
|
||||
return &str->asAtom();
|
||||
@ -525,13 +542,12 @@ js_AtomizeString(JSContext *cx, JSString *str, uintN flags)
|
||||
return NULL;
|
||||
|
||||
JS_ASSERT(length <= JSString::MAX_LENGTH);
|
||||
return Atomize(cx, &chars, length, flags);
|
||||
return Atomize(cx, &chars, length, ib);
|
||||
}
|
||||
|
||||
JSAtom *
|
||||
js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags, bool useCESU8)
|
||||
js_Atomize(JSContext *cx, const char *bytes, size_t length, InternBehavior ib, bool useCESU8)
|
||||
{
|
||||
JS_ASSERT(!(flags & ATOM_NOCOPY));
|
||||
CHECK_REQUEST(cx);
|
||||
|
||||
if (!CheckStringLength(cx, length))
|
||||
@ -549,6 +565,7 @@ js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags, bool us
|
||||
size_t inflatedLength = ATOMIZE_BUF_MAX - 1;
|
||||
|
||||
const jschar *chars;
|
||||
OwnCharsBehavior ocb = CopyChars;
|
||||
if (length < ATOMIZE_BUF_MAX) {
|
||||
if (useCESU8)
|
||||
js_InflateUTF8StringToBuffer(cx, bytes, length, inflated, &inflatedLength, true);
|
||||
@ -561,25 +578,24 @@ js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags, bool us
|
||||
chars = js_InflateString(cx, bytes, &inflatedLength, useCESU8);
|
||||
if (!chars)
|
||||
return NULL;
|
||||
flags |= ATOM_NOCOPY;
|
||||
ocb = TakeCharOwnership;
|
||||
}
|
||||
|
||||
JSAtom *atom = Atomize(cx, &chars, inflatedLength, flags);
|
||||
if ((flags & ATOM_NOCOPY) && chars)
|
||||
JSAtom *atom = Atomize(cx, &chars, inflatedLength, ib, ocb);
|
||||
if (ocb == TakeCharOwnership && chars)
|
||||
cx->free_((void *)chars);
|
||||
return atom;
|
||||
}
|
||||
|
||||
JSAtom *
|
||||
js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags)
|
||||
js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, InternBehavior ib)
|
||||
{
|
||||
JS_ASSERT(!(flags & ATOM_NOCOPY));
|
||||
CHECK_REQUEST(cx);
|
||||
|
||||
if (!CheckStringLength(cx, length))
|
||||
return NULL;
|
||||
|
||||
return Atomize(cx, &chars, length, flags);
|
||||
return Atomize(cx, &chars, length, ib);
|
||||
}
|
||||
|
||||
JSAtom *
|
||||
@ -589,7 +605,7 @@ js_GetExistingStringAtom(JSContext *cx, const jschar *chars, size_t length)
|
||||
return atom;
|
||||
AutoLockAtomsCompartment lock(cx);
|
||||
AtomSet::Ptr p = cx->runtime->atomState.atoms.lookup(AtomHasher::Lookup(chars, length));
|
||||
return p ? AtomEntryToKey(*p) : NULL;
|
||||
return p ? p->toAtom() : NULL;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -601,21 +617,12 @@ js_DumpAtoms(JSContext *cx, FILE *fp)
|
||||
fprintf(fp, "atoms table contents:\n");
|
||||
unsigned number = 0;
|
||||
for (AtomSet::Range r = state->atoms.all(); !r.empty(); r.popFront()) {
|
||||
AtomEntryType entry = r.front();
|
||||
AtomStateEntry entry = r.front();
|
||||
fprintf(fp, "%3u ", number++);
|
||||
if (entry == 0) {
|
||||
fputs("<uninitialized>", fp);
|
||||
} else {
|
||||
JSAtom *key = AtomEntryToKey(entry);
|
||||
FileEscapedString(fp, key, '"');
|
||||
uintN flags = AtomEntryFlags(entry);
|
||||
if (flags != 0) {
|
||||
fputs((flags & (ATOM_PINNED | ATOM_INTERNED))
|
||||
? " pinned | interned"
|
||||
: (flags & ATOM_PINNED) ? " pinned" : " interned",
|
||||
fp);
|
||||
}
|
||||
}
|
||||
JSAtom *key = entry.toAtom();
|
||||
FileEscapeString(fp, key, '"');
|
||||
if (entry.isInterned())
|
||||
fputs(" interned", fp);
|
||||
putc('\n', fp);
|
||||
}
|
||||
putc('\n', fp);
|
||||
|
122
js/src/jsatom.h
122
js/src/jsatom.h
@ -54,10 +54,6 @@
|
||||
#include "jslock.h"
|
||||
#include "jsvalue.h"
|
||||
|
||||
#define ATOM_PINNED 0x1 /* atom is pinned against GC */
|
||||
#define ATOM_INTERNED 0x2 /* pinned variant for JS_Intern* API */
|
||||
#define ATOM_NOCOPY 0x4 /* don't copy atom string bytes */
|
||||
|
||||
/* Engine-internal extensions of jsid */
|
||||
|
||||
static JS_ALWAYS_INLINE jsid
|
||||
@ -278,42 +274,76 @@ struct JSAtomMap {
|
||||
|
||||
namespace js {
|
||||
|
||||
#define ATOM_ENTRY_FLAG_MASK ((size_t)(ATOM_PINNED | ATOM_INTERNED))
|
||||
|
||||
JS_STATIC_ASSERT(ATOM_ENTRY_FLAG_MASK < JS_GCTHING_ALIGN);
|
||||
|
||||
typedef uintptr_t AtomEntryType;
|
||||
|
||||
static JS_ALWAYS_INLINE JSAtom *
|
||||
AtomEntryToKey(AtomEntryType entry)
|
||||
enum InternBehavior
|
||||
{
|
||||
JS_ASSERT(entry != 0);
|
||||
return (JSAtom *)(entry & ~ATOM_ENTRY_FLAG_MASK);
|
||||
}
|
||||
DoNotInternAtom = 0,
|
||||
InternAtom = 1
|
||||
};
|
||||
|
||||
/*
|
||||
* Atom pointer with low bit stolen to indicate whether the atom is interned.
|
||||
* Interned atoms are ignored by the GC, and thus live for the lifetime of the
|
||||
* runtime.
|
||||
*/
|
||||
struct AtomStateEntry {
|
||||
uintptr_t bits;
|
||||
|
||||
static const uintptr_t INTERNED_FLAG = 0x1;
|
||||
|
||||
AtomStateEntry() : bits(0) {}
|
||||
AtomStateEntry(const AtomStateEntry &other) : bits(other.bits) {}
|
||||
|
||||
AtomStateEntry(JSFixedString *futureAtom, bool intern)
|
||||
: bits(uintptr_t(futureAtom) | intern)
|
||||
{}
|
||||
|
||||
bool isInterned() const {
|
||||
return bits & INTERNED_FLAG;
|
||||
}
|
||||
|
||||
/* In static form to avoid accidentally mutating a copy of a hash set value. */
|
||||
static void makeInterned(AtomStateEntry *self, InternBehavior ib) {
|
||||
JS_STATIC_ASSERT(DoNotInternAtom == 0 && InternAtom == 1);
|
||||
JS_ASSERT(ib <= Intern);
|
||||
self->bits |= uintptr_t(ib);
|
||||
}
|
||||
|
||||
JS_ALWAYS_INLINE
|
||||
JSAtom *toAtom() const {
|
||||
JS_ASSERT(bits != 0); /* No NULL values should exist in the atom state. */
|
||||
JS_ASSERT(((JSString *) (bits & ~INTERNED_FLAG))->isAtom());
|
||||
return (JSAtom *) (bits & ~INTERNED_FLAG);
|
||||
}
|
||||
};
|
||||
|
||||
struct AtomHasher
|
||||
{
|
||||
struct Lookup
|
||||
{
|
||||
const jschar *chars;
|
||||
size_t length;
|
||||
Lookup(const jschar *chars, size_t length) : chars(chars), length(length) {}
|
||||
const jschar *chars;
|
||||
size_t length;
|
||||
const JSAtom *atom; /* Optional. */
|
||||
|
||||
Lookup(const jschar *chars, size_t length) : chars(chars), length(length), atom(NULL) {}
|
||||
Lookup(const JSAtom *atom) : chars(atom->chars()), length(atom->length()), atom(atom) {}
|
||||
};
|
||||
|
||||
static HashNumber hash(const Lookup &l) {
|
||||
return HashChars(l.chars, l.length);
|
||||
}
|
||||
|
||||
static bool match(AtomEntryType entry, const Lookup &lookup) {
|
||||
JS_ASSERT(entry);
|
||||
JSAtom *key = AtomEntryToKey(entry);
|
||||
static bool match(AtomStateEntry entry, const Lookup &lookup) {
|
||||
JSAtom *key = entry.toAtom();
|
||||
|
||||
if (lookup.atom)
|
||||
return lookup.atom == key;
|
||||
if (key->length() != lookup.length)
|
||||
return false;
|
||||
return PodEqual(key->chars(), lookup.chars, lookup.length);
|
||||
}
|
||||
};
|
||||
|
||||
typedef HashSet<AtomEntryType, AtomHasher, SystemAllocPolicy> AtomSet;
|
||||
typedef HashSet<AtomStateEntry, AtomHasher, SystemAllocPolicy> AtomSet;
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
@ -463,29 +493,43 @@ struct JSAtomState
|
||||
JSAtom *unwatchAtom;
|
||||
JSAtom *watchAtom;
|
||||
} lazy;
|
||||
|
||||
static const size_t commonAtomsOffset;
|
||||
static const size_t lazyAtomsOffset;
|
||||
|
||||
void clearLazyAtoms() {
|
||||
memset(&lazy, 0, sizeof(lazy));
|
||||
}
|
||||
|
||||
void junkAtoms() {
|
||||
#ifdef DEBUG
|
||||
memset(commonAtomsStart(), JS_FREE_PATTERN, sizeof(*this) - commonAtomsOffset);
|
||||
#endif
|
||||
}
|
||||
|
||||
JSAtom **commonAtomsStart() {
|
||||
return &emptyAtom;
|
||||
}
|
||||
|
||||
void checkStaticInvariants();
|
||||
};
|
||||
|
||||
extern bool
|
||||
AtomIsInterned(JSContext *cx, JSAtom *atom);
|
||||
|
||||
#define ATOM(name) cx->runtime->atomState.name##Atom
|
||||
|
||||
#define ATOM_OFFSET_START offsetof(JSAtomState, emptyAtom)
|
||||
#define LAZY_ATOM_OFFSET_START offsetof(JSAtomState, lazy)
|
||||
#define ATOM_OFFSET_LIMIT (sizeof(JSAtomState))
|
||||
|
||||
#define COMMON_ATOMS_START(state) \
|
||||
((JSAtom **)((uint8 *)(state) + ATOM_OFFSET_START))
|
||||
#define COMMON_ATOM_INDEX(name) \
|
||||
((offsetof(JSAtomState, name##Atom) - ATOM_OFFSET_START) \
|
||||
((offsetof(JSAtomState, name##Atom) - JSAtomState::commonAtomsOffset) \
|
||||
/ sizeof(JSAtom*))
|
||||
#define COMMON_TYPE_ATOM_INDEX(type) \
|
||||
((offsetof(JSAtomState, typeAtoms[type]) - ATOM_OFFSET_START) \
|
||||
((offsetof(JSAtomState, typeAtoms[type]) - JSAtomState::commonAtomsOffset)\
|
||||
/ sizeof(JSAtom*))
|
||||
|
||||
#define ATOM_OFFSET(name) offsetof(JSAtomState, name##Atom)
|
||||
#define OFFSET_TO_ATOM(rt,off) (*(JSAtom **)((char*)&(rt)->atomState + (off)))
|
||||
#define CLASS_ATOM_OFFSET(name) offsetof(JSAtomState,classAtoms[JSProto_##name])
|
||||
|
||||
#define CLASS_ATOM(cx,name) \
|
||||
((cx)->runtime->atomState.classAtoms[JSProto_##name])
|
||||
#define CLASS_ATOM_OFFSET(name) offsetof(JSAtomState, classAtoms[JSProto_##name])
|
||||
#define CLASS_ATOM(cx,name) ((cx)->runtime->atomState.classAtoms[JSProto_##name])
|
||||
|
||||
extern const char *const js_common_atom_names[];
|
||||
extern const size_t js_common_atom_count;
|
||||
@ -588,7 +632,7 @@ js_TraceAtomState(JSTracer *trc);
|
||||
extern void
|
||||
js_SweepAtomState(JSContext *cx);
|
||||
|
||||
extern JSBool
|
||||
extern bool
|
||||
js_InitCommonAtoms(JSContext *cx);
|
||||
|
||||
extern void
|
||||
@ -599,13 +643,15 @@ js_FinishCommonAtoms(JSContext *cx);
|
||||
* memory.
|
||||
*/
|
||||
extern JSAtom *
|
||||
js_AtomizeString(JSContext *cx, JSString *str, uintN flags);
|
||||
js_AtomizeString(JSContext *cx, JSString *str, js::InternBehavior ib = js::DoNotInternAtom);
|
||||
|
||||
extern JSAtom *
|
||||
js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags, bool useCESU8 = false);
|
||||
js_Atomize(JSContext *cx, const char *bytes, size_t length,
|
||||
js::InternBehavior ib = js::DoNotInternAtom, bool useCESU8 = false);
|
||||
|
||||
extern JSAtom *
|
||||
js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags);
|
||||
js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length,
|
||||
js::InternBehavior ib = js::DoNotInternAtom);
|
||||
|
||||
/*
|
||||
* Return an existing atom for the given char array or null if the char
|
||||
|
@ -51,7 +51,7 @@ js_ValueToAtom(JSContext *cx, const js::Value &v, JSAtom **atomp)
|
||||
if (!str)
|
||||
return false;
|
||||
JS::Anchor<JSString *> anchor(str);
|
||||
*atomp = js_AtomizeString(cx, str, 0);
|
||||
*atomp = js_AtomizeString(cx, str);
|
||||
return !!*atomp;
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ js_ValueToAtom(JSContext *cx, const js::Value &v, JSAtom **atomp)
|
||||
return true;
|
||||
}
|
||||
|
||||
*atomp = js_AtomizeString(cx, str, 0);
|
||||
*atomp = js_AtomizeString(cx, str);
|
||||
return !!*atomp;
|
||||
}
|
||||
|
||||
@ -144,7 +144,7 @@ IndexToId(JSContext *cx, uint32 index, jsid *idp)
|
||||
if (!str)
|
||||
return false;
|
||||
|
||||
JSAtom *atom = js_AtomizeString(cx, str, 0);
|
||||
JSAtom *atom = js_AtomizeString(cx, str);
|
||||
if (!atom)
|
||||
return false;
|
||||
*idp = ATOM_TO_JSID(atom);
|
||||
|
@ -260,7 +260,7 @@ HasProperty(JSContext* cx, JSObject* obj, jsid id)
|
||||
JSBool FASTCALL
|
||||
js_HasNamedProperty(JSContext* cx, JSObject* obj, JSString* idstr)
|
||||
{
|
||||
JSAtom *atom = js_AtomizeString(cx, idstr, 0);
|
||||
JSAtom *atom = js_AtomizeString(cx, idstr);
|
||||
if (!atom)
|
||||
return JS_NEITHER;
|
||||
|
||||
|
@ -822,7 +822,7 @@ JSStructuredCloneReader::readId(jsid *idp)
|
||||
JSString *str = readString(data);
|
||||
if (!str)
|
||||
return false;
|
||||
JSAtom *atom = js_AtomizeString(context(), str, 0);
|
||||
JSAtom *atom = js_AtomizeString(context(), str);
|
||||
if (!atom)
|
||||
return false;
|
||||
*idp = ATOM_TO_JSID(atom);
|
||||
|
@ -1389,7 +1389,7 @@ static inline JSAtom **
|
||||
FrameAtomBase(JSContext *cx, js::StackFrame *fp)
|
||||
{
|
||||
return fp->hasImacropc()
|
||||
? COMMON_ATOMS_START(&cx->runtime->atomState)
|
||||
? cx->runtime->atomState.commonAtomsStart()
|
||||
: fp->script()->atomMap.vector;
|
||||
}
|
||||
|
||||
@ -1875,7 +1875,7 @@ class AutoLockAtomsCompartment {
|
||||
|
||||
public:
|
||||
AutoLockAtomsCompartment(JSContext *cx
|
||||
JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: cx(cx)
|
||||
{
|
||||
JS_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
|
@ -1323,8 +1323,8 @@ JSTreeContext::ensureSharpSlots()
|
||||
JS_ASSERT(!(flags & TCF_HAS_SHARPS));
|
||||
if (inFunction()) {
|
||||
JSContext *cx = parser->context;
|
||||
JSAtom *sharpArrayAtom = js_Atomize(cx, "#array", 6, 0);
|
||||
JSAtom *sharpDepthAtom = js_Atomize(cx, "#depth", 6, 0);
|
||||
JSAtom *sharpArrayAtom = js_Atomize(cx, "#array", 6);
|
||||
JSAtom *sharpDepthAtom = js_Atomize(cx, "#depth", 6);
|
||||
if (!sharpArrayAtom || !sharpDepthAtom)
|
||||
return false;
|
||||
|
||||
|
@ -404,9 +404,6 @@ js_InitFunctionClass(JSContext *cx, JSObject *obj);
|
||||
extern JSObject *
|
||||
js_InitArgumentsClass(JSContext *cx, JSObject *obj);
|
||||
|
||||
extern void
|
||||
js_TraceFunction(JSTracer *trc, JSFunction *fun);
|
||||
|
||||
extern void
|
||||
js_FinalizeFunction(JSContext *cx, JSFunction *fun);
|
||||
|
||||
|
@ -2259,7 +2259,7 @@ Interpret(JSContext *cx, StackFrame *entryFrame, uintN inlineCallCount, InterpMo
|
||||
#define LOAD_ATOM(PCOFF, atom) \
|
||||
JS_BEGIN_MACRO \
|
||||
JS_ASSERT(regs.fp()->hasImacropc() \
|
||||
? atoms == COMMON_ATOMS_START(&rt->atomState) && \
|
||||
? atoms == rt->atomState.commonAtomsStart() && \
|
||||
GET_INDEX(regs.pc + PCOFF) < js_common_atom_count \
|
||||
: (size_t)(atoms - script->atomMap.vector) < \
|
||||
(size_t)(script->atomMap.length - \
|
||||
@ -2508,7 +2508,7 @@ Interpret(JSContext *cx, StackFrame *entryFrame, uintN inlineCallCount, InterpMo
|
||||
}
|
||||
|
||||
if (regs.fp()->hasImacropc())
|
||||
atoms = COMMON_ATOMS_START(&rt->atomState);
|
||||
atoms = rt->atomState.commonAtomsStart();
|
||||
#endif
|
||||
|
||||
/* Don't call the script prologue if executing between Method and Trace JIT. */
|
||||
@ -2674,7 +2674,7 @@ Interpret(JSContext *cx, StackFrame *entryFrame, uintN inlineCallCount, InterpMo
|
||||
break;
|
||||
case ARECORD_IMACRO:
|
||||
case ARECORD_IMACRO_ABORTED:
|
||||
atoms = COMMON_ATOMS_START(&rt->atomState);
|
||||
atoms = rt->atomState.commonAtomsStart();
|
||||
op = JSOp(*regs.pc);
|
||||
CLEAR_LEAVE_ON_TRACE_POINT();
|
||||
if (status == ARECORD_IMACRO)
|
||||
|
@ -3995,7 +3995,7 @@ js_InitClass(JSContext *cx, JSObject *obj, JSObject *protoProto,
|
||||
JSPropertySpec *ps, JSFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps, JSFunctionSpec *static_fs)
|
||||
{
|
||||
JSAtom *atom = js_Atomize(cx, clasp->name, strlen(clasp->name), 0);
|
||||
JSAtom *atom = js_Atomize(cx, clasp->name, strlen(clasp->name));
|
||||
if (!atom)
|
||||
return NULL;
|
||||
|
||||
@ -4282,7 +4282,7 @@ js_FindClassObject(JSContext *cx, JSObject *start, JSProtoKey protoKey,
|
||||
}
|
||||
id = ATOM_TO_JSID(cx->runtime->atomState.classAtoms[protoKey]);
|
||||
} else {
|
||||
JSAtom *atom = js_Atomize(cx, clasp->name, strlen(clasp->name), 0);
|
||||
JSAtom *atom = js_Atomize(cx, clasp->name, strlen(clasp->name));
|
||||
if (!atom)
|
||||
return false;
|
||||
id = ATOM_TO_JSID(atom);
|
||||
@ -6323,7 +6323,7 @@ js_XDRObject(JSXDRState *xdr, JSObject **objp)
|
||||
if (protoKey != JSProto_Null) {
|
||||
classDef |= (protoKey << 1);
|
||||
} else {
|
||||
atom = js_Atomize(cx, clasp->name, strlen(clasp->name), 0);
|
||||
atom = js_Atomize(cx, clasp->name, strlen(clasp->name));
|
||||
if (!atom)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ JSONSourceParser::readString()
|
||||
size_t length = current - start;
|
||||
current++;
|
||||
JSFlatString *str = (ST == JSONSourceParser::PropertyName)
|
||||
? js_AtomizeChars(cx, start, length, 0)
|
||||
? js_AtomizeChars(cx, start, length)
|
||||
: js_NewStringCopyN(cx, start, length);
|
||||
if (!str)
|
||||
return token(OOM);
|
||||
|
@ -981,7 +981,7 @@ Compiler::compileScript(JSContext *cx, JSObject *scopeChain, StackFrame *callerF
|
||||
* Save eval program source in script->atomMap.vector[0] for the
|
||||
* eval cache (see EvalCacheLookup in jsobj.cpp).
|
||||
*/
|
||||
JSAtom *atom = js_AtomizeString(cx, source, 0);
|
||||
JSAtom *atom = js_AtomizeString(cx, source);
|
||||
if (!atom || !cg.atomList.add(&parser, atom))
|
||||
goto out;
|
||||
}
|
||||
@ -8880,7 +8880,7 @@ FoldType(JSContext *cx, JSParseNode *pn, TokenKind type)
|
||||
JSString *str = js_NumberToString(cx, pn->pn_dval);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
pn->pn_atom = js_AtomizeString(cx, str, 0);
|
||||
pn->pn_atom = js_AtomizeString(cx, str);
|
||||
if (!pn->pn_atom)
|
||||
return JS_FALSE;
|
||||
pn->pn_type = TOK_STRING;
|
||||
@ -9064,7 +9064,7 @@ FoldXMLConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc)
|
||||
pn1->pn_type = TOK_XMLTEXT;
|
||||
pn1->pn_op = JSOP_STRING;
|
||||
pn1->pn_arity = PN_NULLARY;
|
||||
pn1->pn_atom = js_AtomizeString(cx, accum, 0);
|
||||
pn1->pn_atom = js_AtomizeString(cx, accum);
|
||||
if (!pn1->pn_atom)
|
||||
return JS_FALSE;
|
||||
JS_ASSERT(pnp != &pn1->pn_next);
|
||||
@ -9117,7 +9117,7 @@ FoldXMLConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc)
|
||||
pn1->pn_type = TOK_XMLTEXT;
|
||||
pn1->pn_op = JSOP_STRING;
|
||||
pn1->pn_arity = PN_NULLARY;
|
||||
pn1->pn_atom = js_AtomizeString(cx, accum, 0);
|
||||
pn1->pn_atom = js_AtomizeString(cx, accum);
|
||||
if (!pn1->pn_atom)
|
||||
return JS_FALSE;
|
||||
JS_ASSERT(pnp != &pn1->pn_next);
|
||||
@ -9481,7 +9481,7 @@ js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc, bool inCond)
|
||||
JS_ASSERT(*chars == 0);
|
||||
|
||||
/* Atomize the result string and mutate pn to refer to it. */
|
||||
pn->pn_atom = js_AtomizeString(cx, str, 0);
|
||||
pn->pn_atom = js_AtomizeString(cx, str);
|
||||
if (!pn->pn_atom)
|
||||
return JS_FALSE;
|
||||
pn->pn_type = TOK_STRING;
|
||||
@ -9506,7 +9506,7 @@ js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc, bool inCond)
|
||||
str = js_ConcatStrings(cx, left, right);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
pn->pn_atom = js_AtomizeString(cx, str, 0);
|
||||
pn->pn_atom = js_AtomizeString(cx, str);
|
||||
if (!pn->pn_atom)
|
||||
return JS_FALSE;
|
||||
pn->pn_type = TOK_STRING;
|
||||
|
@ -203,7 +203,7 @@ class NodeBuilder
|
||||
Value funv;
|
||||
|
||||
const char *name = callbackNames[i];
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
if (!atom || !GetPropertyDefault(cx, userobj, ATOM_TO_JSID(atom), NullValue(), &funv))
|
||||
return false;
|
||||
|
||||
@ -313,7 +313,7 @@ class NodeBuilder
|
||||
/*
|
||||
* Bug 575416: instead of js_Atomize, lookup constant atoms in tbl file
|
||||
*/
|
||||
JSAtom *atom = js_Atomize(cx, s, strlen(s), 0);
|
||||
JSAtom *atom = js_Atomize(cx, s, strlen(s));
|
||||
if (!atom)
|
||||
return false;
|
||||
|
||||
@ -425,7 +425,7 @@ class NodeBuilder
|
||||
/*
|
||||
* Bug 575416: instead of js_Atomize, lookup constant atoms in tbl file
|
||||
*/
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
if (!atom)
|
||||
return false;
|
||||
|
||||
|
@ -1020,7 +1020,7 @@ TokenStream::getXMLMarkup(TokenKind *ttp, Token **tpp)
|
||||
atom = cx->runtime->atomState.emptyAtom;
|
||||
} else {
|
||||
atom = js_AtomizeChars(cx, tokenbuf.begin() + contentIndex,
|
||||
tokenbuf.length() - contentIndex, 0);
|
||||
tokenbuf.length() - contentIndex);
|
||||
if (!atom)
|
||||
goto error;
|
||||
}
|
||||
@ -1184,7 +1184,7 @@ TokenStream::newToken(ptrdiff_t adjust)
|
||||
JS_ALWAYS_INLINE JSAtom *
|
||||
TokenStream::atomize(JSContext *cx, CharBuffer &cb)
|
||||
{
|
||||
return js_AtomizeChars(cx, cb.begin(), cb.length(), 0);
|
||||
return js_AtomizeChars(cx, cb.begin(), cb.length());
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -1363,7 +1363,7 @@ TokenStream::getTokenInternal()
|
||||
*/
|
||||
JSAtom *atom;
|
||||
if (!hadUnicodeEscape)
|
||||
atom = js_AtomizeChars(cx, identStart, userbuf.addressOfNextRawChar() - identStart, 0);
|
||||
atom = js_AtomizeChars(cx, identStart, userbuf.addressOfNextRawChar() - identStart);
|
||||
else if (putIdentInTokenbuf(identStart))
|
||||
atom = atomize(cx, tokenbuf);
|
||||
else
|
||||
|
@ -610,6 +610,7 @@ struct Shape : public js::gc::Cell
|
||||
|
||||
void finalize(JSContext *cx);
|
||||
void removeChild(js::Shape *child);
|
||||
void removeChildSlowly(js::Shape *child);
|
||||
};
|
||||
|
||||
struct EmptyShape : public js::Shape
|
||||
|
@ -262,7 +262,7 @@ Bindings::sharpSlotBase(JSContext *cx)
|
||||
{
|
||||
JS_ASSERT(lastBinding);
|
||||
#if JS_HAS_SHARP_VARS
|
||||
if (JSAtom *name = js_Atomize(cx, "#array", 6, 0)) {
|
||||
if (JSAtom *name = js_Atomize(cx, "#array", 6)) {
|
||||
uintN index = uintN(-1);
|
||||
DebugOnly<BindingKind> kind = lookup(cx, name, &index);
|
||||
JS_ASSERT(kind == VARIABLE);
|
||||
|
@ -649,7 +649,7 @@ StackDepth(JSScript *script)
|
||||
if ((pc_) < (script_)->code || \
|
||||
(script_)->code + (script_)->length <= (pc_)) { \
|
||||
JS_ASSERT((size_t)(index) < js_common_atom_count); \
|
||||
(atom) = COMMON_ATOMS_START(&cx->runtime->atomState)[index]; \
|
||||
(atom) = cx->runtime->atomState.commonAtomsStart()[index]; \
|
||||
} else { \
|
||||
(atom) = script_->getAtom(index); \
|
||||
} \
|
||||
|
@ -2068,7 +2068,7 @@ FindReplaceLength(JSContext *cx, RegExpStatics *res, ReplaceData &rdata, size_t
|
||||
if (str->isAtom()) {
|
||||
atom = &str->asAtom();
|
||||
} else {
|
||||
atom = js_AtomizeString(cx, str, 0);
|
||||
atom = js_AtomizeString(cx, str);
|
||||
if (!atom)
|
||||
return false;
|
||||
}
|
||||
@ -3721,7 +3721,7 @@ StringBuffer::finishAtom()
|
||||
if (length == 0)
|
||||
return cx->runtime->atomState.emptyAtom;
|
||||
|
||||
JSAtom *atom = js_AtomizeChars(cx, cb.begin(), length, 0);
|
||||
JSAtom *atom = js_AtomizeChars(cx, cb.begin(), length);
|
||||
cb.clear();
|
||||
return atom;
|
||||
}
|
||||
|
@ -486,10 +486,11 @@ class JSFixedString : public JSFlatString
|
||||
static inline JSFixedString *new_(JSContext *cx, const jschar *chars, size_t length);
|
||||
|
||||
/*
|
||||
* Once a JSFixedString has been added to the atom table, this operation
|
||||
* changes the type (in place) of the JSFixedString into a JSAtom.
|
||||
* Once a JSFixedString has been added to the atom state, this operation
|
||||
* changes the type (in place, as reflected by the flag bits) of the
|
||||
* JSFixedString into a JSAtom.
|
||||
*/
|
||||
inline JSAtom *morphInternedStringIntoAtom();
|
||||
inline JSAtom *morphAtomizedStringIntoAtom();
|
||||
};
|
||||
|
||||
JS_STATIC_ASSERT(sizeof(JSFixedString) == sizeof(JSString));
|
||||
|
@ -344,7 +344,7 @@ JSFixedString::new_(JSContext *cx, const jschar *chars, size_t length)
|
||||
}
|
||||
|
||||
JS_ALWAYS_INLINE JSAtom *
|
||||
JSFixedString::morphInternedStringIntoAtom()
|
||||
JSFixedString::morphAtomizedStringIntoAtom()
|
||||
{
|
||||
JS_ASSERT((d.lengthAndFlags & FLAGS_MASK) == JS_BIT(2));
|
||||
JS_STATIC_ASSERT(NON_STATIC_ATOM == JS_BIT(3));
|
||||
|
@ -12470,11 +12470,11 @@ RootedStringToId(JSContext* cx, JSString** namep, jsid* idp)
|
||||
{
|
||||
JSString* name = *namep;
|
||||
if (name->isAtom()) {
|
||||
*idp = INTERNED_STRING_TO_JSID(name);
|
||||
*idp = ATOM_TO_JSID(&name->asAtom());
|
||||
return true;
|
||||
}
|
||||
|
||||
JSAtom* atom = js_AtomizeString(cx, name, 0);
|
||||
JSAtom* atom = js_AtomizeString(cx, name);
|
||||
if (!atom)
|
||||
return false;
|
||||
*namep = atom; /* write back to GC root */
|
||||
|
@ -87,6 +87,8 @@ JS_Assert(const char *s, const char *file, JSIntn ln);
|
||||
# define JS_THREADSAFE_ASSERT(expr) ((void) 0)
|
||||
# endif
|
||||
|
||||
#define JS_FREE_PATTERN 0xDA
|
||||
|
||||
#else
|
||||
|
||||
#define JS_ASSERT(expr) ((void) 0)
|
||||
|
@ -658,7 +658,7 @@ js_XDRAtom(JSXDRState *xdr, JSAtom **atomp)
|
||||
if (!buf)
|
||||
return false;
|
||||
|
||||
JSAtom *atom = js_Atomize(xdr->cx, buf, len, 0, true);
|
||||
JSAtom *atom = js_Atomize(xdr->cx, buf, len, DoNotInternAtom, true);
|
||||
if (!atom)
|
||||
return false;
|
||||
|
||||
|
@ -2872,7 +2872,7 @@ ToXMLName(JSContext *cx, jsval v, jsid *funidp)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
atomizedName = js_AtomizeString(cx, name, 0);
|
||||
atomizedName = js_AtomizeString(cx, name);
|
||||
if (!atomizedName)
|
||||
return NULL;
|
||||
|
||||
@ -5344,7 +5344,7 @@ ValueToId(JSContext *cx, jsval v, AutoIdRooter *idr)
|
||||
else if (!js_ValueToStringId(cx, Valueify(v), idr->addr()))
|
||||
return JS_FALSE;
|
||||
} else if (JSVAL_IS_STRING(v)) {
|
||||
JSAtom *atom = js_AtomizeString(cx, JSVAL_TO_STRING(v), 0);
|
||||
JSAtom *atom = js_AtomizeString(cx, JSVAL_TO_STRING(v));
|
||||
if (!atom)
|
||||
return JS_FALSE;
|
||||
*idr->addr() = ATOM_TO_JSID(atom);
|
||||
|
@ -190,7 +190,7 @@ PRBool InitializeMember(JSContext * cx, ITypeInfo * pTypeInfo,
|
||||
pInfo = new (pInfo) XPCDispInterface::Member;
|
||||
if(!pInfo)
|
||||
return PR_FALSE;
|
||||
pInfo->SetName(INTERNED_STRING_TO_JSID(str));
|
||||
pInfo->SetName(INTERNED_STRING_TO_JSID(cx, str));
|
||||
pInfo->ResetType();
|
||||
ConvertInvokeKind(pFuncDesc->invkind, *pInfo);
|
||||
pInfo->SetTypeInfo(pFuncDesc->memid, pTypeInfo, pFuncDesc);
|
||||
|
@ -548,7 +548,7 @@ GetMethodInfo(JSContext *cx, jsval *vp, const char **ifaceNamep, jsid *memberIdp
|
||||
NS_ASSERTION(JS_ObjectIsFunction(cx, funobj),
|
||||
"JSNative callee should be Function object");
|
||||
JSString *str = JS_GetFunctionId((JSFunction *) JS_GetPrivate(cx, funobj));
|
||||
jsid methodId = str ? INTERNED_STRING_TO_JSID(str) : JSID_VOID;
|
||||
jsid methodId = str ? INTERNED_STRING_TO_JSID(cx, str) : JSID_VOID;
|
||||
GetMemberInfo(JSVAL_TO_OBJECT(vp[1]), methodId, ifaceNamep);
|
||||
*memberIdp = methodId;
|
||||
}
|
||||
|
@ -382,7 +382,7 @@ XPCNativeInterface::NewInstance(XPCCallContext& ccx,
|
||||
failed = JS_TRUE;
|
||||
break;
|
||||
}
|
||||
name = INTERNED_STRING_TO_JSID(str);
|
||||
name = INTERNED_STRING_TO_JSID(ccx, str);
|
||||
|
||||
if(info->IsSetter())
|
||||
{
|
||||
@ -426,7 +426,7 @@ XPCNativeInterface::NewInstance(XPCCallContext& ccx,
|
||||
failed = JS_TRUE;
|
||||
break;
|
||||
}
|
||||
name = INTERNED_STRING_TO_JSID(str);
|
||||
name = INTERNED_STRING_TO_JSID(ccx, str);
|
||||
|
||||
// XXX need better way to find dups
|
||||
//NS_ASSERTION(!LookupMemberByID(name),"duplicate method/constant name");
|
||||
@ -445,7 +445,7 @@ XPCNativeInterface::NewInstance(XPCCallContext& ccx,
|
||||
{
|
||||
failed = JS_TRUE;
|
||||
}
|
||||
interfaceName = INTERNED_STRING_TO_JSID(str);
|
||||
interfaceName = INTERNED_STRING_TO_JSID(ccx, str);
|
||||
}
|
||||
|
||||
if(!failed)
|
||||
|
Loading…
Reference in New Issue
Block a user