mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out changeset 7b2b90efe57d -- the patch was landed against a tree with a lot of orange. This will hinder the orange resolution.
This commit is contained in:
parent
a69fd0a49f
commit
181c2cdf3a
@ -2417,7 +2417,11 @@ nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj
|
||||
// NOTE: These class and equality hook checks better match
|
||||
// what IS_WRAPPER_CLASS() does in xpconnect!
|
||||
|
||||
if (jsClass->ext.equality == js::Valueify(sXPCWrappedNativeEqualityOps)) {
|
||||
JSEqualityOp op =
|
||||
(jsClass->flags & JSCLASS_IS_EXTENDED) ?
|
||||
reinterpret_cast<const JSExtendedClass*>(jsClass)->equality :
|
||||
nsnull;
|
||||
if (op == sXPCWrappedNativeEqualityOps) {
|
||||
result = sXPConnect->GetPrincipal(aObj,
|
||||
#ifdef DEBUG
|
||||
aAllowShortCircuit
|
||||
|
@ -5703,8 +5703,11 @@ CloneSimpleValues(JSContext* cx,
|
||||
}
|
||||
|
||||
// Security wrapped objects are not allowed either.
|
||||
if (obj->getClass()->ext.wrappedObject)
|
||||
JSClass* clasp = JS_GET_CLASS(cx, obj);
|
||||
if ((clasp->flags & JSCLASS_IS_EXTENDED) &&
|
||||
((JSExtendedClass*)clasp)->wrappedObject) {
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
}
|
||||
|
||||
// See if this JSObject is backed by some C++ object. If it is then we assume
|
||||
// that it is inappropriate to clone.
|
||||
|
@ -72,8 +72,6 @@
|
||||
#include <gdk/gdkx.h>
|
||||
#endif
|
||||
|
||||
#include "jsobj.h"
|
||||
|
||||
static PRBool IsUniversalXPConnectCapable()
|
||||
{
|
||||
PRBool hasCap = PR_FALSE;
|
||||
@ -1349,10 +1347,14 @@ nsDOMWindowUtils::GetParent()
|
||||
JSObject *parent = JS_GetParent(cx, JSVAL_TO_OBJECT(argv[0]));
|
||||
*rval = OBJECT_TO_JSVAL(parent);
|
||||
|
||||
// Outerize if necessary.
|
||||
// Outerize if necessary. Embrace the ugliness!
|
||||
if (parent) {
|
||||
if (JSObjectOp outerize = parent->getClass()->ext.outerObject)
|
||||
*rval = OBJECT_TO_JSVAL(outerize(cx, parent));
|
||||
JSClass* clasp = JS_GET_CLASS(cx, parent);
|
||||
if (clasp->flags & JSCLASS_IS_EXTENDED) {
|
||||
JSExtendedClass* xclasp = reinterpret_cast<JSExtendedClass*>(clasp);
|
||||
if (JSObjectOp outerize = xclasp->outerObject)
|
||||
*rval = OBJECT_TO_JSVAL(outerize(cx, parent));
|
||||
}
|
||||
}
|
||||
|
||||
cc->SetReturnValueWasSet(PR_TRUE);
|
||||
|
@ -169,32 +169,36 @@ with_error(JSContext* cx,
|
||||
return rval;
|
||||
}
|
||||
|
||||
const js::Class ObjectWrapperParent::sCPOW_JSClass = {
|
||||
"CrossProcessObjectWrapper",
|
||||
JSCLASS_NEW_RESOLVE | JSCLASS_NEW_ENUMERATE |
|
||||
const JSExtendedClass ObjectWrapperParent::sCPOW_JSClass = {
|
||||
// JSClass (JSExtendedClass.base) initialization
|
||||
{ "CrossProcessObjectWrapper",
|
||||
JSCLASS_NEW_RESOLVE | JSCLASS_NEW_ENUMERATE | JSCLASS_IS_EXTENDED |
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(sNumSlots),
|
||||
js::Valueify(ObjectWrapperParent::CPOW_AddProperty),
|
||||
js::Valueify(ObjectWrapperParent::CPOW_DelProperty),
|
||||
js::Valueify(ObjectWrapperParent::CPOW_GetProperty),
|
||||
js::Valueify(ObjectWrapperParent::CPOW_SetProperty),
|
||||
ObjectWrapperParent::CPOW_AddProperty,
|
||||
ObjectWrapperParent::CPOW_DelProperty,
|
||||
ObjectWrapperParent::CPOW_GetProperty,
|
||||
ObjectWrapperParent::CPOW_SetProperty,
|
||||
(JSEnumerateOp) ObjectWrapperParent::CPOW_NewEnumerate,
|
||||
(JSResolveOp) ObjectWrapperParent::CPOW_NewResolve,
|
||||
js::Valueify(ObjectWrapperParent::CPOW_Convert),
|
||||
(JSResolveOp) ObjectWrapperParent::CPOW_NewResolve,
|
||||
ObjectWrapperParent::CPOW_Convert,
|
||||
ObjectWrapperParent::CPOW_Finalize,
|
||||
nsnull, // reserved1
|
||||
nsnull, // getObjectOps
|
||||
nsnull, // checkAccess
|
||||
js::Valueify(ObjectWrapperParent::CPOW_Call),
|
||||
js::Valueify(ObjectWrapperParent::CPOW_Construct),
|
||||
ObjectWrapperParent::CPOW_Call,
|
||||
ObjectWrapperParent::CPOW_Construct,
|
||||
nsnull, // xdrObject
|
||||
js::Valueify(ObjectWrapperParent::CPOW_HasInstance),
|
||||
ObjectWrapperParent::CPOW_HasInstance,
|
||||
nsnull, // mark
|
||||
{
|
||||
js::Valueify(ObjectWrapperParent::CPOW_Equality),
|
||||
nsnull, // outerObject
|
||||
nsnull, // innerObject
|
||||
nsnull, // iteratorObject
|
||||
nsnull, // wrappedObject
|
||||
}
|
||||
nsnull, // reserveSlots
|
||||
},
|
||||
|
||||
// JSExtendedClass initialization
|
||||
ObjectWrapperParent::CPOW_Equality,
|
||||
nsnull, // outerObject
|
||||
nsnull, // innerObject
|
||||
nsnull, // iterator
|
||||
nsnull, // wrappedObject
|
||||
JSCLASS_NO_RESERVED_MEMBERS
|
||||
};
|
||||
|
||||
void
|
||||
@ -216,8 +220,8 @@ ObjectWrapperParent::Manager()
|
||||
JSObject*
|
||||
ObjectWrapperParent::GetJSObject(JSContext* cx) const
|
||||
{
|
||||
js::Class *clasp = const_cast<js::Class *>(&ObjectWrapperParent::sCPOW_JSClass);
|
||||
if (!mObj && (mObj = JS_NewObject(cx, js::Jsvalify(clasp), NULL, NULL))) {
|
||||
JSClass* clasp = const_cast<JSClass*>(&ObjectWrapperParent::sCPOW_JSClass.base);
|
||||
if (!mObj && (mObj = JS_NewObject(cx, clasp, NULL, NULL))) {
|
||||
JS_SetPrivate(cx, mObj, (void*)this);
|
||||
JS_SetReservedSlot(cx, mObj, sFlagsSlot, JSVAL_ZERO);
|
||||
}
|
||||
@ -227,7 +231,7 @@ ObjectWrapperParent::GetJSObject(JSContext* cx) const
|
||||
static ObjectWrapperParent*
|
||||
Unwrap(JSContext* cx, JSObject* obj)
|
||||
{
|
||||
while (obj->getClass() != &ObjectWrapperParent::sCPOW_JSClass)
|
||||
while (obj->getJSClass() != &ObjectWrapperParent::sCPOW_JSClass.base)
|
||||
if (!(obj = obj->getProto()))
|
||||
return NULL;
|
||||
|
||||
|
@ -43,7 +43,6 @@
|
||||
|
||||
#include "mozilla/jsipc/PObjectWrapperParent.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsvalue.h"
|
||||
#include "nsAutoJSValHolder.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -76,7 +75,7 @@ public:
|
||||
void CheckOperation(JSContext* cx,
|
||||
OperationStatus* status);
|
||||
|
||||
static const js::Class sCPOW_JSClass;
|
||||
static const JSExtendedClass sCPOW_JSClass;
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -42,7 +42,20 @@
|
||||
#include "jsd.h"
|
||||
#include "jsapi.h"
|
||||
#include "jspubtd.h"
|
||||
#include "jsprvtd.h"
|
||||
|
||||
/*
|
||||
* Lifted with slight modification from jsobj.h
|
||||
*/
|
||||
|
||||
#define OBJ_TO_OUTER_OBJECT(cx, obj) \
|
||||
do { \
|
||||
JSClass *clasp_ = JS_GetClass(cx, obj); \
|
||||
if (clasp_->flags & JSCLASS_IS_EXTENDED) { \
|
||||
JSExtendedClass *xclasp_ = (JSExtendedClass*) clasp_; \
|
||||
if (xclasp_->outerObject) \
|
||||
obj = xclasp_->outerObject(cx, obj); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#ifdef DEBUG
|
||||
void JSD_ASSERT_VALID_VALUE(JSDValue* jsdval)
|
||||
@ -301,7 +314,8 @@ jsd_GetValueWrappedJSVal(JSDContext* jsdc, JSDValue* jsdval)
|
||||
jsval val = jsdval->val;
|
||||
if (!JSVAL_IS_PRIMITIVE(val)) {
|
||||
cx = JSD_GetDefaultJSContext(jsdc);
|
||||
obj = js_ObjectToOuterObject(cx, JSVAL_TO_OBJECT(val));
|
||||
obj = JSVAL_TO_OBJECT(val);
|
||||
OBJ_TO_OUTER_OBJECT(cx, obj);
|
||||
if (!obj)
|
||||
{
|
||||
JS_ClearPendingException(cx);
|
||||
|
@ -6,7 +6,6 @@
|
||||
*/
|
||||
|
||||
#include "tests.h"
|
||||
#include "jsobj.h"
|
||||
|
||||
static JSBool
|
||||
my_Equality(JSContext *cx, JSObject *obj, const jsval *, JSBool *bp)
|
||||
@ -15,37 +14,24 @@ my_Equality(JSContext *cx, JSObject *obj, const jsval *, JSBool *bp)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
js::Class TestExtendedEq_JSClass = {
|
||||
"TestExtendedEq",
|
||||
0,
|
||||
js::PropertyStub, /* addProperty */
|
||||
js::PropertyStub, /* delProperty */
|
||||
js::PropertyStub, /* getProperty */
|
||||
js::PropertyStub, /* setProperty */
|
||||
JS_EnumerateStub,
|
||||
JS_ResolveStub,
|
||||
NULL, /* convert */
|
||||
NULL, /* finalize */
|
||||
NULL, /* reserved0 */
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
NULL, /* hasInstance */
|
||||
NULL, /* mark */
|
||||
{
|
||||
js::Valueify(my_Equality),
|
||||
NULL, /* outerObject */
|
||||
NULL, /* innerObject */
|
||||
NULL, /* iteratorObject */
|
||||
NULL, /* wrappedObject */
|
||||
}
|
||||
JSExtendedClass TestExtendedEq_JSClass = {
|
||||
{ "TestExtendedEq",
|
||||
JSCLASS_IS_EXTENDED,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL
|
||||
},
|
||||
// JSExtendedClass initialization
|
||||
my_Equality,
|
||||
NULL, NULL, NULL, NULL, JSCLASS_NO_RESERVED_MEMBERS
|
||||
};
|
||||
|
||||
BEGIN_TEST(testExtendedEq_bug530489)
|
||||
{
|
||||
JSClass *clasp = (JSClass *) &TestExtendedEq_JSClass;
|
||||
|
||||
JSObject *global = JS_GetGlobalObject(cx);
|
||||
CHECK(JS_InitClass(cx, global, global, clasp, NULL, 0, NULL, NULL, NULL, NULL));
|
||||
|
||||
CHECK(JS_DefineObject(cx, global, "obj1", clasp, NULL, 0));
|
||||
|
@ -1342,10 +1342,11 @@ JS_InitStandardClasses(JSContext *cx, JSObject *obj)
|
||||
}
|
||||
|
||||
#define CLASP(name) (&js_##name##Class)
|
||||
#define TYPED_ARRAY_CLASP(type) (&TypedArray::fastClasses[TypedArray::type])
|
||||
#define XCLASP(name) (&js_##name##Class.base)
|
||||
#define EAGER_ATOM(name) ATOM_OFFSET(name), NULL
|
||||
#define EAGER_CLASS_ATOM(name) CLASS_ATOM_OFFSET(name), NULL
|
||||
#define EAGER_ATOM_AND_CLASP(name) EAGER_CLASS_ATOM(name), CLASP(name)
|
||||
#define EAGER_ATOM_AND_XCLASP(name) EAGER_CLASS_ATOM(name), XCLASP(name)
|
||||
#define LAZY_ATOM(name) ATOM_OFFSET(lazy.name), js_##name##_str
|
||||
|
||||
typedef struct JSStdName {
|
||||
@ -1391,8 +1392,8 @@ static JSStdName standard_class_atoms[] = {
|
||||
{js_InitRegExpClass, EAGER_ATOM_AND_CLASP(RegExp)},
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
{js_InitXMLClass, EAGER_ATOM_AND_CLASP(XML)},
|
||||
{js_InitNamespaceClass, EAGER_ATOM_AND_CLASP(Namespace)},
|
||||
{js_InitQNameClass, EAGER_ATOM_AND_CLASP(QName)},
|
||||
{js_InitNamespaceClass, EAGER_ATOM_AND_XCLASP(Namespace)},
|
||||
{js_InitQNameClass, EAGER_ATOM_AND_XCLASP(QName)},
|
||||
#endif
|
||||
#if JS_HAS_GENERATORS
|
||||
{js_InitIteratorClasses, EAGER_ATOM_AND_CLASP(StopIteration)},
|
||||
@ -1447,22 +1448,21 @@ static JSStdName standard_class_names[] = {
|
||||
#endif
|
||||
|
||||
#if JS_HAS_GENERATORS
|
||||
{js_InitIteratorClasses, EAGER_ATOM_AND_CLASP(Iterator)},
|
||||
{js_InitIteratorClasses, EAGER_ATOM_AND_CLASP(Generator)},
|
||||
{js_InitIteratorClasses, EAGER_ATOM_AND_XCLASP(Iterator)},
|
||||
{js_InitIteratorClasses, EAGER_ATOM_AND_XCLASP(Generator)},
|
||||
#endif
|
||||
|
||||
/* Typed Arrays */
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(ArrayBuffer), &js::ArrayBuffer::jsclass},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Int8Array), TYPED_ARRAY_CLASP(TYPE_INT8)},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Uint8Array), TYPED_ARRAY_CLASP(TYPE_UINT8)},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Int16Array), TYPED_ARRAY_CLASP(TYPE_INT16)},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Uint16Array), TYPED_ARRAY_CLASP(TYPE_UINT16)},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Int32Array), TYPED_ARRAY_CLASP(TYPE_INT32)},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Uint32Array), TYPED_ARRAY_CLASP(TYPE_UINT32)},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Float32Array), TYPED_ARRAY_CLASP(TYPE_FLOAT32)},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Float64Array), TYPED_ARRAY_CLASP(TYPE_FLOAT64)},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Uint8ClampedArray),
|
||||
TYPED_ARRAY_CLASP(TYPE_UINT8_CLAMPED)},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Int8Array), &TypedArray::fastClasses[TypedArray::TYPE_INT8]},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Uint8Array), &TypedArray::fastClasses[TypedArray::TYPE_UINT8]},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Int16Array), &TypedArray::fastClasses[TypedArray::TYPE_INT16]},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Uint16Array), &TypedArray::fastClasses[TypedArray::TYPE_UINT16]},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Int32Array), &TypedArray::fastClasses[TypedArray::TYPE_INT32]},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Uint32Array), &TypedArray::fastClasses[TypedArray::TYPE_UINT32]},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Float32Array), &TypedArray::fastClasses[TypedArray::TYPE_FLOAT32]},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Float64Array), &TypedArray::fastClasses[TypedArray::TYPE_FLOAT64]},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Uint8ClampedArray), &TypedArray::fastClasses[TypedArray::TYPE_UINT8_CLAMPED]},
|
||||
|
||||
{js_InitProxyClass, EAGER_ATOM_AND_CLASP(Proxy)},
|
||||
|
||||
@ -3707,12 +3707,8 @@ JS_ClearScope(JSContext *cx, JSObject *obj)
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj);
|
||||
|
||||
JSFinalizeOp clearOp = obj->getOps()->clear;
|
||||
if (clearOp)
|
||||
clearOp(cx, obj);
|
||||
|
||||
if (obj->isNative())
|
||||
js_ClearNative(cx, obj);
|
||||
if (obj->map->ops->clear)
|
||||
obj->map->ops->clear(cx, obj);
|
||||
|
||||
/* Clear cached class objects on the global object. */
|
||||
if (obj->getClass()->flags & JSCLASS_IS_GLOBAL) {
|
||||
@ -3785,21 +3781,10 @@ static Class prop_iter_class = {
|
||||
"PropertyIterator",
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(1) |
|
||||
JSCLASS_MARK_IS_TRACE,
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub,
|
||||
prop_iter_finalize,
|
||||
NULL, /* reserved0 */
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
NULL, /* hasInstance */
|
||||
JS_CLASS_TRACE(prop_iter_trace)
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, ConvertStub, prop_iter_finalize,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, JS_CLASS_TRACE(prop_iter_trace), NULL
|
||||
};
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
|
@ -1595,34 +1595,45 @@ JS_SetScriptStackQuota(JSContext *cx, size_t quota);
|
||||
/*
|
||||
* Classes, objects, and properties.
|
||||
*/
|
||||
typedef void (*JSClassInternal)();
|
||||
|
||||
/* For detailed comments on the function pointer types, see jspubtd.h. */
|
||||
struct JSClass {
|
||||
const char *name; \
|
||||
uint32 flags; \
|
||||
\
|
||||
/* Mandatory non-null function pointer members. */ \
|
||||
JSPropertyOp addProperty; \
|
||||
JSPropertyOp delProperty; \
|
||||
JSPropertyOp getProperty; \
|
||||
JSPropertyOp setProperty; \
|
||||
JSEnumerateOp enumerate; \
|
||||
JSResolveOp resolve; \
|
||||
JSConvertOp convert; \
|
||||
JSFinalizeOp finalize; \
|
||||
\
|
||||
/* Optionally non-null members start here. */ \
|
||||
JSClassInternal reserved0; \
|
||||
JSCheckAccessOp checkAccess; \
|
||||
JSNative call; \
|
||||
JSNative construct; \
|
||||
JSXDRObjectOp xdrObject; \
|
||||
JSHasInstanceOp hasInstance; \
|
||||
JSMarkOp mark;
|
||||
const char *name;
|
||||
uint32 flags;
|
||||
|
||||
JSClassInternal reserved1;
|
||||
void *reserved[19];
|
||||
/* Mandatory non-null function pointer members. */
|
||||
JSPropertyOp addProperty;
|
||||
JSPropertyOp delProperty;
|
||||
JSPropertyOp getProperty;
|
||||
JSPropertyOp setProperty;
|
||||
JSEnumerateOp enumerate;
|
||||
JSResolveOp resolve;
|
||||
JSConvertOp convert;
|
||||
JSFinalizeOp finalize;
|
||||
|
||||
/* Optionally non-null members start here. */
|
||||
JSGetObjectOps getObjectOps;
|
||||
JSCheckAccessOp checkAccess;
|
||||
JSNative call;
|
||||
JSNative construct;
|
||||
JSXDRObjectOp xdrObject;
|
||||
JSHasInstanceOp hasInstance;
|
||||
JSMarkOp mark;
|
||||
void (*reserved0)(void);
|
||||
};
|
||||
|
||||
struct JSExtendedClass {
|
||||
JSClass base;
|
||||
JSEqualityOp equality;
|
||||
JSObjectOp outerObject;
|
||||
JSObjectOp innerObject;
|
||||
JSIteratorOp iteratorObject;
|
||||
JSObjectOp wrappedObject; /* NB: infallible, null
|
||||
returns are treated as
|
||||
the original object */
|
||||
void (*reserved0)(void);
|
||||
void (*reserved1)(void);
|
||||
void (*reserved2)(void);
|
||||
};
|
||||
|
||||
#define JSCLASS_HAS_PRIVATE (1<<0) /* objects have private slot */
|
||||
@ -1655,13 +1666,15 @@ struct JSClass {
|
||||
#define JSCLASS_HIGH_FLAGS_SHIFT (JSCLASS_RESERVED_SLOTS_SHIFT + \
|
||||
JSCLASS_RESERVED_SLOTS_WIDTH)
|
||||
|
||||
#define JSCLASS_INTERNAL_FLAG1 (1<<(JSCLASS_HIGH_FLAGS_SHIFT+0))
|
||||
/* True if JSClass is really a JSExtendedClass. */
|
||||
#define JSCLASS_IS_EXTENDED (1<<(JSCLASS_HIGH_FLAGS_SHIFT+0))
|
||||
#define JSCLASS_IS_ANONYMOUS (1<<(JSCLASS_HIGH_FLAGS_SHIFT+1))
|
||||
#define JSCLASS_IS_GLOBAL (1<<(JSCLASS_HIGH_FLAGS_SHIFT+2))
|
||||
|
||||
/* Indicates that JSClass.mark is a tracer with JSTraceOp type. */
|
||||
#define JSCLASS_MARK_IS_TRACE (1<<(JSCLASS_HIGH_FLAGS_SHIFT+3))
|
||||
#define JSCLASS_INTERNAL_FLAG2 (1<<(JSCLASS_HIGH_FLAGS_SHIFT+4))
|
||||
|
||||
#define JSCLASS_LAST_API_FLAG_SHIFT (JSCLASS_HIGH_FLAGS_SHIFT+3)
|
||||
|
||||
/*
|
||||
* ECMA-262 requires that most constructors used internally create objects
|
||||
@ -1691,8 +1704,8 @@ struct JSClass {
|
||||
& JSCLASS_CACHED_PROTO_MASK))
|
||||
|
||||
/* Initializer for unused members of statically initialized JSClass structs. */
|
||||
#define JSCLASS_NO_INTERNAL_MEMBERS 0,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
|
||||
#define JSCLASS_NO_OPTIONAL_MEMBERS 0,0,0,0,0,0,0,JSCLASS_NO_INTERNAL_MEMBERS
|
||||
#define JSCLASS_NO_OPTIONAL_MEMBERS 0,0,0,0,0,0,0,0
|
||||
#define JSCLASS_NO_RESERVED_MEMBERS 0,0,0
|
||||
|
||||
struct JSIdArray {
|
||||
jsint length;
|
||||
|
@ -1004,53 +1004,49 @@ array_trace(JSTracer *trc, JSObject *obj)
|
||||
}
|
||||
}
|
||||
|
||||
extern JSObjectOps js_ArrayObjectOps;
|
||||
|
||||
static const JSObjectMap SharedArrayMap(&js_ArrayObjectOps, JSObjectMap::SHAPELESS);
|
||||
|
||||
JSObjectOps js_ArrayObjectOps = {
|
||||
&SharedArrayMap,
|
||||
array_lookupProperty,
|
||||
array_defineProperty,
|
||||
array_getProperty,
|
||||
array_setProperty,
|
||||
array_getAttributes,
|
||||
array_setAttributes,
|
||||
array_deleteProperty,
|
||||
js_Enumerate,
|
||||
array_typeOf,
|
||||
array_trace,
|
||||
NULL, /* thisObject */
|
||||
NULL /* clear */
|
||||
};
|
||||
|
||||
static JSObjectOps *
|
||||
array_getObjectOps(JSContext *cx, Class *clasp)
|
||||
{
|
||||
return &js_ArrayObjectOps;
|
||||
}
|
||||
|
||||
Class js_ArrayClass = {
|
||||
"Array",
|
||||
Class::NON_NATIVE |
|
||||
JSCLASS_HAS_RESERVED_SLOTS(JSObject::DENSE_ARRAY_FIXED_RESERVED_SLOTS) |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Array),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
js_TryValueOf,
|
||||
array_finalize,
|
||||
NULL, /* reserved0 */
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
NULL, /* hasInstance */
|
||||
NULL, /* mark */
|
||||
JS_NULL_CLASS_EXT,
|
||||
{
|
||||
array_lookupProperty,
|
||||
array_defineProperty,
|
||||
array_getProperty,
|
||||
array_setProperty,
|
||||
array_getAttributes,
|
||||
array_setAttributes,
|
||||
array_deleteProperty,
|
||||
NULL, /* enumerate */
|
||||
array_typeOf,
|
||||
array_trace,
|
||||
NULL, /* thisObject */
|
||||
NULL, /* clear */
|
||||
}
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, js_TryValueOf, array_finalize,
|
||||
array_getObjectOps, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
Class js_SlowArrayClass = {
|
||||
"Array",
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Array),
|
||||
slowarray_addProperty,
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
js_TryValueOf
|
||||
JSCLASS_HAS_PRIVATE |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Array),
|
||||
slowarray_addProperty, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, js_TryValueOf, NULL,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1076,7 +1072,7 @@ JSObject::makeDenseArraySlow(JSContext *cx)
|
||||
JS_ASSERT(arrayProto->getClass() == &js_SlowArrayClass);
|
||||
emptyShape = arrayProto->scope()->emptyScope->shape;
|
||||
}
|
||||
JSScope *scope = JSScope::create(cx, &js_SlowArrayClass, obj, emptyShape);
|
||||
JSScope *scope = JSScope::create(cx, &js_ObjectOps, &js_SlowArrayClass, obj, emptyShape);
|
||||
if (!scope)
|
||||
return JS_FALSE;
|
||||
|
||||
@ -2995,7 +2991,7 @@ js_NewEmptyArray(JSContext* cx, JSObject* proto, int32 len)
|
||||
return NULL;
|
||||
|
||||
/* Initialize all fields of JSObject. */
|
||||
obj->map = const_cast<JSObjectMap *>(&JSObjectMap::sharedNonNative);
|
||||
obj->map = const_cast<JSObjectMap *>(&SharedArrayMap);
|
||||
obj->init(&js_ArrayClass, proto, proto->getParent(), NullValue());
|
||||
obj->setArrayLength(len);
|
||||
obj->setDenseArrayCapacity(0);
|
||||
|
@ -56,18 +56,15 @@
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
|
||||
using namespace js;
|
||||
|
||||
Class js_BooleanClass = {
|
||||
"Boolean",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_HAS_CACHED_PROTO(JSProto_Boolean),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, ConvertStub, NULL,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
};
|
||||
|
||||
#if JS_HAS_TOSOURCE
|
||||
|
@ -256,7 +256,7 @@ HasProperty(JSContext* cx, JSObject* obj, jsid id)
|
||||
{
|
||||
// Check that we know how the lookup op will behave.
|
||||
for (JSObject* pobj = obj; pobj; pobj = pobj->getProto()) {
|
||||
if (pobj->getOps()->lookupProperty)
|
||||
if (pobj->map->ops->lookupProperty != js_LookupProperty)
|
||||
return JS_NEITHER;
|
||||
Class* clasp = pobj->getClass();
|
||||
if (clasp->resolve != JS_ResolveStub && clasp != &js_StringClass)
|
||||
|
@ -485,13 +485,9 @@ Class js_DateClass = {
|
||||
js_Date_str,
|
||||
JSCLASS_HAS_RESERVED_SLOTS(JSObject::DATE_FIXED_RESERVED_SLOTS) |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Date),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, ConvertStub, NULL,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
};
|
||||
|
||||
/* for use by date_parse */
|
||||
|
@ -88,21 +88,10 @@ Class js_ErrorClass = {
|
||||
js_Error_str,
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_MARK_IS_TRACE |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Error),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
exn_enumerate,
|
||||
(JSResolveOp)exn_resolve,
|
||||
ConvertStub,
|
||||
exn_finalize,
|
||||
NULL, /* reserved0 */
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
Exception, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
NULL, /* hasInstance */
|
||||
JS_CLASS_TRACE(exn_trace)
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
exn_enumerate, (JSResolveOp)exn_resolve, ConvertStub, exn_finalize,
|
||||
NULL, NULL, NULL, Exception,
|
||||
NULL, NULL, JS_CLASS_TRACE(exn_trace), NULL
|
||||
};
|
||||
|
||||
typedef struct JSStackTraceElem {
|
||||
|
@ -681,21 +681,14 @@ Class js_ArgumentsClass = {
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE |
|
||||
JSCLASS_HAS_RESERVED_SLOTS(JSObject::ARGS_FIXED_RESERVED_SLOTS) |
|
||||
JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
|
||||
PropertyStub, /* addProperty */
|
||||
args_delProperty,
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
args_enumerate,
|
||||
(JSResolveOp) args_resolve,
|
||||
ConvertStub,
|
||||
NULL, /* finalize */
|
||||
NULL, /* reserved0 */
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
NULL, /* hasInstance */
|
||||
JS_CLASS_TRACE(args_or_call_trace)
|
||||
PropertyStub, args_delProperty,
|
||||
PropertyStub, PropertyStub,
|
||||
args_enumerate, (JSResolveOp) args_resolve,
|
||||
ConvertStub, NULL,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
JS_CLASS_TRACE(args_or_call_trace), NULL
|
||||
};
|
||||
|
||||
const uint32 JSSLOT_CALLEE = JSSLOT_PRIVATE + 1;
|
||||
@ -709,13 +702,9 @@ const uint32 CALL_CLASS_FIXED_RESERVED_SLOTS = 2;
|
||||
Class js_DeclEnvClass = {
|
||||
js_Object_str,
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, ConvertStub, NULL,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
};
|
||||
|
||||
static JSBool
|
||||
@ -1273,21 +1262,14 @@ JS_PUBLIC_DATA(Class) js_CallClass = {
|
||||
JSCLASS_HAS_PRIVATE |
|
||||
JSCLASS_HAS_RESERVED_SLOTS(CALL_CLASS_FIXED_RESERVED_SLOTS) |
|
||||
JSCLASS_NEW_RESOLVE | JSCLASS_IS_ANONYMOUS | JSCLASS_MARK_IS_TRACE,
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
call_enumerate,
|
||||
(JSResolveOp)call_resolve,
|
||||
NULL, /* convert */
|
||||
NULL, /* finalize */
|
||||
NULL, /* reserved0 */
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
NULL, /* hasInstance */
|
||||
JS_CLASS_TRACE(args_or_call_trace)
|
||||
PropertyStub, PropertyStub,
|
||||
PropertyStub, PropertyStub,
|
||||
call_enumerate, (JSResolveOp)call_resolve,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
JS_CLASS_TRACE(args_or_call_trace), NULL
|
||||
};
|
||||
|
||||
bool
|
||||
@ -1923,21 +1905,14 @@ JS_PUBLIC_DATA(Class) js_FunctionClass = {
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE |
|
||||
JSCLASS_HAS_RESERVED_SLOTS(JSObject::FUN_FIXED_RESERVED_SLOTS) |
|
||||
JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_Function),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
fun_enumerate,
|
||||
(JSResolveOp)fun_resolve,
|
||||
ConvertStub,
|
||||
fun_finalize,
|
||||
NULL, /* reserved0 */
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
js_XDRFunctionObject,
|
||||
fun_hasInstance,
|
||||
JS_CLASS_TRACE(fun_trace)
|
||||
PropertyStub, PropertyStub,
|
||||
PropertyStub, PropertyStub,
|
||||
fun_enumerate, (JSResolveOp)fun_resolve,
|
||||
ConvertStub, fun_finalize,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
js_XDRFunctionObject, fun_hasInstance,
|
||||
JS_CLASS_TRACE(fun_trace), NULL
|
||||
};
|
||||
|
||||
namespace js {
|
||||
|
@ -1855,8 +1855,7 @@ JS_TraceChildren(JSTracer *trc, void *thing, uint32 kind)
|
||||
JSObject *obj = (JSObject *) thing;
|
||||
if (!obj->map)
|
||||
break;
|
||||
JSTraceOp op = obj->getOps()->trace;
|
||||
(op ? op : js_TraceObject)(trc, obj);
|
||||
obj->map->ops->trace(trc, obj);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -336,13 +336,9 @@ const uint32 JSSLOT_SAVED_ID = JSSLOT_PRIVATE + 1;
|
||||
Class js_NoSuchMethodClass = {
|
||||
"NoSuchMethod",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_IS_ANONYMOUS,
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub,
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, ConvertStub, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
/*
|
||||
@ -624,7 +620,7 @@ DoSlowCall(JSContext *cx, uintN argc, Value *vp)
|
||||
|
||||
JSObject *callee = &JS_CALLEE(cx, vp).toObject();
|
||||
Class *clasp = callee->getClass();
|
||||
JS_ASSERT(!(clasp->flags & Class::CALL_IS_FAST));
|
||||
JS_ASSERT(!(clasp->flags & CLASS_CALL_IS_FAST));
|
||||
if (!clasp->call) {
|
||||
js_ReportIsNotFunction(cx, &vp[0], 0);
|
||||
return JS_FALSE;
|
||||
@ -727,7 +723,7 @@ Invoke(JSContext *cx, const InvokeArgsGuard &args, uintN flags)
|
||||
}
|
||||
return InvokeCommon(cx, NULL, NULL, DoConstruct, args, flags);
|
||||
}
|
||||
CallOp callOp = (clasp->flags & Class::CALL_IS_FAST) ? (CallOp) clasp->call : DoSlowCall;
|
||||
CallOp callOp = (clasp->flags & CLASS_CALL_IS_FAST) ? (CallOp) clasp->call : DoSlowCall;
|
||||
return InvokeCommon(cx, NULL, NULL, callOp, args, flags);
|
||||
}
|
||||
|
||||
@ -877,7 +873,7 @@ Execute(JSContext *cx, JSObject *chain, JSScript *script,
|
||||
? chain->getGlobal()
|
||||
: chain;
|
||||
}
|
||||
JS_ASSERT(!initialVarObj->getOps()->defineProperty);
|
||||
JS_ASSERT(initialVarObj->map->ops->defineProperty == js_DefineProperty);
|
||||
|
||||
fp->script = script;
|
||||
fp->imacpc = NULL;
|
||||
@ -1116,7 +1112,7 @@ TypeOfValue(JSContext *cx, const Value &vref)
|
||||
if (v.isUndefined())
|
||||
return JSTYPE_VOID;
|
||||
if (v.isObject())
|
||||
return v.toObject().typeOf(cx);
|
||||
return v.toObject().map->ops->typeOf(cx, &v.toObject());
|
||||
JS_ASSERT(v.isBoolean());
|
||||
return JSTYPE_BOOLEAN;
|
||||
}
|
||||
@ -2028,7 +2024,7 @@ JS_STATIC_ASSERT(JSOP_INCNAME_LENGTH == JSOP_NAMEDEC_LENGTH);
|
||||
static inline bool
|
||||
IteratorMore(JSContext *cx, JSObject *iterobj, bool *cond, Value *rval)
|
||||
{
|
||||
if (iterobj->getClass() == &js_IteratorClass) {
|
||||
if (iterobj->getClass() == &js_IteratorClass.base) {
|
||||
NativeIterator *ni = (NativeIterator *) iterobj->getPrivate();
|
||||
*cond = (ni->props_cursor < ni->props_end);
|
||||
} else {
|
||||
@ -2042,7 +2038,7 @@ IteratorMore(JSContext *cx, JSObject *iterobj, bool *cond, Value *rval)
|
||||
static inline bool
|
||||
IteratorNext(JSContext *cx, JSObject *iterobj, Value *rval)
|
||||
{
|
||||
if (iterobj->getClass() == &js_IteratorClass) {
|
||||
if (iterobj->getClass() == &js_IteratorClass.base) {
|
||||
NativeIterator *ni = (NativeIterator *) iterobj->getPrivate();
|
||||
JS_ASSERT(ni->props_cursor < ni->props_end);
|
||||
if (ni->isKeyIter()) {
|
||||
@ -3218,8 +3214,9 @@ END_CASE(JSOP_BITAND)
|
||||
} else
|
||||
|
||||
#define EXTENDED_EQUALITY_OP(OP) \
|
||||
if (EqualityOp eq = l->getClass()->ext.equality) { \
|
||||
if (!eq(cx, l, &rval, &cond)) \
|
||||
if (((clasp = l->getClass())->flags & JSCLASS_IS_EXTENDED) && \
|
||||
((ExtendedClass *)clasp)->equality) { \
|
||||
if (!((ExtendedClass *)clasp)->equality(cx, l, &rval, &cond)) \
|
||||
goto error; \
|
||||
cond = cond OP JS_TRUE; \
|
||||
} else
|
||||
@ -3230,6 +3227,7 @@ END_CASE(JSOP_BITAND)
|
||||
|
||||
#define EQUALITY_OP(OP, IFNAN) \
|
||||
JS_BEGIN_MACRO \
|
||||
Class *clasp; \
|
||||
JSBool cond; \
|
||||
Value rval = regs.sp[-1]; \
|
||||
Value lval = regs.sp[-2]; \
|
||||
@ -4048,7 +4046,7 @@ BEGIN_CASE(JSOP_GETXPROP)
|
||||
}
|
||||
|
||||
jsid id = ATOM_TO_JSID(atom);
|
||||
if (JS_LIKELY(!aobj->getOps()->getProperty)
|
||||
if (JS_LIKELY(aobj->map->ops->getProperty == js_GetProperty)
|
||||
? !js_GetPropertyHelper(cx, obj, id,
|
||||
(fp->imacpc ||
|
||||
regs.pc[JSOP_GETPROP_LENGTH + i] == JSOP_IFEQ)
|
||||
@ -4152,7 +4150,7 @@ BEGIN_CASE(JSOP_CALLPROP)
|
||||
PUSH_NULL();
|
||||
if (lval.isObject()) {
|
||||
if (!js_GetMethod(cx, &objv.toObject(), id,
|
||||
JS_LIKELY(!aobj->getOps()->getProperty)
|
||||
JS_LIKELY(aobj->map->ops->getProperty == js_GetProperty)
|
||||
? JSGET_CACHE_RESULT | JSGET_NO_METHOD_BARRIER
|
||||
: JSGET_NO_METHOD_BARRIER,
|
||||
&rval)) {
|
||||
@ -4161,7 +4159,7 @@ BEGIN_CASE(JSOP_CALLPROP)
|
||||
regs.sp[-1] = objv;
|
||||
regs.sp[-2] = rval;
|
||||
} else {
|
||||
JS_ASSERT(!objv.toObject().getOps()->getProperty);
|
||||
JS_ASSERT(objv.toObject().map->ops->getProperty == js_GetProperty);
|
||||
if (!js_GetPropertyHelper(cx, &objv.toObject(), id,
|
||||
JSGET_CACHE_RESULT | JSGET_NO_METHOD_BARRIER,
|
||||
&rval)) {
|
||||
@ -4385,7 +4383,7 @@ BEGIN_CASE(JSOP_SETMETHOD)
|
||||
if (!atom)
|
||||
LOAD_ATOM(0, atom);
|
||||
jsid id = ATOM_TO_JSID(atom);
|
||||
if (entry && JS_LIKELY(!obj->getOps()->setProperty)) {
|
||||
if (entry && JS_LIKELY(obj->map->ops->setProperty == js_SetProperty)) {
|
||||
uintN defineHow;
|
||||
if (op == JSOP_SETMETHOD)
|
||||
defineHow = JSDNP_CACHE_RESULT | JSDNP_SET_METHOD;
|
||||
@ -5359,7 +5357,7 @@ BEGIN_CASE(JSOP_DEFVAR)
|
||||
*/
|
||||
index += atoms - script->atomMap.vector;
|
||||
JSObject *obj = fp->varobj(cx);
|
||||
JS_ASSERT(!obj->getOps()->defineProperty);
|
||||
JS_ASSERT(obj->map->ops->defineProperty == js_DefineProperty);
|
||||
uintN attrs = JSPROP_ENUMERATE;
|
||||
if (!(fp->flags & JSFRAME_EVAL))
|
||||
attrs |= JSPROP_PERMANENT;
|
||||
|
@ -85,31 +85,19 @@ static void iterator_finalize(JSContext *cx, JSObject *obj);
|
||||
static void iterator_trace(JSTracer *trc, JSObject *obj);
|
||||
static JSObject *iterator_iterator(JSContext *cx, JSObject *obj, JSBool keysonly);
|
||||
|
||||
Class js_IteratorClass = {
|
||||
"Iterator",
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Iterator) | JSCLASS_MARK_IS_TRACE,
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub,
|
||||
iterator_finalize,
|
||||
NULL, /* reserved */
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
NULL, /* hasInstance */
|
||||
JS_CLASS_TRACE(iterator_trace),
|
||||
{
|
||||
NULL, /* equality */
|
||||
NULL, /* outerObject */
|
||||
NULL, /* innerObject */
|
||||
iterator_iterator,
|
||||
NULL /* wrappedObject */
|
||||
}
|
||||
ExtendedClass js_IteratorClass = {
|
||||
{ "Iterator",
|
||||
JSCLASS_HAS_PRIVATE |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Iterator) |
|
||||
JSCLASS_MARK_IS_TRACE |
|
||||
JSCLASS_IS_EXTENDED,
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, ConvertStub, iterator_finalize,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, JS_CLASS_TRACE(iterator_trace), NULL },
|
||||
NULL, NULL, NULL, iterator_iterator,
|
||||
NULL,
|
||||
JSCLASS_NO_RESERVED_MEMBERS
|
||||
};
|
||||
|
||||
void
|
||||
@ -130,7 +118,7 @@ NativeIterator::mark(JSTracer *trc)
|
||||
static void
|
||||
iterator_finalize(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(obj->getClass() == &js_IteratorClass);
|
||||
JS_ASSERT(obj->getClass() == &js_IteratorClass.base);
|
||||
|
||||
/* Avoid double work if the iterator was closed by JSOP_ENDITER. */
|
||||
NativeIterator *ni = obj->getNativeIterator();
|
||||
@ -320,7 +308,7 @@ Snapshot(JSContext *cx, JSObject *obj, uintN flags, typename EnumPolicy::ResultV
|
||||
do {
|
||||
Class *clasp = pobj->getClass();
|
||||
if (pobj->isNative() &&
|
||||
!pobj->getOps()->enumerate &&
|
||||
pobj->map->ops->enumerate == js_Enumerate &&
|
||||
!(clasp->flags & JSCLASS_NEW_ENUMERATE)) {
|
||||
if (!clasp->enumerate(cx, pobj))
|
||||
return false;
|
||||
@ -461,11 +449,11 @@ NewIteratorObject(JSContext *cx, uintN flags)
|
||||
if (!obj)
|
||||
return false;
|
||||
obj->map = cx->runtime->emptyEnumeratorScope->hold();
|
||||
obj->init(&js_IteratorClass, NULL, NULL, NullValue());
|
||||
obj->init(&js_IteratorClass.base, NULL, NULL, NullValue());
|
||||
return obj;
|
||||
}
|
||||
|
||||
return NewBuiltinClassInstance(cx, &js_IteratorClass);
|
||||
return NewBuiltinClassInstance(cx, &js_IteratorClass.base);
|
||||
}
|
||||
|
||||
NativeIterator *
|
||||
@ -622,7 +610,7 @@ GetIterator(JSContext *cx, JSObject *obj, uintN flags, Value *vp)
|
||||
JSObject *pobj = obj;
|
||||
do {
|
||||
if (!pobj->isNative() ||
|
||||
obj->getOps()->enumerate ||
|
||||
obj->map->ops->enumerate != js_Enumerate ||
|
||||
pobj->getClass()->enumerate != JS_EnumerateStub) {
|
||||
shapes.clear();
|
||||
goto miss;
|
||||
@ -710,7 +698,7 @@ iterator_next(JSContext *cx, uintN argc, Value *vp)
|
||||
JSObject *obj;
|
||||
|
||||
obj = ComputeThisFromVp(cx, vp);
|
||||
if (!InstanceOf(cx, obj, &js_IteratorClass, vp + 2))
|
||||
if (!InstanceOf(cx, obj, &js_IteratorClass.base, vp + 2))
|
||||
return false;
|
||||
|
||||
if (!js_IteratorMore(cx, obj, vp))
|
||||
@ -772,14 +760,18 @@ js_ValueToIterator(JSContext *cx, uintN flags, Value *vp)
|
||||
|
||||
AutoObjectRooter tvr(cx, obj);
|
||||
|
||||
/* Enumerate Iterator.prototype directly. */
|
||||
JSIteratorOp op = obj->getClass()->ext.iteratorObject;
|
||||
if (op && (obj->getClass() != &js_IteratorClass || obj->getNativeIterator())) {
|
||||
JSObject *iterobj = op(cx, obj, !(flags & JSITER_FOREACH));
|
||||
if (!iterobj)
|
||||
return false;
|
||||
vp->setObject(*iterobj);
|
||||
return true;
|
||||
Class *clasp = obj->getClass();
|
||||
ExtendedClass *xclasp;
|
||||
if ((clasp->flags & JSCLASS_IS_EXTENDED) &&
|
||||
(xclasp = (ExtendedClass *) clasp)->iteratorObject) {
|
||||
/* Enumerate Iterator.prototype directly. */
|
||||
if (clasp != &js_IteratorClass.base || obj->getNativeIterator()) {
|
||||
JSObject *iterobj = xclasp->iteratorObject(cx, obj, !(flags & JSITER_FOREACH));
|
||||
if (!iterobj)
|
||||
return false;
|
||||
vp->setObject(*iterobj);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return GetIterator(cx, obj, flags, vp);
|
||||
@ -796,7 +788,7 @@ js_CloseIterator(JSContext *cx, JSObject *obj)
|
||||
cx->iterValue.setMagic(JS_NO_ITER_VALUE);
|
||||
|
||||
Class *clasp = obj->getClass();
|
||||
if (clasp == &js_IteratorClass) {
|
||||
if (clasp == &js_IteratorClass.base) {
|
||||
/* Remove enumerators from the active list, which is a stack. */
|
||||
NativeIterator *ni = obj->getNativeIterator();
|
||||
if (ni->flags & JSITER_ENUMERATE) {
|
||||
@ -816,7 +808,7 @@ js_CloseIterator(JSContext *cx, JSObject *obj)
|
||||
}
|
||||
}
|
||||
#if JS_HAS_GENERATORS
|
||||
else if (clasp == &js_GeneratorClass) {
|
||||
else if (clasp == &js_GeneratorClass.base) {
|
||||
return CloseGenerator(cx, obj);
|
||||
}
|
||||
#endif
|
||||
@ -901,7 +893,7 @@ JSBool
|
||||
js_IteratorMore(JSContext *cx, JSObject *iterobj, Value *rval)
|
||||
{
|
||||
/* Fast path for native iterators */
|
||||
if (iterobj->getClass() == &js_IteratorClass) {
|
||||
if (iterobj->getClass() == &js_IteratorClass.base) {
|
||||
/*
|
||||
* Implement next directly as all the methods of native iterator are
|
||||
* read-only and permanent.
|
||||
@ -945,7 +937,7 @@ JSBool
|
||||
js_IteratorNext(JSContext *cx, JSObject *iterobj, Value *rval)
|
||||
{
|
||||
/* Fast path for native iterators */
|
||||
if (iterobj->getClass() == &js_IteratorClass) {
|
||||
if (iterobj->getClass() == &js_IteratorClass.base) {
|
||||
/*
|
||||
* Implement next directly as all the methods of the native iterator are
|
||||
* read-only and permanent.
|
||||
@ -994,20 +986,14 @@ stopiter_hasInstance(JSContext *cx, JSObject *obj, const Value *v, JSBool *bp)
|
||||
Class js_StopIterationClass = {
|
||||
js_StopIteration_str,
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_StopIteration),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub,
|
||||
NULL, /* finalize */
|
||||
NULL, /* reserved0 */
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
stopiter_hasInstance
|
||||
PropertyStub, PropertyStub,
|
||||
PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub,
|
||||
ConvertStub, NULL,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
NULL, stopiter_hasInstance,
|
||||
NULL, NULL
|
||||
};
|
||||
|
||||
#if JS_HAS_GENERATORS
|
||||
@ -1050,32 +1036,20 @@ generator_trace(JSTracer *trc, JSObject *obj)
|
||||
MarkValueRange(trc, fp->slots(), gen->savedRegs.sp, "generator slots");
|
||||
}
|
||||
|
||||
Class js_GeneratorClass = {
|
||||
js_Generator_str,
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Generator) |
|
||||
JSCLASS_IS_ANONYMOUS | JSCLASS_MARK_IS_TRACE,
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub,
|
||||
generator_finalize,
|
||||
NULL, /* reserved */
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
NULL, /* hasInstance */
|
||||
JS_CLASS_TRACE(generator_trace),
|
||||
{
|
||||
NULL, /* equality */
|
||||
NULL, /* outerObject */
|
||||
NULL, /* innerObject */
|
||||
iterator_iterator,
|
||||
NULL, /* wrappedObject */
|
||||
}
|
||||
ExtendedClass js_GeneratorClass = {
|
||||
{ js_Generator_str,
|
||||
JSCLASS_HAS_PRIVATE |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Generator) |
|
||||
JSCLASS_IS_ANONYMOUS |
|
||||
JSCLASS_MARK_IS_TRACE |
|
||||
JSCLASS_IS_EXTENDED,
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, ConvertStub, generator_finalize,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, JS_CLASS_TRACE(generator_trace), NULL },
|
||||
NULL, NULL, NULL, iterator_iterator,
|
||||
NULL,
|
||||
JSCLASS_NO_RESERVED_MEMBERS
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1089,7 +1063,7 @@ Class js_GeneratorClass = {
|
||||
JS_REQUIRES_STACK JSObject *
|
||||
js_NewGenerator(JSContext *cx)
|
||||
{
|
||||
JSObject *obj = NewBuiltinClassInstance(cx, &js_GeneratorClass);
|
||||
JSObject *obj = NewBuiltinClassInstance(cx, &js_GeneratorClass.base);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
@ -1331,7 +1305,7 @@ SendToGenerator(JSContext *cx, JSGeneratorOp op, JSObject *obj,
|
||||
static JS_REQUIRES_STACK JSBool
|
||||
CloseGenerator(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(obj->getClass() == &js_GeneratorClass);
|
||||
JS_ASSERT(obj->getClass() == &js_GeneratorClass.base);
|
||||
|
||||
JSGenerator *gen = (JSGenerator *) obj->getPrivate();
|
||||
if (!gen) {
|
||||
@ -1355,7 +1329,7 @@ generator_op(JSContext *cx, JSGeneratorOp op, Value *vp, uintN argc)
|
||||
LeaveTrace(cx);
|
||||
|
||||
obj = ComputeThisFromVp(cx, vp);
|
||||
if (!InstanceOf(cx, obj, &js_GeneratorClass, vp + 2))
|
||||
if (!InstanceOf(cx, obj, &js_GeneratorClass.base, vp + 2))
|
||||
return JS_FALSE;
|
||||
|
||||
JSGenerator *gen = (JSGenerator *) obj->getPrivate();
|
||||
@ -1450,14 +1424,14 @@ js_InitIteratorClasses(JSContext *cx, JSObject *obj)
|
||||
if (stop)
|
||||
return stop;
|
||||
|
||||
proto = js_InitClass(cx, obj, NULL, &js_IteratorClass, Iterator, 2,
|
||||
proto = js_InitClass(cx, obj, NULL, &js_IteratorClass.base, Iterator, 2,
|
||||
NULL, iterator_methods, NULL, NULL);
|
||||
if (!proto)
|
||||
return NULL;
|
||||
|
||||
#if JS_HAS_GENERATORS
|
||||
/* Initialize the generator internals if configured. */
|
||||
if (!js_InitClass(cx, obj, NULL, &js_GeneratorClass, NULL, 0,
|
||||
if (!js_InitClass(cx, obj, NULL, &js_GeneratorClass.base, NULL, 0,
|
||||
NULL, generator_methods, NULL, NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -249,9 +249,9 @@ js_LiveFrameIfGenerator(JSStackFrame *fp)
|
||||
|
||||
#endif
|
||||
|
||||
extern js::Class js_GeneratorClass;
|
||||
extern js::Class js_IteratorClass;
|
||||
extern js::Class js_StopIterationClass;
|
||||
extern js::ExtendedClass js_GeneratorClass;
|
||||
extern js::ExtendedClass js_IteratorClass;
|
||||
extern js::Class js_StopIterationClass;
|
||||
|
||||
static inline bool
|
||||
js_ValueIsStopIteration(const js::Value &v)
|
||||
|
@ -150,7 +150,9 @@ struct JSTitle {
|
||||
/*
|
||||
* NB: The JS_LOCK_OBJ and JS_UNLOCK_OBJ macros work *only* on native objects
|
||||
* (objects for which obj->isNative() returns true). All uses of these macros in
|
||||
* the engine are predicated on obj->isNative or equivalent checks.
|
||||
* the engine are predicated on obj->isNative or equivalent checks. These uses
|
||||
* are for optimizations above the JSObjectOps layer, under which object locks
|
||||
* normally hide.
|
||||
*/
|
||||
#define CX_OWNS_SCOPE_TITLE(cx,scope) ((scope)->title.ownercx == (cx))
|
||||
|
||||
|
@ -97,13 +97,9 @@ static JSConstDoubleSpec math_constants[] = {
|
||||
Class js_MathClass = {
|
||||
js_Math_str,
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Math),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, ConvertStub, NULL,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
};
|
||||
|
||||
static JSBool
|
||||
|
@ -271,13 +271,9 @@ static JSFunctionSpec number_functions[] = {
|
||||
Class js_NumberClass = {
|
||||
js_Number_str,
|
||||
JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_HAS_CACHED_PROTO(JSProto_Number),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, ConvertStub, NULL,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
};
|
||||
|
||||
static JSBool
|
||||
|
171
js/src/jsobj.cpp
171
js/src/jsobj.cpp
@ -102,27 +102,30 @@
|
||||
|
||||
using namespace js;
|
||||
|
||||
JS_FRIEND_DATA(const JSObjectMap) JSObjectMap::sharedNonNative(JSObjectMap::SHAPELESS);
|
||||
JS_FRIEND_DATA(JSObjectOps) js_ObjectOps = {
|
||||
NULL,
|
||||
js_LookupProperty,
|
||||
js_DefineProperty,
|
||||
js_GetProperty,
|
||||
js_SetProperty,
|
||||
js_GetAttributes,
|
||||
js_SetAttributes,
|
||||
js_DeleteProperty,
|
||||
js_Enumerate,
|
||||
js_TypeOf,
|
||||
js_TraceObject,
|
||||
NULL, /* thisObject */
|
||||
js_Clear
|
||||
};
|
||||
|
||||
Class js_ObjectClass = {
|
||||
js_Object_str,
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, ConvertStub, NULL,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
};
|
||||
|
||||
JS_FRIEND_API(JSObject *)
|
||||
js_ObjectToOuterObject(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
OBJ_TO_OUTER_OBJECT(cx, obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
#if JS_HAS_OBJ_PROTO_PROP
|
||||
|
||||
static JSBool
|
||||
@ -914,6 +917,8 @@ js_CheckPrincipalsAccess(JSContext *cx, JSObject *scopeobj,
|
||||
JSObject *
|
||||
js_CheckScopeChainValidity(JSContext *cx, JSObject *scopeobj, const char *caller)
|
||||
{
|
||||
Class *clasp;
|
||||
JSExtendedClass *xclasp;
|
||||
JSObject *inner;
|
||||
|
||||
if (!scopeobj)
|
||||
@ -923,12 +928,19 @@ js_CheckScopeChainValidity(JSContext *cx, JSObject *scopeobj, const char *caller
|
||||
if (!scopeobj)
|
||||
return NULL;
|
||||
|
||||
/* XXX This is an awful gross hack. */
|
||||
inner = scopeobj;
|
||||
|
||||
/* XXX This is an awful gross hack. */
|
||||
while (scopeobj) {
|
||||
JSObjectOp op = scopeobj->getClass()->ext.innerObject;
|
||||
if (op && op(cx, scopeobj) != scopeobj)
|
||||
goto bad;
|
||||
clasp = scopeobj->getClass();
|
||||
if (clasp->flags & JSCLASS_IS_EXTENDED) {
|
||||
xclasp = (JSExtendedClass*)clasp;
|
||||
if (xclasp->innerObject &&
|
||||
xclasp->innerObject(cx, scopeobj) != scopeobj) {
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
|
||||
scopeobj = scopeobj->getParent();
|
||||
}
|
||||
|
||||
@ -1355,7 +1367,7 @@ obj_hasOwnProperty(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
JSObject *obj = ComputeThisFromVp(cx, vp);
|
||||
return obj &&
|
||||
js_HasOwnPropertyHelper(cx, obj->getOps()->lookupProperty, argc, vp);
|
||||
js_HasOwnPropertyHelper(cx, obj->map->ops->lookupProperty, argc, vp);
|
||||
}
|
||||
|
||||
JSBool
|
||||
@ -1394,7 +1406,7 @@ js_HasOwnProperty(JSContext *cx, JSLookupPropOp lookup, JSObject *obj, jsid id,
|
||||
JSObject **objp, JSProperty **propp)
|
||||
{
|
||||
JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_DETECTING);
|
||||
if (!(lookup ? lookup : js_LookupProperty)(cx, obj, id, objp, propp))
|
||||
if (!lookup(cx, obj, id, objp, propp))
|
||||
return false;
|
||||
if (!*propp)
|
||||
return true;
|
||||
@ -1402,10 +1414,14 @@ js_HasOwnProperty(JSContext *cx, JSLookupPropOp lookup, JSObject *obj, jsid id,
|
||||
if (*objp == obj)
|
||||
return true;
|
||||
|
||||
JSExtendedClass *xclasp;
|
||||
JSObject *outer;
|
||||
Class *clasp = (*objp)->getClass();
|
||||
JSObject *outer = NULL;
|
||||
if (JSObjectOp op = (*objp)->getClass()->ext.outerObject) {
|
||||
outer = op(cx, *objp);
|
||||
if (!(clasp->flags & JSCLASS_IS_EXTENDED) ||
|
||||
!(xclasp = (JSExtendedClass *) clasp)->outerObject) {
|
||||
outer = NULL;
|
||||
} else {
|
||||
outer = xclasp->outerObject(cx, *objp);
|
||||
if (!outer)
|
||||
return false;
|
||||
}
|
||||
@ -1691,7 +1707,7 @@ js_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
||||
|
||||
JSObject *pobj;
|
||||
JSProperty *prop;
|
||||
if (!js_HasOwnProperty(cx, obj->getOps()->lookupProperty, obj, id, &pobj, &prop))
|
||||
if (!js_HasOwnProperty(cx, obj->map->ops->lookupProperty, obj, id, &pobj, &prop))
|
||||
return false;
|
||||
if (!prop) {
|
||||
vp->setUndefined();
|
||||
@ -1967,11 +1983,11 @@ DefinePropertyOnObject(JSContext *cx, JSObject *obj, const PropDesc &desc,
|
||||
/* 8.12.9 step 1. */
|
||||
JSProperty *current;
|
||||
JSObject *obj2;
|
||||
JS_ASSERT(!obj->getOps()->lookupProperty);
|
||||
if (!js_HasOwnProperty(cx, NULL, obj, desc.id, &obj2, ¤t))
|
||||
JS_ASSERT(obj->map->ops->lookupProperty == js_LookupProperty);
|
||||
if (!js_HasOwnProperty(cx, js_LookupProperty, obj, desc.id, &obj2, ¤t))
|
||||
return JS_FALSE;
|
||||
|
||||
JS_ASSERT(!obj->getOps()->defineProperty);
|
||||
JS_ASSERT(obj->map->ops->defineProperty == js_DefineProperty);
|
||||
|
||||
/* 8.12.9 steps 2-4. */
|
||||
JSScope *scope = obj->scope();
|
||||
@ -1982,7 +1998,7 @@ DefinePropertyOnObject(JSContext *cx, JSObject *obj, const PropDesc &desc,
|
||||
*rval = true;
|
||||
|
||||
if (desc.isGenericDescriptor() || desc.isDataDescriptor()) {
|
||||
JS_ASSERT(!obj->getOps()->defineProperty);
|
||||
JS_ASSERT(obj->map->ops->defineProperty == js_DefineProperty);
|
||||
return js_DefineProperty(cx, obj, desc.id, &desc.value,
|
||||
PropertyStub, PropertyStub, desc.attrs);
|
||||
}
|
||||
@ -2287,7 +2303,7 @@ DefineProperty(JSContext *cx, JSObject *obj, const PropDesc &desc, bool throwErr
|
||||
if (obj->isArray())
|
||||
return DefinePropertyOnArray(cx, obj, desc, throwError, rval);
|
||||
|
||||
if (obj->getOps()->lookupProperty) {
|
||||
if (obj->map->ops->lookupProperty != js_LookupProperty) {
|
||||
if (obj->isProxy())
|
||||
return JSProxy::defineProperty(cx, obj, desc.id, desc.pd);
|
||||
return Reject(cx, JSMSG_OBJECT_NOT_EXTENSIBLE, throwError, rval);
|
||||
@ -2568,7 +2584,8 @@ JSObject*
|
||||
js_NewObjectWithClassProto(JSContext *cx, Class *clasp, JSObject *proto,
|
||||
const Value &privateSlotValue)
|
||||
{
|
||||
JS_ASSERT(clasp->isNative());
|
||||
JS_ASSERT(!clasp->getObjectOps);
|
||||
JS_ASSERT(proto->map->ops == &js_ObjectOps);
|
||||
|
||||
JSObject* obj = js_NewGCObject(cx);
|
||||
if (!obj)
|
||||
@ -2848,39 +2865,35 @@ with_ThisObject(JSContext *cx, JSObject *obj)
|
||||
return obj->getWithThis();
|
||||
}
|
||||
|
||||
JS_FRIEND_DATA(JSObjectOps) js_WithObjectOps = {
|
||||
NULL,
|
||||
with_LookupProperty,
|
||||
js_DefineProperty,
|
||||
with_GetProperty,
|
||||
with_SetProperty,
|
||||
with_GetAttributes,
|
||||
with_SetAttributes,
|
||||
with_DeleteProperty,
|
||||
with_Enumerate,
|
||||
with_TypeOf,
|
||||
js_TraceObject,
|
||||
with_ThisObject,
|
||||
js_Clear
|
||||
};
|
||||
|
||||
static JSObjectOps *
|
||||
with_getObjectOps(JSContext *cx, Class *clasp)
|
||||
{
|
||||
return &js_WithObjectOps;
|
||||
}
|
||||
|
||||
Class js_WithClass = {
|
||||
"With",
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_IS_ANONYMOUS,
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub,
|
||||
NULL, /* finalize */
|
||||
NULL, /* reserved */
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
NULL, /* hasInstance */
|
||||
NULL, /* mark */
|
||||
JS_NULL_CLASS_EXT,
|
||||
{
|
||||
with_LookupProperty,
|
||||
NULL, /* defineProperty */
|
||||
with_GetProperty,
|
||||
with_SetProperty,
|
||||
with_GetAttributes,
|
||||
with_SetAttributes,
|
||||
with_DeleteProperty,
|
||||
with_Enumerate,
|
||||
with_TypeOf,
|
||||
NULL, /* trace */
|
||||
with_ThisObject,
|
||||
NULL, /* clear */
|
||||
}
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, ConvertStub, NULL,
|
||||
with_getObjectOps,
|
||||
0,0,0,0,0,0,0
|
||||
};
|
||||
|
||||
JS_REQUIRES_STACK JSObject *
|
||||
@ -3227,13 +3240,9 @@ js_XDRBlockObject(JSXDRState *xdr, JSObject **objp)
|
||||
Class js_BlockClass = {
|
||||
"Block",
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_IS_ANONYMOUS,
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, ConvertStub, NULL,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
};
|
||||
|
||||
JSObject *
|
||||
@ -4462,7 +4471,7 @@ js_FindPropertyHelper(JSContext *cx, jsid id, JSBool cacheResult,
|
||||
for (scopeIndex = 0;
|
||||
parent
|
||||
? js_IsCacheableNonGlobalScope(obj)
|
||||
: !obj->getOps()->lookupProperty;
|
||||
: obj->map->ops->lookupProperty == js_LookupProperty;
|
||||
++scopeIndex) {
|
||||
protoIndex =
|
||||
js_LookupPropertyWithFlags(cx, obj, id, cx->resolveFlags,
|
||||
@ -4843,11 +4852,8 @@ js_GetMethod(JSContext *cx, JSObject *obj, jsid id, uintN getHow, Value *vp)
|
||||
{
|
||||
JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
|
||||
|
||||
PropertyIdOp op = obj->getOps()->getProperty;
|
||||
if (!op) {
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
JS_ASSERT(!obj->isXML());
|
||||
#endif
|
||||
if (obj->map->ops == &js_ObjectOps ||
|
||||
obj->map->ops->getProperty == js_GetProperty) {
|
||||
return js_GetPropertyHelper(cx, obj, id, getHow, vp);
|
||||
}
|
||||
JS_ASSERT_IF(getHow & JSGET_CACHE_RESULT, obj->isDenseArray());
|
||||
@ -4855,7 +4861,7 @@ js_GetMethod(JSContext *cx, JSObject *obj, jsid id, uintN getHow, Value *vp)
|
||||
if (obj->isXML())
|
||||
return js_GetXMLMethod(cx, obj, id, vp);
|
||||
#endif
|
||||
return op(cx, obj, id, vp);
|
||||
return obj->getProperty(cx, id, vp);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
@ -5375,7 +5381,7 @@ DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp)
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
JSBool
|
||||
js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, Value *statep, jsid *idp)
|
||||
{
|
||||
/* If the class has a custom JSCLASS_NEW_ENUMERATE hook, call it. */
|
||||
@ -5953,7 +5959,7 @@ js_TraceObject(JSTracer *trc, JSObject *obj)
|
||||
}
|
||||
|
||||
void
|
||||
js_ClearNative(JSContext *cx, JSObject *obj)
|
||||
js_Clear(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JSScope *scope;
|
||||
uint32 i, n;
|
||||
@ -6042,9 +6048,12 @@ js_SetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, const Value &v)
|
||||
JSObject *
|
||||
JSObject::wrappedObject(JSContext *cx) const
|
||||
{
|
||||
if (JSObjectOp op = getClass()->ext.wrappedObject) {
|
||||
if (JSObject *obj = op(cx, const_cast<JSObject *>(this)))
|
||||
return obj;
|
||||
Class *clasp = getClass();
|
||||
if (clasp->flags & JSCLASS_IS_EXTENDED) {
|
||||
if (JSObjectOp wrappedObject = reinterpret_cast<JSExtendedClass *>(clasp)->wrappedObject) {
|
||||
if (JSObject *obj = wrappedObject(cx, const_cast<JSObject *>(this)))
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
return const_cast<JSObject *>(this);
|
||||
}
|
||||
@ -6080,7 +6089,7 @@ JSObject::getCompartment(JSContext *cx)
|
||||
return cx->runtime->defaultCompartment;
|
||||
|
||||
// The magic function namespace object is runtime-wide.
|
||||
if (clasp == &js_NamespaceClass &&
|
||||
if (clasp == &js_NamespaceClass.base &&
|
||||
obj->getNameURI() == ATOM_TO_JSVAL(cx->runtime->atomState.lazy.functionNamespaceURIAtom)) {
|
||||
return cx->runtime->defaultCompartment;
|
||||
}
|
||||
|
211
js/src/jsobj.h
211
js/src/jsobj.h
@ -170,62 +170,73 @@ namespace js {
|
||||
|
||||
typedef Vector<PropDesc, 1> PropDescArray;
|
||||
|
||||
/*
|
||||
* Flag and type-safe cast helper to denote that Class::call is a fast native.
|
||||
*/
|
||||
const uint32 CLASS_CALL_IS_FAST = uint32(1) << (JSCLASS_LAST_API_FLAG_SHIFT + 1);
|
||||
|
||||
inline Native CastCallOpAsNative(CallOp op)
|
||||
{
|
||||
return reinterpret_cast<Native>(op);
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
struct JSObjectMap {
|
||||
static JS_FRIEND_DATA(const JSObjectMap) sharedNonNative;
|
||||
/* For detailed comments on these function pointer types, see jsprvtd.h. */
|
||||
struct JSObjectOps {
|
||||
/*
|
||||
* Custom shared object map for non-native objects. For native objects
|
||||
* this should be null indicating, that JSObject.map is an instance of
|
||||
* JSScope.
|
||||
*/
|
||||
const JSObjectMap *objectMap;
|
||||
|
||||
/* Mandatory non-null function pointer members. */
|
||||
JSLookupPropOp lookupProperty;
|
||||
js::DefinePropOp defineProperty;
|
||||
js::PropertyIdOp getProperty;
|
||||
js::PropertyIdOp setProperty;
|
||||
JSAttributesOp getAttributes;
|
||||
JSAttributesOp setAttributes;
|
||||
js::PropertyIdOp deleteProperty;
|
||||
js::NewEnumerateOp enumerate;
|
||||
JSTypeOfOp typeOf;
|
||||
JSTraceOp trace;
|
||||
|
||||
/* Optionally non-null members start here. */
|
||||
JSObjectOp thisObject;
|
||||
JSFinalizeOp clear;
|
||||
|
||||
bool inline isNative() const;
|
||||
};
|
||||
|
||||
extern JS_FRIEND_DATA(JSObjectOps) js_ObjectOps;
|
||||
extern JS_FRIEND_DATA(JSObjectOps) js_WithObjectOps;
|
||||
|
||||
/*
|
||||
* Test whether the ops is native. FIXME bug 492938: consider how it would
|
||||
* affect the performance to do just the !objectMap check.
|
||||
*/
|
||||
inline bool
|
||||
JSObjectOps::isNative() const
|
||||
{
|
||||
return JS_LIKELY(this == &js_ObjectOps) || !objectMap;
|
||||
}
|
||||
|
||||
struct JSObjectMap {
|
||||
const JSObjectOps * const ops; /* high level object operation vtable */
|
||||
uint32 shape; /* shape identifier */
|
||||
|
||||
explicit JSObjectMap(uint32 shape) : shape(shape) {}
|
||||
explicit JSObjectMap(const JSObjectOps *ops, uint32 shape) : ops(ops), shape(shape) {}
|
||||
|
||||
enum { SHAPELESS = 0xffffffff };
|
||||
|
||||
bool isNative() const { return this != &sharedNonNative; }
|
||||
|
||||
private:
|
||||
private:
|
||||
/* No copy or assignment semantics. */
|
||||
JSObjectMap(JSObjectMap &);
|
||||
void operator=(JSObjectMap &);
|
||||
};
|
||||
|
||||
/*
|
||||
* Unlike js_DefineNativeProperty, propp must be non-null. On success, and if
|
||||
* id was found, return true with *objp non-null and locked, and with a held
|
||||
* property stored in *propp. If successful but id was not found, return true
|
||||
* with both *objp and *propp null. Therefore all callers who receive a
|
||||
* non-null *propp must later call (*objp)->dropProperty(cx, *propp).
|
||||
*/
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
|
||||
JSProperty **propp);
|
||||
|
||||
extern JSBool
|
||||
js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, const js::Value *value,
|
||||
js::PropertyOp getter, js::PropertyOp setter, uintN attrs);
|
||||
|
||||
extern JSBool
|
||||
js_GetProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
|
||||
|
||||
extern JSBool
|
||||
js_SetProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
|
||||
|
||||
extern JSBool
|
||||
js_GetAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp);
|
||||
|
||||
extern JSBool
|
||||
js_SetAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp);
|
||||
|
||||
extern JSBool
|
||||
js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *rval);
|
||||
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
||||
js::Value *statep, jsid *idp);
|
||||
|
||||
extern JSType
|
||||
js_TypeOf(JSContext *cx, JSObject *obj);
|
||||
|
||||
struct NativeIterator;
|
||||
|
||||
const uint32 JS_INITIAL_NSLOTS = 4;
|
||||
@ -291,9 +302,7 @@ struct JSObject {
|
||||
#endif
|
||||
js::Value fslots[JS_INITIAL_NSLOTS]; /* small number of fixed slots */
|
||||
|
||||
bool isNative() const {
|
||||
return map->isNative();
|
||||
}
|
||||
bool isNative() const { return map->ops->isNative(); }
|
||||
|
||||
js::Class *getClass() const {
|
||||
return clasp;
|
||||
@ -307,10 +316,6 @@ struct JSObject {
|
||||
return c == clasp;
|
||||
}
|
||||
|
||||
const js::ObjectOps *getOps() const {
|
||||
return &getClass()->ops;
|
||||
}
|
||||
|
||||
inline JSScope *scope() const;
|
||||
inline uint32 shape() const;
|
||||
|
||||
@ -682,62 +687,53 @@ struct JSObject {
|
||||
/* This method can only be called when hasSlotsArray() returns true. */
|
||||
inline void freeSlotsArray(JSContext *cx);
|
||||
|
||||
JSBool lookupProperty(JSContext *cx, jsid id, JSObject **objp, JSProperty **propp) {
|
||||
JSLookupPropOp op = getOps()->lookupProperty;
|
||||
return (op ? op : js_LookupProperty)(cx, this, id, objp, propp);
|
||||
JSBool lookupProperty(JSContext *cx, jsid id,
|
||||
JSObject **objp, JSProperty **propp) {
|
||||
return map->ops->lookupProperty(cx, this, id, objp, propp);
|
||||
}
|
||||
|
||||
JSBool defineProperty(JSContext *cx, jsid id, const js::Value &value,
|
||||
js::PropertyOp getter = js::PropertyStub,
|
||||
js::PropertyOp setter = js::PropertyStub,
|
||||
uintN attrs = JSPROP_ENUMERATE) {
|
||||
js::DefinePropOp op = getOps()->defineProperty;
|
||||
return (op ? op : js_DefineProperty)(cx, this, id, &value, getter, setter, attrs);
|
||||
return map->ops->defineProperty(cx, this, id, &value, getter, setter, attrs);
|
||||
}
|
||||
|
||||
JSBool getProperty(JSContext *cx, jsid id, js::Value *vp) {
|
||||
js::PropertyIdOp op = getOps()->getProperty;
|
||||
return (op ? op : js_GetProperty)(cx, this, id, vp);
|
||||
return map->ops->getProperty(cx, this, id, vp);
|
||||
}
|
||||
|
||||
JSBool setProperty(JSContext *cx, jsid id, js::Value *vp) {
|
||||
js::PropertyIdOp op = getOps()->setProperty;
|
||||
return (op ? op : js_SetProperty)(cx, this, id, vp);
|
||||
return map->ops->setProperty(cx, this, id, vp);
|
||||
}
|
||||
|
||||
JSBool getAttributes(JSContext *cx, jsid id, uintN *attrsp) {
|
||||
JSAttributesOp op = getOps()->getAttributes;
|
||||
return (op ? op : js_GetAttributes)(cx, this, id, attrsp);
|
||||
return map->ops->getAttributes(cx, this, id, attrsp);
|
||||
}
|
||||
|
||||
JSBool setAttributes(JSContext *cx, jsid id, uintN *attrsp) {
|
||||
JSAttributesOp op = getOps()->setAttributes;
|
||||
return (op ? op : js_SetAttributes)(cx, this, id, attrsp);
|
||||
return map->ops->setAttributes(cx, this, id, attrsp);
|
||||
}
|
||||
|
||||
JSBool deleteProperty(JSContext *cx, jsid id, js::Value *rval) {
|
||||
js::PropertyIdOp op = getOps()->deleteProperty;
|
||||
return (op ? op : js_DeleteProperty)(cx, this, id, rval);
|
||||
return map->ops->deleteProperty(cx, this, id, rval);
|
||||
}
|
||||
|
||||
JSBool enumerate(JSContext *cx, JSIterateOp iterop, js::Value *statep, jsid *idp) {
|
||||
js::NewEnumerateOp op = getOps()->enumerate;
|
||||
return (op ? op : js_Enumerate)(cx, this, iterop, statep, idp);
|
||||
JSBool enumerate(JSContext *cx, JSIterateOp op, js::Value *statep,
|
||||
jsid *idp) {
|
||||
return map->ops->enumerate(cx, this, op, statep, idp);
|
||||
}
|
||||
|
||||
JSType typeOf(JSContext *cx) {
|
||||
JSTypeOfOp op = getOps()->typeOf;
|
||||
return (op ? op : js_TypeOf)(cx, this);
|
||||
return map->ops->typeOf(cx, this);
|
||||
}
|
||||
|
||||
JSObject *wrappedObject(JSContext *cx) const;
|
||||
|
||||
/* These four are time-optimized to avoid stub calls. */
|
||||
JSObject *thisObject(JSContext *cx) {
|
||||
JSObjectOp op = getOps()->thisObject;
|
||||
return op ? op(cx, this) : this;
|
||||
return map->ops->thisObject ? map->ops->thisObject(cx, this) : this;
|
||||
}
|
||||
|
||||
static bool thisObject(JSContext *cx, const js::Value &v, js::Value *vp);
|
||||
|
||||
inline void dropProperty(JSContext *cx, JSProperty *prop);
|
||||
@ -818,8 +814,12 @@ JS_STATIC_ASSERT(sizeof(JSObject) % JS_GCTHING_ALIGN == 0);
|
||||
inline void
|
||||
OBJ_TO_INNER_OBJECT(JSContext *cx, JSObject *&obj)
|
||||
{
|
||||
if (JSObjectOp op = obj->getClass()->ext.innerObject)
|
||||
obj = op(cx, obj);
|
||||
js::Class *clasp = obj->getClass();
|
||||
if (clasp->flags & JSCLASS_IS_EXTENDED) {
|
||||
js::ExtendedClass *xclasp = (js::ExtendedClass *) clasp;
|
||||
if (xclasp->innerObject)
|
||||
obj = xclasp->innerObject(cx, obj);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -829,8 +829,12 @@ OBJ_TO_INNER_OBJECT(JSContext *cx, JSObject *&obj)
|
||||
inline void
|
||||
OBJ_TO_OUTER_OBJECT(JSContext *cx, JSObject *&obj)
|
||||
{
|
||||
if (JSObjectOp op = obj->getClass()->ext.outerObject)
|
||||
obj = op(cx, obj);
|
||||
js::Class *clasp = obj->getClass();
|
||||
if (clasp->flags & JSCLASS_IS_EXTENDED) {
|
||||
js::ExtendedClass *xclasp = (js::ExtendedClass *) clasp;
|
||||
if (xclasp->outerObject)
|
||||
obj = xclasp->outerObject(cx, obj);
|
||||
}
|
||||
}
|
||||
|
||||
class JSValueArray {
|
||||
@ -1072,12 +1076,14 @@ js_CheckForStringIndex(jsid id);
|
||||
extern void
|
||||
js_PurgeScopeChainHelper(JSContext *cx, JSObject *obj, jsid id);
|
||||
|
||||
inline void
|
||||
#ifdef __cplusplus /* Aargh, libgjs, bug 492720. */
|
||||
static JS_INLINE void
|
||||
js_PurgeScopeChain(JSContext *cx, JSObject *obj, jsid id)
|
||||
{
|
||||
if (obj->isDelegate())
|
||||
js_PurgeScopeChainHelper(cx, obj, id);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Find or create a property named by id in obj's scope, with the given getter
|
||||
@ -1098,6 +1104,10 @@ js_ChangeNativePropertyAttrs(JSContext *cx, JSObject *obj,
|
||||
JSScopeProperty *sprop, uintN attrs, uintN mask,
|
||||
js::PropertyOp getter, js::PropertyOp setter);
|
||||
|
||||
extern JSBool
|
||||
js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, const js::Value *value,
|
||||
js::PropertyOp getter, js::PropertyOp setter, uintN attrs);
|
||||
|
||||
extern JSBool
|
||||
js_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id,
|
||||
const js::Value &descriptor, JSBool *bp);
|
||||
@ -1127,6 +1137,17 @@ js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const js::Value &
|
||||
uintN flags, intN shortid, JSProperty **propp,
|
||||
uintN defineHow = 0);
|
||||
|
||||
/*
|
||||
* Unlike js_DefineNativeProperty, propp must be non-null. On success, and if
|
||||
* id was found, return true with *objp non-null and locked, and with a held
|
||||
* property stored in *propp. If successful but id was not found, return true
|
||||
* with both *objp and *propp null. Therefore all callers who receive a
|
||||
* non-null *propp must later call (*objp)->dropProperty(cx, *propp).
|
||||
*/
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
|
||||
JSProperty **propp);
|
||||
|
||||
/*
|
||||
* Specialized subroutine that allows caller to preset JSRESOLVE_* flags and
|
||||
* returns the index along the prototype chain in which *propp was found, or
|
||||
@ -1142,7 +1163,7 @@ js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
||||
* non-global objects without prototype or with prototype that never mutates,
|
||||
* see bug 462734 and bug 487039.
|
||||
*/
|
||||
inline bool
|
||||
static inline bool
|
||||
js_IsCacheableNonGlobalScope(JSObject *obj)
|
||||
{
|
||||
extern JS_FRIEND_DATA(js::Class) js_CallClass;
|
||||
@ -1154,7 +1175,7 @@ js_IsCacheableNonGlobalScope(JSObject *obj)
|
||||
clasp == &js_BlockClass ||
|
||||
clasp == &js_DeclEnvClass);
|
||||
|
||||
JS_ASSERT_IF(cacheable, !obj->getOps()->lookupProperty);
|
||||
JS_ASSERT_IF(cacheable, obj->map->ops->lookupProperty == js_LookupProperty);
|
||||
return cacheable;
|
||||
}
|
||||
|
||||
@ -1214,6 +1235,9 @@ extern JSBool
|
||||
js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN getHow,
|
||||
js::Value *vp);
|
||||
|
||||
extern JSBool
|
||||
js_GetProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
|
||||
|
||||
extern JSBool
|
||||
js_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
|
||||
|
||||
@ -1233,6 +1257,15 @@ extern JSBool
|
||||
js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
|
||||
js::Value *vp);
|
||||
|
||||
extern JSBool
|
||||
js_SetProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
|
||||
|
||||
extern JSBool
|
||||
js_GetAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp);
|
||||
|
||||
extern JSBool
|
||||
js_SetAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp);
|
||||
|
||||
/*
|
||||
* Change attributes for the given native property. The caller must ensure
|
||||
* that obj is locked and this function always unlocks obj on return.
|
||||
@ -1241,16 +1274,30 @@ extern JSBool
|
||||
js_SetNativeAttributes(JSContext *cx, JSObject *obj, JSScopeProperty *sprop,
|
||||
uintN attrs);
|
||||
|
||||
extern JSBool
|
||||
js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *rval);
|
||||
|
||||
namespace js {
|
||||
|
||||
extern JSBool
|
||||
DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp);
|
||||
|
||||
}
|
||||
|
||||
extern JSBool
|
||||
js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
||||
js::Value *statep, jsid *idp);
|
||||
|
||||
namespace js {
|
||||
|
||||
extern JSBool
|
||||
CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
|
||||
js::Value *vp, uintN *attrsp);
|
||||
|
||||
} /* namespace js */
|
||||
}
|
||||
|
||||
extern JSType
|
||||
js_TypeOf(JSContext *cx, JSObject *obj);
|
||||
|
||||
extern bool
|
||||
js_IsDelegate(JSContext *cx, JSObject *obj, const js::Value &v);
|
||||
@ -1305,7 +1352,7 @@ extern void
|
||||
js_PrintObjectSlotName(JSTracer *trc, char *buf, size_t bufsize);
|
||||
|
||||
extern void
|
||||
js_ClearNative(JSContext *cx, JSObject *obj);
|
||||
js_Clear(JSContext *cx, JSObject *obj);
|
||||
|
||||
extern bool
|
||||
js_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, js::Value *vp);
|
||||
|
@ -493,9 +493,9 @@ class AutoPropertyDescriptorRooter : private AutoGCRooter, public PropertyDescri
|
||||
};
|
||||
|
||||
static inline bool
|
||||
InitScopeForObject(JSContext* cx, JSObject* obj, js::Class *clasp, JSObject* proto)
|
||||
InitScopeForObject(JSContext* cx, JSObject* obj, js::Class *clasp, JSObject* proto, JSObjectOps* ops)
|
||||
{
|
||||
JS_ASSERT(clasp->isNative());
|
||||
JS_ASSERT(ops->isNative());
|
||||
JS_ASSERT(proto == obj->getProto());
|
||||
|
||||
/* Share proto's emptyScope only if obj is similar to proto. */
|
||||
@ -504,7 +504,7 @@ InitScopeForObject(JSContext* cx, JSObject* obj, js::Class *clasp, JSObject* pro
|
||||
if (proto && proto->isNative()) {
|
||||
JS_LOCK_OBJ(cx, proto);
|
||||
scope = proto->scope();
|
||||
if (scope->canProvideEmptyScope(clasp)) {
|
||||
if (scope->canProvideEmptyScope(ops, clasp)) {
|
||||
JSScope *emptyScope = scope->getEmptyScope(cx, clasp);
|
||||
JS_UNLOCK_SCOPE(cx, scope);
|
||||
if (!emptyScope)
|
||||
@ -517,7 +517,7 @@ InitScopeForObject(JSContext* cx, JSObject* obj, js::Class *clasp, JSObject* pro
|
||||
}
|
||||
|
||||
if (!scope) {
|
||||
scope = JSScope::create(cx, clasp, obj, js_GenerateShape(cx, false));
|
||||
scope = JSScope::create(cx, ops, clasp, obj, js_GenerateShape(cx, false));
|
||||
if (!scope)
|
||||
goto bad;
|
||||
uint32 freeslot = JSSLOT_FREE(clasp);
|
||||
@ -570,7 +570,7 @@ NewNativeClassInstance(JSContext *cx, Class *clasp, JSObject *proto, JSObject *p
|
||||
|
||||
JS_LOCK_OBJ(cx, proto);
|
||||
JSScope *scope = proto->scope();
|
||||
JS_ASSERT(scope->canProvideEmptyScope(clasp));
|
||||
JS_ASSERT(scope->canProvideEmptyScope(&js_ObjectOps, clasp));
|
||||
scope = scope->getEmptyScope(cx, clasp);
|
||||
JS_UNLOCK_OBJ(cx, proto);
|
||||
|
||||
@ -638,6 +638,11 @@ NewObjectWithGivenProto(JSContext *cx, Class *clasp, JSObject *proto, JSObject *
|
||||
{
|
||||
DTrace::ObjectCreationScope objectCreationScope(cx, cx->fp, clasp);
|
||||
|
||||
/* Always call the class's getObjectOps hook if it has one. */
|
||||
JSObjectOps *ops = clasp->getObjectOps
|
||||
? clasp->getObjectOps(cx, clasp)
|
||||
: &js_ObjectOps;
|
||||
|
||||
/*
|
||||
* Allocate an object from the GC heap and initialize all its fields before
|
||||
* doing any operation that can potentially trigger GC. Functions have a
|
||||
@ -667,13 +672,14 @@ NewObjectWithGivenProto(JSContext *cx, Class *clasp, JSObject *proto, JSObject *
|
||||
(!parent && proto) ? proto->getParent() : parent,
|
||||
JSObject::defaultPrivate(clasp));
|
||||
|
||||
if (clasp->isNative()) {
|
||||
if (!InitScopeForObject(cx, obj, clasp, proto)) {
|
||||
if (ops->isNative()) {
|
||||
if (!InitScopeForObject(cx, obj, clasp, proto, ops)) {
|
||||
obj = NULL;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
obj->map = const_cast<JSObjectMap *>(&JSObjectMap::sharedNonNative);
|
||||
JS_ASSERT(ops->objectMap->ops == ops);
|
||||
obj->map = const_cast<JSObjectMap *>(ops->objectMap);
|
||||
}
|
||||
|
||||
out:
|
||||
|
@ -99,13 +99,9 @@ struct JSONParser
|
||||
Class js_JSONClass = {
|
||||
js_JSON_str,
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_JSON),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, ConvertStub, NULL,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
};
|
||||
|
||||
JSBool
|
||||
|
@ -905,6 +905,12 @@ proxy_TraceObject(JSTracer *trc, JSObject *obj)
|
||||
}
|
||||
}
|
||||
|
||||
static JSType
|
||||
proxy_TypeOf_obj(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return JSTYPE_OBJECT;
|
||||
}
|
||||
|
||||
void
|
||||
proxy_Finalize(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
@ -913,39 +919,51 @@ proxy_Finalize(JSContext *cx, JSObject *obj)
|
||||
obj->getProxyHandler()->finalize(cx, obj);
|
||||
}
|
||||
|
||||
extern JSObjectOps js_ObjectProxyObjectOps;
|
||||
|
||||
static const JSObjectMap SharedObjectProxyMap(&js_ObjectProxyObjectOps, JSObjectMap::SHAPELESS);
|
||||
|
||||
JSObjectOps js_ObjectProxyObjectOps = {
|
||||
&SharedObjectProxyMap,
|
||||
proxy_LookupProperty,
|
||||
proxy_DefineProperty,
|
||||
proxy_GetProperty,
|
||||
proxy_SetProperty,
|
||||
proxy_GetAttributes,
|
||||
proxy_SetAttributes,
|
||||
proxy_DeleteProperty,
|
||||
js_Enumerate,
|
||||
proxy_TypeOf_obj,
|
||||
proxy_TraceObject,
|
||||
NULL, /* thisObject */
|
||||
proxy_Finalize
|
||||
};
|
||||
|
||||
static JSObjectOps *
|
||||
obj_proxy_getObjectOps(JSContext *cx, Class *clasp)
|
||||
{
|
||||
return &js_ObjectProxyObjectOps;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(Class) ObjectProxyClass = {
|
||||
"Proxy",
|
||||
Class::NON_NATIVE | JSCLASS_HAS_RESERVED_SLOTS(2),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
JSCLASS_HAS_RESERVED_SLOTS(2),
|
||||
PropertyStub,
|
||||
PropertyStub,
|
||||
PropertyStub,
|
||||
PropertyStub,
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub,
|
||||
NULL, /* finalize */
|
||||
NULL, /* reserved0 */
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
NULL, /* hasInstance */
|
||||
NULL, /* mark */
|
||||
JS_NULL_CLASS_EXT,
|
||||
{
|
||||
proxy_LookupProperty,
|
||||
proxy_DefineProperty,
|
||||
proxy_GetProperty,
|
||||
proxy_SetProperty,
|
||||
proxy_GetAttributes,
|
||||
proxy_SetAttributes,
|
||||
proxy_DeleteProperty,
|
||||
NULL, /* enumerate */
|
||||
NULL, /* typeof */
|
||||
proxy_TraceObject,
|
||||
NULL, /* thisObject */
|
||||
proxy_Finalize, /* clear */
|
||||
}
|
||||
NULL,
|
||||
obj_proxy_getObjectOps,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
JSBool
|
||||
@ -970,41 +988,53 @@ proxy_TypeOf_fun(JSContext *cx, JSObject *obj)
|
||||
return JSTYPE_FUNCTION;
|
||||
}
|
||||
|
||||
extern JSObjectOps js_FunctionProxyObjectOps;
|
||||
|
||||
static const JSObjectMap SharedFunctionProxyMap(&js_FunctionProxyObjectOps, JSObjectMap::SHAPELESS);
|
||||
|
||||
#define proxy_HasInstance js_FunctionClass.hasInstance
|
||||
|
||||
JSObjectOps js_FunctionProxyObjectOps = {
|
||||
&SharedFunctionProxyMap,
|
||||
proxy_LookupProperty,
|
||||
proxy_DefineProperty,
|
||||
proxy_GetProperty,
|
||||
proxy_SetProperty,
|
||||
proxy_GetAttributes,
|
||||
proxy_SetAttributes,
|
||||
proxy_DeleteProperty,
|
||||
js_Enumerate,
|
||||
proxy_TypeOf_fun,
|
||||
proxy_TraceObject,
|
||||
NULL, /* thisObject */
|
||||
NULL /* clear */
|
||||
};
|
||||
|
||||
static JSObjectOps *
|
||||
fun_proxy_getObjectOps(JSContext *cx, Class *clasp)
|
||||
{
|
||||
return &js_FunctionProxyObjectOps;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(Class) FunctionProxyClass = {
|
||||
"Proxy",
|
||||
Class::NON_NATIVE | JSCLASS_HAS_RESERVED_SLOTS(4) | Class::CALL_IS_FAST,
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
JSCLASS_HAS_RESERVED_SLOTS(4) | CLASS_CALL_IS_FAST,
|
||||
PropertyStub,
|
||||
PropertyStub,
|
||||
PropertyStub,
|
||||
PropertyStub,
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub,
|
||||
NULL, /* finalize */
|
||||
NULL, /* reserved0 */
|
||||
NULL, /* checkAccess */
|
||||
NULL,
|
||||
fun_proxy_getObjectOps,
|
||||
NULL,
|
||||
CastCallOpAsNative(proxy_Call),
|
||||
proxy_Construct,
|
||||
NULL, /* xdrObject */
|
||||
NULL,
|
||||
proxy_HasInstance,
|
||||
NULL, /* mark */
|
||||
JS_NULL_CLASS_EXT,
|
||||
{
|
||||
proxy_LookupProperty,
|
||||
proxy_DefineProperty,
|
||||
proxy_GetProperty,
|
||||
proxy_SetProperty,
|
||||
proxy_GetAttributes,
|
||||
proxy_SetAttributes,
|
||||
proxy_DeleteProperty,
|
||||
NULL, /* enumerate */
|
||||
proxy_TypeOf_fun,
|
||||
proxy_TraceObject,
|
||||
NULL, /* thisObject */
|
||||
NULL, /* clear */
|
||||
}
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
JS_FRIEND_API(JSObject *)
|
||||
@ -1213,18 +1243,10 @@ callable_Construct(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value
|
||||
Class CallableObjectClass = {
|
||||
"Function",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(2),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub,
|
||||
NULL, /* finalize */
|
||||
NULL, /* reserved0 */
|
||||
NULL, /* checkAccess */
|
||||
callable_Call,
|
||||
callable_Construct,
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, ConvertStub, NULL,
|
||||
NULL, NULL, callable_Call, callable_Construct,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
@ -1282,13 +1304,9 @@ FixProxy(JSContext *cx, JSObject *proxy, JSBool *bp)
|
||||
Class js_ProxyClass = {
|
||||
"Proxy",
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Proxy),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, ConvertStub, NULL,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
};
|
||||
|
||||
JS_FRIEND_API(JSObject *)
|
||||
|
@ -345,20 +345,6 @@ typedef JSBool
|
||||
typedef JSBool
|
||||
(* JSCallOp)(JSContext *cx, uintN argc, jsval *vp);
|
||||
|
||||
/*
|
||||
* A generic type for functions mapping an object to another object, or null
|
||||
* if an error or exception was thrown on cx.
|
||||
*/
|
||||
typedef JSObject *
|
||||
(* JSObjectOp)(JSContext *cx, JSObject *obj);
|
||||
|
||||
/*
|
||||
* Hook that creates an iterator object for a given object. Returns the
|
||||
* iterator object or null if an error or exception was thrown on cx.
|
||||
*/
|
||||
typedef JSObject *
|
||||
(* JSIteratorOp)(JSContext *cx, JSObject *obj, JSBool keysonly);
|
||||
|
||||
/*
|
||||
* The following determines whether JS_EncodeCharacters and JS_DecodeBytes
|
||||
* treat char[] as utf-8 or simply as bytes that need to be inflated/deflated.
|
||||
@ -369,13 +355,6 @@ typedef JSObject *
|
||||
extern JSBool js_CStringsAreUTF8;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Hack to expose obj->getOps()->outer to the C implementation of the debugger
|
||||
* interface.
|
||||
*/
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
js_ObjectToOuterObject(JSContext *cx, JSObject *obj);
|
||||
|
||||
JS_END_EXTERN_C
|
||||
|
||||
#endif /* jsprvtd_h___ */
|
||||
|
@ -107,7 +107,7 @@ typedef enum JSProtoKey {
|
||||
JSProto_LIMIT
|
||||
} JSProtoKey;
|
||||
|
||||
/* js_CheckAccess mode enumeration. */
|
||||
/* JSObjectOps.checkAccess mode enumeration. */
|
||||
typedef enum JSAccessMode {
|
||||
JSACC_PROTO = 0, /* XXXbe redundant w.r.t. id */
|
||||
JSACC_PARENT = 1, /* XXXbe redundant w.r.t. id */
|
||||
@ -145,6 +145,7 @@ typedef enum JSIterateOp {
|
||||
|
||||
/* Struct typedefs. */
|
||||
typedef struct JSClass JSClass;
|
||||
typedef struct JSExtendedClass JSExtendedClass;
|
||||
typedef struct JSConstDoubleSpec JSConstDoubleSpec;
|
||||
typedef struct JSContext JSContext;
|
||||
typedef struct JSErrorReport JSErrorReport;
|
||||
@ -155,6 +156,7 @@ typedef struct JSIdArray JSIdArray;
|
||||
typedef struct JSPropertyDescriptor JSPropertyDescriptor;
|
||||
typedef struct JSPropertySpec JSPropertySpec;
|
||||
typedef struct JSObjectMap JSObjectMap;
|
||||
typedef struct JSObjectOps JSObjectOps;
|
||||
typedef struct JSRuntime JSRuntime;
|
||||
typedef struct JSScript JSScript;
|
||||
typedef struct JSStackFrame JSStackFrame;
|
||||
@ -301,6 +303,29 @@ typedef void
|
||||
typedef void
|
||||
(* JSStringFinalizeOp)(JSContext *cx, JSString *str);
|
||||
|
||||
/*
|
||||
* The signature for JSClass.getObjectOps, used by JS_NewObject's internals
|
||||
* to discover the set of high-level object operations to use for new objects
|
||||
* of the given class. All native objects have a JSClass, which is stored as
|
||||
* a private (int-tagged) pointer in obj slots. In contrast, all native and
|
||||
* host objects have a JSObjectMap at obj->map, which may be shared among a
|
||||
* number of objects, and which contains the JSObjectOps *ops pointer used to
|
||||
* dispatch object operations from API calls.
|
||||
*
|
||||
* Thus JSClass (which pre-dates JSObjectOps in the API) provides a low-level
|
||||
* interface to class-specific code and data, while JSObjectOps allows for a
|
||||
* higher level of operation, which does not use the object's class except to
|
||||
* find the class's JSObjectOps struct, by calling clasp->getObjectOps, and to
|
||||
* finalize the object.
|
||||
*
|
||||
* If this seems backwards, that's because it is! API compatibility requires
|
||||
* a JSClass *clasp parameter to JS_NewObject, etc. Most host objects do not
|
||||
* need to implement the larger JSObjectOps, and can share the common JSScope
|
||||
* code and data used by the native (js_ObjectOps, see jsobj.c) ops.
|
||||
*/
|
||||
typedef JSObjectOps *
|
||||
(* JSGetObjectOps)(JSContext *cx, JSClass *clasp);
|
||||
|
||||
/*
|
||||
* JSClass.checkAccess type: check whether obj[id] may be accessed per mode,
|
||||
* returning false on error/exception, true on success with obj[id]'s last-got
|
||||
@ -393,9 +418,26 @@ typedef void
|
||||
typedef void
|
||||
(* JSTraceNamePrinter)(JSTracer *trc, char *buf, size_t bufsize);
|
||||
|
||||
/* JSExtendedClass function pointer typedefs. */
|
||||
|
||||
typedef JSBool
|
||||
(* JSEqualityOp)(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp);
|
||||
|
||||
/*
|
||||
* A generic type for functions mapping an object to another object, or null
|
||||
* if an error or exception was thrown on cx. Used by JSObjectOps.thisObject
|
||||
* at present.
|
||||
*/
|
||||
typedef JSObject *
|
||||
(* JSObjectOp)(JSContext *cx, JSObject *obj);
|
||||
|
||||
/*
|
||||
* Hook that creates an iterator object for a given object. Returns the
|
||||
* iterator object or null if an error or exception was thrown on cx.
|
||||
*/
|
||||
typedef JSObject *
|
||||
(* JSIteratorOp)(JSContext *cx, JSObject *obj, JSBool keysonly);
|
||||
|
||||
/* Typedef for native functions called by the JS VM. */
|
||||
|
||||
typedef JSBool
|
||||
|
@ -5417,21 +5417,14 @@ Class js_RegExpClass = {
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE |
|
||||
JSCLASS_HAS_RESERVED_SLOTS(JSObject::REGEXP_FIXED_RESERVED_SLOTS) |
|
||||
JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_RegExp),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
regexp_enumerate,
|
||||
reinterpret_cast<JSResolveOp>(regexp_resolve),
|
||||
ConvertStub,
|
||||
regexp_finalize,
|
||||
NULL, /* reserved0 */
|
||||
NULL, /* checkAccess */
|
||||
regexp_call,
|
||||
NULL, /* construct */
|
||||
js_XDRRegExpObject,
|
||||
NULL, /* hasInstance */
|
||||
JS_CLASS_TRACE(regexp_trace)
|
||||
PropertyStub, PropertyStub,
|
||||
PropertyStub, PropertyStub,
|
||||
regexp_enumerate, reinterpret_cast<JSResolveOp>(regexp_resolve),
|
||||
ConvertStub, regexp_finalize,
|
||||
NULL, NULL,
|
||||
regexp_call, NULL,
|
||||
js_XDRRegExpObject, NULL,
|
||||
JS_CLASS_TRACE(regexp_trace), 0
|
||||
};
|
||||
|
||||
static const jschar empty_regexp_ucstr[] = {'(', '?', ':', ')', 0};
|
||||
|
@ -99,7 +99,7 @@ js_GetMutableScope(JSContext *cx, JSObject *obj)
|
||||
if (!scope->isSharedEmpty())
|
||||
return scope;
|
||||
|
||||
JSScope *newscope = JSScope::create(cx, obj->getClass(), obj, scope->shape);
|
||||
JSScope *newscope = JSScope::create(cx, scope->ops, obj->getClass(), obj, scope->shape);
|
||||
if (!newscope)
|
||||
return NULL;
|
||||
|
||||
@ -211,11 +211,13 @@ JSScope::createTable(JSContext *cx, bool report)
|
||||
}
|
||||
|
||||
JSScope *
|
||||
JSScope::create(JSContext *cx, Class *clasp, JSObject *obj, uint32 shape)
|
||||
JSScope::create(JSContext *cx, const JSObjectOps *ops, Class *clasp,
|
||||
JSObject *obj, uint32 shape)
|
||||
{
|
||||
JS_ASSERT(ops->isNative());
|
||||
JS_ASSERT(obj);
|
||||
|
||||
JSScope *scope = cx->create<JSScope>(obj);
|
||||
JSScope *scope = cx->create<JSScope>(ops, obj);
|
||||
if (!scope)
|
||||
return NULL;
|
||||
|
||||
@ -231,8 +233,9 @@ JSScope::create(JSContext *cx, Class *clasp, JSObject *obj, uint32 shape)
|
||||
return scope;
|
||||
}
|
||||
|
||||
JSEmptyScope::JSEmptyScope(JSContext *cx, Class *clasp)
|
||||
: JSScope(NULL), clasp(clasp)
|
||||
JSEmptyScope::JSEmptyScope(JSContext *cx, const JSObjectOps *ops,
|
||||
Class *clasp)
|
||||
: JSScope(ops, NULL), clasp(clasp)
|
||||
{
|
||||
/*
|
||||
* This scope holds a reference to the new empty scope. Our only caller,
|
||||
@ -287,14 +290,14 @@ JSScope::initRuntimeState(JSContext *cx)
|
||||
#define SCOPE(Name) rt->empty##Name##Scope
|
||||
#define CLASP(Name) &js_##Name##Class
|
||||
|
||||
#define INIT_EMPTY_SCOPE(Name,NAME) \
|
||||
INIT_EMPTY_SCOPE_WITH_CLASS(Name, NAME, CLASP(Name))
|
||||
#define INIT_EMPTY_SCOPE(Name,NAME,ops) \
|
||||
INIT_EMPTY_SCOPE_WITH_CLASS(Name, NAME, ops, CLASP(Name))
|
||||
|
||||
#define INIT_EMPTY_SCOPE_WITH_CLASS(Name,NAME,clasp) \
|
||||
INIT_EMPTY_SCOPE_WITH_FREESLOT(Name, NAME, clasp, JSSLOT_FREE(clasp))
|
||||
#define INIT_EMPTY_SCOPE_WITH_CLASS(Name,NAME,ops,clasp) \
|
||||
INIT_EMPTY_SCOPE_WITH_FREESLOT(Name, NAME, ops, clasp, JSSLOT_FREE(clasp))
|
||||
|
||||
#define INIT_EMPTY_SCOPE_WITH_FREESLOT(Name,NAME,clasp,slot) \
|
||||
SCOPE(Name) = cx->create<JSEmptyScope>(cx, clasp); \
|
||||
#define INIT_EMPTY_SCOPE_WITH_FREESLOT(Name,NAME,ops,clasp,slot) \
|
||||
SCOPE(Name) = cx->create<JSEmptyScope>(cx, ops, clasp); \
|
||||
if (!SCOPE(Name)) \
|
||||
return false; \
|
||||
JS_ASSERT(SCOPE(Name)->shape == JSScope::EMPTY_##NAME##_SHAPE); \
|
||||
@ -320,10 +323,10 @@ JSScope::initRuntimeState(JSContext *cx)
|
||||
* arguments objects. This helps ensure that any arguments object needing
|
||||
* its own mutable scope (with unique shape) is a rare event.
|
||||
*/
|
||||
INIT_EMPTY_SCOPE_WITH_FREESLOT(Arguments, ARGUMENTS, CLASP(Arguments),
|
||||
INIT_EMPTY_SCOPE_WITH_FREESLOT(Arguments, ARGUMENTS, &js_ObjectOps, CLASP(Arguments),
|
||||
JS_INITIAL_NSLOTS + JS_ARGS_LENGTH_MAX);
|
||||
|
||||
INIT_EMPTY_SCOPE(Block, BLOCK);
|
||||
INIT_EMPTY_SCOPE(Block, BLOCK, &js_ObjectOps);
|
||||
|
||||
/*
|
||||
* Initialize the shared scope for all empty Call objects so gets for args
|
||||
@ -332,17 +335,17 @@ JSScope::initRuntimeState(JSContext *cx)
|
||||
*
|
||||
* See comment above for rt->emptyArgumentsScope->freeslot initialization.
|
||||
*/
|
||||
INIT_EMPTY_SCOPE_WITH_FREESLOT(Call, CALL, CLASP(Call),
|
||||
INIT_EMPTY_SCOPE_WITH_FREESLOT(Call, CALL, &js_ObjectOps, CLASP(Call),
|
||||
JS_INITIAL_NSLOTS + JSFunction::MAX_ARGS_AND_VARS);
|
||||
|
||||
/* A DeclEnv object holds the name binding for a named function expression. */
|
||||
INIT_EMPTY_SCOPE(DeclEnv, DECL_ENV);
|
||||
INIT_EMPTY_SCOPE(DeclEnv, DECL_ENV, &js_ObjectOps);
|
||||
|
||||
/* Non-escaping native enumerator objects share this empty scope. */
|
||||
INIT_EMPTY_SCOPE_WITH_CLASS(Enumerator, ENUMERATOR, &js_IteratorClass);
|
||||
INIT_EMPTY_SCOPE_WITH_CLASS(Enumerator, ENUMERATOR, &js_ObjectOps, &js_IteratorClass.base);
|
||||
|
||||
/* Same drill for With objects. */
|
||||
INIT_EMPTY_SCOPE_WITH_CLASS(With, WITH, &js_WithClass);
|
||||
INIT_EMPTY_SCOPE(With, WITH, &js_WithObjectOps);
|
||||
|
||||
#undef SCOPE
|
||||
#undef CLASP
|
||||
|
@ -294,11 +294,12 @@ struct JSScope : public JSObjectMap
|
||||
JSScopeProperty **spp);
|
||||
|
||||
public:
|
||||
JSScope(JSObject *obj)
|
||||
: JSObjectMap(0), object(obj) {}
|
||||
JSScope(const JSObjectOps *ops, JSObject *obj)
|
||||
: JSObjectMap(ops, 0), object(obj) {}
|
||||
|
||||
/* Create a mutable, owned, empty scope. */
|
||||
static JSScope *create(JSContext *cx, js::Class *clasp, JSObject *obj, uint32 shape);
|
||||
static JSScope *create(JSContext *cx, const JSObjectOps *ops,
|
||||
js::Class *clasp, JSObject *obj, uint32 shape);
|
||||
|
||||
void destroy(JSContext *cx);
|
||||
|
||||
@ -313,7 +314,7 @@ struct JSScope : public JSObjectMap
|
||||
|
||||
inline bool ensureEmptyScope(JSContext *cx, js::Class *clasp);
|
||||
|
||||
inline bool canProvideEmptyScope(js::Class *clasp);
|
||||
inline bool canProvideEmptyScope(JSObjectOps *ops, js::Class *clasp);
|
||||
|
||||
JSScopeProperty *lookup(jsid id);
|
||||
|
||||
@ -527,7 +528,7 @@ struct JSEmptyScope : public JSScope
|
||||
js::Class * const clasp;
|
||||
jsrefcount nrefs; /* count of all referencing objects */
|
||||
|
||||
JSEmptyScope(JSContext *cx, js::Class *clasp);
|
||||
JSEmptyScope(JSContext *cx, const JSObjectOps *ops, js::Class *clasp);
|
||||
|
||||
JSEmptyScope *hold() {
|
||||
/* The method is only called for already held objects. */
|
||||
@ -959,7 +960,7 @@ JSScope::search(jsid id, bool adding)
|
||||
#undef METER
|
||||
|
||||
inline bool
|
||||
JSScope::canProvideEmptyScope(js::Class *clasp)
|
||||
JSScope::canProvideEmptyScope(JSObjectOps *ops, js::Class *clasp)
|
||||
{
|
||||
/*
|
||||
* An empty scope cannot provide another empty scope, or wrongful two-level
|
||||
@ -967,7 +968,7 @@ JSScope::canProvideEmptyScope(js::Class *clasp)
|
||||
*/
|
||||
if (!object)
|
||||
return false;
|
||||
return !emptyScope || emptyScope->clasp == clasp;
|
||||
return this->ops == ops && (!emptyScope || emptyScope->clasp == clasp);
|
||||
}
|
||||
|
||||
inline bool
|
||||
|
@ -53,7 +53,7 @@ JSScope::createEmptyScope(JSContext *cx, js::Class *clasp)
|
||||
{
|
||||
JS_ASSERT(!isSharedEmpty());
|
||||
JS_ASSERT(!emptyScope);
|
||||
emptyScope = cx->create<JSEmptyScope>(cx, clasp);
|
||||
emptyScope = cx->create<JSEmptyScope>(cx, ops, clasp);
|
||||
return emptyScope;
|
||||
}
|
||||
|
||||
|
@ -413,21 +413,10 @@ Class js_ScriptClass = {
|
||||
"Script",
|
||||
JSCLASS_HAS_PRIVATE |
|
||||
JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub,
|
||||
script_finalize,
|
||||
NULL, /* reserved0 */
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
NULL, /* hasInstance */
|
||||
JS_CLASS_TRACE(script_trace)
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, ConvertStub, script_finalize,
|
||||
NULL, NULL, NULL, NULL,/*XXXbe xdr*/
|
||||
NULL, NULL, JS_CLASS_TRACE(script_trace), NULL
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -806,13 +806,9 @@ Class js_StringClass = {
|
||||
js_String_str,
|
||||
JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_NEW_RESOLVE |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_String),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
str_getProperty,
|
||||
PropertyStub, /* setProperty */
|
||||
str_enumerate,
|
||||
(JSResolveOp)str_resolve,
|
||||
ConvertStub
|
||||
PropertyStub, PropertyStub, str_getProperty, PropertyStub,
|
||||
str_enumerate, (JSResolveOp)str_resolve, ConvertStub, NULL,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
};
|
||||
|
||||
#define NORMALIZE_THIS(cx,vp,str) \
|
||||
|
@ -2911,7 +2911,7 @@ NativeToValue(JSContext* cx, Value& v, JSValueType type, double* slot)
|
||||
debug_only_printf(LC_TMTracer, "nullablestr<%p> ", v.isNull() ? NULL : (void *)&v.toObject());
|
||||
break;
|
||||
case JSVAL_TYPE_BOXED:
|
||||
debug_only_printf(LC_TMTracer, "box<%llx> ", (unsigned long long)v.asRawBits());
|
||||
debug_only_printf(LC_TMTracer, "box<%llx> ", v.asRawBits());
|
||||
break;
|
||||
default:
|
||||
JS_NOT_REACHED("unexpected type");
|
||||
@ -8972,7 +8972,8 @@ TraceRecorder::equalityHelper(Value& l, Value& r, LIns* l_ins, LIns* r_ins,
|
||||
if (l.isNull())
|
||||
op = LIR_eqp;
|
||||
} else if (l.isObject()) {
|
||||
if (l.toObject().getClass()->ext.equality)
|
||||
Class *clasp = l.toObject().getClass();
|
||||
if ((clasp->flags & JSCLASS_IS_EXTENDED) && ((JSExtendedClass*) clasp)->equality)
|
||||
RETURN_STOP_A("Can't trace extended class equality operator");
|
||||
op = LIR_eqp;
|
||||
cond = (l == r);
|
||||
@ -9382,6 +9383,8 @@ TraceRecorder::forgetGuardedShapes()
|
||||
guardedShapeTable.clear();
|
||||
}
|
||||
|
||||
JS_STATIC_ASSERT(offsetof(JSObjectOps, objectMap) == 0);
|
||||
|
||||
inline LIns*
|
||||
TraceRecorder::map(LIns* obj_ins)
|
||||
{
|
||||
@ -11382,7 +11385,7 @@ TraceRecorder::callNative(uintN argc, JSOp mode)
|
||||
if (clasp == &js_FunctionClass)
|
||||
RETURN_STOP("new Function");
|
||||
|
||||
if (!clasp->isNative())
|
||||
if (clasp->getObjectOps)
|
||||
RETURN_STOP("new with non-native ops");
|
||||
|
||||
args[0] = INS_CONSTOBJ(funobj);
|
||||
@ -11810,7 +11813,7 @@ TraceRecorder::record_JSOP_SETPROP()
|
||||
RETURN_STOP_A("primitive this for SETPROP");
|
||||
|
||||
JSObject* obj = &l.toObject();
|
||||
if (obj->getOps()->setProperty)
|
||||
if (obj->map->ops->setProperty != js_SetProperty)
|
||||
RETURN_STOP_A("non-native JSObjectOps::setProperty");
|
||||
return ARECORD_CONTINUE;
|
||||
}
|
||||
@ -13513,7 +13516,7 @@ TraceRecorder::prop(JSObject* obj, LIns* obj_ins, uint32 *slotp, LIns** v_insp,
|
||||
* object not having the same op must have a different class, and therefore
|
||||
* must differ in its shape (or not be the global object).
|
||||
*/
|
||||
if (!obj->isDenseArray() && obj->getOps()->getProperty)
|
||||
if (!obj->isDenseArray() && obj->map->ops->getProperty != js_GetProperty)
|
||||
RETURN_STOP_A("non-dense-array, non-native JSObjectOps::getProperty");
|
||||
|
||||
JS_ASSERT((slotp && v_insp && !outp) || (!slotp && !v_insp && outp));
|
||||
@ -14196,8 +14199,8 @@ TraceRecorder::record_JSOP_MOREITER()
|
||||
LIns* cond_ins;
|
||||
|
||||
/* JSOP_FOR* already guards on this, but in certain rare cases we might record misformed loop traces. */
|
||||
if (iterobj->hasClass(&js_IteratorClass)) {
|
||||
guardClass(iterobj_ins, &js_IteratorClass, snapshot(BRANCH_EXIT), LOAD_NORMAL);
|
||||
if (iterobj->hasClass(&js_IteratorClass.base)) {
|
||||
guardClass(iterobj_ins, &js_IteratorClass.base, snapshot(BRANCH_EXIT), LOAD_NORMAL);
|
||||
NativeIterator *ni = (NativeIterator *) iterobj->getPrivate();
|
||||
void *cursor = ni->props_cursor;
|
||||
void *end = ni->props_end;
|
||||
@ -14213,7 +14216,7 @@ TraceRecorder::record_JSOP_MOREITER()
|
||||
cond = cursor < end;
|
||||
cond_ins = lir->ins2(LIR_ltp, cursor_ins, end_ins);
|
||||
} else {
|
||||
guardNotClass(iterobj_ins, &js_IteratorClass, snapshot(BRANCH_EXIT), LOAD_NORMAL);
|
||||
guardNotClass(iterobj_ins, &js_IteratorClass.base, snapshot(BRANCH_EXIT), LOAD_NORMAL);
|
||||
|
||||
enterDeepBailCall();
|
||||
|
||||
@ -14311,8 +14314,8 @@ TraceRecorder::unboxNextValue(LIns* &v_ins)
|
||||
JSObject *iterobj = &iterobj_val.toObject();
|
||||
LIns* iterobj_ins = get(&iterobj_val);
|
||||
|
||||
if (iterobj->hasClass(&js_IteratorClass)) {
|
||||
guardClass(iterobj_ins, &js_IteratorClass, snapshot(BRANCH_EXIT), LOAD_NORMAL);
|
||||
if (iterobj->hasClass(&js_IteratorClass.base)) {
|
||||
guardClass(iterobj_ins, &js_IteratorClass.base, snapshot(BRANCH_EXIT), LOAD_NORMAL);
|
||||
NativeIterator *ni = (NativeIterator *) iterobj->getPrivate();
|
||||
|
||||
LIns *ni_ins = stobj_get_const_private_ptr(iterobj_ins);
|
||||
@ -14352,10 +14355,9 @@ TraceRecorder::unboxNextValue(LIns* &v_ins)
|
||||
cursor_ins = lir->ins2(LIR_addp, cursor_ins, INS_CONSTWORD(sizeof(Value)));
|
||||
}
|
||||
|
||||
lir->insStore(LIR_stp, cursor_ins, ni_ins, offsetof(NativeIterator, props_cursor),
|
||||
ACCSET_OTHER);
|
||||
lir->insStore(LIR_stp, cursor_ins, ni_ins, offsetof(NativeIterator, props_cursor), ACCSET_OTHER);
|
||||
} else {
|
||||
guardNotClass(iterobj_ins, &js_IteratorClass, snapshot(BRANCH_EXIT), LOAD_NORMAL);
|
||||
guardNotClass(iterobj_ins, &js_IteratorClass.base, snapshot(BRANCH_EXIT), LOAD_NORMAL);
|
||||
|
||||
v_ins = unbox_value(cx->iterValue, cx_ins, offsetof(JSContext, iterValue),
|
||||
snapshot(BRANCH_EXIT));
|
||||
|
@ -493,6 +493,9 @@ class TypedArrayTemplate
|
||||
static const bool ArrayTypeIsUnsigned() { return TypeIsUnsigned<NativeType>(); }
|
||||
static const bool ArrayTypeIsFloatingPoint() { return TypeIsFloatingPoint<NativeType>(); }
|
||||
|
||||
static JSObjectOps fastObjectOps;
|
||||
static JSObjectMap fastObjectMap;
|
||||
|
||||
static JSFunctionSpec jsfuncs[];
|
||||
|
||||
static inline Class *slowClass()
|
||||
@ -505,6 +508,11 @@ class TypedArrayTemplate
|
||||
return &TypedArray::fastClasses[ArrayTypeID()];
|
||||
}
|
||||
|
||||
static JSObjectOps *getObjectOps(JSContext *cx, Class *clasp)
|
||||
{
|
||||
return &fastObjectOps;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
obj_getProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
||||
{
|
||||
@ -918,7 +926,7 @@ class TypedArrayTemplate
|
||||
JS_ASSERT(obj->getClass() == slowClass());
|
||||
obj->setPrivate(tarray);
|
||||
obj->clasp = fastClass();
|
||||
obj->map = const_cast<JSObjectMap *>(&JSObjectMap::sharedNonNative);
|
||||
obj->map = &fastObjectMap;
|
||||
}
|
||||
|
||||
public:
|
||||
@ -1256,14 +1264,9 @@ TypedArrayTemplate<double>::copyIndexToValue(JSContext *cx, uint32 index, Value
|
||||
Class ArrayBuffer::jsclass = {
|
||||
"ArrayBuffer",
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_ArrayBuffer),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub,
|
||||
ArrayBuffer::class_finalize,
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, ConvertStub, ArrayBuffer::class_finalize,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
};
|
||||
|
||||
JSPropertySpec ArrayBuffer::jsprops[] = {
|
||||
@ -1298,6 +1301,23 @@ JSPropertySpec TypedArray::jsprops[] = {
|
||||
*/
|
||||
|
||||
#define IMPL_TYPED_ARRAY_STATICS(_typedArray) \
|
||||
template<> JSObjectMap _typedArray::fastObjectMap(&_typedArray::fastObjectOps, \
|
||||
JSObjectMap::SHAPELESS); \
|
||||
template<> JSObjectOps _typedArray::fastObjectOps = { \
|
||||
&_typedArray::fastObjectMap, \
|
||||
_typedArray::obj_lookupProperty, \
|
||||
_typedArray::obj_defineProperty, \
|
||||
_typedArray::obj_getProperty, \
|
||||
_typedArray::obj_setProperty, \
|
||||
_typedArray::obj_getAttributes, \
|
||||
_typedArray::obj_setAttributes, \
|
||||
_typedArray::obj_deleteProperty, \
|
||||
_typedArray::obj_enumerate, \
|
||||
_typedArray::obj_typeOf, \
|
||||
_typedArray::obj_trace, \
|
||||
NULL, /* thisObject */ \
|
||||
NULL /* clear */ \
|
||||
}; \
|
||||
template<> JSFunctionSpec _typedArray::jsfuncs[] = { \
|
||||
JS_FN("slice", _typedArray::fun_slice, 2, 0), \
|
||||
JS_FS_END \
|
||||
@ -1307,50 +1327,20 @@ template<> JSFunctionSpec _typedArray::jsfuncs[] = { \
|
||||
{ \
|
||||
#_typedArray, \
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_##_typedArray), \
|
||||
PropertyStub, /* addProperty */ \
|
||||
PropertyStub, /* delProperty */ \
|
||||
PropertyStub, /* getProperty */ \
|
||||
PropertyStub, /* setProperty */ \
|
||||
EnumerateStub, \
|
||||
ResolveStub, \
|
||||
ConvertStub, \
|
||||
FinalizeStub \
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub, \
|
||||
EnumerateStub, ResolveStub, ConvertStub, FinalizeStub, \
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS \
|
||||
}
|
||||
|
||||
#define IMPL_TYPED_ARRAY_FAST_CLASS(_typedArray) \
|
||||
{ \
|
||||
#_typedArray, \
|
||||
Class::NON_NATIVE | JSCLASS_HAS_PRIVATE, \
|
||||
PropertyStub, /* addProperty */ \
|
||||
PropertyStub, /* delProperty */ \
|
||||
PropertyStub, /* getProperty */ \
|
||||
PropertyStub, /* setProperty */ \
|
||||
EnumerateStub, \
|
||||
ResolveStub, \
|
||||
ConvertStub, \
|
||||
JSCLASS_HAS_PRIVATE, \
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub, \
|
||||
EnumerateStub, ResolveStub, ConvertStub, \
|
||||
_typedArray::class_finalize, \
|
||||
NULL, /* reserved0 */ \
|
||||
NULL, /* checkAccess */ \
|
||||
NULL, /* call */ \
|
||||
NULL, /* construct */ \
|
||||
NULL, /* xdrObject */ \
|
||||
NULL, /* hasInstance */ \
|
||||
NULL, /* mark */ \
|
||||
JS_NULL_CLASS_EXT, \
|
||||
{ \
|
||||
_typedArray::obj_lookupProperty, \
|
||||
_typedArray::obj_defineProperty, \
|
||||
_typedArray::obj_getProperty, \
|
||||
_typedArray::obj_setProperty, \
|
||||
_typedArray::obj_getAttributes, \
|
||||
_typedArray::obj_setAttributes, \
|
||||
_typedArray::obj_deleteProperty, \
|
||||
_typedArray::obj_enumerate, \
|
||||
_typedArray::obj_typeOf, \
|
||||
_typedArray::obj_trace, \
|
||||
NULL, /* thisObject */ \
|
||||
NULL, /* clear */ \
|
||||
} \
|
||||
_typedArray::getObjectOps, NULL, NULL, NULL, \
|
||||
NULL, NULL, NULL, NULL \
|
||||
}
|
||||
|
||||
#define INIT_TYPED_ARRAY_CLASS(_typedArray,_type) \
|
||||
|
134
js/src/jsvalue.h
134
js/src/jsvalue.h
@ -779,6 +779,8 @@ typedef JSBool
|
||||
typedef JSBool
|
||||
(* CheckAccessOp)(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
|
||||
Value *vp);
|
||||
typedef JSObjectOps *
|
||||
(* GetObjectOps)(JSContext *cx, Class *clasp);
|
||||
typedef JSBool
|
||||
(* EqualityOp)(JSContext *cx, JSObject *obj, const Value *v, JSBool *bp);
|
||||
typedef JSBool
|
||||
@ -803,6 +805,8 @@ static inline HasInstanceOp Valueify(JSHasInstanceOp f) { return (HasInsta
|
||||
static inline JSHasInstanceOp Jsvalify(HasInstanceOp f) { return (JSHasInstanceOp)f; }
|
||||
static inline CheckAccessOp Valueify(JSCheckAccessOp f) { return (CheckAccessOp)f; }
|
||||
static inline JSCheckAccessOp Jsvalify(CheckAccessOp f) { return (JSCheckAccessOp)f; }
|
||||
static inline GetObjectOps Valueify(JSGetObjectOps f) { return (GetObjectOps)f; }
|
||||
static inline JSGetObjectOps Jsvalify(GetObjectOps f) { return (JSGetObjectOps)f; }
|
||||
static inline EqualityOp Valueify(JSEqualityOp f); /* Same type as JSHasInstanceOp */
|
||||
static inline JSEqualityOp Jsvalify(EqualityOp f); /* Same type as HasInstanceOp */
|
||||
static inline DefinePropOp Valueify(JSDefinePropOp f) { return (DefinePropOp)f; }
|
||||
@ -818,91 +822,30 @@ static const JSResolveOp ResolveStub = JS_ResolveStub;
|
||||
static const ConvertOp ConvertStub = (ConvertOp)JS_ConvertStub;
|
||||
static const JSFinalizeOp FinalizeStub = JS_FinalizeStub;
|
||||
|
||||
#define JS_CLASS_MEMBERS \
|
||||
const char *name; \
|
||||
uint32 flags; \
|
||||
\
|
||||
/* Mandatory non-null function pointer members. */ \
|
||||
PropertyOp addProperty; \
|
||||
PropertyOp delProperty; \
|
||||
PropertyOp getProperty; \
|
||||
PropertyOp setProperty; \
|
||||
JSEnumerateOp enumerate; \
|
||||
JSResolveOp resolve; \
|
||||
ConvertOp convert; \
|
||||
JSFinalizeOp finalize; \
|
||||
\
|
||||
/* Optionally non-null members start here. */ \
|
||||
JSClassInternal reserved0; \
|
||||
CheckAccessOp checkAccess; \
|
||||
Native call; \
|
||||
Native construct; \
|
||||
JSXDRObjectOp xdrObject; \
|
||||
HasInstanceOp hasInstance; \
|
||||
JSMarkOp mark
|
||||
|
||||
|
||||
/*
|
||||
* The helper struct to measure the size of JS_CLASS_MEMBERS to know how much
|
||||
* we have to padd js::Class to match the size of JSClass;
|
||||
*/
|
||||
struct ClassSizeMeasurement {
|
||||
JS_CLASS_MEMBERS;
|
||||
};
|
||||
|
||||
struct ClassExtension {
|
||||
EqualityOp equality;
|
||||
JSObjectOp outerObject;
|
||||
JSObjectOp innerObject;
|
||||
JSIteratorOp iteratorObject;
|
||||
JSObjectOp wrappedObject; /* NB: infallible, null returns are
|
||||
treated as the original object */
|
||||
};
|
||||
|
||||
#define JS_NULL_CLASS_EXT {NULL,NULL,NULL,NULL,NULL}
|
||||
|
||||
struct ObjectOps {
|
||||
JSLookupPropOp lookupProperty;
|
||||
js::DefinePropOp defineProperty;
|
||||
js::PropertyIdOp getProperty;
|
||||
js::PropertyIdOp setProperty;
|
||||
JSAttributesOp getAttributes;
|
||||
JSAttributesOp setAttributes;
|
||||
js::PropertyIdOp deleteProperty;
|
||||
js::NewEnumerateOp enumerate;
|
||||
JSTypeOfOp typeOf;
|
||||
JSTraceOp trace;
|
||||
JSObjectOp thisObject;
|
||||
JSFinalizeOp clear;
|
||||
};
|
||||
|
||||
#define JS_NULL_OBJECT_OPS {NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL}
|
||||
|
||||
struct Class {
|
||||
JS_CLASS_MEMBERS;
|
||||
ClassExtension ext;
|
||||
ObjectOps ops;
|
||||
uint8 pad[sizeof(JSClass) - sizeof(ClassSizeMeasurement) -
|
||||
sizeof(ClassExtension) - sizeof(ObjectOps)];
|
||||
const char *name;
|
||||
uint32 flags;
|
||||
|
||||
/* Flag indicating that Class::call is a fast native. */
|
||||
static const uint32 CALL_IS_FAST = JSCLASS_INTERNAL_FLAG1;
|
||||
/* Mandatory non-null function pointer members. */
|
||||
PropertyOp addProperty;
|
||||
PropertyOp delProperty;
|
||||
PropertyOp getProperty;
|
||||
PropertyOp setProperty;
|
||||
JSEnumerateOp enumerate;
|
||||
JSResolveOp resolve;
|
||||
ConvertOp convert;
|
||||
JSFinalizeOp finalize;
|
||||
|
||||
/* Class is not native and its map is not a scope. */
|
||||
static const uint32 NON_NATIVE = JSCLASS_INTERNAL_FLAG2;
|
||||
|
||||
bool isNative() const {
|
||||
return !(flags & NON_NATIVE);
|
||||
}
|
||||
/* Optionally non-null members start here. */
|
||||
GetObjectOps getObjectOps;
|
||||
CheckAccessOp checkAccess;
|
||||
Native call;
|
||||
Native construct;
|
||||
JSXDRObjectOp xdrObject;
|
||||
HasInstanceOp hasInstance;
|
||||
JSMarkOp mark;
|
||||
void (*reserved0)(void);
|
||||
};
|
||||
|
||||
/* Helper to initialize Class::call when Class::CALL_IS_FAST. */
|
||||
inline Native
|
||||
CastCallOpAsNative(CallOp op)
|
||||
{
|
||||
return reinterpret_cast<Native>(op);
|
||||
}
|
||||
|
||||
JS_STATIC_ASSERT(offsetof(JSClass, name) == offsetof(Class, name));
|
||||
JS_STATIC_ASSERT(offsetof(JSClass, flags) == offsetof(Class, flags));
|
||||
JS_STATIC_ASSERT(offsetof(JSClass, addProperty) == offsetof(Class, addProperty));
|
||||
@ -913,15 +856,40 @@ JS_STATIC_ASSERT(offsetof(JSClass, enumerate) == offsetof(Class, enumerate));
|
||||
JS_STATIC_ASSERT(offsetof(JSClass, resolve) == offsetof(Class, resolve));
|
||||
JS_STATIC_ASSERT(offsetof(JSClass, convert) == offsetof(Class, convert));
|
||||
JS_STATIC_ASSERT(offsetof(JSClass, finalize) == offsetof(Class, finalize));
|
||||
JS_STATIC_ASSERT(offsetof(JSClass, reserved0) == offsetof(Class, reserved0));
|
||||
JS_STATIC_ASSERT(offsetof(JSClass, getObjectOps) == offsetof(Class, getObjectOps));
|
||||
JS_STATIC_ASSERT(offsetof(JSClass, checkAccess) == offsetof(Class, checkAccess));
|
||||
JS_STATIC_ASSERT(offsetof(JSClass, call) == offsetof(Class, call));
|
||||
JS_STATIC_ASSERT(offsetof(JSClass, construct) == offsetof(Class, construct));
|
||||
JS_STATIC_ASSERT(offsetof(JSClass, xdrObject) == offsetof(Class, xdrObject));
|
||||
JS_STATIC_ASSERT(offsetof(JSClass, hasInstance) == offsetof(Class, hasInstance));
|
||||
JS_STATIC_ASSERT(offsetof(JSClass, mark) == offsetof(Class, mark));
|
||||
JS_STATIC_ASSERT(offsetof(JSClass, reserved0) == offsetof(Class, reserved0));
|
||||
JS_STATIC_ASSERT(sizeof(JSClass) == sizeof(Class));
|
||||
|
||||
struct ExtendedClass {
|
||||
Class base;
|
||||
EqualityOp equality;
|
||||
JSObjectOp outerObject;
|
||||
JSObjectOp innerObject;
|
||||
JSIteratorOp iteratorObject;
|
||||
JSObjectOp wrappedObject; /* NB: infallible, null
|
||||
returns are treated as
|
||||
the original object */
|
||||
void (*reserved0)(void);
|
||||
void (*reserved1)(void);
|
||||
void (*reserved2)(void);
|
||||
};
|
||||
JS_STATIC_ASSERT(offsetof(JSExtendedClass, base) == offsetof(ExtendedClass, base));
|
||||
JS_STATIC_ASSERT(offsetof(JSExtendedClass, equality) == offsetof(ExtendedClass, equality));
|
||||
JS_STATIC_ASSERT(offsetof(JSExtendedClass, outerObject) == offsetof(ExtendedClass, outerObject));
|
||||
JS_STATIC_ASSERT(offsetof(JSExtendedClass, innerObject) == offsetof(ExtendedClass, innerObject));
|
||||
JS_STATIC_ASSERT(offsetof(JSExtendedClass, iteratorObject) == offsetof(ExtendedClass, iteratorObject));
|
||||
JS_STATIC_ASSERT(offsetof(JSExtendedClass, wrappedObject) == offsetof(ExtendedClass, wrappedObject));
|
||||
JS_STATIC_ASSERT(offsetof(JSExtendedClass, reserved0) == offsetof(ExtendedClass, reserved0));
|
||||
JS_STATIC_ASSERT(offsetof(JSExtendedClass, reserved1) == offsetof(ExtendedClass, reserved1));
|
||||
JS_STATIC_ASSERT(offsetof(JSExtendedClass, reserved2) == offsetof(ExtendedClass, reserved2));
|
||||
JS_STATIC_ASSERT(sizeof(JSExtendedClass) == sizeof(ExtendedClass));
|
||||
|
||||
struct PropertyDescriptor {
|
||||
JSObject *obj;
|
||||
uintN attrs;
|
||||
@ -940,6 +908,8 @@ JS_STATIC_ASSERT(sizeof(JSPropertyDescriptor) == sizeof(PropertyDescriptor));
|
||||
|
||||
static JS_ALWAYS_INLINE JSClass * Jsvalify(Class *c) { return (JSClass *)c; }
|
||||
static JS_ALWAYS_INLINE Class * Valueify(JSClass *c) { return (Class *)c; }
|
||||
static JS_ALWAYS_INLINE JSExtendedClass * Jsvalify(ExtendedClass *c) { return (JSExtendedClass *)c; }
|
||||
static JS_ALWAYS_INLINE ExtendedClass * Valueify(JSExtendedClass *c) { return (ExtendedClass *)c; }
|
||||
static JS_ALWAYS_INLINE JSPropertyDescriptor * Jsvalify(PropertyDescriptor *p) { return (JSPropertyDescriptor *) p; }
|
||||
static JS_ALWAYS_INLINE PropertyDescriptor * Valueify(JSPropertyDescriptor *p) { return (PropertyDescriptor *) p; }
|
||||
|
||||
|
@ -684,7 +684,7 @@ CanReify(Value *vp)
|
||||
{
|
||||
JSObject *obj;
|
||||
return vp->isObject() &&
|
||||
(obj = &vp->toObject())->getClass() == &js_IteratorClass &&
|
||||
(obj = &vp->toObject())->getClass() == &js_IteratorClass.base &&
|
||||
(obj->getNativeIterator()->flags & JSITER_ENUMERATE);
|
||||
}
|
||||
|
||||
|
263
js/src/jsxml.cpp
263
js/src/jsxml.cpp
@ -190,7 +190,7 @@ IsDeclared(const JSObject *obj)
|
||||
{
|
||||
jsval v;
|
||||
|
||||
JS_ASSERT(obj->getClass() == &js_NamespaceClass);
|
||||
JS_ASSERT(obj->getClass() == &js_NamespaceClass.base);
|
||||
v = obj->getNamespaceDeclared();
|
||||
JS_ASSERT(JSVAL_IS_VOID(v) || v == JSVAL_TRUE);
|
||||
return v == JSVAL_TRUE;
|
||||
@ -224,9 +224,9 @@ AppendString(JSCharBuffer &cb, JSString *str)
|
||||
* Namespace class and library functions.
|
||||
*/
|
||||
DEFINE_GETTER(NamePrefix_getter,
|
||||
if (obj->getClass() == &js_NamespaceClass) *vp = obj->getNamePrefix())
|
||||
if (obj->getClass() == &js_NamespaceClass.base) *vp = obj->getNamePrefix())
|
||||
DEFINE_GETTER(NameURI_getter,
|
||||
if (obj->getClass() == &js_NamespaceClass) *vp = obj->getNameURI())
|
||||
if (obj->getClass() == &js_NamespaceClass.base) *vp = obj->getNameURI())
|
||||
|
||||
static void
|
||||
namespace_finalize(JSContext *cx, JSObject *obj)
|
||||
@ -242,39 +242,23 @@ namespace_equality(JSContext *cx, JSObject *obj, const Value *v, JSBool *bp)
|
||||
|
||||
JS_ASSERT(v->isObjectOrNull());
|
||||
obj2 = v->toObjectOrNull();
|
||||
*bp = (!obj2 || obj2->getClass() != &js_NamespaceClass)
|
||||
*bp = (!obj2 || obj2->getClass() != &js_NamespaceClass.base)
|
||||
? JS_FALSE
|
||||
: js_EqualStrings(GetURI(obj), GetURI(obj2));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_FRIEND_DATA(Class) js_NamespaceClass = {
|
||||
"Namespace",
|
||||
JSCLASS_CONSTRUCT_PROTOTYPE |
|
||||
JS_FRIEND_DATA(ExtendedClass) js_NamespaceClass = {
|
||||
{ "Namespace",
|
||||
JSCLASS_CONSTRUCT_PROTOTYPE | JSCLASS_IS_EXTENDED |
|
||||
JSCLASS_HAS_RESERVED_SLOTS(JSObject::NAMESPACE_FIXED_RESERVED_SLOTS) |
|
||||
JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_Namespace),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub,
|
||||
namespace_finalize,
|
||||
NULL, /* reserved0 */
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
NULL, /* hasInstance */
|
||||
NULL, /* mark */
|
||||
{
|
||||
namespace_equality,
|
||||
NULL, /* outerObject */
|
||||
NULL, /* innerObject */
|
||||
NULL, /* iteratorObject */
|
||||
NULL, /* wrappedObject */
|
||||
}
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, ConvertStub, namespace_finalize,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL },
|
||||
namespace_equality,NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
#define NAMESPACE_ATTRS \
|
||||
@ -292,7 +276,7 @@ namespace_toString(JSContext *cx, uintN argc, jsval *vp)
|
||||
JSObject *obj;
|
||||
|
||||
obj = JS_THIS_OBJECT(cx, vp);
|
||||
if (!JS_InstanceOf(cx, obj, Jsvalify(&js_NamespaceClass), vp + 2))
|
||||
if (!JS_InstanceOf(cx, obj, Jsvalify(&js_NamespaceClass.base), vp + 2))
|
||||
return JS_FALSE;
|
||||
*vp = obj->getNameURI();
|
||||
return JS_TRUE;
|
||||
@ -308,7 +292,7 @@ NewXMLNamespace(JSContext *cx, JSString *prefix, JSString *uri, JSBool declared)
|
||||
{
|
||||
JSObject *obj;
|
||||
|
||||
obj = NewBuiltinClassInstance(cx, &js_NamespaceClass);
|
||||
obj = NewBuiltinClassInstance(cx, &js_NamespaceClass.base);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
JS_ASSERT(JSVAL_IS_VOID(obj->getNamePrefix()));
|
||||
@ -328,10 +312,10 @@ NewXMLNamespace(JSContext *cx, JSString *prefix, JSString *uri, JSBool declared)
|
||||
* QName class and library functions.
|
||||
*/
|
||||
DEFINE_GETTER(QNameNameURI_getter,
|
||||
if (obj->getClass() == &js_QNameClass)
|
||||
if (obj->getClass() == &js_QNameClass.base)
|
||||
*vp = JSVAL_IS_VOID(obj->getNameURI()) ? JSVAL_NULL : obj->getNameURI())
|
||||
DEFINE_GETTER(QNameLocalName_getter,
|
||||
if (obj->getClass() == &js_QNameClass)
|
||||
if (obj->getClass() == &js_QNameClass.base)
|
||||
*vp = obj->getQNameLocalName())
|
||||
|
||||
static void
|
||||
@ -361,39 +345,23 @@ qname_equality(JSContext *cx, JSObject *qn, const Value *v, JSBool *bp)
|
||||
JSObject *obj2;
|
||||
|
||||
obj2 = v->toObjectOrNull();
|
||||
*bp = (!obj2 || obj2->getClass() != &js_QNameClass)
|
||||
*bp = (!obj2 || obj2->getClass() != &js_QNameClass.base)
|
||||
? JS_FALSE
|
||||
: qname_identity(qn, obj2);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_FRIEND_DATA(Class) js_QNameClass = {
|
||||
"QName",
|
||||
JSCLASS_CONSTRUCT_PROTOTYPE |
|
||||
JS_FRIEND_DATA(ExtendedClass) js_QNameClass = {
|
||||
{ "QName",
|
||||
JSCLASS_CONSTRUCT_PROTOTYPE | JSCLASS_IS_EXTENDED |
|
||||
JSCLASS_HAS_RESERVED_SLOTS(JSObject::QNAME_FIXED_RESERVED_SLOTS) |
|
||||
JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_QName),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub,
|
||||
FinalizeStub,
|
||||
NULL, /* reserved0 */
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
NULL, /* hasInstance */
|
||||
NULL, /* mark */
|
||||
{
|
||||
qname_equality,
|
||||
NULL, /* outerObject */
|
||||
NULL, /* innerObject */
|
||||
NULL, /* iteratorObject */
|
||||
NULL, /* wrappedObject */
|
||||
}
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, ConvertStub, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL },
|
||||
qname_equality, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
/*
|
||||
@ -407,13 +375,10 @@ JS_FRIEND_DATA(Class) js_AttributeNameClass = {
|
||||
JSCLASS_CONSTRUCT_PROTOTYPE |
|
||||
JSCLASS_HAS_RESERVED_SLOTS(JSObject::QNAME_FIXED_RESERVED_SLOTS) |
|
||||
JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_AttributeName),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, ConvertStub, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
JS_FRIEND_DATA(Class) js_AnyNameClass = {
|
||||
@ -421,17 +386,14 @@ JS_FRIEND_DATA(Class) js_AnyNameClass = {
|
||||
JSCLASS_CONSTRUCT_PROTOTYPE |
|
||||
JSCLASS_HAS_RESERVED_SLOTS(JSObject::QNAME_FIXED_RESERVED_SLOTS) |
|
||||
JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_AnyName),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub,
|
||||
anyname_finalize
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, ConvertStub, anyname_finalize,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
#define QNAME_ATTRS (JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_SHARED)
|
||||
#define QNAME_ATTRS \
|
||||
(JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_SHARED)
|
||||
|
||||
static JSPropertySpec qname_props[] = {
|
||||
{js_uri_str, 0, QNAME_ATTRS, QNameNameURI_getter, 0},
|
||||
@ -454,7 +416,7 @@ qname_toString(JSContext *cx, uintN argc, jsval *vp)
|
||||
clasp = obj->getClass();
|
||||
if (clasp != &js_AttributeNameClass &&
|
||||
clasp != &js_AnyNameClass &&
|
||||
!JS_InstanceOf(cx, obj, Jsvalify(&js_QNameClass), vp + 2)) {
|
||||
!JS_InstanceOf(cx, obj, Jsvalify(&js_QNameClass.base), vp + 2)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
@ -517,7 +479,7 @@ InitXMLQName(JSObject *obj, JSString *uri, JSString *prefix,
|
||||
|
||||
static JSObject *
|
||||
NewXMLQName(JSContext *cx, JSString *uri, JSString *prefix, JSString *localName,
|
||||
Class *clasp = &js_QNameClass)
|
||||
Class *clasp = &js_QNameClass.base)
|
||||
{
|
||||
JSObject *obj = NewBuiltinClassInstance(cx, clasp);
|
||||
if (!obj)
|
||||
@ -545,7 +507,7 @@ js_ConstructXMLQNameObject(JSContext *cx, const Value &nsval, const Value &lnval
|
||||
argv[0] = nsval;
|
||||
}
|
||||
argv[1] = lnval;
|
||||
return js_ConstructObject(cx, &js_QNameClass, NULL, NULL, 2, argv);
|
||||
return js_ConstructObject(cx, &js_QNameClass.base, NULL, NULL, 2, argv);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@ -619,8 +581,8 @@ NamespaceHelper(JSContext *cx, JSObject *obj, intN argc, jsval *argv,
|
||||
if (!JSVAL_IS_PRIMITIVE(urival)) {
|
||||
uriobj = JSVAL_TO_OBJECT(urival);
|
||||
clasp = uriobj->getClass();
|
||||
isNamespace = (clasp == &js_NamespaceClass);
|
||||
isQName = (clasp == &js_QNameClass);
|
||||
isNamespace = (clasp == &js_NamespaceClass.base);
|
||||
isQName = (clasp == &js_QNameClass.base);
|
||||
}
|
||||
}
|
||||
|
||||
@ -632,7 +594,7 @@ NamespaceHelper(JSContext *cx, JSObject *obj, intN argc, jsval *argv,
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
obj = NewBuiltinClassInstance(cx, &js_NamespaceClass);
|
||||
obj = NewBuiltinClassInstance(cx, &js_NamespaceClass.base);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
*rval = OBJECT_TO_JSVAL(obj);
|
||||
@ -715,7 +677,7 @@ QNameHelper(JSContext *cx, JSObject *obj, Class *clasp, intN argc,
|
||||
JSString *uri, *prefix, *name;
|
||||
JSObject *obj2;
|
||||
|
||||
JS_ASSERT(clasp == &js_QNameClass ||
|
||||
JS_ASSERT(clasp == &js_QNameClass.base ||
|
||||
clasp == &js_AttributeNameClass);
|
||||
if (argc <= 0) {
|
||||
nameval = JSVAL_VOID;
|
||||
@ -724,7 +686,7 @@ QNameHelper(JSContext *cx, JSObject *obj, Class *clasp, intN argc,
|
||||
nameval = argv[argc > 1];
|
||||
isQName =
|
||||
!JSVAL_IS_PRIMITIVE(nameval) &&
|
||||
JSVAL_TO_OBJECT(nameval)->getClass() == &js_QNameClass;
|
||||
JSVAL_TO_OBJECT(nameval)->getClass() == &js_QNameClass.base;
|
||||
}
|
||||
|
||||
if (!obj) {
|
||||
@ -780,7 +742,7 @@ QNameHelper(JSContext *cx, JSObject *obj, Class *clasp, intN argc,
|
||||
return JS_FALSE;
|
||||
JS_ASSERT(!JSVAL_IS_PRIMITIVE(nsval));
|
||||
JS_ASSERT(JSVAL_TO_OBJECT(nsval)->getClass() ==
|
||||
&js_NamespaceClass);
|
||||
&js_NamespaceClass.base);
|
||||
}
|
||||
|
||||
if (JSVAL_IS_NULL(nsval)) {
|
||||
@ -798,8 +760,8 @@ QNameHelper(JSContext *cx, JSObject *obj, Class *clasp, intN argc,
|
||||
if (!JSVAL_IS_PRIMITIVE(nsval)) {
|
||||
obj2 = JSVAL_TO_OBJECT(nsval);
|
||||
clasp = obj2->getClass();
|
||||
isNamespace = (clasp == &js_NamespaceClass);
|
||||
isQName = (clasp == &js_QNameClass);
|
||||
isNamespace = (clasp == &js_NamespaceClass.base);
|
||||
isQName = (clasp == &js_QNameClass.base);
|
||||
}
|
||||
#ifdef __GNUC__ /* suppress bogus gcc warnings */
|
||||
else obj2 = NULL;
|
||||
@ -832,7 +794,7 @@ static JSBool
|
||||
QName(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
|
||||
{
|
||||
return QNameHelper(cx, cx->isConstructing() ? obj : NULL,
|
||||
&js_QNameClass, argc, Jsvalify(argv), Jsvalify(rval));
|
||||
&js_QNameClass.base, argc, Jsvalify(argv), Jsvalify(rval));
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@ -2197,7 +2159,7 @@ GetNamespace(JSContext *cx, JSObject *qn, const JSXMLArray *inScopeNSes)
|
||||
if (!match) {
|
||||
argv[0] = prefix ? STRING_TO_JSVAL(prefix) : JSVAL_VOID;
|
||||
argv[1] = STRING_TO_JSVAL(uri);
|
||||
ns = js_ConstructObject(cx, &js_NamespaceClass, NULL, NULL,
|
||||
ns = js_ConstructObject(cx, &js_NamespaceClass.base, NULL, NULL,
|
||||
2, Valueify(argv));
|
||||
if (!ns)
|
||||
return NULL;
|
||||
@ -2752,7 +2714,7 @@ ToAttributeName(JSContext *cx, jsval v)
|
||||
if (clasp == &js_AttributeNameClass)
|
||||
return obj;
|
||||
|
||||
if (clasp == &js_QNameClass) {
|
||||
if (clasp == &js_QNameClass.base) {
|
||||
qn = obj;
|
||||
uri = GetURI(qn);
|
||||
prefix = GetPrefix(qn);
|
||||
@ -2801,7 +2763,7 @@ IsFunctionQName(JSContext *cx, JSObject *qn, jsid *funidp)
|
||||
JSBool
|
||||
js_IsFunctionQName(JSContext *cx, JSObject *obj, jsid *funidp)
|
||||
{
|
||||
if (obj->getClass() == &js_QNameClass)
|
||||
if (obj->getClass() == &js_QNameClass.base)
|
||||
return IsFunctionQName(cx, obj, funidp);
|
||||
*funidp = JSID_VOID;
|
||||
return JS_TRUE;
|
||||
@ -2826,7 +2788,7 @@ ToXMLName(JSContext *cx, jsval v, jsid *funidp)
|
||||
|
||||
obj = JSVAL_TO_OBJECT(v);
|
||||
clasp = obj->getClass();
|
||||
if (clasp == &js_AttributeNameClass || clasp == &js_QNameClass)
|
||||
if (clasp == &js_AttributeNameClass || clasp == &js_QNameClass.base)
|
||||
goto out;
|
||||
if (clasp == &js_AnyNameClass) {
|
||||
name = ATOM_TO_STRING(cx->runtime->atomState.starAtom);
|
||||
@ -2867,7 +2829,7 @@ ToXMLName(JSContext *cx, jsval v, jsid *funidp)
|
||||
|
||||
construct:
|
||||
v = STRING_TO_JSVAL(name);
|
||||
obj = js_ConstructObject(cx, &js_QNameClass, NULL, NULL, 1, Valueify(&v));
|
||||
obj = js_ConstructObject(cx, &js_QNameClass.base, NULL, NULL, 1, Valueify(&v));
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
@ -4639,13 +4601,13 @@ xml_trace_vector(JSTracer *trc, JSXML **vec, uint32 len)
|
||||
}
|
||||
|
||||
/*
|
||||
* XML objects are native. Thus xml_lookupProperty must return a valid
|
||||
* JSScopeProperty pointer parameter via *propp to signify "property found".
|
||||
* Since the only call to xml_lookupProperty is via JSObject::lookupProperty,
|
||||
* and then only from js_FindProperty (in jsobj.c, called from jsinterp.c) or
|
||||
* from JSOP_IN case in the interpreter, the only time we add a
|
||||
* JSScopeProperty here is when an unqualified name is being accessed or when
|
||||
* "name in xml" is called.
|
||||
* js_XMLObjectOps.newObjectMap is null, so XML objects appear to be native.
|
||||
* Thus xml_lookupProperty must return a valid JSScopeProperty pointer
|
||||
* parameter via *propp to signify "property found". Since the only call to
|
||||
* xml_lookupProperty is via JSObject::lookupProperty, and then only from
|
||||
* js_FindProperty (in jsobj.c, called from jsinterp.c) or from JSOP_IN case
|
||||
* in the interpreter, the only time we add a JSScopeProperty here is when an
|
||||
* unqualified name is being accessed or when "name in xml" is called.
|
||||
*
|
||||
* This scope property keeps the JSOP_NAME code in js_Interpret happy by
|
||||
* giving it an sprop with (getter, setter) == (GetProperty, PutProperty).
|
||||
@ -5068,39 +5030,37 @@ out:
|
||||
return ok;
|
||||
}
|
||||
|
||||
/* Use NULL for objectMap so XML objects satisfy obj->isNative() tests. */
|
||||
JS_FRIEND_DATA(JSObjectOps) js_XMLObjectOps = {
|
||||
NULL,
|
||||
xml_lookupProperty,
|
||||
xml_defineProperty,
|
||||
xml_getProperty,
|
||||
xml_setProperty,
|
||||
xml_getAttributes,
|
||||
xml_setAttributes,
|
||||
xml_deleteProperty,
|
||||
xml_enumerate,
|
||||
xml_typeOf,
|
||||
js_TraceObject,
|
||||
NULL, /* thisObject */
|
||||
xml_clear
|
||||
};
|
||||
|
||||
static JSObjectOps *
|
||||
xml_getObjectOps(JSContext *cx, Class *clasp)
|
||||
{
|
||||
return &js_XMLObjectOps;
|
||||
}
|
||||
|
||||
JS_FRIEND_DATA(Class) js_XMLClass = {
|
||||
js_XML_str,
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_XML),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
xml_convert,
|
||||
xml_finalize,
|
||||
NULL, /* reserved0 */
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
xml_hasInstance,
|
||||
JS_CLASS_TRACE(xml_trace),
|
||||
JS_NULL_CLASS_EXT,
|
||||
{
|
||||
xml_lookupProperty,
|
||||
xml_defineProperty,
|
||||
xml_getProperty,
|
||||
xml_setProperty,
|
||||
xml_getAttributes,
|
||||
xml_setAttributes,
|
||||
xml_deleteProperty,
|
||||
xml_enumerate,
|
||||
xml_typeOf,
|
||||
NULL, /* trace */
|
||||
NULL, /* thisObject */
|
||||
xml_clear
|
||||
}
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_MARK_IS_TRACE |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_XML),
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, xml_convert, xml_finalize,
|
||||
xml_getObjectOps, NULL, NULL, NULL,
|
||||
NULL, xml_hasInstance, JS_CLASS_TRACE(xml_trace), NULL
|
||||
};
|
||||
|
||||
static JSXML *
|
||||
@ -6294,7 +6254,7 @@ xml_replace(JSContext *cx, uintN argc, jsval *vp)
|
||||
* Call function QName per spec, not ToXMLName, to avoid attribute
|
||||
* names.
|
||||
*/
|
||||
if (!QNameHelper(cx, NULL, &js_QNameClass, argc == 0 ? -1 : 1,
|
||||
if (!QNameHelper(cx, NULL, &js_QNameClass.base, argc == 0 ? -1 : 1,
|
||||
vp + 2, vp)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
@ -6357,7 +6317,7 @@ xml_setLocalName(JSContext *cx, uintN argc, jsval *vp)
|
||||
} else {
|
||||
name = vp[2];
|
||||
if (!JSVAL_IS_PRIMITIVE(name) &&
|
||||
JSVAL_TO_OBJECT(name)->getClass() == &js_QNameClass) {
|
||||
JSVAL_TO_OBJECT(name)->getClass() == &js_QNameClass.base) {
|
||||
nameqn = JSVAL_TO_OBJECT(name);
|
||||
namestr = GetLocalName(nameqn);
|
||||
} else {
|
||||
@ -6394,13 +6354,13 @@ xml_setName(JSContext *cx, uintN argc, jsval *vp)
|
||||
} else {
|
||||
name = vp[2];
|
||||
if (!JSVAL_IS_PRIMITIVE(name) &&
|
||||
JSVAL_TO_OBJECT(name)->getClass() == &js_QNameClass &&
|
||||
JSVAL_TO_OBJECT(name)->getClass() == &js_QNameClass.base &&
|
||||
!GetURI(nameqn = JSVAL_TO_OBJECT(name))) {
|
||||
name = vp[2] = nameqn->getQNameLocalName();
|
||||
}
|
||||
}
|
||||
|
||||
nameqn = js_ConstructObject(cx, &js_QNameClass, NULL, NULL, 1, Valueify(&name));
|
||||
nameqn = js_ConstructObject(cx, &js_QNameClass.base, NULL, NULL, 1, Valueify(&name));
|
||||
if (!nameqn)
|
||||
return JS_FALSE;
|
||||
|
||||
@ -6499,7 +6459,7 @@ xml_setNamespace(JSContext *cx, uintN argc, jsval *vp)
|
||||
if (!xml)
|
||||
return JS_FALSE;
|
||||
|
||||
ns = js_ConstructObject(cx, &js_NamespaceClass, NULL, obj,
|
||||
ns = js_ConstructObject(cx, &js_NamespaceClass.base, NULL, obj,
|
||||
argc == 0 ? 0 : 1, Valueify(vp + 2));
|
||||
if (!ns)
|
||||
return JS_FALSE;
|
||||
@ -6508,7 +6468,7 @@ xml_setNamespace(JSContext *cx, uintN argc, jsval *vp)
|
||||
|
||||
qnargv[0] = vp[2] = OBJECT_TO_JSVAL(ns);
|
||||
qnargv[1] = OBJECT_TO_JSVAL(xml->name);
|
||||
qn = js_ConstructObject(cx, &js_QNameClass, NULL, NULL, 2, Valueify(qnargv));
|
||||
qn = js_ConstructObject(cx, &js_QNameClass.base, NULL, NULL, 2, Valueify(qnargv));
|
||||
if (!qn)
|
||||
return JS_FALSE;
|
||||
|
||||
@ -7035,14 +6995,14 @@ js_GetXMLObject(JSContext *cx, JSXML *xml)
|
||||
JSObject *
|
||||
js_InitNamespaceClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return js_InitClass(cx, obj, NULL, &js_NamespaceClass, Namespace, 2,
|
||||
return js_InitClass(cx, obj, NULL, &js_NamespaceClass.base, Namespace, 2,
|
||||
namespace_props, namespace_methods, NULL, NULL);
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js_InitQNameClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return js_InitClass(cx, obj, NULL, &js_QNameClass, QName, 2,
|
||||
return js_InitClass(cx, obj, NULL, &js_QNameClass.base, QName, 2,
|
||||
qname_props, qname_methods, NULL, NULL);
|
||||
}
|
||||
|
||||
@ -7238,7 +7198,7 @@ js_GetDefaultXMLNamespace(JSContext *cx, jsval *vp)
|
||||
obj = tmp;
|
||||
}
|
||||
|
||||
ns = js_ConstructObject(cx, &js_NamespaceClass, NULL, obj, 0, NULL);
|
||||
ns = js_ConstructObject(cx, &js_NamespaceClass.base, NULL, obj, 0, NULL);
|
||||
if (!ns)
|
||||
return JS_FALSE;
|
||||
v = OBJECT_TO_JSVAL(ns);
|
||||
@ -7259,7 +7219,7 @@ js_SetDefaultXMLNamespace(JSContext *cx, const Value &v)
|
||||
|
||||
argv[0].setString(cx->runtime->emptyString);
|
||||
argv[1] = v;
|
||||
ns = js_ConstructObject(cx, &js_NamespaceClass, NULL, NULL, 2, argv);
|
||||
ns = js_ConstructObject(cx, &js_NamespaceClass.base, NULL, NULL, 2, argv);
|
||||
if (!ns)
|
||||
return JS_FALSE;
|
||||
|
||||
@ -7425,13 +7385,13 @@ js_FindXMLProperty(JSContext *cx, const Value &nameval, JSObject **objp, jsid *i
|
||||
nameobj = &nameval.toObject();
|
||||
if (nameobj->getClass() == &js_AnyNameClass) {
|
||||
v = ATOM_TO_JSVAL(cx->runtime->atomState.starAtom);
|
||||
nameobj = js_ConstructObject(cx, &js_QNameClass, NULL, NULL, 1,
|
||||
nameobj = js_ConstructObject(cx, &js_QNameClass.base, NULL, NULL, 1,
|
||||
Valueify(&v));
|
||||
if (!nameobj)
|
||||
return JS_FALSE;
|
||||
} else {
|
||||
JS_ASSERT(nameobj->getClass() == &js_AttributeNameClass ||
|
||||
nameobj->getClass() == &js_QNameClass);
|
||||
nameobj->getClass() == &js_QNameClass.base);
|
||||
}
|
||||
|
||||
qn = nameobj;
|
||||
@ -7606,21 +7566,10 @@ xmlfilter_finalize(JSContext *cx, JSObject *obj)
|
||||
Class js_XMLFilterClass = {
|
||||
"XMLFilter",
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_IS_ANONYMOUS | JSCLASS_MARK_IS_TRACE,
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
PropertyStub, /* setProperty */
|
||||
EnumerateStub,
|
||||
ResolveStub,
|
||||
ConvertStub,
|
||||
xmlfilter_finalize,
|
||||
NULL, /* reserved0 */
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
NULL, /* hasInstance */
|
||||
JS_CLASS_TRACE(xmlfilter_trace)
|
||||
PropertyStub, PropertyStub, PropertyStub, PropertyStub,
|
||||
EnumerateStub, ResolveStub, ConvertStub, xmlfilter_finalize,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, JS_CLASS_TRACE(xmlfilter_trace), NULL
|
||||
};
|
||||
|
||||
JSBool
|
||||
|
@ -216,12 +216,13 @@ js_NewXMLObject(JSContext *cx, JSXMLClass xml_class);
|
||||
extern JSObject *
|
||||
js_GetXMLObject(JSContext *cx, JSXML *xml);
|
||||
|
||||
extern JS_FRIEND_DATA(js::Class) js_XMLClass;
|
||||
extern JS_FRIEND_DATA(js::Class) js_NamespaceClass;
|
||||
extern JS_FRIEND_DATA(js::Class) js_QNameClass;
|
||||
extern JS_FRIEND_DATA(js::Class) js_AttributeNameClass;
|
||||
extern JS_FRIEND_DATA(js::Class) js_AnyNameClass;
|
||||
extern js::Class js_XMLFilterClass;
|
||||
extern JS_FRIEND_DATA(JSObjectOps) js_XMLObjectOps;
|
||||
extern JS_FRIEND_DATA(js::Class) js_XMLClass;
|
||||
extern JS_FRIEND_DATA(js::ExtendedClass) js_NamespaceClass;
|
||||
extern JS_FRIEND_DATA(js::ExtendedClass) js_QNameClass;
|
||||
extern JS_FRIEND_DATA(js::Class) js_AttributeNameClass;
|
||||
extern JS_FRIEND_DATA(js::Class) js_AnyNameClass;
|
||||
extern js::Class js_XMLFilterClass;
|
||||
|
||||
/*
|
||||
* Methods to test whether an object or a value is of type "xml" (per typeof).
|
||||
@ -229,14 +230,14 @@ extern js::Class js_XMLFilterClass;
|
||||
inline bool
|
||||
JSObject::isXML() const
|
||||
{
|
||||
return getClass() == &js_XMLClass;
|
||||
return map->ops == &js_XMLObjectOps;
|
||||
}
|
||||
|
||||
inline bool
|
||||
JSObject::isXMLId() const
|
||||
{
|
||||
js::Class *clasp = getClass();
|
||||
return clasp == &js_QNameClass ||
|
||||
return clasp == &js_QNameClass.base ||
|
||||
clasp == &js_AttributeNameClass ||
|
||||
clasp == &js_AnyNameClass;
|
||||
}
|
||||
@ -246,14 +247,14 @@ JSObject::isXMLId() const
|
||||
inline bool
|
||||
JSObject::isNamespace() const
|
||||
{
|
||||
return getClass() == &js_NamespaceClass;
|
||||
return getClass() == &js_NamespaceClass.base;
|
||||
}
|
||||
|
||||
inline bool
|
||||
JSObject::isQName() const
|
||||
{
|
||||
js::Class* clasp = getClass();
|
||||
return clasp == &js_QNameClass ||
|
||||
return clasp == &js_QNameClass.base ||
|
||||
clasp == &js_AttributeNameClass ||
|
||||
clasp == &js_AnyNameClass;
|
||||
}
|
||||
|
@ -1393,7 +1393,7 @@ ValueToScript(JSContext *cx, jsval v)
|
||||
|
||||
if (clasp == Jsvalify(&js_ScriptClass)) {
|
||||
script = (JSScript *) JS_GetPrivate(cx, obj);
|
||||
} else if (clasp == Jsvalify(&js_GeneratorClass)) {
|
||||
} else if (clasp == Jsvalify(&js_GeneratorClass.base)) {
|
||||
JSGenerator *gen = (JSGenerator *) JS_GetPrivate(cx, obj);
|
||||
fun = gen->getFloatingFrame()->fun;
|
||||
script = FUN_SCRIPT(fun);
|
||||
@ -2743,6 +2743,18 @@ split_thisObject(JSContext *cx, JSObject *obj)
|
||||
return obj;
|
||||
}
|
||||
|
||||
static JSObjectOps split_objectops;
|
||||
|
||||
static JSObjectOps *
|
||||
split_getObjectOps(JSContext *cx, JSClass *clasp)
|
||||
{
|
||||
if (!split_objectops.thisObject) {
|
||||
memcpy(&split_objectops, &js_ObjectOps, sizeof split_objectops);
|
||||
split_objectops.thisObject = split_thisObject;
|
||||
}
|
||||
|
||||
return &split_objectops;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
split_equality(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp);
|
||||
@ -2760,45 +2772,19 @@ split_innerObject(JSContext *cx, JSObject *obj)
|
||||
return !cpx->isInner ? cpx->inner : obj;
|
||||
}
|
||||
|
||||
static Class split_global_class = {
|
||||
"split_global",
|
||||
JSCLASS_NEW_RESOLVE | JSCLASS_NEW_ENUMERATE | JSCLASS_HAS_PRIVATE | JSCLASS_GLOBAL_FLAGS,
|
||||
Valueify(split_addProperty),
|
||||
Valueify(split_delProperty),
|
||||
Valueify(split_getProperty),
|
||||
Valueify(split_setProperty),
|
||||
static JSExtendedClass split_global_class = {
|
||||
{"split_global",
|
||||
JSCLASS_NEW_RESOLVE | JSCLASS_NEW_ENUMERATE | JSCLASS_HAS_PRIVATE |
|
||||
JSCLASS_GLOBAL_FLAGS | JSCLASS_IS_EXTENDED,
|
||||
split_addProperty, split_delProperty,
|
||||
split_getProperty, split_setProperty,
|
||||
(JSEnumerateOp)split_enumerate,
|
||||
(JSResolveOp)split_resolve,
|
||||
ConvertStub,
|
||||
split_finalize,
|
||||
NULL, /* reserved0 */
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
NULL, /* hasInstance */
|
||||
split_mark,
|
||||
{
|
||||
Valueify(split_equality),
|
||||
split_outerObject,
|
||||
split_innerObject,
|
||||
NULL, /* iteratorObject */
|
||||
NULL, /* wrappedObject */
|
||||
},
|
||||
{
|
||||
NULL, /* lookupProperty */
|
||||
NULL, /* defineProperty */
|
||||
NULL, /* getProperty */
|
||||
NULL, /* setProperty */
|
||||
NULL, /* getAttributes */
|
||||
NULL, /* setAttributes */
|
||||
NULL, /* deleteProperty */
|
||||
NULL, /* enumerate */
|
||||
NULL, /* typeOf */
|
||||
NULL, /* trace */
|
||||
split_thisObject,
|
||||
NULL, /* clear */
|
||||
},
|
||||
JS_ConvertStub, split_finalize,
|
||||
split_getObjectOps, NULL, NULL, NULL, NULL, NULL,
|
||||
split_mark, NULL},
|
||||
split_equality, split_outerObject, split_innerObject,
|
||||
NULL, NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
static JSBool
|
||||
@ -2809,7 +2795,7 @@ split_equality(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp)
|
||||
return JS_TRUE;
|
||||
|
||||
JSObject *obj2 = JSVAL_TO_OBJECT(*v);
|
||||
if (obj2->getClass() != &split_global_class)
|
||||
if (JS_GET_CLASS(cx, obj2) != &split_global_class.base)
|
||||
return JS_TRUE;
|
||||
|
||||
ComplexObject *cpx = (ComplexObject *) JS_GetPrivate(cx, obj2);
|
||||
@ -2836,7 +2822,7 @@ split_create_outer(JSContext *cx)
|
||||
cpx->inner = NULL;
|
||||
cpx->outer = NULL;
|
||||
|
||||
obj = JS_NewGlobalObject(cx, Jsvalify(&split_global_class));
|
||||
obj = JS_NewGlobalObject(cx, &split_global_class.base);
|
||||
if (!obj || !JS_SetParent(cx, obj, NULL)) {
|
||||
JS_free(cx, cpx);
|
||||
return NULL;
|
||||
@ -2856,7 +2842,7 @@ split_create_inner(JSContext *cx, JSObject *outer)
|
||||
ComplexObject *cpx, *outercpx;
|
||||
JSObject *obj;
|
||||
|
||||
JS_ASSERT(outer->getClass() == &split_global_class);
|
||||
JS_ASSERT(JS_GET_CLASS(cx, outer) == &split_global_class.base);
|
||||
|
||||
cpx = (ComplexObject *) JS_malloc(cx, sizeof *cpx);
|
||||
if (!cpx)
|
||||
@ -2866,7 +2852,7 @@ split_create_inner(JSContext *cx, JSObject *outer)
|
||||
cpx->inner = NULL;
|
||||
cpx->outer = outer;
|
||||
|
||||
obj = JS_NewGlobalObject(cx, Jsvalify(&split_global_class));
|
||||
obj = JS_NewGlobalObject(cx, &split_global_class.base);
|
||||
if (!obj || !JS_SetParent(cx, obj, NULL) || !JS_SetPrivate(cx, obj, cpx)) {
|
||||
JS_free(cx, cpx);
|
||||
return NULL;
|
||||
@ -2883,7 +2869,7 @@ static ComplexObject *
|
||||
split_get_private(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
do {
|
||||
if (obj->getClass() == &split_global_class)
|
||||
if (JS_GET_CLASS(cx, obj) == &split_global_class.base)
|
||||
return (ComplexObject *) JS_GetPrivate(cx, obj);
|
||||
obj = JS_GetParent(cx, obj);
|
||||
} while (obj);
|
||||
@ -3668,8 +3654,12 @@ Parent(JSContext *cx, uintN argc, jsval *vp)
|
||||
|
||||
/* Outerize if necessary. Embrace the ugliness! */
|
||||
if (parent) {
|
||||
if (JSObjectOp op = parent->getClass()->ext.outerObject)
|
||||
*vp = OBJECT_TO_JSVAL(op(cx, parent));
|
||||
JSClass *clasp = JS_GET_CLASS(cx, parent);
|
||||
if (clasp->flags & JSCLASS_IS_EXTENDED) {
|
||||
JSExtendedClass *xclasp = reinterpret_cast<JSExtendedClass *>(clasp);
|
||||
if (JSObjectOp outerize = xclasp->outerObject)
|
||||
*vp = OBJECT_TO_JSVAL(outerize(cx, parent));
|
||||
}
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
|
@ -59,7 +59,6 @@
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "jsobj.h"
|
||||
|
||||
#include "mozilla/FunctionTimer.h"
|
||||
|
||||
@ -205,13 +204,18 @@ mozJSSubScriptLoader::LoadSubScript (const PRUnichar * aURL
|
||||
|
||||
// Innerize the target_obj so that we compile the loaded script in the
|
||||
// correct (inner) scope.
|
||||
if (JSObjectOp op = target_obj->getClass()->ext.innerObject)
|
||||
JSClass *target_class = JS_GET_CLASS(cx, target_obj);
|
||||
if (target_class->flags & JSCLASS_IS_EXTENDED)
|
||||
{
|
||||
target_obj = op(cx, target_obj);
|
||||
if (!target_obj) return NS_ERROR_FAILURE;
|
||||
JSExtendedClass *extended = (JSExtendedClass*)target_class;
|
||||
if (extended->innerObject)
|
||||
{
|
||||
target_obj = extended->innerObject(cx, target_obj);
|
||||
if (!target_obj) return NS_ERROR_FAILURE;
|
||||
#ifdef DEBUG_rginda
|
||||
fprintf (stderr, "Final global: %p\n", target_obj);
|
||||
fprintf (stderr, "Final global: %p\n", target_obj);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* load up the url. From here on, failures are reflected as ``custom''
|
||||
|
@ -251,34 +251,28 @@ using namespace XPCWrapper;
|
||||
|
||||
namespace ChromeObjectWrapper {
|
||||
|
||||
js::Class COWClass = {
|
||||
"ChromeObjectWrapper",
|
||||
JSCLASS_NEW_RESOLVE |
|
||||
JSExtendedClass COWClass = {
|
||||
// JSClass (JSExtendedClass.base) initialization
|
||||
{ "ChromeObjectWrapper",
|
||||
JSCLASS_NEW_RESOLVE | JSCLASS_IS_EXTENDED |
|
||||
JSCLASS_HAS_RESERVED_SLOTS(XPCWrapper::sNumSlots + 1),
|
||||
js::Valueify(XPC_COW_AddProperty),
|
||||
js::Valueify(XPC_COW_DelProperty),
|
||||
js::Valueify(XPC_COW_GetProperty),
|
||||
js::Valueify(XPC_COW_SetProperty),
|
||||
XPC_COW_Enumerate,
|
||||
(JSResolveOp)XPC_COW_NewResolve,
|
||||
js::Valueify(XPC_COW_Convert),
|
||||
JS_FinalizeStub,
|
||||
nsnull, // reserved0
|
||||
js::Valueify(XPC_COW_CheckAccess),
|
||||
nsnull, // call
|
||||
nsnull, // construct
|
||||
nsnull, // xdrObject
|
||||
nsnull, // hasInstance
|
||||
nsnull, // mark
|
||||
XPC_COW_AddProperty, XPC_COW_DelProperty,
|
||||
XPC_COW_GetProperty, XPC_COW_SetProperty,
|
||||
XPC_COW_Enumerate, (JSResolveOp)XPC_COW_NewResolve,
|
||||
XPC_COW_Convert, JS_FinalizeStub,
|
||||
nsnull, XPC_COW_CheckAccess,
|
||||
nsnull, nsnull,
|
||||
nsnull, nsnull,
|
||||
nsnull, nsnull
|
||||
},
|
||||
|
||||
// ClassExtension
|
||||
{
|
||||
js::Valueify(XPC_COW_Equality),
|
||||
nsnull, // outerObject
|
||||
nsnull, // innerObject
|
||||
XPC_COW_Iterator,
|
||||
XPC_COW_WrappedObject
|
||||
}
|
||||
// JSExtendedClass initialization
|
||||
XPC_COW_Equality,
|
||||
nsnull, // outerObject
|
||||
nsnull, // innerObject
|
||||
XPC_COW_Iterator,
|
||||
XPC_COW_WrappedObject,
|
||||
JSCLASS_NO_RESERVED_MEMBERS
|
||||
};
|
||||
|
||||
JSBool
|
||||
@ -289,7 +283,7 @@ WrapObject(JSContext *cx, JSObject *parent, jsval v, jsval *vp)
|
||||
}
|
||||
|
||||
JSObject *wrapperObj =
|
||||
JS_NewObjectWithGivenProto(cx, js::Jsvalify(&COWClass), NULL, parent);
|
||||
JS_NewObjectWithGivenProto(cx, &COWClass.base, NULL, parent);
|
||||
if (!wrapperObj) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
@ -329,8 +323,13 @@ ThrowException(nsresult rv, JSContext *cx)
|
||||
static inline JSObject *
|
||||
GetWrappedJSObject(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JSObjectOp op = obj->getClass()->ext.wrappedObject;
|
||||
if (!op) {
|
||||
JSClass *clasp = obj->getJSClass();
|
||||
if (!(clasp->flags & JSCLASS_IS_EXTENDED)) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
JSExtendedClass *xclasp = (JSExtendedClass *)clasp;
|
||||
if (!xclasp->wrappedObject) {
|
||||
if (XPCNativeWrapper::IsNativeWrapper(obj)) {
|
||||
XPCWrappedNative *wn = XPCNativeWrapper::SafeGetWrappedNative(obj);
|
||||
return wn ? wn->GetFlatJSObject() : nsnull;
|
||||
@ -339,7 +338,7 @@ GetWrappedJSObject(JSContext *cx, JSObject *obj)
|
||||
return obj;
|
||||
}
|
||||
|
||||
return op(cx, obj);
|
||||
return xclasp->wrappedObject(cx, obj);
|
||||
}
|
||||
|
||||
// Get the (possibly nonexistent) COW off of an object
|
||||
@ -348,7 +347,7 @@ static inline
|
||||
JSObject *
|
||||
GetWrapper(JSObject *obj)
|
||||
{
|
||||
while (obj->getClass() != &COWClass) {
|
||||
while (obj->getJSClass() != &COWClass.base) {
|
||||
obj = obj->getProto();
|
||||
if (!obj) {
|
||||
break;
|
||||
@ -749,7 +748,8 @@ XPC_COW_Equality(JSContext *cx, JSObject *obj, const jsval *valp, JSBool *bp)
|
||||
obj = me->GetFlatJSObject();
|
||||
test = other->GetFlatJSObject();
|
||||
jsval testVal = OBJECT_TO_JSVAL(test);
|
||||
return js::Jsvalify(obj->getClass()->ext.equality)(cx, obj, &testVal, bp);
|
||||
return ((JSExtendedClass *)obj->getJSClass())->
|
||||
equality(cx, obj, &testVal, bp);
|
||||
}
|
||||
|
||||
static JSObject *
|
||||
|
@ -125,7 +125,7 @@ static inline
|
||||
JSObject *
|
||||
GetWrapper(JSObject *obj)
|
||||
{
|
||||
while (obj->getClass() != &XPCCrossOriginWrapper::XOWClass) {
|
||||
while (obj->getJSClass() != &XPCCrossOriginWrapper::XOWClass.base) {
|
||||
obj = obj->getProto();
|
||||
if (!obj) {
|
||||
break;
|
||||
@ -156,34 +156,28 @@ static const PRUint32 FLAG_IS_CACHED = XPCWrapper::LAST_FLAG << 2;
|
||||
|
||||
namespace XPCCrossOriginWrapper {
|
||||
|
||||
js::Class XOWClass = {
|
||||
"XPCCrossOriginWrapper",
|
||||
JSCLASS_NEW_RESOLVE |
|
||||
JSExtendedClass XOWClass = {
|
||||
// JSClass (JSExtendedClass.base) initialization
|
||||
{ "XPCCrossOriginWrapper",
|
||||
JSCLASS_NEW_RESOLVE | JSCLASS_IS_EXTENDED |
|
||||
JSCLASS_HAS_RESERVED_SLOTS(XPCWrapper::sNumSlots + 2),
|
||||
js::Valueify(XPC_XOW_AddProperty),
|
||||
js::Valueify(XPC_XOW_DelProperty),
|
||||
js::Valueify(XPC_XOW_GetProperty),
|
||||
js::Valueify(XPC_XOW_SetProperty),
|
||||
XPC_XOW_Enumerate,
|
||||
(JSResolveOp)XPC_XOW_NewResolve,
|
||||
js::Valueify(XPC_XOW_Convert),
|
||||
XPC_XOW_Finalize,
|
||||
nsnull, // reserved0
|
||||
js::Valueify(XPC_XOW_CheckAccess),
|
||||
js::Valueify(XPC_XOW_Call),
|
||||
js::Valueify(XPC_XOW_Construct),
|
||||
nsnull, // xdrObject
|
||||
js::Valueify(XPC_XOW_HasInstance),
|
||||
nsnull, // mark
|
||||
XPC_XOW_AddProperty, XPC_XOW_DelProperty,
|
||||
XPC_XOW_GetProperty, XPC_XOW_SetProperty,
|
||||
XPC_XOW_Enumerate, (JSResolveOp)XPC_XOW_NewResolve,
|
||||
XPC_XOW_Convert, XPC_XOW_Finalize,
|
||||
nsnull, XPC_XOW_CheckAccess,
|
||||
XPC_XOW_Call, XPC_XOW_Construct,
|
||||
nsnull, XPC_XOW_HasInstance,
|
||||
nsnull, nsnull
|
||||
},
|
||||
|
||||
// ClassExtension
|
||||
{
|
||||
js::Valueify(XPC_XOW_Equality),
|
||||
nsnull, // outerObject
|
||||
nsnull, // innerObject
|
||||
XPC_XOW_Iterator,
|
||||
XPC_XOW_WrappedObject
|
||||
}
|
||||
// JSExtendedClass initialization
|
||||
XPC_XOW_Equality,
|
||||
nsnull, // outerObject
|
||||
nsnull, // innerObject
|
||||
XPC_XOW_Iterator,
|
||||
XPC_XOW_WrappedObject,
|
||||
JSCLASS_NO_RESERVED_MEMBERS
|
||||
};
|
||||
|
||||
JSBool
|
||||
@ -382,7 +376,7 @@ RewrapIfNeeded(JSContext *cx, JSObject *outerObj, jsval *vp)
|
||||
}
|
||||
|
||||
XPCWrappedNative *wn = nsnull;
|
||||
if (obj->getClass() == &XOWClass &&
|
||||
if (obj->getJSClass() == &XOWClass.base &&
|
||||
outerObj->getParent() != obj->getParent()) {
|
||||
*vp = OBJECT_TO_JSVAL(GetWrappedObject(cx, obj));
|
||||
} else if (!(wn = XPCWrappedNative::GetAndMorphWrappedNativeOfJSObject(cx, obj))) {
|
||||
@ -403,7 +397,7 @@ WrapObject(JSContext *cx, JSObject *parent, jsval *vp, XPCWrappedNative* wn)
|
||||
JSObject *wrappedObj;
|
||||
if (JSVAL_IS_PRIMITIVE(*vp) ||
|
||||
!(wrappedObj = JSVAL_TO_OBJECT(*vp)) ||
|
||||
wrappedObj->getClass() == &XOWClass) {
|
||||
wrappedObj->getJSClass() == &XOWClass.base) {
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
@ -451,7 +445,7 @@ WrapObject(JSContext *cx, JSObject *parent, jsval *vp, XPCWrappedNative* wn)
|
||||
|
||||
outerObj = map->Find(wrappedObj);
|
||||
if (outerObj) {
|
||||
NS_ASSERTION(outerObj->getClass() == &XOWClass,
|
||||
NS_ASSERTION(outerObj->getJSClass() == &XOWClass.base,
|
||||
"What crazy object are we getting here?");
|
||||
*vp = OBJECT_TO_JSVAL(outerObj);
|
||||
|
||||
@ -464,7 +458,7 @@ WrapObject(JSContext *cx, JSObject *parent, jsval *vp, XPCWrappedNative* wn)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
outerObj = JS_NewObjectWithGivenProto(cx, js::Jsvalify(&XOWClass), nsnull,
|
||||
outerObj = JS_NewObjectWithGivenProto(cx, &XOWClass.base, nsnull,
|
||||
parent);
|
||||
if (!outerObj) {
|
||||
return JS_FALSE;
|
||||
@ -596,14 +590,14 @@ WrapSameOriginProp(JSContext *cx, JSObject *outerObj, jsval *vp)
|
||||
}
|
||||
|
||||
JSObject *wrappedObj = JSVAL_TO_OBJECT(*vp);
|
||||
js::Class *clasp = wrappedObj->getClass();
|
||||
JSClass *clasp = wrappedObj->getJSClass();
|
||||
if (ClassNeedsXOW(clasp->name)) {
|
||||
return WrapObject(cx, JS_GetGlobalForObject(cx, outerObj), vp);
|
||||
}
|
||||
|
||||
// Check if wrappedObj is an XOW. If so, verify that it's from the
|
||||
// right scope.
|
||||
if (clasp == &XOWClass &&
|
||||
if (clasp == &XOWClass.base &&
|
||||
wrappedObj->getParent() != outerObj->getParent()) {
|
||||
*vp = OBJECT_TO_JSVAL(GetWrappedObject(cx, wrappedObj));
|
||||
return WrapObject(cx, outerObj->getParent(), vp);
|
||||
@ -626,7 +620,7 @@ XPC_XOW_AddProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
|
||||
if (!JSVAL_IS_PRIMITIVE(*vp)) {
|
||||
JSObject *addedObj = JSVAL_TO_OBJECT(*vp);
|
||||
if (addedObj->getClass() == &XOWClass &&
|
||||
if (addedObj->getJSClass() == &XOWClass.base &&
|
||||
addedObj->getParent() != obj->getParent()) {
|
||||
*vp = OBJECT_TO_JSVAL(GetWrappedObject(cx, addedObj));
|
||||
if (!WrapObject(cx, obj->getParent(), vp, nsnull)) {
|
||||
@ -848,7 +842,7 @@ XPC_XOW_Enumerate(JSContext *cx, JSObject *obj)
|
||||
static JSObject *
|
||||
GetUXPCObject(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
NS_ASSERTION(obj->getClass() == &XOWClass, "wrong object");
|
||||
NS_ASSERTION(obj->getJSClass() == &XOWClass.base, "wrong object");
|
||||
|
||||
jsval v;
|
||||
if (!JS_GetReservedSlot(cx, obj, sFlagsSlot, &v)) {
|
||||
@ -868,8 +862,7 @@ GetUXPCObject(JSContext *cx, JSObject *obj)
|
||||
}
|
||||
|
||||
JSObject *uxpco =
|
||||
JS_NewObjectWithGivenProto(cx, js::Jsvalify(&XOWClass), nsnull,
|
||||
obj->getParent());
|
||||
JS_NewObjectWithGivenProto(cx, &XOWClass.base, nsnull, obj->getParent());
|
||||
if (!uxpco) {
|
||||
return nsnull;
|
||||
}
|
||||
@ -1188,7 +1181,7 @@ XPC_XOW_Equality(JSContext *cx, JSObject *obj, const jsval *valp, JSBool *bp)
|
||||
}
|
||||
|
||||
JSObject *test = JSVAL_TO_OBJECT(v);
|
||||
if (test->getClass() == &XOWClass) {
|
||||
if (test->getJSClass() == &XOWClass.base) {
|
||||
if (!JS_GetReservedSlot(cx, test, sWrappedObjSlot, &v)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
@ -1216,7 +1209,8 @@ XPC_XOW_Equality(JSContext *cx, JSObject *obj, const jsval *valp, JSBool *bp)
|
||||
obj = me->GetFlatJSObject();
|
||||
test = other->GetFlatJSObject();
|
||||
jsval testVal = OBJECT_TO_JSVAL(test);
|
||||
return js::Jsvalify(obj->getClass()->ext.equality)(cx, obj, &testVal, bp);
|
||||
return ((JSExtendedClass *)obj->getJSClass())->
|
||||
equality(cx, obj, &testVal, bp);
|
||||
}
|
||||
|
||||
static JSObject *
|
||||
@ -1246,7 +1240,7 @@ XPC_XOW_Iterator(JSContext *cx, JSObject *obj, JSBool keysonly)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
JSObject *wrapperIter = JS_NewObject(cx, js::Jsvalify(&XOWClass), nsnull,
|
||||
JSObject *wrapperIter = JS_NewObject(cx, &XOWClass.base, nsnull,
|
||||
JS_GetGlobalForObject(cx, obj));
|
||||
if (!wrapperIter) {
|
||||
return nsnull;
|
||||
|
@ -109,68 +109,56 @@ namespace XPCNativeWrapper { namespace internal {
|
||||
// JS class for XPCNativeWrapper (and this doubles as the constructor
|
||||
// for XPCNativeWrapper for the moment too...)
|
||||
|
||||
js::Class NW_NoCall_Class = {
|
||||
"XPCNativeWrapper",
|
||||
JSExtendedClass NW_NoCall_Class = {
|
||||
// JSClass (JSExtendedClass.base) initialization
|
||||
{ "XPCNativeWrapper",
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS |
|
||||
// Our one reserved slot holds a jsint of flag bits
|
||||
JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(1) |
|
||||
JSCLASS_MARK_IS_TRACE | JSCLASS_CONSTRUCT_PROTOTYPE,
|
||||
js::Valueify(XPC_NW_AddProperty),
|
||||
js::Valueify(XPC_NW_DelProperty),
|
||||
js::Valueify(XPC_NW_GetProperty),
|
||||
js::Valueify(XPC_NW_SetProperty),
|
||||
XPC_NW_Enumerate,
|
||||
(JSResolveOp)XPC_NW_NewResolve,
|
||||
js::Valueify(XPC_NW_Convert),
|
||||
XPC_NW_Finalize,
|
||||
nsnull, // reserved0
|
||||
js::Valueify(XPC_NW_CheckAccess),
|
||||
nsnull, // call
|
||||
js::Valueify(XPC_NW_Construct),
|
||||
nsnull, // xdrObject
|
||||
js::Valueify(XPC_NW_HasInstance),
|
||||
JS_CLASS_TRACE(XPC_NW_Trace),
|
||||
JSCLASS_MARK_IS_TRACE | JSCLASS_IS_EXTENDED | JSCLASS_CONSTRUCT_PROTOTYPE,
|
||||
XPC_NW_AddProperty, XPC_NW_DelProperty,
|
||||
XPC_NW_GetProperty, XPC_NW_SetProperty,
|
||||
XPC_NW_Enumerate, (JSResolveOp)XPC_NW_NewResolve,
|
||||
XPC_NW_Convert, XPC_NW_Finalize,
|
||||
nsnull, XPC_NW_CheckAccess,
|
||||
nsnull, XPC_NW_Construct,
|
||||
nsnull, XPC_NW_HasInstance,
|
||||
JS_CLASS_TRACE(XPC_NW_Trace), nsnull
|
||||
},
|
||||
|
||||
// ClassExtension
|
||||
{
|
||||
js::Valueify(XPC_NW_Equality),
|
||||
nsnull, // outerObject
|
||||
nsnull, // innerObject
|
||||
XPC_NW_Iterator,
|
||||
nsnull, // wrappedObject
|
||||
}
|
||||
// JSExtendedClass initialization
|
||||
XPC_NW_Equality,
|
||||
nsnull, // outerObject
|
||||
nsnull, // innerObject
|
||||
XPC_NW_Iterator,
|
||||
nsnull, // wrappedObject
|
||||
JSCLASS_NO_RESERVED_MEMBERS
|
||||
};
|
||||
|
||||
js::Class NW_Call_Class = {
|
||||
"XPCNativeWrapper",
|
||||
JSExtendedClass NW_Call_Class = {
|
||||
// JSClass (JSExtendedClass.base) initialization
|
||||
{ "XPCNativeWrapper",
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS |
|
||||
// Our one reserved slot holds a jsint of flag bits
|
||||
JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(1) |
|
||||
JSCLASS_MARK_IS_TRACE | JSCLASS_CONSTRUCT_PROTOTYPE,
|
||||
js::Valueify(XPC_NW_AddProperty),
|
||||
js::Valueify(XPC_NW_DelProperty),
|
||||
js::Valueify(XPC_NW_GetProperty),
|
||||
js::Valueify(XPC_NW_SetProperty),
|
||||
XPC_NW_Enumerate,
|
||||
(JSResolveOp)XPC_NW_NewResolve,
|
||||
js::Valueify(XPC_NW_Convert),
|
||||
XPC_NW_Finalize,
|
||||
nsnull, // reserved0
|
||||
js::Valueify(XPC_NW_CheckAccess),
|
||||
js::Valueify(XPC_NW_Call),
|
||||
js::Valueify(XPC_NW_Construct),
|
||||
nsnull, // xdrObject
|
||||
js::Valueify(XPC_NW_HasInstance),
|
||||
JS_CLASS_TRACE(XPC_NW_Trace),
|
||||
JSCLASS_MARK_IS_TRACE | JSCLASS_IS_EXTENDED | JSCLASS_CONSTRUCT_PROTOTYPE,
|
||||
XPC_NW_AddProperty, XPC_NW_DelProperty,
|
||||
XPC_NW_GetProperty, XPC_NW_SetProperty,
|
||||
XPC_NW_Enumerate, (JSResolveOp)XPC_NW_NewResolve,
|
||||
XPC_NW_Convert, XPC_NW_Finalize,
|
||||
nsnull, XPC_NW_CheckAccess,
|
||||
XPC_NW_Call, XPC_NW_Construct,
|
||||
nsnull, XPC_NW_HasInstance,
|
||||
JS_CLASS_TRACE(XPC_NW_Trace), nsnull
|
||||
},
|
||||
|
||||
// ClassExtension
|
||||
{
|
||||
js::Valueify(XPC_NW_Equality),
|
||||
nsnull, // outerObject
|
||||
nsnull, // innerObject
|
||||
XPC_NW_Iterator,
|
||||
nsnull, // wrappedObject
|
||||
}
|
||||
// JSExtendedClass initialization
|
||||
XPC_NW_Equality,
|
||||
nsnull, // outerObject
|
||||
nsnull, // innerObject
|
||||
XPC_NW_Iterator,
|
||||
nsnull, // wrappedObject
|
||||
JSCLASS_NO_RESERVED_MEMBERS
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
@ -1040,8 +1028,7 @@ XPCNativeWrapper::AttachNewConstructorObject(XPCCallContext &ccx,
|
||||
JSObject *aGlobalObject)
|
||||
{
|
||||
JSObject *class_obj =
|
||||
::JS_InitClass(ccx, aGlobalObject, nsnull,
|
||||
js::Jsvalify(&internal::NW_Call_Class),
|
||||
::JS_InitClass(ccx, aGlobalObject, nsnull, &internal::NW_Call_Class.base,
|
||||
XPCNativeWrapperCtor, 0, nsnull, nsnull,
|
||||
nsnull, static_functions);
|
||||
if (!class_obj) {
|
||||
@ -1059,7 +1046,7 @@ XPCNativeWrapper::AttachNewConstructorObject(XPCCallContext &ccx,
|
||||
|
||||
JSBool found;
|
||||
return ::JS_SetPropertyAttributes(ccx, aGlobalObject,
|
||||
internal::NW_Call_Class.name,
|
||||
internal::NW_Call_Class.base.name,
|
||||
JSPROP_READONLY | JSPROP_PERMANENT,
|
||||
&found);
|
||||
}
|
||||
|
@ -45,8 +45,8 @@ class nsIPrincipal;
|
||||
namespace XPCNativeWrapper {
|
||||
|
||||
namespace internal {
|
||||
extern js::Class NW_NoCall_Class;
|
||||
extern js::Class NW_Call_Class;
|
||||
extern JSExtendedClass NW_NoCall_Class;
|
||||
extern JSExtendedClass NW_Call_Class;
|
||||
}
|
||||
|
||||
PRBool
|
||||
@ -59,16 +59,16 @@ JSBool
|
||||
CreateExplicitWrapper(JSContext *cx, XPCWrappedNative *wrapper, jsval *rval);
|
||||
|
||||
inline PRBool
|
||||
IsNativeWrapperClass(js::Class *clazz)
|
||||
IsNativeWrapperClass(JSClass *clazz)
|
||||
{
|
||||
return clazz == &internal::NW_NoCall_Class ||
|
||||
clazz == &internal::NW_Call_Class;
|
||||
return clazz == &internal::NW_NoCall_Class.base ||
|
||||
clazz == &internal::NW_Call_Class.base;
|
||||
}
|
||||
|
||||
inline PRBool
|
||||
IsNativeWrapper(JSObject *obj)
|
||||
{
|
||||
return IsNativeWrapperClass(obj->getClass());
|
||||
return IsNativeWrapperClass(obj->getJSClass());
|
||||
}
|
||||
|
||||
JSBool
|
||||
@ -86,8 +86,8 @@ inline JSClass *
|
||||
GetJSClass(bool call)
|
||||
{
|
||||
return call
|
||||
? js::Jsvalify(&internal::NW_Call_Class)
|
||||
: js::Jsvalify(&internal::NW_NoCall_Class);
|
||||
? &internal::NW_Call_Class.base
|
||||
: &internal::NW_NoCall_Class.base;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -233,7 +233,7 @@ FindObjectPrincipals(JSContext *cx, JSObject *safeObj, JSObject *innerObj)
|
||||
static inline JSObject *
|
||||
FindSafeObject(JSObject *obj)
|
||||
{
|
||||
while (obj->getClass() != &SJOWClass) {
|
||||
while (obj->getJSClass() != &SJOWClass.base) {
|
||||
obj = obj->getProto();
|
||||
|
||||
if (!obj) {
|
||||
@ -253,34 +253,27 @@ namespace XPCSafeJSObjectWrapper {
|
||||
// JS class for XPCSafeJSObjectWrapper (and this doubles as the
|
||||
// constructor for XPCSafeJSObjectWrapper for the moment too...)
|
||||
|
||||
js::Class SJOWClass = {
|
||||
"XPCSafeJSObjectWrapper",
|
||||
JSCLASS_NEW_RESOLVE |
|
||||
JSExtendedClass SJOWClass = {
|
||||
// JSClass (JSExtendedClass.base) initialization
|
||||
{ "XPCSafeJSObjectWrapper",
|
||||
JSCLASS_NEW_RESOLVE | JSCLASS_IS_EXTENDED |
|
||||
JSCLASS_HAS_RESERVED_SLOTS(sSJOWSlots),
|
||||
js::Valueify(XPC_SJOW_AddProperty),
|
||||
js::Valueify(XPC_SJOW_DelProperty),
|
||||
js::Valueify(XPC_SJOW_GetProperty),
|
||||
js::Valueify(XPC_SJOW_SetProperty),
|
||||
XPC_SJOW_Enumerate,
|
||||
(JSResolveOp)XPC_SJOW_NewResolve,
|
||||
js::Valueify(XPC_SJOW_Convert),
|
||||
XPC_SJOW_Finalize,
|
||||
nsnull, // reserved0
|
||||
js::Valueify(XPC_SJOW_CheckAccess),
|
||||
js::Valueify(XPC_SJOW_Call),
|
||||
js::Valueify(XPC_SJOW_Create),
|
||||
nsnull, // xdrObject
|
||||
nsnull, // hasInstance
|
||||
nsnull, // mark
|
||||
|
||||
// ClassExtension
|
||||
{
|
||||
js::Valueify(XPC_SJOW_Equality),
|
||||
nsnull, // outerObject
|
||||
nsnull, // innerObject
|
||||
XPC_SJOW_Iterator,
|
||||
XPC_SJOW_WrappedObject
|
||||
}
|
||||
XPC_SJOW_AddProperty, XPC_SJOW_DelProperty,
|
||||
XPC_SJOW_GetProperty, XPC_SJOW_SetProperty,
|
||||
XPC_SJOW_Enumerate, (JSResolveOp)XPC_SJOW_NewResolve,
|
||||
XPC_SJOW_Convert, XPC_SJOW_Finalize,
|
||||
nsnull, XPC_SJOW_CheckAccess,
|
||||
XPC_SJOW_Call, XPC_SJOW_Create,
|
||||
nsnull, nsnull,
|
||||
nsnull, nsnull
|
||||
},
|
||||
// JSExtendedClass initialization
|
||||
XPC_SJOW_Equality,
|
||||
nsnull, // outerObject
|
||||
nsnull, // innerObject
|
||||
XPC_SJOW_Iterator,
|
||||
XPC_SJOW_WrappedObject,
|
||||
JSCLASS_NO_RESERVED_MEMBERS
|
||||
};
|
||||
|
||||
JSBool
|
||||
@ -325,7 +318,7 @@ WrapObject(JSContext *cx, JSObject *scope, jsval v, jsval *vp)
|
||||
}
|
||||
|
||||
JSObject *wrapperObj =
|
||||
JS_NewObjectWithGivenProto(cx, js::Jsvalify(&SJOWClass), nsnull, scope);
|
||||
JS_NewObjectWithGivenProto(cx, &SJOWClass.base, nsnull, scope);
|
||||
|
||||
if (!wrapperObj) {
|
||||
// JS_NewObjectWithGivenProto already threw.
|
||||
@ -353,7 +346,7 @@ AttachNewConstructorObject(XPCCallContext &ccx, JSObject *aGlobalObject)
|
||||
}
|
||||
|
||||
JSObject *class_obj =
|
||||
::JS_InitClass(ccx, aGlobalObject, nsnull, js::Jsvalify(&SJOWClass),
|
||||
::JS_InitClass(ccx, aGlobalObject, nsnull, &SJOWClass.base,
|
||||
XPC_SJOW_Construct, 0, nsnull, nsnull, nsnull, nsnull);
|
||||
if (!class_obj) {
|
||||
NS_WARNING("can't initialize the XPCSafeJSObjectWrapper class");
|
||||
@ -375,7 +368,7 @@ AttachNewConstructorObject(XPCCallContext &ccx, JSObject *aGlobalObject)
|
||||
|
||||
JSBool found;
|
||||
return ::JS_SetPropertyAttributes(ccx, aGlobalObject,
|
||||
SJOWClass.name,
|
||||
SJOWClass.base.name,
|
||||
JSPROP_READONLY | JSPROP_PERMANENT,
|
||||
&found);
|
||||
}
|
||||
@ -453,7 +446,7 @@ WrapJSValue(JSContext *cx, JSObject *obj, jsval val, jsval *rval)
|
||||
// parent we pass in here, the construct hook will ensure we get
|
||||
// the right parent for the wrapper.
|
||||
JSObject *safeObj = JSVAL_TO_OBJECT(*rval);
|
||||
if (safeObj->getClass() == &SJOWClass &&
|
||||
if (safeObj->getJSClass() == &SJOWClass.base &&
|
||||
JS_GetGlobalForObject(cx, obj) != JS_GetGlobalForObject(cx, safeObj)) {
|
||||
// Check to see if the new object we just wrapped is accessible
|
||||
// from the unsafe object we got the new object through. If not,
|
||||
@ -1037,7 +1030,7 @@ XPC_SJOW_Iterator(JSContext *cx, JSObject *obj, JSBool keysonly)
|
||||
|
||||
// Create our dummy SJOW.
|
||||
JSObject *wrapperIter =
|
||||
JS_NewObjectWithGivenProto(cx, js::Jsvalify(&SJOWClass), nsnull,
|
||||
JS_NewObjectWithGivenProto(cx, &SJOWClass.base, nsnull,
|
||||
JS_GetGlobalForObject(cx, obj));
|
||||
if (!wrapperIter) {
|
||||
return nsnull;
|
||||
|
@ -98,34 +98,28 @@ static const char prefix[] = "chrome://global/";
|
||||
|
||||
namespace SystemOnlyWrapper {
|
||||
|
||||
js::Class SOWClass = {
|
||||
"SystemOnlyWrapper",
|
||||
JSCLASS_NEW_RESOLVE |
|
||||
JSExtendedClass SOWClass = {
|
||||
// JSClass (JSExtendedClass.base) initialization
|
||||
{ "SystemOnlyWrapper",
|
||||
JSCLASS_NEW_RESOLVE | JSCLASS_IS_EXTENDED |
|
||||
JSCLASS_HAS_RESERVED_SLOTS(XPCWrapper::sNumSlots),
|
||||
js::Valueify(XPC_SOW_AddProperty),
|
||||
js::Valueify(XPC_SOW_DelProperty),
|
||||
js::Valueify(XPC_SOW_GetProperty),
|
||||
js::Valueify(XPC_SOW_SetProperty),
|
||||
XPC_SOW_Enumerate,
|
||||
(JSResolveOp)XPC_SOW_NewResolve,
|
||||
js::Valueify(XPC_SOW_Convert),
|
||||
nsnull, // finalize
|
||||
nsnull, // reserved0
|
||||
js::Valueify(XPC_SOW_CheckAccess),
|
||||
nsnull, // call
|
||||
nsnull, // construct
|
||||
nsnull, // xdrObject
|
||||
js::Valueify(XPC_SOW_HasInstance),
|
||||
nsnull, // mark
|
||||
XPC_SOW_AddProperty, XPC_SOW_DelProperty,
|
||||
XPC_SOW_GetProperty, XPC_SOW_SetProperty,
|
||||
XPC_SOW_Enumerate, (JSResolveOp)XPC_SOW_NewResolve,
|
||||
XPC_SOW_Convert, nsnull,
|
||||
nsnull, XPC_SOW_CheckAccess,
|
||||
nsnull, nsnull,
|
||||
nsnull, XPC_SOW_HasInstance,
|
||||
nsnull, nsnull
|
||||
},
|
||||
|
||||
// ClassExtension
|
||||
{
|
||||
js::Valueify(XPC_SOW_Equality),
|
||||
nsnull, // outerObject
|
||||
nsnull, // innerObject
|
||||
XPC_SOW_Iterator,
|
||||
XPC_SOW_WrappedObject
|
||||
}
|
||||
// JSExtendedClass initialization
|
||||
XPC_SOW_Equality,
|
||||
nsnull, // outerObject
|
||||
nsnull, // innerObject
|
||||
XPC_SOW_Iterator,
|
||||
XPC_SOW_WrappedObject,
|
||||
JSCLASS_NO_RESERVED_MEMBERS
|
||||
};
|
||||
|
||||
JSBool
|
||||
@ -139,7 +133,7 @@ WrapObject(JSContext *cx, JSObject *parent, jsval v, jsval *vp)
|
||||
}
|
||||
|
||||
JSObject *wrapperObj =
|
||||
JS_NewObjectWithGivenProto(cx, js::Jsvalify(&SOWClass), NULL, parent);
|
||||
JS_NewObjectWithGivenProto(cx, &SOWClass.base, NULL, parent);
|
||||
if (!wrapperObj) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
@ -160,9 +154,9 @@ MakeSOW(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
{
|
||||
js::Class *clasp = obj->getClass();
|
||||
NS_ASSERTION(clasp != &SystemOnlyWrapper::SOWClass &&
|
||||
clasp != &XPCCrossOriginWrapper::XOWClass,
|
||||
JSClass *clasp = obj->getJSClass();
|
||||
NS_ASSERTION(clasp != &SystemOnlyWrapper::SOWClass.base &&
|
||||
clasp != &XPCCrossOriginWrapper::XOWClass.base,
|
||||
"bad call");
|
||||
}
|
||||
#endif
|
||||
@ -274,9 +268,17 @@ using namespace SystemOnlyWrapper;
|
||||
static inline JSObject *
|
||||
GetWrappedJSObject(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
if (JSObjectOp op = obj->getClass()->ext.wrappedObject)
|
||||
return op(cx, obj);
|
||||
return obj;
|
||||
JSClass *clasp = obj->getJSClass();
|
||||
if (!(clasp->flags & JSCLASS_IS_EXTENDED)) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
JSExtendedClass *xclasp = (JSExtendedClass *)clasp;
|
||||
if (!xclasp->wrappedObject) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
return xclasp->wrappedObject(cx, obj);
|
||||
}
|
||||
|
||||
// Get the (possibly nonexistent) SOW off of an object
|
||||
@ -284,7 +286,7 @@ static inline
|
||||
JSObject *
|
||||
GetWrapper(JSObject *obj)
|
||||
{
|
||||
while (obj->getClass() != &SOWClass) {
|
||||
while (obj->getJSClass() != &SOWClass.base) {
|
||||
obj = obj->getProto();
|
||||
if (!obj) {
|
||||
break;
|
||||
@ -403,7 +405,7 @@ XPC_SOW_RewrapValue(JSContext *cx, JSObject *wrapperObj, jsval *vp)
|
||||
return XPC_SOW_WrapFunction(cx, wrapperObj, obj, vp);
|
||||
}
|
||||
|
||||
if (obj->getClass() == &SOWClass) {
|
||||
if (obj->getJSClass() == &SOWClass.base) {
|
||||
// We are extra careful about content-polluted wrappers here. I don't know
|
||||
// if it's possible to reach them through objects that we wrap, but figuring
|
||||
// that out is more expensive (and harder) than simply checking and
|
||||
@ -428,7 +430,7 @@ XPC_SOW_RewrapValue(JSContext *cx, JSObject *wrapperObj, jsval *vp)
|
||||
static JSBool
|
||||
XPC_SOW_AddProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
{
|
||||
NS_ASSERTION(obj->getClass() == &SOWClass, "Wrong object");
|
||||
NS_ASSERTION(obj->getJSClass() == &SOWClass.base, "Wrong object");
|
||||
|
||||
jsval resolving;
|
||||
if (!JS_GetReservedSlot(cx, obj, sFlagsSlot, &resolving)) {
|
||||
@ -651,16 +653,23 @@ XPC_SOW_Equality(JSContext *cx, JSObject *obj, const jsval *valp, JSBool *bp)
|
||||
}
|
||||
|
||||
if (lhs) {
|
||||
if (JSEqualityOp op = js::Jsvalify(lhs->getClass()->ext.equality)) {
|
||||
// Delegate to our wrapped object if we can.
|
||||
JSClass *clasp = lhs->getJSClass();
|
||||
if (clasp->flags & JSCLASS_IS_EXTENDED) {
|
||||
JSExtendedClass *xclasp = (JSExtendedClass *) clasp;
|
||||
// NB: JSExtendedClass.equality is a required field.
|
||||
jsval rhsVal = OBJECT_TO_JSVAL(rhs);
|
||||
return op(cx, lhs, &rhsVal, bp);
|
||||
return xclasp->equality(cx, lhs, &rhsVal, bp);
|
||||
}
|
||||
}
|
||||
|
||||
// We know rhs is non-null.
|
||||
if (JSEqualityOp op = js::Jsvalify(rhs->getClass()->ext.equality)) {
|
||||
JSClass *clasp = rhs->getJSClass();
|
||||
if (clasp->flags & JSCLASS_IS_EXTENDED) {
|
||||
JSExtendedClass *xclasp = (JSExtendedClass *) clasp;
|
||||
// NB: JSExtendedClass.equality is a required field.
|
||||
jsval lhsVal = OBJECT_TO_JSVAL(lhs);
|
||||
return op(cx, rhs, &lhsVal, bp);
|
||||
return xclasp->equality(cx, rhs, &lhsVal, bp);
|
||||
}
|
||||
|
||||
*bp = JS_FALSE;
|
||||
@ -676,7 +685,7 @@ XPC_SOW_Iterator(JSContext *cx, JSObject *obj, JSBool keysonly)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
JSObject *wrapperIter = JS_NewObject(cx, js::Jsvalify(&SOWClass), nsnull,
|
||||
JSObject *wrapperIter = JS_NewObject(cx, &SOWClass.base, nsnull,
|
||||
JS_GetGlobalForObject(cx, obj));
|
||||
if (!wrapperIter) {
|
||||
return nsnull;
|
||||
|
@ -60,8 +60,8 @@ const PRUint32 sSecMgrGetProp = nsIXPCSecurityManager::ACCESS_GET_PROPERTY;
|
||||
JSObject *
|
||||
Unwrap(JSContext *cx, JSObject *wrapper)
|
||||
{
|
||||
js::Class *clasp = wrapper->getClass();
|
||||
if (clasp == &XPCCrossOriginWrapper::XOWClass) {
|
||||
JSClass *clasp = wrapper->getJSClass();
|
||||
if (clasp == &XPCCrossOriginWrapper::XOWClass.base) {
|
||||
return UnwrapXOW(cx, wrapper);
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ Unwrap(JSContext *cx, JSObject *wrapper)
|
||||
return wrappedObj->GetFlatJSObject();
|
||||
}
|
||||
|
||||
if (clasp == &XPCSafeJSObjectWrapper::SJOWClass) {
|
||||
if (clasp == &XPCSafeJSObjectWrapper::SJOWClass.base) {
|
||||
JSObject *wrappedObj =
|
||||
XPCSafeJSObjectWrapper::GetUnsafeObject(cx, wrapper);
|
||||
|
||||
@ -88,10 +88,10 @@ Unwrap(JSContext *cx, JSObject *wrapper)
|
||||
return wrappedObj;
|
||||
}
|
||||
|
||||
if (clasp == &SystemOnlyWrapper::SOWClass) {
|
||||
if (clasp == &SystemOnlyWrapper::SOWClass.base) {
|
||||
return UnwrapSOW(cx, wrapper);
|
||||
}
|
||||
if (clasp == &ChromeObjectWrapper::COWClass) {
|
||||
if (clasp == &ChromeObjectWrapper::COWClass.base) {
|
||||
return UnwrapCOW(cx, wrapper);
|
||||
}
|
||||
|
||||
@ -160,33 +160,22 @@ IteratorIterator(JSContext *, JSObject *obj, JSBool)
|
||||
return obj;
|
||||
}
|
||||
|
||||
static js::Class IteratorClass = {
|
||||
"Wrapper iterator",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(3),
|
||||
js::PropertyStub, // addProperty
|
||||
js::PropertyStub, // delProperty
|
||||
js::PropertyStub, // getProperty
|
||||
js::PropertyStub, // setProperty
|
||||
JS_EnumerateStub,
|
||||
JS_ResolveStub,
|
||||
js::ConvertStub,
|
||||
IteratorFinalize,
|
||||
nsnull, // reserved0
|
||||
nsnull, // checkAccess
|
||||
nsnull, // call
|
||||
nsnull, // construct
|
||||
nsnull, // xdrObject
|
||||
nsnull, // hasInstance
|
||||
nsnull, // mark
|
||||
static JSExtendedClass IteratorClass = {
|
||||
{ "Wrapper iterator",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(3) | JSCLASS_IS_EXTENDED,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub,
|
||||
JS_ConvertStub, IteratorFinalize,
|
||||
|
||||
// ClassExtension
|
||||
{
|
||||
nsnull, // equality
|
||||
nsnull, // outerObject
|
||||
nsnull, // innerObject
|
||||
IteratorIterator,
|
||||
nsnull, // wrappedObject
|
||||
}
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
},
|
||||
|
||||
nsnull, // equality
|
||||
nsnull, nsnull, // innerObject/outerObject
|
||||
IteratorIterator,
|
||||
nsnull, // wrappedObject
|
||||
JSCLASS_NO_RESERVED_MEMBERS
|
||||
};
|
||||
|
||||
JSBool
|
||||
@ -342,7 +331,7 @@ CreateIteratorObj(JSContext *cx, JSObject *tempWrapper,
|
||||
// delegates (via the __proto__ link) to the wrapper.
|
||||
|
||||
JSObject *iterObj =
|
||||
JS_NewObjectWithGivenProto(cx, js::Jsvalify(&IteratorClass), tempWrapper, wrapperObj);
|
||||
JS_NewObjectWithGivenProto(cx, &IteratorClass.base, tempWrapper, wrapperObj);
|
||||
if (!iterObj) {
|
||||
return nsnull;
|
||||
}
|
||||
@ -405,7 +394,7 @@ JSObject *
|
||||
CreateSimpleIterator(JSContext *cx, JSObject *scope, JSBool keysonly,
|
||||
JSObject *propertyContainer)
|
||||
{
|
||||
JSObject *iterObj = JS_NewObjectWithGivenProto(cx, js::Jsvalify(&IteratorClass),
|
||||
JSObject *iterObj = JS_NewObjectWithGivenProto(cx, &IteratorClass.base,
|
||||
propertyContainer, scope);
|
||||
if (!iterObj) {
|
||||
return nsnull;
|
||||
|
@ -162,10 +162,10 @@ CheckFilename(JSContext *cx, jsid id, JSStackFrame *fp);
|
||||
|
||||
}
|
||||
|
||||
namespace ChromeObjectWrapper { extern js::Class COWClass; }
|
||||
namespace XPCSafeJSObjectWrapper { extern js::Class SJOWClass; }
|
||||
namespace SystemOnlyWrapper { extern js::Class SOWClass; }
|
||||
namespace XPCCrossOriginWrapper { extern js::Class XOWClass; }
|
||||
namespace ChromeObjectWrapper { extern JSExtendedClass COWClass; }
|
||||
namespace XPCSafeJSObjectWrapper { extern JSExtendedClass SJOWClass; }
|
||||
namespace SystemOnlyWrapper { extern JSExtendedClass SOWClass; }
|
||||
namespace XPCCrossOriginWrapper { extern JSExtendedClass XOWClass; }
|
||||
|
||||
extern nsIScriptSecurityManager *gScriptSecurityManager;
|
||||
|
||||
@ -321,7 +321,9 @@ MaybePreserveWrapper(JSContext *cx, XPCWrappedNative *wn, uintN flags)
|
||||
inline JSBool
|
||||
IsSecurityWrapper(JSObject *wrapper)
|
||||
{
|
||||
return !!wrapper->getClass()->ext.wrappedObject;
|
||||
JSClass *clasp = wrapper->getJSClass();
|
||||
return (clasp->flags & JSCLASS_IS_EXTENDED) &&
|
||||
((JSExtendedClass*)clasp)->wrappedObject;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -341,9 +343,9 @@ Unwrap(JSContext *cx, JSObject *wrapper);
|
||||
* Unwraps objects whose class is |xclasp|.
|
||||
*/
|
||||
inline JSObject *
|
||||
UnwrapGeneric(JSContext *cx, const js::Class *xclasp, JSObject *wrapper)
|
||||
UnwrapGeneric(JSContext *cx, const JSExtendedClass *xclasp, JSObject *wrapper)
|
||||
{
|
||||
if (wrapper->getClass() != xclasp) {
|
||||
if (wrapper->getJSClass() != &xclasp->base) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
@ -627,7 +627,7 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb)
|
||||
|
||||
uint32 traceKind = js_GetGCThingTraceKind(p);
|
||||
JSObject *obj;
|
||||
js::Class *clazz;
|
||||
JSClass *clazz;
|
||||
|
||||
// We do not want to add wrappers to the cycle collector if they're not
|
||||
// explicitly marked as main thread only, because the cycle collector isn't
|
||||
@ -640,7 +640,7 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb)
|
||||
if(traceKind == JSTRACE_OBJECT)
|
||||
{
|
||||
obj = static_cast<JSObject*>(p);
|
||||
clazz = obj->getClass();
|
||||
clazz = obj->getJSClass();
|
||||
|
||||
if(clazz == &XPC_WN_Tearoff_JSClass)
|
||||
{
|
||||
@ -689,7 +689,7 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb)
|
||||
if(traceKind == JSTRACE_OBJECT)
|
||||
{
|
||||
JSObject *obj = static_cast<JSObject*>(p);
|
||||
js::Class *clazz = obj->getClass();
|
||||
JSClass *clazz = obj->getJSClass();
|
||||
if(XPCNativeWrapper::IsNativeWrapperClass(clazz))
|
||||
{
|
||||
XPCWrappedNative* wn;
|
||||
@ -749,7 +749,7 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb)
|
||||
JS_snprintf(name, sizeof(name), "JS Object (%s - %s)",
|
||||
clazz->name, si->GetJSClass()->name);
|
||||
}
|
||||
else if(clazz == &js_ScriptClass)
|
||||
else if(clazz == Jsvalify(&js_ScriptClass))
|
||||
{
|
||||
JSScript* script = (JSScript*) xpc_GetJSPrivate(obj);
|
||||
if(script->filename)
|
||||
@ -763,7 +763,7 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb)
|
||||
JS_snprintf(name, sizeof(name), "JS Object (Script)");
|
||||
}
|
||||
}
|
||||
else if(clazz == &js_FunctionClass)
|
||||
else if(clazz == Jsvalify(&js_FunctionClass))
|
||||
{
|
||||
JSFunction* fun = (JSFunction*) xpc_GetJSPrivate(obj);
|
||||
JSString* str = JS_GetFunctionId(fun);
|
||||
@ -1016,6 +1016,9 @@ nsXPConnect::InitClasses(JSContext * aJSContext, JSObject * aGlobalJSObj)
|
||||
|
||||
xpc_InitJSxIDClassObjects();
|
||||
|
||||
if(!xpc_InitWrappedNativeJSOps())
|
||||
return UnexpectedFailure(NS_ERROR_FAILURE);
|
||||
|
||||
XPCWrappedNativeScope* scope =
|
||||
XPCWrappedNativeScope::GetNewOrUsed(ccx, aGlobalJSObj);
|
||||
|
||||
@ -1914,7 +1917,7 @@ nsXPConnect::RestoreWrappedNativePrototype(JSContext * aJSContext,
|
||||
if(NS_FAILED(rv))
|
||||
return UnexpectedFailure(rv);
|
||||
|
||||
if(!IS_PROTO_CLASS(protoJSObject->getClass()))
|
||||
if(!IS_PROTO_CLASS(protoJSObject->getJSClass()))
|
||||
return UnexpectedFailure(NS_ERROR_INVALID_ARG);
|
||||
|
||||
XPCWrappedNativeScope* scope =
|
||||
|
@ -134,8 +134,8 @@ xpcJSWeakReference::Get()
|
||||
// arguments! It turns out that the thisObject hook on XPConnect
|
||||
// objects does the right thing though, so...
|
||||
|
||||
if (obj->getOps()->thisObject &&
|
||||
!(obj = obj->getOps()->thisObject(cx, obj)))
|
||||
if (obj->map->ops->thisObject &&
|
||||
!(obj = obj->map->ops->thisObject(cx, obj)))
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -3117,7 +3117,7 @@ sandbox_setProto(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
|
||||
JSObject *pobj = JSVAL_TO_OBJECT(*vp);
|
||||
if (pobj) {
|
||||
if (pobj->getClass() == &XPCCrossOriginWrapper::XOWClass &&
|
||||
if (pobj->getJSClass() == &XPCCrossOriginWrapper::XOWClass.base &&
|
||||
!XPCWrapper::RewrapObject(cx, obj, pobj,
|
||||
XPCWrapper::XPCNW_EXPLICIT, vp)) {
|
||||
return JS_FALSE;
|
||||
@ -3825,9 +3825,13 @@ nsXPCComponents_Utils::GetGlobalForObject()
|
||||
JSObject *obj = JS_GetGlobalForObject(cx, JSVAL_TO_OBJECT(argv[0]));
|
||||
*rval = OBJECT_TO_JSVAL(obj);
|
||||
|
||||
// Outerize if necessary.
|
||||
if (JSObjectOp outerize = obj->getClass()->ext.outerObject)
|
||||
// Outerize if necessary. Embrace the ugliness!
|
||||
JSClass *clasp = JS_GetClass(cx, obj);
|
||||
if (clasp->flags & JSCLASS_IS_EXTENDED) {
|
||||
JSExtendedClass *xclasp = reinterpret_cast<JSExtendedClass *>(clasp);
|
||||
if (JSObjectOp outerize = xclasp->outerObject)
|
||||
*rval = OBJECT_TO_JSVAL(outerize(cx, obj));
|
||||
}
|
||||
|
||||
cc->SetReturnValueWasSet(PR_TRUE);
|
||||
return NS_OK;
|
||||
|
@ -1267,17 +1267,20 @@ private:
|
||||
// These are the various JSClasses and callbacks whose use that required
|
||||
// visibility from more than one .cpp file.
|
||||
|
||||
extern js::Class XPC_WN_NoHelper_JSClass;
|
||||
extern js::Class XPC_WN_NoMods_WithCall_Proto_JSClass;
|
||||
extern js::Class XPC_WN_NoMods_NoCall_Proto_JSClass;
|
||||
extern js::Class XPC_WN_ModsAllowed_WithCall_Proto_JSClass;
|
||||
extern js::Class XPC_WN_ModsAllowed_NoCall_Proto_JSClass;
|
||||
extern js::Class XPC_WN_Tearoff_JSClass;
|
||||
extern js::Class XPC_WN_NoHelper_Proto_JSClass;
|
||||
extern JSExtendedClass XPC_WN_NoHelper_JSClass;
|
||||
extern JSClass XPC_WN_NoMods_WithCall_Proto_JSClass;
|
||||
extern JSClass XPC_WN_NoMods_NoCall_Proto_JSClass;
|
||||
extern JSClass XPC_WN_ModsAllowed_WithCall_Proto_JSClass;
|
||||
extern JSClass XPC_WN_ModsAllowed_NoCall_Proto_JSClass;
|
||||
extern JSClass XPC_WN_Tearoff_JSClass;
|
||||
extern JSClass XPC_WN_NoHelper_Proto_JSClass;
|
||||
|
||||
extern JSBool
|
||||
XPC_WN_Equality(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp);
|
||||
|
||||
extern JSObjectOps *
|
||||
XPC_WN_Proto_GetObjectOps(JSContext *cx, JSClass *clazz);
|
||||
|
||||
extern JSBool
|
||||
XPC_WN_CallMethod(JSContext *cx, JSObject *obj,
|
||||
uintN argc, jsval *argv, jsval *vp);
|
||||
@ -1287,62 +1290,16 @@ XPC_WN_GetterSetter(JSContext *cx, JSObject *obj,
|
||||
uintN argc, jsval *argv, jsval *vp);
|
||||
|
||||
extern JSBool
|
||||
XPC_WN_JSOp_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
||||
jsval *statep, jsid *idp);
|
||||
|
||||
extern JSType
|
||||
XPC_WN_JSOp_TypeOf_Object(JSContext *cx, JSObject *obj);
|
||||
|
||||
extern JSType
|
||||
XPC_WN_JSOp_TypeOf_Function(JSContext *cx, JSObject *obj);
|
||||
|
||||
extern void
|
||||
XPC_WN_JSOp_Clear(JSContext *cx, JSObject *obj);
|
||||
|
||||
extern JSObject*
|
||||
XPC_WN_JSOp_ThisObject(JSContext *cx, JSObject *obj);
|
||||
|
||||
// Macros to initialize Object or Function like XPC_WN classes
|
||||
#define XPC_WN_WithCall_ObjectOps \
|
||||
{ \
|
||||
nsnull, /* lookupProperty */ \
|
||||
nsnull, /* defineProperty */ \
|
||||
nsnull, /* getProperty */ \
|
||||
nsnull, /* setProperty */ \
|
||||
nsnull, /* getAttributes */ \
|
||||
nsnull, /* setAttributes */ \
|
||||
nsnull, /* deleteProperty */ \
|
||||
js::Valueify(XPC_WN_JSOp_Enumerate), \
|
||||
XPC_WN_JSOp_TypeOf_Function, \
|
||||
nsnull, /* trace */ \
|
||||
XPC_WN_JSOp_ThisObject, \
|
||||
XPC_WN_JSOp_Clear \
|
||||
}
|
||||
|
||||
#define XPC_WN_NoCall_ObjectOps \
|
||||
{ \
|
||||
nsnull, /* lookupProperty */ \
|
||||
nsnull, /* defineProperty */ \
|
||||
nsnull, /* getProperty */ \
|
||||
nsnull, /* setProperty */ \
|
||||
nsnull, /* getAttributes */ \
|
||||
nsnull, /* setAttributes */ \
|
||||
nsnull, /* deleteProperty */ \
|
||||
js::Valueify(XPC_WN_JSOp_Enumerate), \
|
||||
XPC_WN_JSOp_TypeOf_Object, \
|
||||
nsnull, /* trace */ \
|
||||
XPC_WN_JSOp_ThisObject, \
|
||||
XPC_WN_JSOp_Clear \
|
||||
}
|
||||
xpc_InitWrappedNativeJSOps();
|
||||
|
||||
// Maybe this macro should check for class->enumerate ==
|
||||
// XPC_WN_Shared_Proto_Enumerate or something rather than checking for
|
||||
// 4 classes?
|
||||
#define IS_PROTO_CLASS(clazz) \
|
||||
((clazz) == &XPC_WN_NoMods_WithCall_Proto_JSClass || \
|
||||
(clazz) == &XPC_WN_NoMods_NoCall_Proto_JSClass || \
|
||||
(clazz) == &XPC_WN_ModsAllowed_WithCall_Proto_JSClass || \
|
||||
(clazz) == &XPC_WN_ModsAllowed_NoCall_Proto_JSClass)
|
||||
((clazz) == &XPC_WN_NoMods_WithCall_Proto_JSClass || \
|
||||
(clazz) == &XPC_WN_NoMods_NoCall_Proto_JSClass || \
|
||||
(clazz) == &XPC_WN_ModsAllowed_WithCall_Proto_JSClass || \
|
||||
(clazz) == &XPC_WN_ModsAllowed_NoCall_Proto_JSClass)
|
||||
|
||||
// NOTE!!!
|
||||
//
|
||||
@ -1352,7 +1309,8 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JSObject *obj);
|
||||
//
|
||||
// NOTE!!!
|
||||
#define IS_WRAPPER_CLASS(clazz) \
|
||||
(clazz->ext.equality == js::Valueify(XPC_WN_Equality))
|
||||
(((clazz)->flags & JSCLASS_IS_EXTENDED) && \
|
||||
reinterpret_cast<JSExtendedClass*>(clazz)->equality == XPC_WN_Equality)
|
||||
|
||||
inline JSBool
|
||||
DebugCheckWrapperClass(JSObject* obj)
|
||||
@ -1957,9 +1915,8 @@ public:
|
||||
// was a big problem when wrappers are reparented to different scopes (and
|
||||
// thus different protos (the DOM does this).
|
||||
|
||||
struct XPCNativeScriptableSharedJSClass
|
||||
struct XPCNativeScriptableSharedJSClass : public JSExtendedClass
|
||||
{
|
||||
js::Class base;
|
||||
PRUint32 interfacesBitmap;
|
||||
};
|
||||
|
||||
@ -1969,8 +1926,7 @@ public:
|
||||
const XPCNativeScriptableFlags& GetFlags() const {return mFlags;}
|
||||
PRUint32 GetInterfacesBitmap() const
|
||||
{return mJSClass.interfacesBitmap;}
|
||||
JSClass* GetJSClass()
|
||||
{return js::Jsvalify(&mJSClass.base);}
|
||||
JSClass* GetJSClass() {return &mJSClass.base;}
|
||||
JSClass* GetSlimJSClass()
|
||||
{if(mCanBeSlim) return GetJSClass(); return nsnull;}
|
||||
|
||||
|
@ -296,7 +296,7 @@ LookupGetterOrSetter(JSContext *cx, JSBool wantGetter, uintN argc, jsval *vp)
|
||||
? JS_GetStringBytes(JSVAL_TO_STRING(idval))
|
||||
: nsnull;
|
||||
if(!name ||
|
||||
!IS_PROTO_CLASS(desc.obj->getClass()) ||
|
||||
!IS_PROTO_CLASS(desc.obj->getJSClass()) ||
|
||||
(desc.attrs & (JSPROP_GETTER | JSPROP_SETTER)) ||
|
||||
!(desc.getter || desc.setter) ||
|
||||
desc.setter == desc.obj->getJSClass()->setProperty)
|
||||
@ -363,7 +363,7 @@ DefineGetterOrSetter(JSContext *cx, uintN argc, JSBool wantGetter, jsval *vp)
|
||||
if(!obj2 ||
|
||||
(attrs & (JSPROP_GETTER | JSPROP_SETTER)) ||
|
||||
!(getter || setter) ||
|
||||
!IS_PROTO_CLASS(obj2->getClass()))
|
||||
!IS_PROTO_CLASS(obj2->getJSClass()))
|
||||
return forward(cx, argc, vp);
|
||||
|
||||
// Reify the getter and setter...
|
||||
@ -504,8 +504,8 @@ GetMemberInfo(JSObject *obj,
|
||||
// but this code often produces a more specific error message, e.g.
|
||||
*ifaceName = "Unknown";
|
||||
|
||||
NS_ASSERTION(IS_WRAPPER_CLASS(obj->getClass()) ||
|
||||
obj->getClass() == &XPC_WN_Tearoff_JSClass,
|
||||
NS_ASSERTION(IS_WRAPPER_CLASS(obj->getJSClass()) ||
|
||||
obj->getJSClass() == &XPC_WN_Tearoff_JSClass,
|
||||
"obj must be a wrapper");
|
||||
XPCWrappedNativeProto *proto;
|
||||
if(IS_SLIM_WRAPPER(obj))
|
||||
|
@ -1124,9 +1124,7 @@ XPCWrappedNative::Init(XPCCallContext& ccx,
|
||||
|
||||
// create our flatJSObject
|
||||
|
||||
js::Class* jsclazz = si
|
||||
? js::Valueify(si->GetJSClass())
|
||||
: &XPC_WN_NoHelper_JSClass;
|
||||
JSClass* jsclazz = si ? si->GetJSClass() : &XPC_WN_NoHelper_JSClass.base;
|
||||
|
||||
if(isGlobal)
|
||||
{
|
||||
@ -1160,8 +1158,8 @@ XPCWrappedNative::Init(XPCCallContext& ccx,
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
mFlatJSObject = xpc_NewSystemInheritingJSObject(ccx, js::Jsvalify(jsclazz),
|
||||
protoJSObject, parent);
|
||||
mFlatJSObject = xpc_NewSystemInheritingJSObject(ccx, jsclazz, protoJSObject,
|
||||
parent);
|
||||
if(!mFlatJSObject)
|
||||
return JS_FALSE;
|
||||
|
||||
@ -1685,7 +1683,7 @@ XPCWrappedNative::GetWrappedNativeOfJSObject(JSContext* cx,
|
||||
JSObject* funObjParent = funobj->getParent();
|
||||
NS_ASSERTION(funObjParent, "funobj has no parent");
|
||||
|
||||
js::Class* funObjParentClass = funObjParent->getClass();
|
||||
JSClass* funObjParentClass = funObjParent->getJSClass();
|
||||
|
||||
if(IS_PROTO_CLASS(funObjParentClass))
|
||||
{
|
||||
@ -1715,8 +1713,8 @@ XPCWrappedNative::GetWrappedNativeOfJSObject(JSContext* cx,
|
||||
for(cur = obj; cur; cur = cur->getProto())
|
||||
{
|
||||
// this is on two lines to make the compiler happy given the goto.
|
||||
js::Class* clazz;
|
||||
clazz = cur->getClass();
|
||||
JSClass* clazz;
|
||||
clazz = cur->getJSClass();
|
||||
|
||||
if(IS_WRAPPER_CLASS(clazz))
|
||||
{
|
||||
@ -1773,9 +1771,12 @@ return_tearoff:
|
||||
// If we didn't find a wrapper using the given funobj and obj, try
|
||||
// again with obj's outer object, if it's got one.
|
||||
|
||||
if(JSObjectOp op = obj->getClass()->ext.outerObject)
|
||||
JSClass *clazz = obj->getJSClass();
|
||||
|
||||
if((clazz->flags & JSCLASS_IS_EXTENDED) &&
|
||||
((JSExtendedClass*)clazz)->outerObject)
|
||||
{
|
||||
JSObject *outer = op(cx, obj);
|
||||
JSObject *outer = ((JSExtendedClass*)clazz)->outerObject(cx, obj);
|
||||
if(outer && outer != obj)
|
||||
return GetWrappedNativeOfJSObject(cx, outer, funobj, pobj2,
|
||||
pTearOff);
|
||||
@ -2117,7 +2118,7 @@ XPCWrappedNative::InitTearOffJSObject(XPCCallContext& ccx,
|
||||
// This is only called while locked (during XPCWrappedNative::FindTearOff).
|
||||
|
||||
JSObject* obj =
|
||||
xpc_NewSystemInheritingJSObject(ccx, js::Jsvalify(&XPC_WN_Tearoff_JSClass),
|
||||
xpc_NewSystemInheritingJSObject(ccx, &XPC_WN_Tearoff_JSClass,
|
||||
GetScope()->GetPrototypeJSObject(),
|
||||
mFlatJSObject);
|
||||
|
||||
|
@ -813,7 +813,7 @@ XPC_WN_Equality(JSContext *cx, JSObject *obj, const jsval *valp, JSBool *bp)
|
||||
return Throw(rv, cx);
|
||||
|
||||
if(!*bp && !JSVAL_IS_PRIMITIVE(v) &&
|
||||
JSVAL_TO_OBJECT(v)->getClass() == &XPCSafeJSObjectWrapper::SJOWClass)
|
||||
JSVAL_TO_OBJECT(v)->getJSClass() == &XPCSafeJSObjectWrapper::SJOWClass.base)
|
||||
{
|
||||
v = OBJECT_TO_JSVAL(XPCSafeJSObjectWrapper::GetUnsafeObject(cx, JSVAL_TO_OBJECT(v)));
|
||||
|
||||
@ -912,56 +912,41 @@ XPC_WN_InnerObject(JSContext *cx, JSObject *obj)
|
||||
return obj;
|
||||
}
|
||||
|
||||
js::Class XPC_WN_NoHelper_JSClass = {
|
||||
"XPCWrappedNative_NoHelper", // name;
|
||||
WRAPPER_SLOTS |
|
||||
JSCLASS_PRIVATE_IS_NSISUPPORTS |
|
||||
JSCLASS_MARK_IS_TRACE, // flags;
|
||||
JSObjectOps *XPC_WN_GetObjectOpsNoCall(JSContext *cx, JSClass *clazz);
|
||||
|
||||
/* Mandatory non-null function pointer members. */
|
||||
js::Valueify(XPC_WN_OnlyIWrite_PropertyStub), // addProperty
|
||||
js::Valueify(XPC_WN_CannotModifyPropertyStub),// delProperty
|
||||
js::PropertyStub, // getProperty
|
||||
js::Valueify(XPC_WN_OnlyIWrite_PropertyStub), // setProperty
|
||||
|
||||
XPC_WN_Shared_Enumerate, // enumerate
|
||||
XPC_WN_NoHelper_Resolve, // resolve
|
||||
js::Valueify(XPC_WN_Shared_Convert), // convert
|
||||
XPC_WN_NoHelper_Finalize, // finalize
|
||||
|
||||
/* Optionally non-null members start here. */
|
||||
nsnull, // reserved0
|
||||
nsnull, // checkAccess
|
||||
nsnull, // call
|
||||
nsnull, // construct
|
||||
nsnull, // xdrObject;
|
||||
nsnull, // hasInstance
|
||||
JS_CLASS_TRACE(XPC_WN_Shared_Trace), // mark/trace
|
||||
|
||||
// ClassExtension
|
||||
JSExtendedClass XPC_WN_NoHelper_JSClass = {
|
||||
{
|
||||
js::Valueify(XPC_WN_Equality),
|
||||
XPC_WN_OuterObject,
|
||||
XPC_WN_InnerObject,
|
||||
nsnull, // iteratorObject
|
||||
nsnull, // wrappedObject
|
||||
"XPCWrappedNative_NoHelper", // name;
|
||||
WRAPPER_SLOTS |
|
||||
JSCLASS_PRIVATE_IS_NSISUPPORTS |
|
||||
JSCLASS_MARK_IS_TRACE |
|
||||
JSCLASS_IS_EXTENDED, // flags;
|
||||
|
||||
/* Mandatory non-null function pointer members. */
|
||||
XPC_WN_OnlyIWrite_PropertyStub, // addProperty;
|
||||
XPC_WN_CannotModifyPropertyStub,// delProperty;
|
||||
JS_PropertyStub, // getProperty;
|
||||
XPC_WN_OnlyIWrite_PropertyStub, // setProperty;
|
||||
|
||||
XPC_WN_Shared_Enumerate, // enumerate;
|
||||
XPC_WN_NoHelper_Resolve, // resolve;
|
||||
XPC_WN_Shared_Convert, // convert;
|
||||
XPC_WN_NoHelper_Finalize, // finalize;
|
||||
|
||||
/* Optionally non-null members start here. */
|
||||
XPC_WN_GetObjectOpsNoCall, // getObjectOps;
|
||||
nsnull, // checkAccess;
|
||||
nsnull, // call;
|
||||
nsnull, // construct;
|
||||
nsnull, // xdrObject;
|
||||
nsnull, // hasInstance;
|
||||
JS_CLASS_TRACE(XPC_WN_Shared_Trace), // mark/trace;
|
||||
nsnull // spare;
|
||||
},
|
||||
|
||||
// ObjectOps
|
||||
{
|
||||
nsnull, // lookupProperty
|
||||
nsnull, // defineProperty
|
||||
nsnull, // getProperty
|
||||
nsnull, // setProperty
|
||||
nsnull, // getAttributes
|
||||
nsnull, // setAttributes
|
||||
nsnull, // deleteProperty
|
||||
js::Valueify(XPC_WN_JSOp_Enumerate),
|
||||
XPC_WN_JSOp_TypeOf_Object,
|
||||
nsnull, // trace
|
||||
XPC_WN_JSOp_ThisObject,
|
||||
XPC_WN_JSOp_Clear
|
||||
}
|
||||
XPC_WN_Equality,
|
||||
XPC_WN_OuterObject,
|
||||
XPC_WN_InnerObject,
|
||||
nsnull,nsnull,nsnull,nsnull,nsnull
|
||||
};
|
||||
|
||||
|
||||
@ -1253,6 +1238,11 @@ XPC_WN_Helper_NewResolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
extern JS_IMPORT_DATA(JSObjectOps) js_ObjectOps;
|
||||
|
||||
static JSObjectOps XPC_WN_WithCall_JSOps;
|
||||
static JSObjectOps XPC_WN_NoCall_JSOps;
|
||||
|
||||
/*
|
||||
Here are the enumerator cases:
|
||||
|
||||
@ -1288,18 +1278,18 @@ XPC_WN_Helper_NewResolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
||||
do shared enumerate - don't use this JSOp thing at all
|
||||
*/
|
||||
|
||||
JSBool
|
||||
static JSBool
|
||||
XPC_WN_JSOp_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
||||
jsval *statep, jsid *idp)
|
||||
{
|
||||
js::Class *clazz = obj->getClass();
|
||||
if(!IS_WRAPPER_CLASS(clazz) || clazz == &XPC_WN_NoHelper_JSClass)
|
||||
JSClass *clazz = obj->getJSClass();
|
||||
if(!IS_WRAPPER_CLASS(clazz) || clazz == &XPC_WN_NoHelper_JSClass.base)
|
||||
{
|
||||
// obj must be a prototype object or a wrapper w/o a
|
||||
// helper. Short circuit this call to the default
|
||||
// implementation.
|
||||
// helper. Short circuit this call to
|
||||
// js_ObjectOps.enumerate().
|
||||
|
||||
return js_Enumerate(cx, obj, enum_op, js::Valueify(statep), idp);
|
||||
return js_ObjectOps.enumerate(cx, obj, enum_op, js::Valueify(statep), idp);
|
||||
}
|
||||
|
||||
MORPH_SLIM_WRAPPER(cx, obj);
|
||||
@ -1366,28 +1356,28 @@ XPC_WN_JSOp_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
||||
return Throw(rv, cx);
|
||||
if(!retval)
|
||||
return JS_FALSE;
|
||||
// Then fall through and call the default implementation...
|
||||
// Then fall through and call js_ObjectOps.enumerate...
|
||||
}
|
||||
}
|
||||
|
||||
// else call js_ObjectOps.enumerate...
|
||||
|
||||
return js_Enumerate(cx, obj, enum_op, js::Valueify(statep), idp);
|
||||
return js_ObjectOps.enumerate(cx, obj, enum_op, js::Valueify(statep), idp);
|
||||
}
|
||||
|
||||
JSType
|
||||
static JSType
|
||||
XPC_WN_JSOp_TypeOf_Object(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return JSTYPE_OBJECT;
|
||||
}
|
||||
|
||||
JSType
|
||||
static JSType
|
||||
XPC_WN_JSOp_TypeOf_Function(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return JSTYPE_FUNCTION;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
XPC_WN_JSOp_Clear(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
// We're likely to enter this JSOp with a wrapper prototype
|
||||
@ -1406,6 +1396,8 @@ XPC_WN_JSOp_Clear(JSContext *cx, JSObject *obj)
|
||||
nsXPConnect* xpc = nsXPConnect::GetXPConnect();
|
||||
xpc->UpdateXOWs(cx, wrapper, nsIXPConnect::XPC_XOW_CLEARSCOPE);
|
||||
}
|
||||
|
||||
js_ObjectOps.clear(cx, obj);
|
||||
}
|
||||
|
||||
namespace {
|
||||
@ -1444,7 +1436,7 @@ private:
|
||||
|
||||
} // namespace
|
||||
|
||||
JSObject*
|
||||
static JSObject*
|
||||
XPC_WN_JSOp_ThisObject(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
// None of the wrappers we could potentially hand out are threadsafe so
|
||||
@ -1541,6 +1533,37 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JSObject *obj)
|
||||
return JSVAL_TO_OBJECT(retval.jsval_value());
|
||||
}
|
||||
|
||||
JSObjectOps *
|
||||
XPC_WN_GetObjectOpsNoCall(JSContext *cx, JSClass *clazz)
|
||||
{
|
||||
return &XPC_WN_NoCall_JSOps;
|
||||
}
|
||||
|
||||
JSObjectOps *
|
||||
XPC_WN_GetObjectOpsWithCall(JSContext *cx, JSClass *clazz)
|
||||
{
|
||||
return &XPC_WN_WithCall_JSOps;
|
||||
}
|
||||
|
||||
JSBool xpc_InitWrappedNativeJSOps()
|
||||
{
|
||||
if(!XPC_WN_NoCall_JSOps.lookupProperty)
|
||||
{
|
||||
memcpy(&XPC_WN_NoCall_JSOps, &js_ObjectOps, sizeof(JSObjectOps));
|
||||
XPC_WN_NoCall_JSOps.enumerate = js::Valueify(XPC_WN_JSOp_Enumerate);
|
||||
XPC_WN_NoCall_JSOps.typeOf = XPC_WN_JSOp_TypeOf_Object;
|
||||
XPC_WN_NoCall_JSOps.clear = XPC_WN_JSOp_Clear;
|
||||
XPC_WN_NoCall_JSOps.thisObject = XPC_WN_JSOp_ThisObject;
|
||||
|
||||
memcpy(&XPC_WN_WithCall_JSOps, &js_ObjectOps, sizeof(JSObjectOps));
|
||||
XPC_WN_WithCall_JSOps.enumerate = js::Valueify(XPC_WN_JSOp_Enumerate);
|
||||
XPC_WN_WithCall_JSOps.typeOf = XPC_WN_JSOp_TypeOf_Function;
|
||||
XPC_WN_WithCall_JSOps.clear = XPC_WN_JSOp_Clear;
|
||||
XPC_WN_WithCall_JSOps.thisObject = XPC_WN_JSOp_ThisObject;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
// static
|
||||
@ -1591,54 +1614,49 @@ XPCNativeScriptableShared::PopulateJSClass(JSBool isGlobal)
|
||||
mJSClass.base.flags = WRAPPER_SLOTS |
|
||||
JSCLASS_PRIVATE_IS_NSISUPPORTS |
|
||||
JSCLASS_NEW_RESOLVE |
|
||||
JSCLASS_MARK_IS_TRACE;
|
||||
JSCLASS_MARK_IS_TRACE |
|
||||
JSCLASS_IS_EXTENDED;
|
||||
|
||||
if(isGlobal)
|
||||
mJSClass.base.flags |= JSCLASS_GLOBAL_FLAGS;
|
||||
|
||||
JSPropertyOp addProperty;
|
||||
if(mFlags.WantAddProperty())
|
||||
addProperty = XPC_WN_Helper_AddProperty;
|
||||
mJSClass.base.addProperty = XPC_WN_Helper_AddProperty;
|
||||
else if(mFlags.UseJSStubForAddProperty())
|
||||
addProperty = JS_PropertyStub;
|
||||
mJSClass.base.addProperty = JS_PropertyStub;
|
||||
else if(mFlags.AllowPropModsDuringResolve())
|
||||
addProperty = XPC_WN_MaybeResolvingPropertyStub;
|
||||
mJSClass.base.addProperty = XPC_WN_MaybeResolvingPropertyStub;
|
||||
else
|
||||
addProperty = XPC_WN_CannotModifyPropertyStub;
|
||||
mJSClass.base.addProperty = js::Valueify(addProperty);
|
||||
mJSClass.base.addProperty = XPC_WN_CannotModifyPropertyStub;
|
||||
|
||||
JSPropertyOp delProperty;
|
||||
if(mFlags.WantDelProperty())
|
||||
delProperty = XPC_WN_Helper_DelProperty;
|
||||
mJSClass.base.delProperty = XPC_WN_Helper_DelProperty;
|
||||
else if(mFlags.UseJSStubForDelProperty())
|
||||
delProperty = JS_PropertyStub;
|
||||
mJSClass.base.delProperty = JS_PropertyStub;
|
||||
else if(mFlags.AllowPropModsDuringResolve())
|
||||
delProperty = XPC_WN_MaybeResolvingPropertyStub;
|
||||
mJSClass.base.delProperty = XPC_WN_MaybeResolvingPropertyStub;
|
||||
else
|
||||
delProperty = XPC_WN_CannotModifyPropertyStub;
|
||||
mJSClass.base.delProperty = js::Valueify(delProperty);
|
||||
mJSClass.base.delProperty = XPC_WN_CannotModifyPropertyStub;
|
||||
|
||||
if(mFlags.WantGetProperty())
|
||||
mJSClass.base.getProperty = js::Valueify(XPC_WN_Helper_GetProperty);
|
||||
mJSClass.base.getProperty = XPC_WN_Helper_GetProperty;
|
||||
else
|
||||
mJSClass.base.getProperty = js::PropertyStub;
|
||||
mJSClass.base.getProperty = JS_PropertyStub;
|
||||
|
||||
JSPropertyOp setProperty;
|
||||
if(mFlags.WantSetProperty())
|
||||
setProperty = XPC_WN_Helper_SetProperty;
|
||||
mJSClass.base.setProperty = XPC_WN_Helper_SetProperty;
|
||||
else if(mFlags.UseJSStubForSetProperty())
|
||||
setProperty = JS_PropertyStub;
|
||||
mJSClass.base.setProperty = JS_PropertyStub;
|
||||
else if(mFlags.AllowPropModsDuringResolve())
|
||||
setProperty = XPC_WN_MaybeResolvingPropertyStub;
|
||||
mJSClass.base.setProperty = XPC_WN_MaybeResolvingPropertyStub;
|
||||
else
|
||||
setProperty = XPC_WN_CannotModifyPropertyStub;
|
||||
mJSClass.base.setProperty = js::Valueify(setProperty);
|
||||
mJSClass.base.setProperty = XPC_WN_CannotModifyPropertyStub;
|
||||
|
||||
// We figure out most of the enumerate strategy at call time.
|
||||
|
||||
if(mFlags.WantNewEnumerate() || mFlags.WantEnumerate() ||
|
||||
mFlags.DontEnumStaticProps())
|
||||
mJSClass.base.enumerate = js::EnumerateStub;
|
||||
mJSClass.base.enumerate = JS_EnumerateStub;
|
||||
else
|
||||
mJSClass.base.enumerate = XPC_WN_Shared_Enumerate;
|
||||
|
||||
@ -1646,9 +1664,9 @@ XPCNativeScriptableShared::PopulateJSClass(JSBool isGlobal)
|
||||
mJSClass.base.resolve = (JSResolveOp) XPC_WN_Helper_NewResolve;
|
||||
|
||||
if(mFlags.WantConvert())
|
||||
mJSClass.base.convert = js::Valueify(XPC_WN_Helper_Convert);
|
||||
mJSClass.base.convert = XPC_WN_Helper_Convert;
|
||||
else
|
||||
mJSClass.base.convert = js::Valueify(XPC_WN_Shared_Convert);
|
||||
mJSClass.base.convert = XPC_WN_Shared_Convert;
|
||||
|
||||
if(mFlags.WantFinalize())
|
||||
mJSClass.base.finalize = XPC_WN_Helper_Finalize;
|
||||
@ -1657,46 +1675,46 @@ XPCNativeScriptableShared::PopulateJSClass(JSBool isGlobal)
|
||||
|
||||
// We let the rest default to nsnull unless the helper wants them...
|
||||
if(mFlags.WantCheckAccess())
|
||||
mJSClass.base.checkAccess = js::Valueify(XPC_WN_Helper_CheckAccess);
|
||||
mJSClass.base.checkAccess = XPC_WN_Helper_CheckAccess;
|
||||
|
||||
// Note that we *must* set the ObjectOps (even for the cases were it does
|
||||
// not do much) because with these dynamically generated JSClasses, the
|
||||
// code in XPCWrappedNative::GetWrappedNativeOfJSObject() needs to look
|
||||
// for that these callback pointers in order to identify that a given
|
||||
// Note that we *must* set
|
||||
// mJSClass.base.getObjectOps = XPC_WN_GetObjectOpsNoCall
|
||||
// or
|
||||
// mJSClass.base.getObjectOps = XPC_WN_GetObjectOpsWithCall
|
||||
// (even for the cases were it does not do much) because with these
|
||||
// dynamically generated JSClasses, the code in
|
||||
// XPCWrappedNative::GetWrappedNativeOfJSObject() needs to look for
|
||||
// that this callback pointer in order to identify that a given
|
||||
// JSObject represents a wrapper.
|
||||
js::ObjectOps *ops = &mJSClass.base.ops;
|
||||
ops->enumerate = js::Valueify(XPC_WN_JSOp_Enumerate);
|
||||
ops->clear = XPC_WN_JSOp_Clear;
|
||||
ops->thisObject = XPC_WN_JSOp_ThisObject;
|
||||
|
||||
if(mFlags.WantCall() || mFlags.WantConstruct())
|
||||
{
|
||||
ops->typeOf = XPC_WN_JSOp_TypeOf_Function;
|
||||
mJSClass.base.getObjectOps = XPC_WN_GetObjectOpsWithCall;
|
||||
if(mFlags.WantCall())
|
||||
mJSClass.base.call = js::Valueify(XPC_WN_Helper_Call);
|
||||
mJSClass.base.call = XPC_WN_Helper_Call;
|
||||
if(mFlags.WantConstruct())
|
||||
mJSClass.base.construct = js::Valueify(XPC_WN_Helper_Construct);
|
||||
mJSClass.base.construct = XPC_WN_Helper_Construct;
|
||||
}
|
||||
else
|
||||
{
|
||||
ops->typeOf = XPC_WN_JSOp_TypeOf_Object;
|
||||
mJSClass.base.getObjectOps = XPC_WN_GetObjectOpsNoCall;
|
||||
}
|
||||
|
||||
// Equality is a required hook.
|
||||
mJSClass.base.ext.equality = js::Valueify(XPC_WN_Equality);
|
||||
|
||||
if(mFlags.WantHasInstance())
|
||||
mJSClass.base.hasInstance = js::Valueify(XPC_WN_Helper_HasInstance);
|
||||
mJSClass.base.hasInstance = XPC_WN_Helper_HasInstance;
|
||||
|
||||
if(mFlags.WantTrace())
|
||||
mJSClass.base.mark = JS_CLASS_TRACE(XPC_WN_Helper_Trace);
|
||||
else
|
||||
mJSClass.base.mark = JS_CLASS_TRACE(XPC_WN_Shared_Trace);
|
||||
|
||||
// Equality is a required hook.
|
||||
mJSClass.equality = XPC_WN_Equality;
|
||||
|
||||
if(mFlags.WantOuterObject())
|
||||
mJSClass.base.ext.outerObject = XPC_WN_OuterObject;
|
||||
mJSClass.outerObject = XPC_WN_OuterObject;
|
||||
if(mFlags.WantInnerObject())
|
||||
mJSClass.base.ext.innerObject = XPC_WN_InnerObject;
|
||||
mJSClass.innerObject = XPC_WN_InnerObject;
|
||||
|
||||
if(!(mFlags & (nsIXPCScriptable::WANT_OUTER_OBJECT |
|
||||
nsIXPCScriptable::WANT_INNER_OBJECT)))
|
||||
@ -1788,10 +1806,12 @@ static JSBool
|
||||
XPC_WN_Shared_Proto_Enumerate(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
NS_ASSERTION(
|
||||
obj->getClass() == &XPC_WN_ModsAllowed_WithCall_Proto_JSClass ||
|
||||
obj->getClass() == &XPC_WN_ModsAllowed_NoCall_Proto_JSClass ||
|
||||
obj->getClass() == &XPC_WN_NoMods_WithCall_Proto_JSClass ||
|
||||
obj->getClass() == &XPC_WN_NoMods_NoCall_Proto_JSClass,
|
||||
JS_InstanceOf(cx, obj, &XPC_WN_ModsAllowed_WithCall_Proto_JSClass,
|
||||
nsnull) ||
|
||||
JS_InstanceOf(cx, obj, &XPC_WN_ModsAllowed_NoCall_Proto_JSClass,
|
||||
nsnull) ||
|
||||
JS_InstanceOf(cx, obj, &XPC_WN_NoMods_WithCall_Proto_JSClass, nsnull) ||
|
||||
JS_InstanceOf(cx, obj, &XPC_WN_NoMods_NoCall_Proto_JSClass, nsnull),
|
||||
"bad proto");
|
||||
XPCWrappedNativeProto* self =
|
||||
(XPCWrappedNativeProto*) xpc_GetJSPrivate(obj);
|
||||
@ -1859,9 +1879,11 @@ static JSBool
|
||||
XPC_WN_ModsAllowed_Proto_Resolve(JSContext *cx, JSObject *obj, jsid id)
|
||||
{
|
||||
NS_ASSERTION(
|
||||
obj->getClass() == &XPC_WN_ModsAllowed_WithCall_Proto_JSClass ||
|
||||
obj->getClass() == &XPC_WN_ModsAllowed_NoCall_Proto_JSClass,
|
||||
"bad proto");
|
||||
JS_InstanceOf(cx, obj, &XPC_WN_ModsAllowed_WithCall_Proto_JSClass,
|
||||
nsnull) ||
|
||||
JS_InstanceOf(cx, obj, &XPC_WN_ModsAllowed_NoCall_Proto_JSClass,
|
||||
nsnull),
|
||||
"bad proto");
|
||||
|
||||
XPCWrappedNativeProto* self =
|
||||
(XPCWrappedNativeProto*) xpc_GetJSPrivate(obj);
|
||||
@ -1883,58 +1905,83 @@ XPC_WN_ModsAllowed_Proto_Resolve(JSContext *cx, JSObject *obj, jsid id)
|
||||
enumFlag, nsnull);
|
||||
}
|
||||
|
||||
js::Class XPC_WN_ModsAllowed_WithCall_Proto_JSClass = {
|
||||
// Give our proto classes object ops that match the respective
|
||||
// wrappers so that the JS engine can share scope (maps) among
|
||||
// wrappers. This essentially duplicates the number of JSClasses we
|
||||
// use for prototype objects (from 2 to 4), but the scope sharing
|
||||
// benefit is well worth it.
|
||||
JSObjectOps *
|
||||
XPC_WN_Proto_GetObjectOps(JSContext *cx, JSClass *clazz)
|
||||
{
|
||||
// Protos for wrappers that want calls to their call() hooks get
|
||||
// jsops with a call hook, others get jsops w/o a call hook.
|
||||
|
||||
if(clazz == &XPC_WN_ModsAllowed_WithCall_Proto_JSClass ||
|
||||
clazz == &XPC_WN_NoMods_WithCall_Proto_JSClass)
|
||||
return &XPC_WN_WithCall_JSOps;
|
||||
|
||||
NS_ASSERTION(clazz == &XPC_WN_ModsAllowed_NoCall_Proto_JSClass ||
|
||||
clazz == &XPC_WN_NoMods_NoCall_Proto_JSClass ||
|
||||
clazz == &XPC_WN_NoHelper_Proto_JSClass,
|
||||
"bad proto");
|
||||
|
||||
return &XPC_WN_NoCall_JSOps;
|
||||
}
|
||||
|
||||
JSClass XPC_WN_ModsAllowed_WithCall_Proto_JSClass = {
|
||||
"XPC_WN_ModsAllowed_WithCall_Proto_JSClass", // name;
|
||||
WRAPPER_SLOTS | JSCLASS_MARK_IS_TRACE, // flags;
|
||||
|
||||
/* Mandatory non-null function pointer members. */
|
||||
js::PropertyStub, // addProperty;
|
||||
js::PropertyStub, // delProperty;
|
||||
js::PropertyStub, // getProperty;
|
||||
js::PropertyStub, // setProperty;
|
||||
XPC_WN_Shared_Proto_Enumerate, // enumerate;
|
||||
XPC_WN_ModsAllowed_Proto_Resolve, // resolve;
|
||||
js::Valueify(XPC_WN_Shared_Proto_Convert), // convert;
|
||||
XPC_WN_Shared_Proto_Finalize, // finalize;
|
||||
JS_PropertyStub, // addProperty;
|
||||
JS_PropertyStub, // delProperty;
|
||||
JS_PropertyStub, // getProperty;
|
||||
JS_PropertyStub, // setProperty;
|
||||
XPC_WN_Shared_Proto_Enumerate, // enumerate;
|
||||
XPC_WN_ModsAllowed_Proto_Resolve, // resolve;
|
||||
XPC_WN_Shared_Proto_Convert, // convert;
|
||||
XPC_WN_Shared_Proto_Finalize, // finalize;
|
||||
|
||||
/* Optionally non-null members start here. */
|
||||
nsnull, // reserved0;
|
||||
XPC_WN_Proto_GetObjectOps, // getObjectOps;
|
||||
nsnull, // checkAccess;
|
||||
nsnull, // call;
|
||||
nsnull, // construct;
|
||||
nsnull, // xdrObject;
|
||||
nsnull, // hasInstance;
|
||||
JS_CLASS_TRACE(XPC_WN_Shared_Proto_Trace), // mark/trace;
|
||||
|
||||
JS_NULL_CLASS_EXT,
|
||||
XPC_WN_WithCall_ObjectOps
|
||||
nsnull // spare;
|
||||
};
|
||||
|
||||
js::Class XPC_WN_ModsAllowed_NoCall_Proto_JSClass = {
|
||||
JSObjectOps *
|
||||
XPC_WN_ModsAllowedProto_NoCall_GetObjectOps(JSContext *cx, JSClass *clazz)
|
||||
{
|
||||
return &XPC_WN_NoCall_JSOps;
|
||||
}
|
||||
|
||||
JSClass XPC_WN_ModsAllowed_NoCall_Proto_JSClass = {
|
||||
"XPC_WN_ModsAllowed_NoCall_Proto_JSClass", // name;
|
||||
WRAPPER_SLOTS | JSCLASS_MARK_IS_TRACE, // flags;
|
||||
|
||||
/* Mandatory non-null function pointer members. */
|
||||
js::PropertyStub, // addProperty;
|
||||
js::PropertyStub, // delProperty;
|
||||
js::PropertyStub, // getProperty;
|
||||
js::PropertyStub, // setProperty;
|
||||
XPC_WN_Shared_Proto_Enumerate, // enumerate;
|
||||
XPC_WN_ModsAllowed_Proto_Resolve,// resolve;
|
||||
js::Valueify(XPC_WN_Shared_Proto_Convert), // convert;
|
||||
XPC_WN_Shared_Proto_Finalize, // finalize;
|
||||
JS_PropertyStub, // addProperty;
|
||||
JS_PropertyStub, // delProperty;
|
||||
JS_PropertyStub, // getProperty;
|
||||
JS_PropertyStub, // setProperty;
|
||||
XPC_WN_Shared_Proto_Enumerate, // enumerate;
|
||||
XPC_WN_ModsAllowed_Proto_Resolve, // resolve;
|
||||
XPC_WN_Shared_Proto_Convert, // convert;
|
||||
XPC_WN_Shared_Proto_Finalize, // finalize;
|
||||
|
||||
/* Optionally non-null members start here. */
|
||||
nsnull, // reserved0;
|
||||
XPC_WN_Proto_GetObjectOps, // getObjectOps;
|
||||
nsnull, // checkAccess;
|
||||
nsnull, // call;
|
||||
nsnull, // construct;
|
||||
nsnull, // xdrObject;
|
||||
nsnull, // hasInstance;
|
||||
JS_CLASS_TRACE(XPC_WN_Shared_Proto_Trace), // mark/trace;
|
||||
|
||||
JS_NULL_CLASS_EXT,
|
||||
XPC_WN_NoCall_ObjectOps
|
||||
nsnull // spare;
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
@ -1942,8 +1989,9 @@ js::Class XPC_WN_ModsAllowed_NoCall_Proto_JSClass = {
|
||||
static JSBool
|
||||
XPC_WN_OnlyIWrite_Proto_PropertyStub(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
{
|
||||
NS_ASSERTION(obj->getClass() == &XPC_WN_NoMods_WithCall_Proto_JSClass ||
|
||||
obj->getClass() == &XPC_WN_NoMods_NoCall_Proto_JSClass,
|
||||
NS_ASSERTION(
|
||||
JS_InstanceOf(cx, obj, &XPC_WN_NoMods_WithCall_Proto_JSClass, nsnull) ||
|
||||
JS_InstanceOf(cx, obj, &XPC_WN_NoMods_NoCall_Proto_JSClass, nsnull),
|
||||
"bad proto");
|
||||
|
||||
XPCWrappedNativeProto* self =
|
||||
@ -1965,8 +2013,9 @@ XPC_WN_OnlyIWrite_Proto_PropertyStub(JSContext *cx, JSObject *obj, jsid id, jsva
|
||||
static JSBool
|
||||
XPC_WN_NoMods_Proto_Resolve(JSContext *cx, JSObject *obj, jsid id)
|
||||
{
|
||||
NS_ASSERTION(obj->getClass() == &XPC_WN_NoMods_WithCall_Proto_JSClass ||
|
||||
obj->getClass() == &XPC_WN_NoMods_NoCall_Proto_JSClass,
|
||||
NS_ASSERTION(
|
||||
JS_InstanceOf(cx, obj, &XPC_WN_NoMods_WithCall_Proto_JSClass, nsnull) ||
|
||||
JS_InstanceOf(cx, obj, &XPC_WN_NoMods_NoCall_Proto_JSClass, nsnull),
|
||||
"bad proto");
|
||||
|
||||
XPCWrappedNativeProto* self =
|
||||
@ -1991,58 +2040,54 @@ XPC_WN_NoMods_Proto_Resolve(JSContext *cx, JSObject *obj, jsid id)
|
||||
enumFlag, nsnull);
|
||||
}
|
||||
|
||||
js::Class XPC_WN_NoMods_WithCall_Proto_JSClass = {
|
||||
JSClass XPC_WN_NoMods_WithCall_Proto_JSClass = {
|
||||
"XPC_WN_NoMods_WithCall_Proto_JSClass", // name;
|
||||
WRAPPER_SLOTS | JSCLASS_MARK_IS_TRACE, // flags;
|
||||
|
||||
/* Mandatory non-null function pointer members. */
|
||||
js::Valueify(XPC_WN_OnlyIWrite_Proto_PropertyStub), // addProperty;
|
||||
js::Valueify(XPC_WN_CannotModifyPropertyStub), // delProperty;
|
||||
js::PropertyStub, // getProperty;
|
||||
js::Valueify(XPC_WN_OnlyIWrite_Proto_PropertyStub), // setProperty;
|
||||
XPC_WN_Shared_Proto_Enumerate, // enumerate;
|
||||
XPC_WN_NoMods_Proto_Resolve, // resolve;
|
||||
js::Valueify(XPC_WN_Shared_Proto_Convert), // convert;
|
||||
XPC_WN_Shared_Proto_Finalize, // finalize;
|
||||
XPC_WN_OnlyIWrite_Proto_PropertyStub, // addProperty;
|
||||
XPC_WN_CannotModifyPropertyStub, // delProperty;
|
||||
JS_PropertyStub, // getProperty;
|
||||
XPC_WN_OnlyIWrite_Proto_PropertyStub, // setProperty;
|
||||
XPC_WN_Shared_Proto_Enumerate, // enumerate;
|
||||
XPC_WN_NoMods_Proto_Resolve, // resolve;
|
||||
XPC_WN_Shared_Proto_Convert, // convert;
|
||||
XPC_WN_Shared_Proto_Finalize, // finalize;
|
||||
|
||||
/* Optionally non-null members start here. */
|
||||
nsnull, // reserved0;
|
||||
XPC_WN_Proto_GetObjectOps, // getObjectOps;
|
||||
nsnull, // checkAccess;
|
||||
nsnull, // call;
|
||||
nsnull, // construct;
|
||||
nsnull, // xdrObject;
|
||||
nsnull, // hasInstance;
|
||||
JS_CLASS_TRACE(XPC_WN_Shared_Proto_Trace), // mark/trace;
|
||||
|
||||
JS_NULL_CLASS_EXT,
|
||||
XPC_WN_WithCall_ObjectOps
|
||||
nsnull // spare;
|
||||
};
|
||||
|
||||
js::Class XPC_WN_NoMods_NoCall_Proto_JSClass = {
|
||||
"XPC_WN_NoMods_NoCall_Proto_JSClass", // name;
|
||||
WRAPPER_SLOTS | JSCLASS_MARK_IS_TRACE, // flags;
|
||||
JSClass XPC_WN_NoMods_NoCall_Proto_JSClass = {
|
||||
"XPC_WN_NoMods_NoCall_Proto_JSClass", // name;
|
||||
WRAPPER_SLOTS | JSCLASS_MARK_IS_TRACE, // flags;
|
||||
|
||||
/* Mandatory non-null function pointer members. */
|
||||
js::Valueify(XPC_WN_OnlyIWrite_Proto_PropertyStub), // addProperty;
|
||||
js::Valueify(XPC_WN_CannotModifyPropertyStub), // delProperty;
|
||||
js::PropertyStub, // getProperty;
|
||||
js::Valueify(XPC_WN_OnlyIWrite_Proto_PropertyStub), // setProperty;
|
||||
XPC_WN_Shared_Proto_Enumerate, // enumerate;
|
||||
XPC_WN_NoMods_Proto_Resolve, // resolve;
|
||||
js::Valueify(XPC_WN_Shared_Proto_Convert), // convert;
|
||||
XPC_WN_Shared_Proto_Finalize, // finalize;
|
||||
XPC_WN_OnlyIWrite_Proto_PropertyStub, // addProperty;
|
||||
XPC_WN_CannotModifyPropertyStub, // delProperty;
|
||||
JS_PropertyStub, // getProperty;
|
||||
XPC_WN_OnlyIWrite_Proto_PropertyStub, // setProperty;
|
||||
XPC_WN_Shared_Proto_Enumerate, // enumerate;
|
||||
XPC_WN_NoMods_Proto_Resolve, // resolve;
|
||||
XPC_WN_Shared_Proto_Convert, // convert;
|
||||
XPC_WN_Shared_Proto_Finalize, // finalize;
|
||||
|
||||
/* Optionally non-null members start here. */
|
||||
nsnull, // reserved0;
|
||||
XPC_WN_Proto_GetObjectOps, // getObjectOps;
|
||||
nsnull, // checkAccess;
|
||||
nsnull, // call;
|
||||
nsnull, // construct;
|
||||
nsnull, // xdrObject;
|
||||
nsnull, // hasInstance;
|
||||
JS_CLASS_TRACE(XPC_WN_Shared_Proto_Trace), // mark/trace;
|
||||
|
||||
JS_NULL_CLASS_EXT,
|
||||
XPC_WN_NoCall_ObjectOps
|
||||
nsnull // spare;
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
@ -2103,16 +2148,27 @@ XPC_WN_TearOff_Finalize(JSContext *cx, JSObject *obj)
|
||||
p->JSObjectFinalized();
|
||||
}
|
||||
|
||||
js::Class XPC_WN_Tearoff_JSClass = {
|
||||
"WrappedNative_TearOff", // name;
|
||||
WRAPPER_SLOTS | JSCLASS_MARK_IS_TRACE, // flags;
|
||||
JSClass XPC_WN_Tearoff_JSClass = {
|
||||
"WrappedNative_TearOff", // name;
|
||||
WRAPPER_SLOTS | JSCLASS_MARK_IS_TRACE, // flags;
|
||||
|
||||
js::Valueify(XPC_WN_OnlyIWrite_PropertyStub), // addProperty;
|
||||
js::Valueify(XPC_WN_CannotModifyPropertyStub), // delProperty;
|
||||
js::PropertyStub, // getProperty;
|
||||
js::Valueify(XPC_WN_OnlyIWrite_PropertyStub), // setProperty;
|
||||
XPC_WN_TearOff_Enumerate, // enumerate;
|
||||
XPC_WN_TearOff_Resolve, // resolve;
|
||||
js::Valueify(XPC_WN_Shared_Convert), // convert;
|
||||
XPC_WN_TearOff_Finalize // finalize;
|
||||
/* Mandatory non-null function pointer members. */
|
||||
XPC_WN_OnlyIWrite_PropertyStub, // addProperty;
|
||||
XPC_WN_CannotModifyPropertyStub, // delProperty;
|
||||
JS_PropertyStub, // getProperty;
|
||||
XPC_WN_OnlyIWrite_PropertyStub, // setProperty;
|
||||
XPC_WN_TearOff_Enumerate, // enumerate;
|
||||
XPC_WN_TearOff_Resolve, // resolve;
|
||||
XPC_WN_Shared_Convert, // convert;
|
||||
XPC_WN_TearOff_Finalize, // finalize;
|
||||
|
||||
/* Optionally non-null members start here. */
|
||||
nsnull, // getObjectOps;
|
||||
nsnull, // checkAccess;
|
||||
nsnull, // call;
|
||||
nsnull, // construct;
|
||||
nsnull, // xdrObject;
|
||||
nsnull, // hasInstance;
|
||||
nsnull, // mark/trace;
|
||||
nsnull // spare;
|
||||
};
|
||||
|
@ -104,7 +104,7 @@ XPCWrappedNativeProto::Init(
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
js::Class* jsclazz;
|
||||
JSClass* jsclazz;
|
||||
|
||||
|
||||
if(mScriptableInfo)
|
||||
@ -132,7 +132,7 @@ XPCWrappedNativeProto::Init(
|
||||
JSObject *parent = mScope->GetGlobalJSObject();
|
||||
|
||||
mJSProtoObject =
|
||||
xpc_NewSystemInheritingJSObject(ccx, js::Jsvalify(jsclazz),
|
||||
xpc_NewSystemInheritingJSObject(ccx, jsclazz,
|
||||
mScope->GetPrototypeJSObject(),
|
||||
parent);
|
||||
|
||||
|
@ -204,31 +204,29 @@ XPCWrappedNativeScope::SetComponents(nsXPCComponents* aComponents)
|
||||
// reserved slots in this class needs to match that of the wrappers
|
||||
// for the JS engine to share scopes.
|
||||
|
||||
js::Class XPC_WN_NoHelper_Proto_JSClass = {
|
||||
JSClass XPC_WN_NoHelper_Proto_JSClass = {
|
||||
"XPC_WN_NoHelper_Proto_JSClass",// name;
|
||||
WRAPPER_SLOTS, // flags;
|
||||
|
||||
/* Mandatory non-null function pointer members. */
|
||||
js::PropertyStub, // addProperty;
|
||||
js::PropertyStub, // delProperty;
|
||||
js::PropertyStub, // getProperty;
|
||||
js::PropertyStub, // setProperty;
|
||||
js::EnumerateStub, // enumerate;
|
||||
JS_PropertyStub, // addProperty;
|
||||
JS_PropertyStub, // delProperty;
|
||||
JS_PropertyStub, // getProperty;
|
||||
JS_PropertyStub, // setProperty;
|
||||
JS_EnumerateStub, // enumerate;
|
||||
JS_ResolveStub, // resolve;
|
||||
js::ConvertStub, // convert;
|
||||
JS_ConvertStub, // convert;
|
||||
nsnull, // finalize;
|
||||
|
||||
/* Optionally non-null members start here. */
|
||||
nsnull, // reserved0;
|
||||
XPC_WN_Proto_GetObjectOps, // getObjectOps;
|
||||
nsnull, // checkAccess;
|
||||
nsnull, // call;
|
||||
nsnull, // construct;
|
||||
nsnull, // xdrObject;
|
||||
nsnull, // hasInstance;
|
||||
nsnull, // mark/trace;
|
||||
|
||||
JS_NULL_CLASS_EXT,
|
||||
XPC_WN_NoCall_ObjectOps
|
||||
nsnull // spare;
|
||||
};
|
||||
|
||||
|
||||
@ -352,8 +350,7 @@ XPCWrappedNativeScope::GetPrototypeNoHelper(XPCCallContext& ccx)
|
||||
if(!mPrototypeNoHelper)
|
||||
{
|
||||
mPrototypeNoHelper =
|
||||
xpc_NewSystemInheritingJSObject(ccx,
|
||||
js::Jsvalify(&XPC_WN_NoHelper_Proto_JSClass),
|
||||
xpc_NewSystemInheritingJSObject(ccx, &XPC_WN_NoHelper_Proto_JSClass,
|
||||
mPrototypeJSObject,
|
||||
mGlobalJSObject);
|
||||
|
||||
@ -728,7 +725,7 @@ XPCWrappedNativeScope*
|
||||
GetScopeOfObject(JSObject* obj)
|
||||
{
|
||||
nsISupports* supports;
|
||||
js::Class* clazz = obj->getClass();
|
||||
JSClass* clazz = obj->getJSClass();
|
||||
JSBool isWrapper = IS_WRAPPER_CLASS(clazz);
|
||||
|
||||
if(isWrapper && IS_SLIM_WRAPPER_OBJECT(obj))
|
||||
|
Loading…
Reference in New Issue
Block a user