Bug 761695 - Implement expando traps for ProxyXrayTraits DOMXrayTraits. r=peterv

For new DOM proxies, we could probably use the Xray expando machinery for the
regular expando object as well, and free up one of the reserved slots. That's
more than I want to bite off for the moment, though.

I also decided not to block on bug 760095 and just kick the problem of globals
with new binding down the road a little bit.
This commit is contained in:
Bobby Holley 2012-10-05 18:59:23 +02:00
parent bde8b4dc55
commit 9f982e86a6
10 changed files with 63 additions and 11 deletions

View File

@ -629,5 +629,26 @@ HasPropertyOnPrototype(JSContext* cx, JSObject* proxy, DOMProxyHandler* handler,
return !GetPropertyOnPrototype(cx, proxy, id, &found, NULL) || found;
}
JSObject*
GetXrayExpandoChain(JSObject* obj)
{
MOZ_ASSERT(IsDOMObject(obj));
JS::Value v = IsDOMProxy(obj) ? js::GetProxyExtra(obj, JSPROXYSLOT_XRAY_EXPANDO)
: js::GetReservedSlot(obj, DOM_XRAY_EXPANDO_SLOT);
return v.isUndefined() ? nullptr : &v.toObject();
}
void
SetXrayExpandoChain(JSObject* obj, JSObject* chain)
{
MOZ_ASSERT(IsDOMObject(obj));
JS::Value v = chain ? JS::ObjectValue(*chain) : JSVAL_VOID;
if (IsDOMProxy(obj)) {
js::SetProxyExtra(obj, JSPROXYSLOT_XRAY_EXPANDO, v);
} else {
js::SetReservedSlot(obj, DOM_XRAY_EXPANDO_SLOT, v);
}
}
} // namespace dom
} // namespace mozilla

View File

@ -1167,6 +1167,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);
} // namespace dom
} // namespace mozilla

View File

@ -106,6 +106,8 @@ class CGDOMJSClass(CGThing):
def __init__(self, descriptor):
CGThing.__init__(self)
self.descriptor = descriptor
# Our current reserved slot situation is unsafe for globals. Fix bug 760095!
assert "Window" not in descriptor.interface.identifier.name
def declare(self):
return "extern DOMJSClass Class;\n"
def define(self):
@ -113,7 +115,7 @@ class CGDOMJSClass(CGThing):
return """
DOMJSClass Class = {
{ "%s",
JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(1),
JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(2),
%s, /* addProperty */
JS_PropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */

View File

@ -15,6 +15,11 @@
// 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
// All DOM globals must have a slot at DOM_PROTOTYPE_SLOT. We have to
// start at 1 past JSCLASS_GLOBAL_SLOT_COUNT because XPConnect uses
// that one.

View File

@ -19,7 +19,8 @@ namespace mozilla {
namespace dom {
enum {
JSPROXYSLOT_EXPANDO = 0
JSPROXYSLOT_EXPANDO = 0,
JSPROXYSLOT_XRAY_EXPANDO
};
template<typename T> struct Prefable;

View File

@ -304,7 +304,7 @@ MOZ_STATIC_ASSERT(prototypes::MaxProtoChainLength == 3,
DOMJSClass Worker::sClass = {
{
"Worker",
JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(1) |
JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(2) |
JSCLASS_IMPLEMENTS_BARRIERS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize,
@ -429,7 +429,7 @@ MOZ_STATIC_ASSERT(prototypes::MaxProtoChainLength == 3,
// sNativePropertyHooks then sNativePropertyHooks should be removed too.
DOMJSClass ChromeWorker::sClass = {
{ "ChromeWorker",
JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(1) |
JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(2) |
JSCLASS_IMPLEMENTS_BARRIERS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize,

View File

@ -856,6 +856,8 @@ MOZ_STATIC_ASSERT(prototypes::MaxProtoChainLength == 3,
// sNativePropertyHooks then sNativePropertyHooks should be removed too.
DOMJSClass DedicatedWorkerGlobalScope::sClass = {
{
// We don't have to worry about Xray expando slots here because we'll never
// have an Xray wrapper to a worker global scope.
"DedicatedWorkerGlobalScope",
JSCLASS_DOM_GLOBAL | JSCLASS_IS_DOMJSCLASS | JSCLASS_IMPLEMENTS_BARRIERS |
JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(3) | JSCLASS_NEW_RESOLVE,

View File

@ -28,7 +28,8 @@ namespace dom {
namespace oldproxybindings {
enum {
JSPROXYSLOT_EXPANDO = 0
JSPROXYSLOT_EXPANDO = 0,
JSPROXYSLOT_XRAY_EXPANDO
};
static jsid s_prototype_id = JSID_VOID;
@ -1013,6 +1014,19 @@ NoBase::getPrototype(JSContext *cx, XPCWrappedNativeScope *scope, JSObject *rece
return JS_GetObjectPrototype(cx, receiver);
}
JSObject*
GetXrayExpandoChain(JSObject *obj) {
MOZ_ASSERT(instanceIsProxy(obj));
js::Value v = js::GetProxyExtra(obj, JSPROXYSLOT_XRAY_EXPANDO);
return v.isUndefined() ? nullptr : &v.toObject();
}
void
SetXrayExpandoChain(JSObject *obj, JSObject *chain) {
MOZ_ASSERT(instanceIsProxy(obj));
js::Value v = chain ? JS::ObjectValue(*chain) : JSVAL_VOID;
js::SetProxyExtra(obj, JSPROXYSLOT_XRAY_EXPANDO, v);
}
}
}

View File

@ -213,6 +213,9 @@ struct nsISupportsResult
nsWrapperCache *mCache;
};
JSObject* GetXrayExpandoChain(JSObject *obj);
void SetXrayExpandoChain(JSObject *obj, JSObject *chain);
}
}
}

View File

@ -22,6 +22,7 @@
#include "nsJSUtils.h"
#include "mozilla/dom/BindingUtils.h"
#include "dombindings.h"
using namespace mozilla::dom;
@ -238,11 +239,10 @@ public:
virtual JSObject* createHolder(JSContext *cx, JSObject *wrapper);
virtual JSObject* getExpandoChain(JSObject *obj) {
MOZ_NOT_REACHED("Expando chain not yet implemented for non-WN objects");
return NULL;
return mozilla::dom::oldproxybindings::GetXrayExpandoChain(obj);
}
virtual void setExpandoChain(JSObject *obj, JSObject *chain) {
MOZ_NOT_REACHED("Expando chain not yet implemented for non-WN objects");
mozilla::dom::oldproxybindings::SetXrayExpandoChain(obj, chain);
}
static ProxyXrayTraits singleton;
@ -274,11 +274,10 @@ public:
virtual JSObject* createHolder(JSContext *cx, JSObject *wrapper);
virtual JSObject* getExpandoChain(JSObject *obj) {
MOZ_NOT_REACHED("Expando chain not yet implemented for non-WN objects");
return NULL;
return mozilla::dom::GetXrayExpandoChain(obj);
}
virtual void setExpandoChain(JSObject *obj, JSObject *chain) {
MOZ_NOT_REACHED("Expando chain not yet implemented for non-WN objects");
mozilla::dom::SetXrayExpandoChain(obj, chain);
}
static DOMXrayTraits singleton;