From f03da04d02b6ebcb3e2407db1c3e5c2762cf18ae Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 22 Apr 2010 16:37:41 -0700 Subject: [PATCH] Bug 560167 - encapsulate XML-related JSSLOT_* values within JSObject. r=brendan. --- js/src/jsinterp.cpp | 2 +- js/src/jsiter.cpp | 14 ++-- js/src/jsobj.cpp | 2 +- js/src/jsobj.h | 37 +++++++++ js/src/jsobjinlines.h | 57 +++++++++++++ js/src/json.cpp | 2 +- js/src/jsops.cpp | 12 +-- js/src/jsxml.cpp | 183 ++++++++++++++++++------------------------ js/src/jsxml.h | 24 ++++-- 9 files changed, 203 insertions(+), 130 deletions(-) diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index 24d1a8376359..6b3ddbd9a44e 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -1377,7 +1377,7 @@ js_InternNonIntElementId(JSContext *cx, JSObject *obj, jsval idval, jsid *idp) #if JS_HAS_XML_SUPPORT if (!JSVAL_IS_PRIMITIVE(idval)) { - if (OBJECT_IS_XML(cx, obj)) { + if (obj->isXML()) { *idp = OBJECT_JSVAL_TO_JSID(idval); return JS_TRUE; } diff --git a/js/src/jsiter.cpp b/js/src/jsiter.cpp index 521f018daffd..b5970c707caf 100644 --- a/js/src/jsiter.cpp +++ b/js/src/jsiter.cpp @@ -111,7 +111,7 @@ CloseNativeIterator(JSContext *cx, JSObject *iterobj) if (iterable) { #if JS_HAS_XML_SUPPORT uintN flags = JSVAL_TO_INT(iterobj->getSlot(JSSLOT_ITER_FLAGS)); - if ((flags & JSITER_FOREACH) && OBJECT_IS_XML(cx, iterable)) { + if ((flags & JSITER_FOREACH) && iterable->isXML()) { js_EnumerateXMLValues(cx, iterable, JSENUMERATE_DESTROY, &state, NULL, NULL); } else @@ -173,7 +173,7 @@ InitNativeIterator(JSContext *cx, JSObject *iterobj, JSObject *obj, uintN flags) ok = #if JS_HAS_XML_SUPPORT - ((flags & JSITER_FOREACH) && OBJECT_IS_XML(cx, obj)) + ((flags & JSITER_FOREACH) && obj->isXML()) ? js_EnumerateXMLValues(cx, obj, JSENUMERATE_INIT, &state, NULL, NULL) : #endif @@ -250,7 +250,7 @@ IteratorNextImpl(JSContext *cx, JSObject *obj, jsval *rval) foreach = (flags & JSITER_FOREACH) != 0; ok = #if JS_HAS_XML_SUPPORT - (foreach && OBJECT_IS_XML(cx, iterable)) + (foreach && iterable->isXML()) ? js_EnumerateXMLValues(cx, iterable, JSENUMERATE_NEXT, &state, &id, rval) : @@ -265,7 +265,7 @@ IteratorNextImpl(JSContext *cx, JSObject *obj, jsval *rval) if (foreach) { #if JS_HAS_XML_SUPPORT - if (!OBJECT_IS_XML(cx, iterable) && + if (!iterable->isXML() && !iterable->getProperty(cx, id, rval)) { return JS_FALSE; } @@ -501,7 +501,7 @@ CallEnumeratorNext(JSContext *cx, JSObject *iterobj, uintN flags, jsval *rval) * Treat an XML object specially only when it starts the prototype chain. * Otherwise we need to do the usual deleted and shadowed property checks. */ - if (obj == origobj && OBJECT_IS_XML(cx, obj)) { + if (obj == origobj && obj->isXML()) { if (foreach) { if (!js_EnumerateXMLValues(cx, obj, JSENUMERATE_NEXT, &state, &id, rval)) { @@ -524,7 +524,7 @@ CallEnumeratorNext(JSContext *cx, JSObject *iterobj, uintN flags, jsval *rval) iterobj->setSlot(JSSLOT_ITER_STATE, state); if (JSVAL_IS_NULL(state)) { #if JS_HAS_XML_SUPPORT - if (OBJECT_IS_XML(cx, obj)) { + if (obj->isXML()) { /* * We just finished enumerating an XML obj that is present on * the prototype chain of a non-XML origobj. Stop further @@ -532,7 +532,7 @@ CallEnumeratorNext(JSContext *cx, JSObject *iterobj, uintN flags, jsval *rval) * enumerate prototypes. */ JS_ASSERT(origobj != obj); - JS_ASSERT(!OBJECT_IS_XML(cx, origobj)); + JS_ASSERT(!origobj->isXML()); } else #endif { diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 5e6900ce2c53..fa7ae4277745 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -4896,7 +4896,7 @@ js_GetMethod(JSContext *cx, JSObject *obj, jsid id, uintN getHow, jsval *vp) } JS_ASSERT_IF(getHow & JSGET_CACHE_RESULT, obj->isDenseArray()); #if JS_HAS_XML_SUPPORT - if (OBJECT_IS_XML(cx, obj)) + if (obj->isXML()) return js_GetXMLMethod(cx, obj, id, vp); #endif return obj->getProperty(cx, id, vp); diff --git a/js/src/jsobj.h b/js/src/jsobj.h index 95cf064890c9..7e804c602779 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -493,6 +493,41 @@ struct JSObject { inline jsval *addressOfRegExpLastIndex(); inline void zeroRegExpLastIndex(); + /* + * XML-related getters and setters. + */ + + /* + * Slots for XML-related classes are as follows: + * - js_NamespaceClass.base reserves the *_NAME_* and *_NAMESPACE_* slots. + * - js_QNameClass.base, js_AttributeNameClass, js_AnyNameClass reserve + * the *_NAME_* and *_QNAME_* slots. + * - Others (js_XMLClass, js_XMLFilterClass) don't reserve any slots. + */ + private: + static const uint32 JSSLOT_NAME_PREFIX = JSSLOT_PRIVATE; // shared + static const uint32 JSSLOT_NAME_URI = JSSLOT_PRIVATE + 1; // shared + + static const uint32 JSSLOT_NAMESPACE_DECLARED = JSSLOT_PRIVATE + 2; + + static const uint32 JSSLOT_QNAME_LOCAL_NAME = JSSLOT_PRIVATE + 2; + + public: + static const uint32 NAMESPACE_FIXED_RESERVED_SLOTS = 3; + static const uint32 QNAME_FIXED_RESERVED_SLOTS = 3; + + inline jsval getNamePrefix() const; + inline void setNamePrefix(jsval prefix); + + inline jsval getNameURI() const; + inline void setNameURI(jsval uri); + + inline jsval getNamespaceDeclared() const; + inline void setNamespaceDeclared(jsval decl); + + inline jsval getQNameLocalName() const; + inline void setQNameLocalName(jsval decl); + /* * Back to generic stuff. */ @@ -605,6 +640,8 @@ struct JSObject { inline bool isFunction() const; inline bool isRegExp() const; inline bool isXML() const; + inline bool isNamespace() const; + inline bool isQName() const; inline bool unbrand(JSContext *cx); }; diff --git a/js/src/jsobjinlines.h b/js/src/jsobjinlines.h index c5e56d53a1f9..3024b63e9a2f 100644 --- a/js/src/jsobjinlines.h +++ b/js/src/jsobjinlines.h @@ -46,6 +46,7 @@ #include "jsiter.h" #include "jsobj.h" #include "jsscope.h" +#include "jsxml.h" #ifdef INCLUDE_MOZILLA_DTRACE #include "jsdtracef.h" @@ -284,6 +285,62 @@ JSObject::zeroRegExpLastIndex() fslots[JSSLOT_REGEXP_LAST_INDEX] = JSVAL_ZERO; } +inline jsval +JSObject::getNamePrefix() const +{ + JS_ASSERT(isNamespace() || isQName()); + return fslots[JSSLOT_NAME_PREFIX]; +} + +inline void +JSObject::setNamePrefix(jsval prefix) +{ + JS_ASSERT(isNamespace() || isQName()); + fslots[JSSLOT_NAME_PREFIX] = prefix; +} + +inline jsval +JSObject::getNameURI() const +{ + JS_ASSERT(isNamespace() || isQName()); + return fslots[JSSLOT_NAME_URI]; +} + +inline void +JSObject::setNameURI(jsval uri) +{ + JS_ASSERT(isNamespace() || isQName()); + fslots[JSSLOT_NAME_URI] = uri; +} + +inline jsval +JSObject::getNamespaceDeclared() const +{ + JS_ASSERT(isNamespace()); + return fslots[JSSLOT_NAMESPACE_DECLARED]; +} + +inline void +JSObject::setNamespaceDeclared(jsval decl) +{ + JS_ASSERT(isNamespace()); + fslots[JSSLOT_NAMESPACE_DECLARED] = decl; +} + +inline jsval +JSObject::getQNameLocalName() const +{ + JS_ASSERT(isQName()); + return fslots[JSSLOT_QNAME_LOCAL_NAME]; +} + +inline void +JSObject::setQNameLocalName(jsval name) +{ + JS_ASSERT(isQName()); + fslots[JSSLOT_QNAME_LOCAL_NAME] = name; +} + inline void JSObject::initSharingEmptyScope(JSClass *clasp, JSObject *proto, JSObject *parent, jsval privateSlotValue) diff --git a/js/src/json.cpp b/js/src/json.cpp index 6a4fd5183b7a..e396db57f7b8 100644 --- a/js/src/json.cpp +++ b/js/src/json.cpp @@ -498,7 +498,7 @@ Str(JSContext *cx, jsid id, JSObject *holder, StringifyContext *scx, jsval *vp, return scx->cb.append(dstr, dbufSize); } - if (JSVAL_IS_OBJECT(*vp) && !VALUE_IS_FUNCTION(cx, *vp) && !VALUE_IS_XML(cx, *vp)) { + if (JSVAL_IS_OBJECT(*vp) && !VALUE_IS_FUNCTION(cx, *vp) && !VALUE_IS_XML(*vp)) { JSBool ok; scx->depth++; diff --git a/js/src/jsops.cpp b/js/src/jsops.cpp index 500de25ea6c4..130ebaa0669a 100644 --- a/js/src/jsops.cpp +++ b/js/src/jsops.cpp @@ -785,10 +785,10 @@ END_CASE(JSOP_BITAND) #define XML_EQUALITY_OP(OP) \ if ((ltmp == JSVAL_OBJECT && \ (obj2 = JSVAL_TO_OBJECT(lval)) && \ - OBJECT_IS_XML(cx, obj2)) || \ + obj2->isXML()) || \ (rtmp == JSVAL_OBJECT && \ (obj2 = JSVAL_TO_OBJECT(rval)) && \ - OBJECT_IS_XML(cx, obj2))) { \ + obj2->isXML())) { \ if (JSVAL_IS_OBJECT(rval) && obj2 == JSVAL_TO_OBJECT(rval)) \ rval = lval; \ if (!js_TestXMLEquality(cx, obj2, rval, &cond)) \ @@ -963,8 +963,8 @@ BEGIN_CASE(JSOP_ADD) lval = FETCH_OPND(-2); #if JS_HAS_XML_SUPPORT if (!JSVAL_IS_PRIMITIVE(lval) && - (obj2 = JSVAL_TO_OBJECT(lval), OBJECT_IS_XML(cx, obj2)) && - VALUE_IS_XML(cx, rval)) { + (obj2 = JSVAL_TO_OBJECT(lval), obj2->isXML()) && + VALUE_IS_XML(rval)) { if (!js_ConcatenateXML(cx, obj2, rval, &rval)) goto error; regs.sp--; @@ -3828,7 +3828,7 @@ BEGIN_CASE(JSOP_ENDFILTER) * Decrease sp after EnterWith returns as we use sp[-1] there to root * temporaries. */ - JS_ASSERT(VALUE_IS_XML(cx, regs.sp[-1])); + JS_ASSERT(VALUE_IS_XML(regs.sp[-1])); if (!js_EnterWith(cx, -2)) goto error; regs.sp--; @@ -3865,7 +3865,7 @@ END_CASE(JSOP_XMLTAGEXPR) BEGIN_CASE(JSOP_XMLELTEXPR) rval = FETCH_OPND(-1); - if (VALUE_IS_XML(cx, rval)) { + if (VALUE_IS_XML(rval)) { str = js_ValueToXMLString(cx, rval); } else { str = js_ValueToString(cx, rval); diff --git a/js/src/jsxml.cpp b/js/src/jsxml.cpp index c8e947540e13..7d89fdbd7c8a 100644 --- a/js/src/jsxml.cpp +++ b/js/src/jsxml.cpp @@ -125,66 +125,37 @@ const char js_leftcurly_entity_str[] = "{"; #define IS_STAR(str) ((str)->length() == 1 && *(str)->chars() == '*') -/* Slot indexes shared between Namespace and QName objects. */ -const uint32 JSSLOT_PREFIX = JSSLOT_PRIVATE; -const uint32 JSSLOT_URI = JSSLOT_PRIVATE + 1; - -/* Namespace-specific slot. */ -const uint32 JSSLOT_DECLARED = JSSLOT_PRIVATE + 2; - -/* QName-specific slot. */ -const uint32 JSSLOT_LOCAL_NAME = JSSLOT_PRIVATE + 2; - -const uint32 NAMESPACE_RESERVED_SLOTS = 3; -const uint32 QNAME_RESERVED_SLOTS = 3; - static JSBool GetXMLFunction(JSContext *cx, JSObject *obj, jsid id, jsval *vp); -static JSBool -IsQNameClass(JSClass *clasp) +static JS_INLINE JSString * +GetPrefix(const JSObject *obj) { - return clasp == &js_QNameClass.base || - clasp == &js_AttributeNameClass || - clasp == &js_AnyNameClass; -} - -static JSString * -GetSlotString(const JSObject *obj, uint32 slot) -{ - jsval v; - - JS_ASSERT(slot == JSSLOT_PREFIX || - slot == JSSLOT_URI || - slot == JSSLOT_LOCAL_NAME); - JS_ASSERT(obj->getClass() == &js_NamespaceClass.base || - IsQNameClass(obj->getClass())); - JS_ASSERT_IF(obj->getClass() == &js_NamespaceClass.base, - slot != JSSLOT_LOCAL_NAME); - - v = obj->fslots[slot]; + jsval v = obj->getNamePrefix(); if (JSVAL_IS_VOID(v)) return NULL; JS_ASSERT(JSVAL_IS_STRING(v)); return JSVAL_TO_STRING(v); } -static JS_INLINE JSString * -GetPrefix(const JSObject *obj) -{ - return GetSlotString(obj, JSSLOT_PREFIX); -} - static JSString * GetURI(const JSObject *obj) { - return GetSlotString(obj, JSSLOT_URI); + jsval v = obj->getNameURI(); + if (JSVAL_IS_VOID(v)) + return NULL; + JS_ASSERT(JSVAL_IS_STRING(v)); + return JSVAL_TO_STRING(v); } static JSString * GetLocalName(const JSObject *obj) { - return GetSlotString(obj, JSSLOT_LOCAL_NAME); + jsval v = obj->getQNameLocalName(); + if (JSVAL_IS_VOID(v)) + return NULL; + JS_ASSERT(JSVAL_IS_STRING(v)); + return JSVAL_TO_STRING(v); } static JSBool @@ -193,7 +164,7 @@ IsDeclared(const JSObject *obj) jsval v; JS_ASSERT(obj->getClass() == &js_NamespaceClass.base); - v = obj->fslots[JSSLOT_DECLARED]; + v = obj->getNamespaceDeclared(); JS_ASSERT(JSVAL_IS_VOID(v) || v == JSVAL_TRUE); return v == JSVAL_TRUE; } @@ -233,10 +204,10 @@ namespace_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) switch (JSVAL_TO_INT(id)) { case NAMESPACE_PREFIX: - *vp = obj->fslots[JSSLOT_PREFIX]; + *vp = obj->getNamePrefix(); break; case NAMESPACE_URI: - *vp = obj->fslots[JSSLOT_URI]; + *vp = obj->getNameURI(); break; } return JS_TRUE; @@ -265,7 +236,7 @@ namespace_equality(JSContext *cx, JSObject *obj, jsval v, JSBool *bp) JS_FRIEND_DATA(JSExtendedClass) js_NamespaceClass = { { "Namespace", JSCLASS_CONSTRUCT_PROTOTYPE | JSCLASS_IS_EXTENDED | - JSCLASS_HAS_RESERVED_SLOTS(NAMESPACE_RESERVED_SLOTS) | + JSCLASS_HAS_RESERVED_SLOTS(JSObject::NAMESPACE_FIXED_RESERVED_SLOTS) | JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_Namespace), JS_PropertyStub, JS_PropertyStub, namespace_getProperty, NULL, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, namespace_finalize, @@ -292,7 +263,7 @@ namespace_toString(JSContext *cx, uintN argc, jsval *vp) obj = JS_THIS_OBJECT(cx, vp); if (!JS_InstanceOf(cx, obj, &js_NamespaceClass.base, vp)) return JS_FALSE; - *vp = obj->fslots[JSSLOT_URI]; + *vp = obj->getNameURI(); return JS_TRUE; } @@ -309,15 +280,15 @@ NewXMLNamespace(JSContext *cx, JSString *prefix, JSString *uri, JSBool declared) obj = NewObject(cx, &js_NamespaceClass.base, NULL, NULL); if (!obj) return JS_FALSE; - JS_ASSERT(JSVAL_IS_VOID(obj->fslots[JSSLOT_PREFIX])); - JS_ASSERT(JSVAL_IS_VOID(obj->fslots[JSSLOT_URI])); - JS_ASSERT(JSVAL_IS_VOID(obj->fslots[JSSLOT_DECLARED])); + JS_ASSERT(JSVAL_IS_VOID(obj->getNamePrefix())); + JS_ASSERT(JSVAL_IS_VOID(obj->getNameURI())); + JS_ASSERT(JSVAL_IS_VOID(obj->getNamespaceDeclared())); if (prefix) - obj->fslots[JSSLOT_PREFIX] = STRING_TO_JSVAL(prefix); + obj->setNamePrefix(STRING_TO_JSVAL(prefix)); if (uri) - obj->fslots[JSSLOT_URI] = STRING_TO_JSVAL(uri); + obj->setNameURI(STRING_TO_JSVAL(uri)); if (declared) - obj->fslots[JSSLOT_DECLARED] = JSVAL_TRUE; + obj->setNamespaceDeclared(JSVAL_TRUE); METER(xml_stats.xmlnamespace); return obj; } @@ -341,12 +312,12 @@ qname_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) switch (JSVAL_TO_INT(id)) { case QNAME_URI: - *vp = obj->fslots[JSSLOT_URI]; + *vp = obj->getNameURI(); if (*vp == JSVAL_VOID) *vp = JSVAL_NULL; break; case QNAME_LOCALNAME: - *vp = obj->fslots[JSSLOT_LOCAL_NAME]; + *vp = obj->getQNameLocalName(); break; } return JS_TRUE; @@ -389,7 +360,7 @@ qname_equality(JSContext *cx, JSObject *qn, jsval v, JSBool *bp) JS_FRIEND_DATA(JSExtendedClass) js_QNameClass = { { "QName", JSCLASS_CONSTRUCT_PROTOTYPE | JSCLASS_IS_EXTENDED | - JSCLASS_HAS_RESERVED_SLOTS(QNAME_RESERVED_SLOTS) | + JSCLASS_HAS_RESERVED_SLOTS(JSObject::QNAME_FIXED_RESERVED_SLOTS) | JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_QName), JS_PropertyStub, JS_PropertyStub, qname_getProperty, NULL, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL, @@ -408,7 +379,7 @@ JS_FRIEND_DATA(JSExtendedClass) js_QNameClass = { JS_FRIEND_DATA(JSClass) js_AttributeNameClass = { js_AttributeName_str, JSCLASS_CONSTRUCT_PROTOTYPE | - JSCLASS_HAS_RESERVED_SLOTS(QNAME_RESERVED_SLOTS) | + JSCLASS_HAS_RESERVED_SLOTS(JSObject::QNAME_FIXED_RESERVED_SLOTS) | JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_AttributeName), JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL, @@ -419,7 +390,7 @@ JS_FRIEND_DATA(JSClass) js_AttributeNameClass = { JS_FRIEND_DATA(JSClass) js_AnyNameClass = { js_AnyName_str, JSCLASS_CONSTRUCT_PROTOTYPE | - JSCLASS_HAS_RESERVED_SLOTS(QNAME_RESERVED_SLOTS) | + JSCLASS_HAS_RESERVED_SLOTS(JSObject::QNAME_FIXED_RESERVED_SLOTS) | JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_AnyName), JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, anyname_finalize, @@ -501,15 +472,15 @@ static void InitXMLQName(JSObject *obj, JSString *uri, JSString *prefix, JSString *localName) { - JS_ASSERT(JSVAL_IS_VOID(obj->fslots[JSSLOT_PREFIX])); - JS_ASSERT(JSVAL_IS_VOID(obj->fslots[JSSLOT_URI])); - JS_ASSERT(JSVAL_IS_VOID(obj->fslots[JSSLOT_LOCAL_NAME])); + JS_ASSERT(JSVAL_IS_VOID(obj->getNamePrefix())); + JS_ASSERT(JSVAL_IS_VOID(obj->getNameURI())); + JS_ASSERT(JSVAL_IS_VOID(obj->getQNameLocalName())); if (uri) - obj->fslots[JSSLOT_URI] = STRING_TO_JSVAL(uri); + obj->setNameURI(STRING_TO_JSVAL(uri)); if (prefix) - obj->fslots[JSSLOT_PREFIX] = STRING_TO_JSVAL(prefix); + obj->setNamePrefix(STRING_TO_JSVAL(prefix)); if (localName) - obj->fslots[JSSLOT_LOCAL_NAME] = STRING_TO_JSVAL(localName); + obj->setQNameLocalName(STRING_TO_JSVAL(localName)); } static JSObject * @@ -518,8 +489,8 @@ NewXMLQName(JSContext *cx, JSString *uri, JSString *prefix, JSString *localName, { JSObject *obj; - JS_ASSERT(IsQNameClass(clasp)); obj = NewObject(cx, clasp, NULL, NULL); + JS_ASSERT(obj->isQName()); if (!obj) return NULL; InitXMLQName(obj, uri, prefix, localName); @@ -578,7 +549,7 @@ js_IsXMLName(JSContext *cx, jsval v) * See ECMA-357 13.1.2.1 step 1 and 13.3.2. */ if (!JSVAL_IS_PRIMITIVE(v) && - IsQNameClass(JSVAL_TO_OBJECT(v)->getClass())) { + JSVAL_TO_OBJECT(v)->isQName()) { name = GetLocalName(JSVAL_TO_OBJECT(v)); } else { older = JS_SetErrorReporter(cx, NULL); @@ -639,23 +610,23 @@ NamespaceHelper(JSContext *cx, JSObject *obj, intN argc, jsval *argv, METER(xml_stats.xmlnamespace); empty = cx->runtime->emptyString; - obj->fslots[JSSLOT_PREFIX] = STRING_TO_JSVAL(empty); - obj->fslots[JSSLOT_URI] = STRING_TO_JSVAL(empty); + obj->setNamePrefix(STRING_TO_JSVAL(empty)); + obj->setNameURI(STRING_TO_JSVAL(empty)); if (argc == 1 || argc == -1) { if (isNamespace) { - obj->fslots[JSSLOT_URI] = uriobj->fslots[JSSLOT_URI]; - obj->fslots[JSSLOT_PREFIX] = uriobj->fslots[JSSLOT_PREFIX]; + obj->setNameURI(uriobj->getNameURI()); + obj->setNamePrefix(uriobj->getNamePrefix()); } else if (isQName && (uri = GetURI(uriobj))) { - obj->fslots[JSSLOT_URI] = STRING_TO_JSVAL(uri); - obj->fslots[JSSLOT_PREFIX] = uriobj->fslots[JSSLOT_PREFIX]; + obj->setNameURI(STRING_TO_JSVAL(uri)); + obj->setNamePrefix(uriobj->getNamePrefix()); } else { uri = js_ValueToString(cx, urival); if (!uri) return JS_FALSE; - obj->fslots[JSSLOT_URI] = STRING_TO_JSVAL(uri); + obj->setNameURI(STRING_TO_JSVAL(uri)); if (!uri->empty()) - obj->fslots[JSSLOT_PREFIX] = JSVAL_VOID; + obj->setNamePrefix(JSVAL_VOID); } } else if (argc == 2) { if (!isQName || !(uri = GetURI(uriobj))) { @@ -663,7 +634,7 @@ NamespaceHelper(JSContext *cx, JSObject *obj, intN argc, jsval *argv, if (!uri) return JS_FALSE; } - obj->fslots[JSSLOT_URI] = STRING_TO_JSVAL(uri); + obj->setNameURI(STRING_TO_JSVAL(uri)); prefixval = argv[0]; if (uri->empty()) { @@ -680,12 +651,12 @@ NamespaceHelper(JSContext *cx, JSObject *obj, intN argc, jsval *argv, } } } else if (JSVAL_IS_VOID(prefixval) || !js_IsXMLName(cx, prefixval)) { - obj->fslots[JSSLOT_PREFIX] = JSVAL_VOID; + obj->setNamePrefix(JSVAL_VOID); } else { prefix = js_ValueToString(cx, prefixval); if (!prefix) return JS_FALSE; - obj->fslots[JSSLOT_PREFIX] = STRING_TO_JSVAL(prefix); + obj->setNamePrefix(STRING_TO_JSVAL(prefix)); } } @@ -756,7 +727,7 @@ QNameHelper(JSContext *cx, JSObject *obj, JSClass *clasp, intN argc, } /* Namespace and qname were passed -- use the qname's localName. */ - nameval = qn->fslots[JSSLOT_LOCAL_NAME]; + nameval = qn->getQNameLocalName(); } if (argc == 0) { @@ -1893,7 +1864,7 @@ OrphanXMLChild(JSContext *cx, JSXML *xml, uint32 i) if (xml->xml_class == JSXML_CLASS_ELEMENT) { if (!XMLARRAY_APPEND(cx, &xml->xml_namespaces, ns)) return NULL; - ns->fslots[JSSLOT_DECLARED] = JSVAL_VOID; + ns->setNamespaceDeclared(JSVAL_VOID); } xml->parent = NULL; return xml; @@ -1913,7 +1884,7 @@ ToXML(JSContext *cx, jsval v) goto bad; } else { obj = JSVAL_TO_OBJECT(v); - if (OBJECT_IS_XML(cx, obj)) { + if (obj->isXML()) { xml = (JSXML *) obj->getPrivate(); if (xml->xml_class == JSXML_CLASS_LIST) { if (xml->xml_kids.length != 1) @@ -1994,7 +1965,7 @@ ToXMLList(JSContext *cx, jsval v) goto bad; } else { obj = JSVAL_TO_OBJECT(v); - if (OBJECT_IS_XML(cx, obj)) { + if (obj->isXML()) { xml = (JSXML *) obj->getPrivate(); if (xml->xml_class != JSXML_CLASS_LIST) { listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST); @@ -2722,7 +2693,7 @@ XMLToXMLString(JSContext *cx, JSXML *xml, const JSXMLArray *ancestorNSes, prefix = GeneratePrefix(cx, GetURI(ns3), &ancdecls); if (!prefix) goto out; - ns3->fslots[JSSLOT_PREFIX] = STRING_TO_JSVAL(prefix); + ns3->setNamePrefix(STRING_TO_JSVAL(prefix)); } /* 17(c)(iii). */ @@ -2832,7 +2803,7 @@ ToXMLString(JSContext *cx, jsval v, uint32 toSourceFlag) } obj = JSVAL_TO_OBJECT(v); - if (!OBJECT_IS_XML(cx, obj)) { + if (!obj->isXML()) { if (!obj->defaultValue(cx, JSTYPE_STRING, &v)) return NULL; str = js_ValueToString(cx, v); @@ -3040,7 +3011,7 @@ AddInScopeNamespace(JSContext *cx, JSXML *xml, JSObject *ns) ns2 = XMLARRAY_DELETE(cx, &xml->xml_namespaces, m, JS_TRUE, JSObject); JS_ASSERT(ns2 == match); - match->fslots[JSSLOT_PREFIX] = JSVAL_VOID; + match->setNamePrefix(JSVAL_VOID); if (!AddInScopeNamespace(cx, xml, match)) return JS_FALSE; } @@ -3483,7 +3454,7 @@ Equals(JSContext *cx, JSXML *xml, jsval v, JSBool *bp) } } else { vobj = JSVAL_TO_OBJECT(v); - if (!OBJECT_IS_XML(cx, vobj)) { + if (!vobj->isXML()) { *bp = JS_FALSE; } else { vxml = (JSXML *) vobj->getPrivate(); @@ -3526,7 +3497,7 @@ Insert(JSContext *cx, JSXML *xml, uint32 i, jsval v) vxml = NULL; if (!JSVAL_IS_PRIMITIVE(v)) { vobj = JSVAL_TO_OBJECT(v); - if (OBJECT_IS_XML(cx, vobj)) { + if (vobj->isXML()) { vxml = (JSXML *) vobj->getPrivate(); if (vxml->xml_class == JSXML_CLASS_LIST) { n = vxml->xml_kids.length; @@ -3620,7 +3591,7 @@ Replace(JSContext *cx, JSXML *xml, uint32 i, jsval v) vxml = NULL; if (!JSVAL_IS_PRIMITIVE(v)) { vobj = JSVAL_TO_OBJECT(v); - if (OBJECT_IS_XML(cx, vobj)) + if (vobj->isXML()) vxml = (JSXML *) vobj->getPrivate(); } @@ -3941,7 +3912,7 @@ PutProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) vxml = NULL; if (!JSVAL_IS_PRIMITIVE(*vp)) { vobj = JSVAL_TO_OBJECT(*vp); - if (OBJECT_IS_XML(cx, vobj)) + if (vobj->isXML()) vxml = (JSXML *) vobj->getPrivate(); } @@ -5167,7 +5138,7 @@ js_TestXMLEquality(JSContext *cx, JSObject *obj, jsval v, JSBool *bp) vxml = NULL; if (!JSVAL_IS_PRIMITIVE(v)) { vobj = JSVAL_TO_OBJECT(v); - if (OBJECT_IS_XML(cx, vobj)) + if (vobj->isXML()) vxml = (JSXML *) vobj->getPrivate(); } @@ -5252,7 +5223,7 @@ js_ConcatenateXML(JSContext *cx, JSObject *obj, jsval v, jsval *vp) if (!ok) goto out; - if (VALUE_IS_XML(cx, v)) { + if (VALUE_IS_XML(v)) { rxml = (JSXML *) JSVAL_TO_OBJECT(v)->getPrivate(); } else { robj = ToXML(cx, v); @@ -5368,7 +5339,7 @@ xml_addNamespace(JSContext *cx, uintN argc, jsval *vp) ns = JSVAL_TO_OBJECT(*vp); if (!AddInScopeNamespace(cx, xml, ns)) return JS_FALSE; - ns->fslots[JSSLOT_DECLARED] = JSVAL_TRUE; + ns->setNamespaceDeclared(JSVAL_TRUE); done: *vp = OBJECT_TO_JSVAL(obj); @@ -5395,7 +5366,7 @@ xml_appendChild(JSContext *cx, uintN argc, jsval *vp) JS_ASSERT(!JSVAL_IS_PRIMITIVE(v)); vobj = JSVAL_TO_OBJECT(v); - JS_ASSERT(OBJECT_IS_XML(cx, vobj)); + JS_ASSERT(vobj->isXML()); vxml = (JSXML *) vobj->getPrivate(); JS_ASSERT(vxml->xml_class == JSXML_CLASS_LIST); @@ -5946,7 +5917,7 @@ xml_insertChildAfter(JSContext *cx, uintN argc, jsval *vp) kid = NULL; i = 0; } else { - if (!VALUE_IS_XML(cx, arg)) + if (!VALUE_IS_XML(arg)) return JS_TRUE; kid = (JSXML *) JSVAL_TO_OBJECT(arg)->getPrivate(); i = XMLARRAY_FIND_MEMBER(&xml->xml_kids, kid, NULL); @@ -5978,7 +5949,7 @@ xml_insertChildBefore(JSContext *cx, uintN argc, jsval *vp) kid = NULL; i = xml->xml_kids.length; } else { - if (!VALUE_IS_XML(cx, arg)) + if (!VALUE_IS_XML(arg)) return JS_TRUE; kid = (JSXML *) JSVAL_TO_OBJECT(arg)->getPrivate(); i = XMLARRAY_FIND_MEMBER(&xml->xml_kids, kid, NULL); @@ -6010,7 +5981,7 @@ static JSBool xml_localName(JSContext *cx, uintN argc, jsval *vp) { NON_LIST_XML_METHOD_PROLOG; - *vp = xml->name ? xml->name->fslots[JSSLOT_LOCAL_NAME] : JSVAL_NULL; + *vp = xml->name ? xml->name->getQNameLocalName() : JSVAL_NULL; return JS_TRUE; } @@ -6445,7 +6416,7 @@ xml_replace(JSContext *cx, uintN argc, jsval *vp) typeAtoms[JSTYPE_VOID])); } else { value = vp[3]; - vxml = VALUE_IS_XML(cx, value) + vxml = VALUE_IS_XML(value) ? (JSXML *) JSVAL_TO_OBJECT(value)->getPrivate() : NULL; if (!vxml) { @@ -6546,9 +6517,7 @@ xml_setLocalName(JSContext *cx, uintN argc, jsval *vp) xml = CHECK_COPY_ON_WRITE(cx, xml, obj); if (!xml) return JS_FALSE; - xml->name->fslots[JSSLOT_LOCAL_NAME] = namestr - ? STRING_TO_JSVAL(namestr) - : JSVAL_VOID; + xml->name->setQNameLocalName(namestr ? STRING_TO_JSVAL(namestr) : JSVAL_VOID); return JS_TRUE; } @@ -6574,7 +6543,7 @@ xml_setName(JSContext *cx, uintN argc, jsval *vp) if (!JSVAL_IS_PRIMITIVE(name) && JSVAL_TO_OBJECT(name)->getClass() == &js_QNameClass.base && !GetURI(nameqn = JSVAL_TO_OBJECT(name))) { - name = vp[2] = nameqn->fslots[JSSLOT_LOCAL_NAME]; + name = vp[2] = nameqn->getQNameLocalName(); } } @@ -6584,7 +6553,7 @@ xml_setName(JSContext *cx, uintN argc, jsval *vp) /* ECMA-357 13.4.4.35 Step 4. */ if (xml->xml_class == JSXML_CLASS_PROCESSING_INSTRUCTION) - nameqn->fslots[JSSLOT_URI] = STRING_TO_JSVAL(cx->runtime->emptyString); + nameqn->setNameURI(STRING_TO_JSVAL(cx->runtime->emptyString)); xml = CHECK_COPY_ON_WRITE(cx, xml, obj); if (!xml) @@ -6645,7 +6614,7 @@ xml_setName(JSContext *cx, uintN argc, jsval *vp) for (i = 0, n = nsarray->length; i < n; i++) { ns = XMLARRAY_MEMBER(nsarray, i, JSObject); if (ns && js_EqualStrings(GetURI(ns), GetURI(nameqn))) { - nameqn->fslots[JSSLOT_PREFIX] = ns->fslots[JSSLOT_PREFIX]; + nameqn->setNamePrefix(ns->getNamePrefix()); return JS_TRUE; } } @@ -6682,7 +6651,7 @@ xml_setNamespace(JSContext *cx, uintN argc, jsval *vp) if (!ns) return JS_FALSE; vp[0] = OBJECT_TO_JSVAL(ns); - ns->fslots[JSSLOT_DECLARED] = JSVAL_TRUE; + ns->setNamespaceDeclared(JSVAL_TRUE); qnargv[0] = vp[2] = OBJECT_TO_JSVAL(ns); qnargv[1] = OBJECT_TO_JSVAL(xml->name); @@ -7043,7 +7012,7 @@ XMLList(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) if (cx->isConstructing() && !JSVAL_IS_PRIMITIVE(v)) { vobj = JSVAL_TO_OBJECT(v); - if (OBJECT_IS_XML(cx, vobj)) { + if (vobj->isXML()) { xml = (JSXML *) vobj->getPrivate(); if (xml->xml_class == JSXML_CLASS_LIST) { listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST); @@ -7656,7 +7625,7 @@ js_FindXMLProperty(JSContext *cx, jsval nameval, JSObject **objp, jsid *idp) target = proto; } - if (OBJECT_IS_XML(cx, target)) { + if (target->isXML()) { if (funid == 0) { xml = (JSXML *) target->getPrivate(); found = HasNamedProperty(xml, qn); @@ -7693,7 +7662,7 @@ js_FindXMLProperty(JSContext *cx, jsval nameval, JSObject **objp, jsid *idp) static JSBool GetXMLFunction(JSContext *cx, JSObject *obj, jsid id, jsval *vp) { - JS_ASSERT(OBJECT_IS_XML(cx, obj)); + JS_ASSERT(obj->isXML()); /* * See comments before xml_lookupProperty about the need for the proto @@ -7833,7 +7802,7 @@ js_StepXMLListFilter(JSContext *cx, JSBool initialized) * We haven't iterated yet, so initialize the filter based on the * value stored in sp[-2]. */ - if (!VALUE_IS_XML(cx, sp[-2])) { + if (!VALUE_IS_XML(sp[-2])) { js_ReportValueError(cx, JSMSG_NON_XML_FILTER, -2, sp[-2], NULL); return JS_FALSE; } diff --git a/js/src/jsxml.h b/js/src/jsxml.h index d5b20b0c881b..297fd1588ba9 100644 --- a/js/src/jsxml.h +++ b/js/src/jsxml.h @@ -40,6 +40,7 @@ #define jsxml_h___ #include "jspubtd.h" +#include "jsobj.h" JS_BEGIN_EXTERN_C @@ -219,10 +220,6 @@ extern JSClass js_XMLFilterClass; /* * Methods to test whether an object or a value is of type "xml" (per typeof). - * NB: jsobj.h must be included before any call to OBJECT_IS_XML, and jsapi.h - * and jsobj.h must be included before any call to VALUE_IS_XML. - * - * FIXME: bogus cx parameters for OBJECT_IS_XML and VALUE_IS_XML. */ inline bool JSObject::isXML() const @@ -230,9 +227,22 @@ JSObject::isXML() const return map->ops == &js_XMLObjectOps; } -#define OBJECT_IS_XML(cx,obj) (obj)->isXML() -#define VALUE_IS_XML(cx,v) (!JSVAL_IS_PRIMITIVE(v) && \ - JSVAL_TO_OBJECT(v)->isXML()) +#define VALUE_IS_XML(v) (!JSVAL_IS_PRIMITIVE(v) && JSVAL_TO_OBJECT(v)->isXML()) + +inline bool +JSObject::isNamespace() const +{ + return getClass() == &js_NamespaceClass.base; +} + +inline bool +JSObject::isQName() const +{ + JSClass* clasp = getClass(); + return clasp == &js_QNameClass.base || + clasp == &js_AttributeNameClass || + clasp == &js_AnyNameClass; +} extern JSObject * js_InitNamespaceClass(JSContext *cx, JSObject *obj);