зеркало из https://github.com/mozilla/pjs.git
Add JS_EnumerateResolvedStandardClasses, and fix a few lazy-standard-class-init glitches hindering it (292903, r=shaver, a=me).
This commit is contained in:
Родитель
d029c0d690
Коммит
ea0bf58dc3
110
js/src/jsapi.c
110
js/src/jsapi.c
|
@ -1235,6 +1235,11 @@ static struct {
|
|||
#endif
|
||||
#if JS_HAS_SCRIPT_OBJECT
|
||||
{js_InitScriptClass, ATOM_OFFSET(Script)},
|
||||
#endif
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
{js_InitXMLClass, ATOM_OFFSET(XML)},
|
||||
{js_InitNamespaceClass, ATOM_OFFSET(Namespace)},
|
||||
{js_InitQNameClass, ATOM_OFFSET(QName)},
|
||||
#endif
|
||||
{NULL, 0}
|
||||
};
|
||||
|
@ -1308,13 +1313,10 @@ static JSStdName standard_class_names[] = {
|
|||
#endif
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
{js_InitXMLClass, LAZILY_PINNED_ATOM(isXMLName)},
|
||||
{js_InitNamespaceClass, LAZILY_PINNED_ATOM(Namespace)},
|
||||
{js_InitQNameClass, LAZILY_PINNED_ATOM(QName)},
|
||||
{js_InitQNameClass, LAZILY_PINNED_ATOM(AnyName)},
|
||||
{js_InitQNameClass, LAZILY_PINNED_ATOM(AttributeName)},
|
||||
{js_InitXMLClass, LAZILY_PINNED_ATOM(XML)},
|
||||
{js_InitAnyNameClass, LAZILY_PINNED_ATOM(AnyName)},
|
||||
{js_InitAttributeNameClass, LAZILY_PINNED_ATOM(AttributeName)},
|
||||
{js_InitXMLClass, LAZILY_PINNED_ATOM(XMLList)},
|
||||
{js_InitXMLClass, LAZILY_PINNED_ATOM(isXMLName)},
|
||||
#endif
|
||||
|
||||
{NULL, 0, NULL}
|
||||
|
@ -1372,7 +1374,7 @@ JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsval id,
|
|||
rt = cx->runtime;
|
||||
|
||||
#if JS_HAS_UNDEFINED
|
||||
/* See if we're resolving 'undefined', and define it if so. */
|
||||
/* Check whether we're resolving 'undefined', and define it if so. */
|
||||
atom = rt->atomState.typeAtoms[JSTYPE_VOID];
|
||||
if (idstr == ATOM_TO_STRING(atom)) {
|
||||
*resolved = JS_TRUE;
|
||||
|
@ -1455,7 +1457,7 @@ JS_EnumerateStandardClasses(JSContext *cx, JSObject *obj)
|
|||
rt = cx->runtime;
|
||||
|
||||
#if JS_HAS_UNDEFINED
|
||||
/* See if we need to bind 'undefined' and define it if so. */
|
||||
/* Check whether we need to bind 'undefined' and define it if so. */
|
||||
atom = rt->atomState.typeAtoms[JSTYPE_VOID];
|
||||
if (!HasOwnProperty(cx, obj, atom, &found))
|
||||
return JS_FALSE;
|
||||
|
@ -1478,6 +1480,96 @@ JS_EnumerateStandardClasses(JSContext *cx, JSObject *obj)
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSIdArray *
|
||||
AddAtomToArray(JSContext *cx, JSAtom *atom, JSIdArray *ida, jsint *ip)
|
||||
{
|
||||
jsint i = *ip;
|
||||
|
||||
if (i >= ida->length) {
|
||||
ida = js_SetIdArrayLength(cx, ida, ida->length * 2);
|
||||
if (!ida)
|
||||
return NULL;
|
||||
}
|
||||
ida->vector[i] = ATOM_TO_JSID(atom);
|
||||
*ip = i + 1;
|
||||
return ida;
|
||||
}
|
||||
|
||||
static JSIdArray *
|
||||
EnumerateIfResolved(JSContext *cx, JSObject *obj, JSAtom *atom, JSIdArray *ida,
|
||||
jsint *ip, JSBool *foundp)
|
||||
{
|
||||
if (!HasOwnProperty(cx, obj, atom, foundp)) {
|
||||
JS_DestroyIdArray(cx, ida);
|
||||
return NULL;
|
||||
}
|
||||
if (*foundp) {
|
||||
ida = AddAtomToArray(cx, atom, ida, ip);
|
||||
if (!ida)
|
||||
return NULL;
|
||||
}
|
||||
return ida;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSIdArray *)
|
||||
JS_EnumerateResolvedStandardClasses(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JSRuntime *rt;
|
||||
JSIdArray *ida;
|
||||
JSAtom *atom;
|
||||
jsint i, j, k;
|
||||
JSBool found;
|
||||
JSObjectOp init;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
rt = cx->runtime;
|
||||
ida = js_NewIdArray(cx, 8);
|
||||
if (!ida)
|
||||
return NULL;
|
||||
i = 0;
|
||||
|
||||
#if JS_HAS_UNDEFINED
|
||||
/* Check whether 'undefined' has been resolved and enumerate it if so. */
|
||||
atom = rt->atomState.typeAtoms[JSTYPE_VOID];
|
||||
ida = EnumerateIfResolved(cx, obj, atom, ida, &i, &found);
|
||||
if (!ida)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
/* Enumerate only classes that *have* been resolved. */
|
||||
for (j = 0; standard_class_atoms[j].init; j++) {
|
||||
atom = OFFSET_TO_ATOM(rt, standard_class_atoms[j].atomOffset);
|
||||
ida = EnumerateIfResolved(cx, obj, atom, ida, &i, &found);
|
||||
if (!ida)
|
||||
return NULL;
|
||||
|
||||
if (found) {
|
||||
init = standard_class_atoms[j].init;
|
||||
|
||||
for (k = 0; standard_class_names[k].init; k++) {
|
||||
if (standard_class_names[k].init == init) {
|
||||
atom = StdNameToAtom(cx, &standard_class_names[k]);
|
||||
ida = AddAtomToArray(cx, atom, ida, &i);
|
||||
if (!ida)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (init == js_InitObjectClass) {
|
||||
for (k = 0; object_prototype_names[k].init; k++) {
|
||||
atom = StdNameToAtom(cx, &object_prototype_names[k]);
|
||||
ida = AddAtomToArray(cx, atom, ida, &i);
|
||||
if (!ida)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Trim to exact length via js_SetIdArrayLength. */
|
||||
return js_SetIdArrayLength(cx, ida, i);
|
||||
}
|
||||
|
||||
#undef ATOM_OFFSET
|
||||
#undef OFFSET_TO_ATOM
|
||||
|
||||
|
@ -3028,7 +3120,7 @@ JS_Enumerate(JSContext *cx, JSObject *obj)
|
|||
if (i == ida->length) {
|
||||
/* Grow length by factor of 1.5 instead of doubling. */
|
||||
jsint newlen = ida->length + (((jsuint)ida->length + 1) >> 1);
|
||||
ida = js_GrowIdArray(cx, ida, newlen);
|
||||
ida = js_SetIdArrayLength(cx, ida, newlen);
|
||||
if (!ida)
|
||||
goto error;
|
||||
vector = &ida->vector[0];
|
||||
|
|
|
@ -506,6 +506,9 @@ JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsval id,
|
|||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_EnumerateStandardClasses(JSContext *cx, JSObject *obj);
|
||||
|
||||
extern JS_PUBLIC_API(JSIdArray *)
|
||||
JS_EnumerateResolvedStandardClasses(JSContext *cx, JSObject *obj);
|
||||
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_GetScopeChain(JSContext *cx);
|
||||
|
||||
|
|
|
@ -94,11 +94,14 @@ const char js_Call_str[] = "Call";
|
|||
const char js_Date_str[] = "Date";
|
||||
const char js_Function_str[] = "Function";
|
||||
const char js_Math_str[] = "Math";
|
||||
const char js_Namespace_str[] = "Namespace";
|
||||
const char js_Number_str[] = "Number";
|
||||
const char js_Object_str[] = "Object";
|
||||
const char js_QName_str[] = "QName";
|
||||
const char js_RegExp_str[] = "RegExp";
|
||||
const char js_Script_str[] = "Script";
|
||||
const char js_String_str[] = "String";
|
||||
const char js_XML_str[] = "XML";
|
||||
const char js_anonymous_str[] = "anonymous";
|
||||
const char js_arguments_str[] = "arguments";
|
||||
const char js_arity_str[] = "arity";
|
||||
|
@ -308,11 +311,14 @@ js_InitPinnedAtoms(JSContext *cx, JSAtomState *state)
|
|||
#endif
|
||||
FROB(FunctionAtom, js_Function_str);
|
||||
FROB(MathAtom, js_Math_str);
|
||||
FROB(NamespaceAtom, js_Namespace_str);
|
||||
FROB(NumberAtom, js_Number_str);
|
||||
FROB(ObjectAtom, js_Object_str);
|
||||
FROB(QNameAtom, js_QName_str);
|
||||
FROB(RegExpAtom, js_RegExp_str);
|
||||
FROB(ScriptAtom, js_Script_str);
|
||||
FROB(StringAtom, js_String_str);
|
||||
FROB(XMLAtom, js_XML_str);
|
||||
FROB(anonymousAtom, js_anonymous_str);
|
||||
FROB(argumentsAtom, js_arguments_str);
|
||||
FROB(arityAtom, js_arity_str);
|
||||
|
|
|
@ -172,11 +172,14 @@ struct JSAtomState {
|
|||
JSAtom *ErrorAtom;
|
||||
JSAtom *FunctionAtom;
|
||||
JSAtom *MathAtom;
|
||||
JSAtom *NamespaceAtom;
|
||||
JSAtom *NumberAtom;
|
||||
JSAtom *ObjectAtom;
|
||||
JSAtom *QNameAtom;
|
||||
JSAtom *RegExpAtom;
|
||||
JSAtom *ScriptAtom;
|
||||
JSAtom *StringAtom;
|
||||
JSAtom *XMLAtom;
|
||||
JSAtom *anonymousAtom;
|
||||
JSAtom *argumentsAtom;
|
||||
JSAtom *arityAtom;
|
||||
|
@ -221,14 +224,11 @@ struct JSAtomState {
|
|||
JSAtom *InfinityAtom;
|
||||
JSAtom *InternalErrorAtom;
|
||||
JSAtom *NaNAtom;
|
||||
JSAtom *NamespaceAtom;
|
||||
JSAtom *QNameAtom;
|
||||
JSAtom *RangeErrorAtom;
|
||||
JSAtom *ReferenceErrorAtom;
|
||||
JSAtom *SyntaxErrorAtom;
|
||||
JSAtom *TypeErrorAtom;
|
||||
JSAtom *URIErrorAtom;
|
||||
JSAtom *XMLAtom;
|
||||
JSAtom *XMLListAtom;
|
||||
JSAtom *anynameAtom;
|
||||
JSAtom *decodeURIAtom;
|
||||
|
@ -280,11 +280,14 @@ extern const char js_Call_str[];
|
|||
extern const char js_Date_str[];
|
||||
extern const char js_Function_str[];
|
||||
extern const char js_Math_str[];
|
||||
extern const char js_Namespace_str[];
|
||||
extern const char js_Number_str[];
|
||||
extern const char js_Object_str[];
|
||||
extern const char js_QName_str[];
|
||||
extern const char js_RegExp_str[];
|
||||
extern const char js_Script_str[];
|
||||
extern const char js_String_str[];
|
||||
extern const char js_XML_str[];
|
||||
extern const char js_anonymous_str[];
|
||||
extern const char js_arguments_str[];
|
||||
extern const char js_arity_str[];
|
||||
|
|
|
@ -3249,20 +3249,24 @@ js_NewIdArray(JSContext *cx, jsint length)
|
|||
JSIdArray *ida;
|
||||
|
||||
ida = (JSIdArray *)
|
||||
JS_malloc(cx, sizeof(JSIdArray) + (length - 1) * sizeof(jsval));
|
||||
JS_malloc(cx, sizeof(JSIdArray) + (length-1) * sizeof(jsval));
|
||||
if (ida)
|
||||
ida->length = length;
|
||||
return ida;
|
||||
}
|
||||
|
||||
JSIdArray *
|
||||
js_GrowIdArray(JSContext *cx, JSIdArray *ida, jsint length)
|
||||
js_SetIdArrayLength(JSContext *cx, JSIdArray *ida, jsint length)
|
||||
{
|
||||
ida = (JSIdArray *)
|
||||
JS_realloc(cx, ida, sizeof(JSIdArray) + (length - 1) * sizeof(jsval));
|
||||
if (ida)
|
||||
ida->length = length;
|
||||
return ida;
|
||||
JSIdArray *rida;
|
||||
|
||||
rida = (JSIdArray *)
|
||||
JS_realloc(cx, ida, sizeof(JSIdArray) + (length-1) * sizeof(jsval));
|
||||
if (!rida)
|
||||
JS_DestroyIdArray(cx, ida);
|
||||
else
|
||||
rida->length = length;
|
||||
return rida;
|
||||
}
|
||||
|
||||
/* Private type used to iterate over all properties of a native JS object */
|
||||
|
|
|
@ -412,8 +412,11 @@ js_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp);
|
|||
extern JSIdArray *
|
||||
js_NewIdArray(JSContext *cx, jsint length);
|
||||
|
||||
/*
|
||||
* Unlike realloc(3), this function frees ida on failure.
|
||||
*/
|
||||
extern JSIdArray *
|
||||
js_GrowIdArray(JSContext *cx, JSIdArray *ida, jsint length);
|
||||
js_SetIdArrayLength(JSContext *cx, JSIdArray *ida, jsint length);
|
||||
|
||||
extern JSBool
|
||||
js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
||||
|
|
|
@ -118,9 +118,6 @@ static struct {
|
|||
const char js_AnyName_str[] = "AnyName";
|
||||
const char js_AttributeName_str[] = "AttributeName";
|
||||
const char js_isXMLName_str[] = "isXMLName";
|
||||
const char js_Namespace_str[] = "Namespace";
|
||||
const char js_QName_str[] = "QName";
|
||||
const char js_XML_str[] = "XML";
|
||||
const char js_XMLList_str[] = "XMLList";
|
||||
const char js_localName_str[] = "localName";
|
||||
const char js_xml_parent_str[] = "parent";
|
||||
|
@ -7347,20 +7344,24 @@ js_InitNamespaceClass(JSContext *cx, JSObject *obj)
|
|||
JSObject *
|
||||
js_InitQNameClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
if (!JS_InitClass(cx, obj, NULL, &js_AttributeNameClass, AttributeName, 2,
|
||||
qname_props, qname_methods, NULL, NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!JS_InitClass(cx, obj, NULL, &js_AnyNameClass, AnyName, 0,
|
||||
qname_props, qname_methods, NULL, NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return JS_InitClass(cx, obj, NULL, &js_QNameClass.base, QName, 2,
|
||||
qname_props, qname_methods, NULL, NULL);
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js_InitAttributeNameClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return JS_InitClass(cx, obj, NULL, &js_AttributeNameClass, AttributeName, 2,
|
||||
qname_props, qname_methods, NULL, NULL);
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js_InitAnyNameClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return JS_InitClass(cx, obj, NULL, &js_AnyNameClass, AnyName, 0,
|
||||
qname_props, qname_methods, NULL, NULL);
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js_InitXMLClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
|
@ -7444,7 +7445,13 @@ js_InitXMLClass(JSContext *cx, JSObject *obj)
|
|||
JSObject *
|
||||
js_InitXMLClasses(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
if (!js_InitNamespaceClass(cx, obj) || !js_InitQNameClass(cx, obj))
|
||||
if (!js_InitNamespaceClass(cx, obj))
|
||||
return NULL;
|
||||
if (!js_InitQNameClass(cx, obj))
|
||||
return NULL;
|
||||
if (!js_InitAttributeNameClass(cx, obj))
|
||||
return NULL;
|
||||
if (!js_InitAnyNameClass(cx, obj))
|
||||
return NULL;
|
||||
return js_InitXMLClass(cx, obj);
|
||||
}
|
||||
|
|
|
@ -45,9 +45,6 @@
|
|||
extern const char js_AnyName_str[];
|
||||
extern const char js_AttributeName_str[];
|
||||
extern const char js_isXMLName_str[];
|
||||
extern const char js_Namespace_str[];
|
||||
extern const char js_QName_str[];
|
||||
extern const char js_XML_str[];
|
||||
extern const char js_XMLList_str[];
|
||||
|
||||
extern const char js_amp_entity_str[];
|
||||
|
@ -217,10 +214,10 @@ js_GetXMLObject(JSContext *cx, JSXML *xml);
|
|||
|
||||
extern JS_FRIEND_DATA(JSXMLObjectOps) js_XMLObjectOps;
|
||||
extern JS_FRIEND_DATA(JSClass) js_XMLClass;
|
||||
extern JS_FRIEND_DATA(JSExtendedClass) js_NamespaceClass;
|
||||
extern JS_FRIEND_DATA(JSExtendedClass) js_QNameClass;
|
||||
extern JS_FRIEND_DATA(JSClass) js_AttributeNameClass;
|
||||
extern JS_FRIEND_DATA(JSClass) js_AnyNameClass;
|
||||
extern JS_FRIEND_DATA(JSExtendedClass) js_NamespaceClass;
|
||||
|
||||
/*
|
||||
* Macros to test whether an object or a value is of type "xml" (per typeof).
|
||||
|
@ -236,6 +233,12 @@ js_InitNamespaceClass(JSContext *cx, JSObject *obj);
|
|||
extern JSObject *
|
||||
js_InitQNameClass(JSContext *cx, JSObject *obj);
|
||||
|
||||
extern JSObject *
|
||||
js_InitAttributeNameClass(JSContext *cx, JSObject *obj);
|
||||
|
||||
extern JSObject *
|
||||
js_InitAnyNameClass(JSContext *cx, JSObject *obj);
|
||||
|
||||
extern JSObject *
|
||||
js_InitXMLClass(JSContext *cx, JSObject *obj);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче