зеркало из https://github.com/mozilla/gecko-dev.git
Back out 0f5f58d5d410:8db4d719f5f8 (bug 973780) for debug WinXP mochitest-3 assertions
CLOSED TREE
This commit is contained in:
Родитель
8e5e2743ce
Коммит
01ad150169
|
@ -1512,6 +1512,39 @@ AppendNamedPropertyIds(JSContext* cx, JS::Handle<JSObject*> proxy,
|
|||
return true;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
GetXrayExpandoChain(JSObject* obj)
|
||||
{
|
||||
const js::Class* clasp = js::GetObjectClass(obj);
|
||||
JS::Value v;
|
||||
if (IsNonProxyDOMClass(clasp) || IsDOMIfaceAndProtoClass(clasp)) {
|
||||
v = js::GetReservedSlot(obj, DOM_XRAY_EXPANDO_SLOT);
|
||||
} else if (clasp->isProxy()) {
|
||||
MOZ_ASSERT(js::GetProxyHandler(obj)->family() == ProxyFamily());
|
||||
v = js::GetProxyExtra(obj, JSPROXYSLOT_XRAY_EXPANDO);
|
||||
} else {
|
||||
MOZ_ASSERT(JS_IsNativeFunction(obj, Constructor));
|
||||
v = js::GetFunctionNativeReserved(obj, CONSTRUCTOR_XRAY_EXPANDO_SLOT);
|
||||
}
|
||||
return v.isUndefined() ? nullptr : &v.toObject();
|
||||
}
|
||||
|
||||
void
|
||||
SetXrayExpandoChain(JSObject* obj, JSObject* chain)
|
||||
{
|
||||
JS::Value v = chain ? JS::ObjectValue(*chain) : JSVAL_VOID;
|
||||
const js::Class* clasp = js::GetObjectClass(obj);
|
||||
if (IsNonProxyDOMClass(clasp) || IsDOMIfaceAndProtoClass(clasp)) {
|
||||
js::SetReservedSlot(obj, DOM_XRAY_EXPANDO_SLOT, v);
|
||||
} else if (clasp->isProxy()) {
|
||||
MOZ_ASSERT(js::GetProxyHandler(obj)->family() == ProxyFamily());
|
||||
js::SetProxyExtra(obj, JSPROXYSLOT_XRAY_EXPANDO, v);
|
||||
} else {
|
||||
MOZ_ASSERT(JS_IsNativeFunction(obj, Constructor));
|
||||
js::SetFunctionNativeReserved(obj, CONSTRUCTOR_XRAY_EXPANDO_SLOT, v);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
DictionaryBase::ParseJSON(JSContext* aCx,
|
||||
const nsAString& aJSON,
|
||||
|
@ -1724,6 +1757,7 @@ ReparentWrapper(JSContext* aCx, JS::Handle<JSObject*> aObjArg)
|
|||
|
||||
// Expandos from other compartments are attached to the target JS object.
|
||||
// Copy them over, and let the old ones die a natural death.
|
||||
SetXrayExpandoChain(newobj, nullptr);
|
||||
if (!xpc::XrayUtils::CloneExpandoChain(aCx, newobj, aObj)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
|
@ -1955,12 +1955,14 @@ extern NativePropertyHooks sWorkerNativePropertyHooks;
|
|||
// the real JSNative in the mNative member of a JSNativeHolder in the
|
||||
// CONSTRUCTOR_NATIVE_HOLDER_RESERVED_SLOT slot of the JSFunction object for a
|
||||
// specific interface object. We also store the NativeProperties in the
|
||||
// JSNativeHolder.
|
||||
// JSNativeHolder. The CONSTRUCTOR_XRAY_EXPANDO_SLOT is used to store the
|
||||
// expando chain of the Xray for the interface object.
|
||||
// Note that some interface objects are not yet a JSFunction but a normal
|
||||
// JSObject with a DOMJSClass, those do not use these slots.
|
||||
|
||||
enum {
|
||||
CONSTRUCTOR_NATIVE_HOLDER_RESERVED_SLOT = 0
|
||||
CONSTRUCTOR_NATIVE_HOLDER_RESERVED_SLOT = 0,
|
||||
CONSTRUCTOR_XRAY_EXPANDO_SLOT
|
||||
};
|
||||
|
||||
bool
|
||||
|
@ -2005,6 +2007,11 @@ MustInheritFromNonRefcountedDOMObject(NonRefcountedDOMObject*)
|
|||
{
|
||||
}
|
||||
|
||||
// Set the chain of expando objects for various consumers of the given object.
|
||||
// For Paris Bindings only. See the relevant infrastructure in XrayWrapper.cpp.
|
||||
JSObject* GetXrayExpandoChain(JSObject *obj);
|
||||
void SetXrayExpandoChain(JSObject *obj, JSObject *chain);
|
||||
|
||||
/**
|
||||
* This creates a JSString containing the value that the toString function for
|
||||
* obj should create according to the WebIDL specification, ignoring any
|
||||
|
|
|
@ -21,7 +21,8 @@ namespace dom {
|
|||
class DOMClass;
|
||||
|
||||
enum {
|
||||
JSPROXYSLOT_EXPANDO = 0
|
||||
JSPROXYSLOT_EXPANDO = 0,
|
||||
JSPROXYSLOT_XRAY_EXPANDO
|
||||
};
|
||||
|
||||
template<typename T> struct Prefable;
|
||||
|
|
|
@ -14,15 +14,20 @@
|
|||
// globals and non-globals.
|
||||
#define DOM_OBJECT_SLOT 0
|
||||
|
||||
// We use slot 1 for holding the expando object. This is not safe for globals
|
||||
// until bug 760095 is fixed, so that bug blocks converting Window to new
|
||||
// bindings.
|
||||
#define DOM_XRAY_EXPANDO_SLOT 1
|
||||
|
||||
// We use slot 2 for holding either a JS::ObjectValue which points to the cached
|
||||
// SOW or JS::UndefinedValue if this class doesn't need SOWs. This is not safe
|
||||
// for globals until bug 760095 is fixed, so that bug blocks converting Window
|
||||
// to new bindings.
|
||||
#define DOM_OBJECT_SLOT_SOW 1
|
||||
#define DOM_OBJECT_SLOT_SOW 2
|
||||
|
||||
// The total number of slots non-proxy DOM objects use by default.
|
||||
// Specific objects may have more for storing cached values.
|
||||
#define DOM_INSTANCE_RESERVED_SLOTS 2
|
||||
#define DOM_INSTANCE_RESERVED_SLOTS 3
|
||||
|
||||
// NOTE: This is baked into the Ion JIT as 0 in codegen for LGetDOMProperty and
|
||||
// LSetDOMProperty. Those constants need to be changed accordingly if this value
|
||||
|
@ -31,11 +36,15 @@
|
|||
|
||||
// Interface objects store a number of reserved slots equal to
|
||||
// DOM_INTERFACE_SLOTS_BASE + number of named constructors.
|
||||
#define DOM_INTERFACE_SLOTS_BASE 0
|
||||
#define DOM_INTERFACE_SLOTS_BASE (DOM_XRAY_EXPANDO_SLOT + 1)
|
||||
|
||||
// Interface prototype objects store a number of reserved slots equal to
|
||||
// DOM_INTERFACE_PROTO_SLOTS_BASE or DOM_INTERFACE_PROTO_SLOTS_BASE + 1 if a
|
||||
// slot for the unforgeable holder is needed.
|
||||
#define DOM_INTERFACE_PROTO_SLOTS_BASE (DOM_PROTO_INSTANCE_CLASS_SLOT + 1)
|
||||
#define DOM_INTERFACE_PROTO_SLOTS_BASE (DOM_XRAY_EXPANDO_SLOT + 1)
|
||||
|
||||
static_assert(DOM_PROTO_INSTANCE_CLASS_SLOT != DOM_XRAY_EXPANDO_SLOT,
|
||||
"Interface prototype object use both of these, so they must "
|
||||
"not be the same slot.");
|
||||
|
||||
#endif /* mozilla_dom_DOMSlots_h */
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef js_WeakMapPtr_h
|
||||
#define js_WeakMapPtr_h
|
||||
|
||||
#include "jspubtd.h"
|
||||
|
||||
#include "js/TypeDecls.h"
|
||||
|
||||
namespace JS {
|
||||
|
||||
// A wrapper around the internal C++ representation of SpiderMonkey WeakMaps,
|
||||
// usable outside the engine.
|
||||
//
|
||||
// The supported template specializations are enumerated in WeakMapPtr.cpp. If
|
||||
// you want to use this class for a different key/value combination, add it to
|
||||
// the list and the compiler will generate the relevant machinery.
|
||||
template <typename K, typename V>
|
||||
class JS_PUBLIC_API(WeakMapPtr)
|
||||
{
|
||||
public:
|
||||
WeakMapPtr() : ptr(nullptr) {};
|
||||
bool init(JSContext *cx);
|
||||
bool initialized() { return ptr != nullptr; };
|
||||
void destroy();
|
||||
virtual ~WeakMapPtr() { MOZ_ASSERT(!initialized()); }
|
||||
void trace(JSTracer *tracer);
|
||||
|
||||
V lookup(const K &key);
|
||||
bool put(const K &key, const V &value);
|
||||
|
||||
private:
|
||||
void *ptr;
|
||||
|
||||
// WeakMapPtr is neither copyable nor assignable.
|
||||
WeakMapPtr(const WeakMapPtr &wmp) MOZ_DELETE;
|
||||
WeakMapPtr &operator=(const WeakMapPtr &wmp) MOZ_DELETE;
|
||||
};
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
#endif /* js_WeakMapPtr_h */
|
|
@ -37,7 +37,6 @@
|
|||
#include "js/Utility.h"
|
||||
#include "js/Value.h"
|
||||
#include "js/Vector.h"
|
||||
#include "js/WeakMapPtr.h"
|
||||
#include "jsapi-tests/tests.h"
|
||||
|
||||
/*
|
||||
|
|
|
@ -85,8 +85,7 @@ class WeakMapBase {
|
|||
// Trace all delayed weak map bindings. Used by the cycle collector.
|
||||
static void traceAllMappings(WeakMapTracer *tracer);
|
||||
|
||||
bool isInList() { return next != WeakMapNotInList; }
|
||||
void check() { JS_ASSERT(!isInList()); }
|
||||
void check() { JS_ASSERT(next == WeakMapNotInList); }
|
||||
|
||||
// Remove everything from the weak map list for a compartment.
|
||||
static void resetCompartmentWeakMapList(JSCompartment *c);
|
||||
|
|
|
@ -88,7 +88,6 @@ EXPORTS.js += [
|
|||
'../public/Utility.h',
|
||||
'../public/Value.h',
|
||||
'../public/Vector.h',
|
||||
'../public/WeakMapPtr.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
|
@ -190,7 +189,6 @@ UNIFIED_SOURCES += [
|
|||
'vm/TypedArrayObject.cpp',
|
||||
'vm/Unicode.cpp',
|
||||
'vm/Value.cpp',
|
||||
'vm/WeakMapPtr.cpp',
|
||||
'vm/Xdr.cpp',
|
||||
'yarr/PageBlock.cpp',
|
||||
'yarr/YarrCanonicalizeUCS2.cpp',
|
||||
|
|
|
@ -1,114 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "js/WeakMapPtr.h"
|
||||
|
||||
#include "jsweakmap.h"
|
||||
|
||||
//
|
||||
// Machinery for the externally-linkable JS::WeakMapPtr, which wraps js::WeakMap
|
||||
// for a few public data types.
|
||||
//
|
||||
|
||||
using namespace js;
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename T>
|
||||
struct DataType
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct DataType<JSObject*>
|
||||
{
|
||||
typedef EncapsulatedPtrObject Encapsulated;
|
||||
static JSObject *NullValue() { return nullptr; }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct DataType<JS::Value>
|
||||
{
|
||||
typedef EncapsulatedValue Encapsulated;
|
||||
static JS::Value NullValue() { return JS::UndefinedValue(); }
|
||||
};
|
||||
|
||||
template <typename K, typename V>
|
||||
struct Utils
|
||||
{
|
||||
typedef typename DataType<K>::Encapsulated KeyType;
|
||||
typedef typename DataType<V>::Encapsulated ValueType;
|
||||
typedef WeakMap<KeyType, ValueType> Type;
|
||||
typedef Type* PtrType;
|
||||
static PtrType cast(void *ptr) { return static_cast<PtrType>(ptr); }
|
||||
};
|
||||
|
||||
} /* namespace */
|
||||
|
||||
template <typename K, typename V>
|
||||
void
|
||||
JS::WeakMapPtr<K, V>::destroy()
|
||||
{
|
||||
MOZ_ASSERT(initialized());
|
||||
auto map = Utils<K, V>::cast(ptr);
|
||||
// If this destruction happens mid-GC, we might be in the compartment's list
|
||||
// of known live weakmaps. If we are, remove ourselves before deleting.
|
||||
if (map->isInList())
|
||||
WeakMapBase::removeWeakMapFromList(map);
|
||||
map->check();
|
||||
js_delete(map);
|
||||
ptr = nullptr;
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
bool
|
||||
JS::WeakMapPtr<K, V>::init(JSContext *cx)
|
||||
{
|
||||
MOZ_ASSERT(!initialized());
|
||||
typename Utils<K, V>::PtrType map = cx->runtime()->new_<typename Utils<K,V>::Type>(cx);
|
||||
if (!map || !map->init())
|
||||
return false;
|
||||
ptr = map;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void
|
||||
JS::WeakMapPtr<K, V>::trace(JSTracer *trc)
|
||||
{
|
||||
MOZ_ASSERT(initialized());
|
||||
return Utils<K, V>::cast(ptr)->trace(trc);
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
V
|
||||
JS::WeakMapPtr<K, V>::lookup(const K &key)
|
||||
{
|
||||
MOZ_ASSERT(initialized());
|
||||
typename Utils<K, V>::Type::Ptr result = Utils<K, V>::cast(ptr)->lookup(key);
|
||||
if (!result)
|
||||
return DataType<V>::NullValue();
|
||||
return result->value();
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
bool
|
||||
JS::WeakMapPtr<K, V>::put(const K &key, const V &value)
|
||||
{
|
||||
MOZ_ASSERT(initialized());
|
||||
return Utils<K, V>::cast(ptr)->put(key, value);
|
||||
}
|
||||
|
||||
//
|
||||
// Supported specializations of JS::WeakMap:
|
||||
//
|
||||
|
||||
template class JS::WeakMapPtr<JSObject*, JSObject*>;
|
||||
|
||||
#ifdef DEBUG
|
||||
// Nobody's using this at the moment, but we want to make sure it compiles.
|
||||
template class JS::WeakMapPtr<JSObject*, JS::Value>;
|
||||
#endif
|
|
@ -859,6 +859,10 @@ XPCWrappedNative::FinishInit()
|
|||
{
|
||||
AutoJSContext cx;
|
||||
|
||||
// For all WNs, we want to make sure that the expando chain slot starts out
|
||||
// as null.
|
||||
JS_SetReservedSlot(mFlatJSObject, WN_XRAYEXPANDOCHAIN_SLOT, JSVAL_NULL);
|
||||
|
||||
// This reference will be released when mFlatJSObject is finalized.
|
||||
// Since this reference will push the refcount to 2 it will also root
|
||||
// mFlatJSObject;
|
||||
|
@ -1182,6 +1186,7 @@ XPCWrappedNative::ReparentWrapperIfFound(XPCWrappedNativeScope* aOldScope,
|
|||
|
||||
// Expandos from other compartments are attached to the target JS object.
|
||||
// Copy them over, and let the old ones die a natural death.
|
||||
SetWNExpandoChain(newobj, nullptr);
|
||||
if (!XrayUtils::CloneExpandoChain(cx, newobj, flat))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
|
|
@ -302,9 +302,6 @@ XPCWrappedNativeScope::~XPCWrappedNativeScope()
|
|||
// XXX might not want to do this at xpconnect shutdown time???
|
||||
mComponents = nullptr;
|
||||
|
||||
if (mXrayExpandos.initialized())
|
||||
mXrayExpandos.destroy();
|
||||
|
||||
JSRuntime *rt = XPCJSRuntime::Get()->Runtime();
|
||||
mXBLScope.finalize(rt);
|
||||
mGlobalJSObject.finalize(rt);
|
||||
|
@ -602,27 +599,6 @@ XPCWrappedNativeScope::RemoveWrappedNativeProtos()
|
|||
GetRuntime()->GetDetachedWrappedNativeProtoMap());
|
||||
}
|
||||
|
||||
JSObject *
|
||||
XPCWrappedNativeScope::GetExpandoChain(JSObject *target)
|
||||
{
|
||||
MOZ_ASSERT(GetObjectScope(target) == this);
|
||||
if (!mXrayExpandos.initialized())
|
||||
return nullptr;
|
||||
return mXrayExpandos.lookup(target);
|
||||
}
|
||||
|
||||
bool
|
||||
XPCWrappedNativeScope::SetExpandoChain(JSContext *cx, HandleObject target,
|
||||
HandleObject chain)
|
||||
{
|
||||
MOZ_ASSERT(GetObjectScope(target) == this);
|
||||
MOZ_ASSERT(js::IsObjectInContextCompartment(target, cx));
|
||||
MOZ_ASSERT_IF(chain, GetObjectScope(chain) == this);
|
||||
if (!mXrayExpandos.initialized() && !mXrayExpandos.init(cx))
|
||||
return false;
|
||||
return mXrayExpandos.put(target, chain);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
// static
|
||||
|
|
|
@ -90,7 +90,6 @@
|
|||
|
||||
#include "xpcpublic.h"
|
||||
#include "js/Tracer.h"
|
||||
#include "js/WeakMapPtr.h"
|
||||
#include "pldhash.h"
|
||||
#include "nscore.h"
|
||||
#include "nsXPCOM.h"
|
||||
|
@ -213,10 +212,17 @@ extern const char XPC_XPCONNECT_CONTRACTID[];
|
|||
return (result || !src) ? NS_OK : NS_ERROR_OUT_OF_MEMORY
|
||||
|
||||
|
||||
#define WRAPPER_SLOTS (JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS )
|
||||
#define WRAPPER_SLOTS (JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS | \
|
||||
JSCLASS_HAS_RESERVED_SLOTS(1))
|
||||
|
||||
#define INVALID_OBJECT ((JSObject *)1)
|
||||
|
||||
// NB: This slot isn't actually reserved for us on globals, because SpiderMonkey
|
||||
// uses the first N slots on globals internally. The fact that we use it for
|
||||
// wrapped global objects is totally broken. But due to a happy coincidence, the
|
||||
// JS engine never uses that slot. This still needs fixing though. See bug 760095.
|
||||
#define WN_XRAYEXPANDOCHAIN_SLOT 0
|
||||
|
||||
// If IS_WN_CLASS for the JSClass of an object is true, the object is a
|
||||
// wrappednative wrapper, holding the XPCWrappedNative in its private slot.
|
||||
static inline bool IS_WN_CLASS(const js::Class* clazz)
|
||||
|
@ -229,6 +235,18 @@ static inline bool IS_WN_REFLECTOR(JSObject *obj)
|
|||
return IS_WN_CLASS(js::GetObjectClass(obj));
|
||||
}
|
||||
|
||||
inline void SetWNExpandoChain(JSObject *obj, JSObject *chain)
|
||||
{
|
||||
MOZ_ASSERT(IS_WN_REFLECTOR(obj));
|
||||
JS_SetReservedSlot(obj, WN_XRAYEXPANDOCHAIN_SLOT, JS::ObjectOrNullValue(chain));
|
||||
}
|
||||
|
||||
inline JSObject* GetWNExpandoChain(JSObject *obj)
|
||||
{
|
||||
MOZ_ASSERT(IS_WN_REFLECTOR(obj));
|
||||
return JS_GetReservedSlot(obj, WN_XRAYEXPANDOCHAIN_SLOT).toObjectOrNull();
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
****************************************************************************
|
||||
*
|
||||
|
@ -1019,12 +1037,6 @@ public:
|
|||
return nsJSPrincipals::get(JS_GetCompartmentPrincipals(c));
|
||||
}
|
||||
|
||||
JSObject*
|
||||
GetExpandoChain(JSObject *target);
|
||||
|
||||
bool
|
||||
SetExpandoChain(JSContext *cx, JS::HandleObject target, JS::HandleObject chain);
|
||||
|
||||
void RemoveWrappedNativeProtos();
|
||||
|
||||
static void
|
||||
|
@ -1038,8 +1050,6 @@ public:
|
|||
mGlobalJSObject.trace(trc, "XPCWrappedNativeScope::mGlobalJSObject");
|
||||
if (mXBLScope)
|
||||
mXBLScope.trace(trc, "XPCWrappedNativeScope::mXBLScope");
|
||||
if (mXrayExpandos.initialized())
|
||||
mXrayExpandos.trace(trc);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1159,8 +1169,6 @@ private:
|
|||
|
||||
nsAutoPtr<DOMExpandoSet> mDOMExpandoSet;
|
||||
|
||||
JS::WeakMapPtr<JSObject*, JSObject*> mXrayExpandos;
|
||||
|
||||
bool mIsXBLScope;
|
||||
|
||||
// For remote XUL domains, we run all XBL in the content scope for compat
|
||||
|
|
|
@ -169,13 +169,8 @@ public:
|
|||
JSObject* ensureHolder(JSContext *cx, HandleObject wrapper);
|
||||
virtual JSObject* createHolder(JSContext *cx, JSObject *wrapper) = 0;
|
||||
|
||||
JSObject* getExpandoChain(JSObject *obj) {
|
||||
return GetObjectScope(obj)->GetExpandoChain(obj);
|
||||
}
|
||||
|
||||
bool setExpandoChain(JSContext *cx, HandleObject obj, HandleObject chain) {
|
||||
return GetObjectScope(obj)->SetExpandoChain(cx, obj, chain);
|
||||
}
|
||||
virtual JSObject* getExpandoChain(JSObject *obj) = 0;
|
||||
virtual void setExpandoChain(JSObject *obj, JSObject *chain) = 0;
|
||||
bool cloneExpandoChain(JSContext *cx, HandleObject dst, HandleObject src);
|
||||
|
||||
private:
|
||||
|
@ -226,6 +221,12 @@ public:
|
|||
typedef ResolvingId ResolvingIdImpl;
|
||||
|
||||
virtual JSObject* createHolder(JSContext *cx, JSObject *wrapper);
|
||||
virtual JSObject* getExpandoChain(JSObject *obj) {
|
||||
return GetWNExpandoChain(obj);
|
||||
}
|
||||
virtual void setExpandoChain(JSObject *obj, JSObject *chain) {
|
||||
SetWNExpandoChain(obj, chain);
|
||||
}
|
||||
|
||||
static XPCWrappedNativeXrayTraits singleton;
|
||||
};
|
||||
|
@ -262,6 +263,13 @@ public:
|
|||
|
||||
virtual JSObject* createHolder(JSContext *cx, JSObject *wrapper);
|
||||
|
||||
virtual JSObject* getExpandoChain(JSObject *obj) {
|
||||
return mozilla::dom::GetXrayExpandoChain(obj);
|
||||
}
|
||||
virtual void setExpandoChain(JSObject *obj, JSObject *chain) {
|
||||
mozilla::dom::SetXrayExpandoChain(obj, chain);
|
||||
}
|
||||
|
||||
static DOMXrayTraits singleton;
|
||||
};
|
||||
|
||||
|
@ -432,7 +440,7 @@ XrayTraits::attachExpandoObject(JSContext *cx, HandleObject target,
|
|||
|
||||
// Insert it at the front of the chain.
|
||||
JS_SetReservedSlot(expandoObject, JSSLOT_EXPANDO_NEXT, OBJECT_TO_JSVAL(chain));
|
||||
setExpandoChain(cx, target, expandoObject);
|
||||
setExpandoChain(target, expandoObject);
|
||||
|
||||
return expandoObject;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче