mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 887558 (part 2) - Move various functions into ProxyObject and FunctionProxyObject. r=jorendorff.
--HG-- extra : rebase_source : 14402b9ab7eda3389eb1b812ee961e46067b5b1d
This commit is contained in:
parent
40833186f3
commit
8575db2cf1
@ -128,8 +128,8 @@ IsDOMIfaceAndProtoClass(const js::Class* clasp)
|
||||
return IsDOMIfaceAndProtoClass(Jsvalify(clasp));
|
||||
}
|
||||
|
||||
MOZ_STATIC_ASSERT(DOM_OBJECT_SLOT == js::JSSLOT_PROXY_PRIVATE,
|
||||
"JSSLOT_PROXY_PRIVATE doesn't match DOM_OBJECT_SLOT. "
|
||||
MOZ_STATIC_ASSERT(DOM_OBJECT_SLOT == js::PROXY_PRIVATE_SLOT,
|
||||
"js::PROXY_PRIVATE_SLOT doesn't match DOM_OBJECT_SLOT. "
|
||||
"Expect bad things");
|
||||
template <class T>
|
||||
inline T*
|
||||
|
@ -63,7 +63,7 @@ struct SetDOMProxyInformation
|
||||
{
|
||||
SetDOMProxyInformation() {
|
||||
js::SetDOMProxyInformation((void*) &HandlerFamily,
|
||||
js::JSSLOT_PROXY_EXTRA + JSPROXYSLOT_EXPANDO, DOMProxyShadows);
|
||||
js::PROXY_EXTRA_SLOT + JSPROXYSLOT_EXPANDO, DOMProxyShadows);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include "xpcpublic.h"
|
||||
#include "nsStringGlue.h"
|
||||
|
||||
#define DOM_PROXY_OBJECT_SLOT js::JSSLOT_PROXY_PRIVATE
|
||||
#define DOM_PROXY_OBJECT_SLOT js::PROXY_PRIVATE_SLOT
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -3069,7 +3069,7 @@ IsCacheableDOMProxy(JSObject *obj)
|
||||
if (!obj->is<ProxyObject>())
|
||||
return false;
|
||||
|
||||
BaseProxyHandler *handler = GetProxyHandler(obj);
|
||||
BaseProxyHandler *handler = obj->as<ProxyObject>().handler();
|
||||
|
||||
if (handler->family() != GetDOMProxyHandlerFamily())
|
||||
return false;
|
||||
@ -3101,7 +3101,7 @@ GenerateDOMProxyChecks(JSContext *cx, MacroAssembler &masm, Register object,
|
||||
// 1. The object is a DOMProxy.
|
||||
// 2. The object does not have expando properties, or has an expando
|
||||
// which is known to not have the desired property.
|
||||
Address handlerAddr(object, JSObject::getFixedSlotOffset(JSSLOT_PROXY_HANDLER));
|
||||
Address handlerAddr(object, ProxyObject::offsetOfHandler());
|
||||
Address expandoAddr(object, JSObject::getFixedSlotOffset(GetDOMProxyExpandoSlot()));
|
||||
|
||||
// Check that object is a DOMProxy.
|
||||
@ -5330,8 +5330,9 @@ TryAttachNativeGetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc,
|
||||
} else {
|
||||
kind = ICStub::GetProp_CallDOMProxyNative;
|
||||
}
|
||||
ICGetPropCallDOMProxyNativeCompiler compiler(cx, kind, monitorStub, obj, holder, callee,
|
||||
pc - script->code);
|
||||
Rooted<ProxyObject*> proxy(cx, &obj->as<ProxyObject>());
|
||||
ICGetPropCallDOMProxyNativeCompiler
|
||||
compiler(cx, kind, monitorStub, proxy, holder, callee, pc - script->code);
|
||||
newStub = compiler.getStub(compiler.getStubSpace(script));
|
||||
} else {
|
||||
ICGetProp_CallNative::Compiler compiler(cx, monitorStub, obj, holder, callee,
|
||||
@ -5350,7 +5351,8 @@ TryAttachNativeGetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc,
|
||||
JS_ASSERT(obj == holder);
|
||||
|
||||
IonSpew(IonSpew_BaselineIC, " Generating GetProp(DOMProxyProxy) stub");
|
||||
ICGetProp_DOMProxyShadowed::Compiler compiler(cx, monitorStub, obj, name,
|
||||
Rooted<ProxyObject*> proxy(cx, &obj->as<ProxyObject>());
|
||||
ICGetProp_DOMProxyShadowed::Compiler compiler(cx, monitorStub, proxy, name,
|
||||
pc - script->code);
|
||||
ICStub *newStub = compiler.getStub(compiler.getStubSpace(script));
|
||||
if (!newStub)
|
||||
@ -5956,10 +5958,10 @@ ICGetPropCallDOMProxyNativeCompiler::generateStubCode(MacroAssembler &masm)
|
||||
ICStub *
|
||||
ICGetPropCallDOMProxyNativeCompiler::getStub(ICStubSpace *space)
|
||||
{
|
||||
RootedShape shape(cx, obj_->lastProperty());
|
||||
RootedShape shape(cx, proxy_->lastProperty());
|
||||
RootedShape holderShape(cx, holder_->lastProperty());
|
||||
|
||||
Value expandoSlot = obj_->getFixedSlot(GetDOMProxyExpandoSlot());
|
||||
Value expandoSlot = proxy_->getFixedSlot(GetDOMProxyExpandoSlot());
|
||||
RootedShape expandoShape(cx, NULL);
|
||||
ExpandoAndGeneration *expandoAndGeneration;
|
||||
int32_t generation;
|
||||
@ -5979,12 +5981,12 @@ ICGetPropCallDOMProxyNativeCompiler::getStub(ICStubSpace *space)
|
||||
|
||||
if (kind == ICStub::GetProp_CallDOMProxyNative) {
|
||||
return ICGetProp_CallDOMProxyNative::New(
|
||||
space, getStubCode(), firstMonitorStub_, shape, GetProxyHandler(obj_),
|
||||
space, getStubCode(), firstMonitorStub_, shape, proxy_->handler(),
|
||||
expandoShape, holder_, holderShape, getter_, pcOffset_);
|
||||
}
|
||||
|
||||
return ICGetProp_CallDOMProxyWithGenerationNative::New(
|
||||
space, getStubCode(), firstMonitorStub_, shape, GetProxyHandler(obj_),
|
||||
space, getStubCode(), firstMonitorStub_, shape, proxy_->handler(),
|
||||
expandoAndGeneration, generation, expandoShape, holder_, holderShape, getter_,
|
||||
pcOffset_);
|
||||
}
|
||||
@ -5992,9 +5994,9 @@ ICGetPropCallDOMProxyNativeCompiler::getStub(ICStubSpace *space)
|
||||
ICStub *
|
||||
ICGetProp_DOMProxyShadowed::Compiler::getStub(ICStubSpace *space)
|
||||
{
|
||||
RootedShape shape(cx, obj_->lastProperty());
|
||||
return ICGetProp_DOMProxyShadowed::New(space, getStubCode(), firstMonitorStub_,
|
||||
shape, GetProxyHandler(obj_), name_, pcOffset_);
|
||||
RootedShape shape(cx, proxy_->lastProperty());
|
||||
return ICGetProp_DOMProxyShadowed::New(space, getStubCode(), firstMonitorStub_, shape,
|
||||
proxy_->handler(), name_, pcOffset_);
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -8557,21 +8559,20 @@ ICGetPropCallDOMProxyNativeStub::ICGetPropCallDOMProxyNativeStub(Kind kind, IonC
|
||||
ICGetPropCallDOMProxyNativeCompiler::ICGetPropCallDOMProxyNativeCompiler(JSContext *cx,
|
||||
ICStub::Kind kind,
|
||||
ICStub *firstMonitorStub,
|
||||
HandleObject obj,
|
||||
Handle<ProxyObject*> proxy,
|
||||
HandleObject holder,
|
||||
HandleFunction getter,
|
||||
uint32_t pcOffset)
|
||||
: ICStubCompiler(cx, kind),
|
||||
firstMonitorStub_(firstMonitorStub),
|
||||
obj_(cx, obj),
|
||||
proxy_(cx, proxy),
|
||||
holder_(cx, holder),
|
||||
getter_(cx, getter),
|
||||
pcOffset_(pcOffset)
|
||||
{
|
||||
JS_ASSERT(kind == ICStub::GetProp_CallDOMProxyNative ||
|
||||
kind == ICStub::GetProp_CallDOMProxyWithGenerationNative);
|
||||
JS_ASSERT(obj_->is<ProxyObject>());
|
||||
JS_ASSERT(GetProxyHandler(obj_)->family() == GetDOMProxyHandlerFamily());
|
||||
JS_ASSERT(proxy_->handler()->family() == GetDOMProxyHandlerFamily());
|
||||
}
|
||||
|
||||
ICGetProp_DOMProxyShadowed::ICGetProp_DOMProxyShadowed(IonCode *stubCode,
|
||||
|
@ -4379,7 +4379,7 @@ class ICGetProp_CallDOMProxyWithGenerationNative : public ICGetPropCallDOMProxyN
|
||||
|
||||
class ICGetPropCallDOMProxyNativeCompiler : public ICStubCompiler {
|
||||
ICStub *firstMonitorStub_;
|
||||
RootedObject obj_;
|
||||
Rooted<ProxyObject*> proxy_;
|
||||
RootedObject holder_;
|
||||
RootedFunction getter_;
|
||||
uint32_t pcOffset_;
|
||||
@ -4390,7 +4390,7 @@ class ICGetPropCallDOMProxyNativeCompiler : public ICStubCompiler {
|
||||
|
||||
public:
|
||||
ICGetPropCallDOMProxyNativeCompiler(JSContext *cx, ICStub::Kind kind,
|
||||
ICStub *firstMonitorStub, HandleObject obj,
|
||||
ICStub *firstMonitorStub, Handle<ProxyObject*> proxy,
|
||||
HandleObject holder, HandleFunction getter,
|
||||
uint32_t pcOffset);
|
||||
|
||||
@ -4444,18 +4444,18 @@ class ICGetProp_DOMProxyShadowed : public ICMonitoredStub
|
||||
|
||||
class Compiler : public ICStubCompiler {
|
||||
ICStub *firstMonitorStub_;
|
||||
RootedObject obj_;
|
||||
Rooted<ProxyObject*> proxy_;
|
||||
RootedPropertyName name_;
|
||||
uint32_t pcOffset_;
|
||||
|
||||
bool generateStubCode(MacroAssembler &masm);
|
||||
|
||||
public:
|
||||
Compiler(JSContext *cx, ICStub *firstMonitorStub, HandleObject obj, HandlePropertyName name,
|
||||
uint32_t pcOffset)
|
||||
Compiler(JSContext *cx, ICStub *firstMonitorStub, Handle<ProxyObject*> proxy,
|
||||
HandlePropertyName name, uint32_t pcOffset)
|
||||
: ICStubCompiler(cx, ICStub::GetProp_CallNative),
|
||||
firstMonitorStub_(firstMonitorStub),
|
||||
obj_(cx, obj),
|
||||
proxy_(cx, proxy),
|
||||
name_(cx, name),
|
||||
pcOffset_(pcOffset)
|
||||
{}
|
||||
|
@ -427,7 +427,7 @@ IsCacheableDOMProxy(JSObject *obj)
|
||||
if (!obj->is<ProxyObject>())
|
||||
return false;
|
||||
|
||||
BaseProxyHandler *handler = GetProxyHandler(obj);
|
||||
BaseProxyHandler *handler = obj->as<ProxyObject>().handler();
|
||||
|
||||
if (handler->family() != GetDOMProxyHandlerFamily())
|
||||
return false;
|
||||
@ -637,11 +637,12 @@ GenerateDOMProxyChecks(JSContext *cx, MacroAssembler &masm, JSObject *obj,
|
||||
// 1. The object is a DOMProxy.
|
||||
// 2. The object does not have expando properties, or has an expando
|
||||
// which is known to not have the desired property.
|
||||
Address handlerAddr(object, JSObject::getFixedSlotOffset(JSSLOT_PROXY_HANDLER));
|
||||
Address handlerAddr(object, ProxyObject::offsetOfHandler());
|
||||
Address expandoSlotAddr(object, JSObject::getFixedSlotOffset(GetDOMProxyExpandoSlot()));
|
||||
|
||||
// Check that object is a DOMProxy.
|
||||
masm.branchPrivatePtr(Assembler::NotEqual, handlerAddr, ImmWord(GetProxyHandler(obj)), stubFailure);
|
||||
masm.branchPrivatePtr(Assembler::NotEqual, handlerAddr,
|
||||
ImmWord(obj->as<ProxyObject>().handler()), stubFailure);
|
||||
|
||||
if (skipExpandoCheck)
|
||||
return;
|
||||
|
@ -72,15 +72,15 @@ BEGIN_TEST(testBug604087)
|
||||
|
||||
JS::RootedObject c2wrapper(cx, wrap(cx, outerObj, compartment2));
|
||||
CHECK(c2wrapper);
|
||||
js::SetProxyExtra(c2wrapper, 0, js::Int32Value(2));
|
||||
c2wrapper->as<js::ProxyObject>().setExtra(0, js::Int32Value(2));
|
||||
|
||||
JS::RootedObject c3wrapper(cx, wrap(cx, outerObj, compartment3));
|
||||
CHECK(c3wrapper);
|
||||
js::SetProxyExtra(c3wrapper, 0, js::Int32Value(3));
|
||||
c3wrapper->as<js::ProxyObject>().setExtra(0, js::Int32Value(3));
|
||||
|
||||
JS::RootedObject c4wrapper(cx, wrap(cx, outerObj, compartment4));
|
||||
CHECK(c4wrapper);
|
||||
js::SetProxyExtra(c4wrapper, 0, js::Int32Value(4));
|
||||
c4wrapper->as<js::ProxyObject>().setExtra(0, js::Int32Value(4));
|
||||
compartment4 = c4wrapper = NULL;
|
||||
|
||||
JS::RootedObject next(cx);
|
||||
|
@ -456,15 +456,15 @@ JSCompartment::markCrossCompartmentWrappers(JSTracer *trc)
|
||||
for (WrapperMap::Enum e(crossCompartmentWrappers); !e.empty(); e.popFront()) {
|
||||
Value v = e.front().value;
|
||||
if (e.front().key.kind == CrossCompartmentKey::ObjectWrapper) {
|
||||
JSObject *wrapper = &v.toObject();
|
||||
ProxyObject *wrapper = &v.toObject().as<ProxyObject>();
|
||||
|
||||
/*
|
||||
* We have a cross-compartment wrapper. Its private pointer may
|
||||
* point into the compartment being collected, so we should mark it.
|
||||
*/
|
||||
Value referent = GetProxyPrivate(wrapper);
|
||||
Value referent = wrapper->private_();
|
||||
MarkValueRoot(trc, &referent, "cross-compartment wrapper");
|
||||
JS_ASSERT(referent == GetProxyPrivate(wrapper));
|
||||
JS_ASSERT(referent == wrapper->private_());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -578,8 +578,7 @@ JS_IsDeadWrapper(JSObject *obj)
|
||||
return false;
|
||||
}
|
||||
|
||||
BaseProxyHandler *handler = GetProxyHandler(obj);
|
||||
return handler->family() == &DeadObjectProxy::sDeadObjectFamily;
|
||||
return obj->as<ProxyObject>().handler()->family() == &DeadObjectProxy::sDeadObjectFamily;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -65,6 +65,7 @@ using mozilla::Swap;
|
||||
#include "gc/Marking.h"
|
||||
#include "gc/Memory.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/ProxyObject.h"
|
||||
#include "vm/Shape.h"
|
||||
#include "vm/String.h"
|
||||
#include "vm/ForkJoin.h"
|
||||
@ -3365,20 +3366,19 @@ IsGrayListObject(JSObject *obj)
|
||||
return IsCrossCompartmentWrapper(obj) && !IsDeadProxyObject(obj);
|
||||
}
|
||||
|
||||
const unsigned JSSLOT_GC_GRAY_LINK = JSSLOT_PROXY_EXTRA + 1;
|
||||
|
||||
static unsigned
|
||||
GrayLinkSlot(JSObject *obj)
|
||||
/* static */ unsigned
|
||||
ProxyObject::grayLinkSlot(JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(IsGrayListObject(obj));
|
||||
return JSSLOT_GC_GRAY_LINK;
|
||||
return ProxyObject::EXTRA_SLOT + 1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
AssertNotOnGrayList(JSObject *obj)
|
||||
{
|
||||
JS_ASSERT_IF(IsGrayListObject(obj), obj->getReservedSlot(GrayLinkSlot(obj)).isUndefined());
|
||||
JS_ASSERT_IF(IsGrayListObject(obj),
|
||||
obj->getReservedSlot(ProxyObject::grayLinkSlot(obj)).isUndefined());
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -3386,13 +3386,13 @@ static JSObject *
|
||||
CrossCompartmentPointerReferent(JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(IsGrayListObject(obj));
|
||||
return &GetProxyPrivate(obj).toObject();
|
||||
return &obj->as<ProxyObject>().private_().toObject();
|
||||
}
|
||||
|
||||
static JSObject *
|
||||
NextIncomingCrossCompartmentPointer(JSObject *prev, bool unlink)
|
||||
{
|
||||
unsigned slot = GrayLinkSlot(prev);
|
||||
unsigned slot = ProxyObject::grayLinkSlot(prev);
|
||||
JSObject *next = prev->getReservedSlot(slot).toObjectOrNull();
|
||||
JS_ASSERT_IF(next, IsGrayListObject(next));
|
||||
|
||||
@ -3408,7 +3408,7 @@ js::DelayCrossCompartmentGrayMarking(JSObject *src)
|
||||
JS_ASSERT(IsGrayListObject(src));
|
||||
|
||||
/* Called from MarkCrossCompartmentXXX functions. */
|
||||
unsigned slot = GrayLinkSlot(src);
|
||||
unsigned slot = ProxyObject::grayLinkSlot(src);
|
||||
JSObject *dest = CrossCompartmentPointerReferent(src);
|
||||
JSCompartment *comp = dest->compartment();
|
||||
|
||||
@ -3486,7 +3486,7 @@ RemoveFromGrayList(JSObject *wrapper)
|
||||
if (!IsGrayListObject(wrapper))
|
||||
return false;
|
||||
|
||||
unsigned slot = GrayLinkSlot(wrapper);
|
||||
unsigned slot = ProxyObject::grayLinkSlot(wrapper);
|
||||
if (wrapper->getReservedSlot(slot).isUndefined())
|
||||
return false; /* Not on our list. */
|
||||
|
||||
@ -3501,7 +3501,7 @@ RemoveFromGrayList(JSObject *wrapper)
|
||||
}
|
||||
|
||||
while (obj) {
|
||||
unsigned slot = GrayLinkSlot(obj);
|
||||
unsigned slot = ProxyObject::grayLinkSlot(obj);
|
||||
JSObject *next = obj->getReservedSlot(slot).toObjectOrNull();
|
||||
if (next == wrapper) {
|
||||
obj->setCrossCompartmentSlot(slot, ObjectOrNullValue(tail));
|
||||
|
@ -26,29 +26,6 @@ using namespace js;
|
||||
using namespace js::gc;
|
||||
using mozilla::ArrayLength;
|
||||
|
||||
static inline HeapSlot &
|
||||
GetCall(JSObject *proxy)
|
||||
{
|
||||
JS_ASSERT(proxy->is<FunctionProxyObject>());
|
||||
return proxy->getSlotRef(JSSLOT_PROXY_CALL);
|
||||
}
|
||||
|
||||
static inline Value
|
||||
GetConstruct(JSObject *proxy)
|
||||
{
|
||||
if (proxy->slotSpan() <= JSSLOT_PROXY_CONSTRUCT)
|
||||
return UndefinedValue();
|
||||
return proxy->getSlot(JSSLOT_PROXY_CONSTRUCT);
|
||||
}
|
||||
|
||||
static inline HeapSlot &
|
||||
GetFunctionProxyConstruct(JSObject *proxy)
|
||||
{
|
||||
JS_ASSERT(proxy->is<FunctionProxyObject>());
|
||||
JS_ASSERT(proxy->slotSpan() > JSSLOT_PROXY_CONSTRUCT);
|
||||
return proxy->getSlotRef(JSSLOT_PROXY_CONSTRUCT);
|
||||
}
|
||||
|
||||
void
|
||||
js::AutoEnterPolicy::reportError(JSContext *cx, jsid id)
|
||||
{
|
||||
@ -211,7 +188,7 @@ BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
} else if ((desc.attrs & JSPROP_SETTER) || desc.setter != JS_StrictPropertyStub) {
|
||||
if (!CallSetter(cx, receiver, id, desc.setter, desc.attrs, desc.shortid, strict, vp))
|
||||
return false;
|
||||
if (!proxy->is<ProxyObject>() || GetProxyHandler(proxy) != this)
|
||||
if (!proxy->is<ProxyObject>() || proxy->as<ProxyObject>().handler() != this)
|
||||
return true;
|
||||
if (desc.attrs & JSPROP_SHARED)
|
||||
return true;
|
||||
@ -238,7 +215,7 @@ BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
} else if ((desc.attrs & JSPROP_SETTER) || desc.setter != JS_StrictPropertyStub) {
|
||||
if (!CallSetter(cx, receiver, id, desc.setter, desc.attrs, desc.shortid, strict, vp))
|
||||
return false;
|
||||
if (!proxy->is<ProxyObject>() || GetProxyHandler(proxy) != this)
|
||||
if (!proxy->is<ProxyObject>() || proxy->as<ProxyObject>().handler() != this)
|
||||
return true;
|
||||
if (desc.attrs & JSPROP_SHARED)
|
||||
return true;
|
||||
@ -392,7 +369,7 @@ DirectProxyHandler::getPropertyDescriptor(JSContext *cx, HandleObject proxy, Han
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id);
|
||||
JS_ASSERT(!hasPrototype()); // Should never be called if there's a prototype.
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return JS_GetPropertyDescriptorById(cx, target, id, 0, desc);
|
||||
}
|
||||
|
||||
@ -417,7 +394,7 @@ DirectProxyHandler::getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy,
|
||||
HandleId id, PropertyDescriptor *desc, unsigned flags)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id);
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetOwnPropertyDescriptor(cx, target, id, 0, desc);
|
||||
}
|
||||
|
||||
@ -426,7 +403,7 @@ DirectProxyHandler::defineProperty(JSContext *cx, HandleObject proxy, HandleId i
|
||||
PropertyDescriptor *desc)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id);
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
RootedValue v(cx, desc->value);
|
||||
return CheckDefineProperty(cx, target, id, v, desc->getter, desc->setter, desc->attrs) &&
|
||||
JS_DefinePropertyById(cx, target, id, v, desc->getter, desc->setter, desc->attrs);
|
||||
@ -437,7 +414,7 @@ DirectProxyHandler::getOwnPropertyNames(JSContext *cx, HandleObject proxy,
|
||||
AutoIdVector &props)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetPropertyNames(cx, target, JSITER_OWNONLY | JSITER_HIDDEN, &props);
|
||||
}
|
||||
|
||||
@ -445,7 +422,7 @@ bool
|
||||
DirectProxyHandler::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id);
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
RootedValue v(cx);
|
||||
if (!JS_DeletePropertyById2(cx, target, id, v.address()))
|
||||
return false;
|
||||
@ -462,7 +439,7 @@ DirectProxyHandler::enumerate(JSContext *cx, HandleObject proxy,
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
JS_ASSERT(!hasPrototype()); // Should never be called if there's a prototype.
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetPropertyNames(cx, target, 0, &props);
|
||||
}
|
||||
|
||||
@ -470,7 +447,7 @@ bool
|
||||
DirectProxyHandler::call(JSContext *cx, HandleObject proxy, const CallArgs &args)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
RootedValue target(cx, GetProxyPrivate(proxy));
|
||||
RootedValue target(cx, proxy->as<ProxyObject>().private_());
|
||||
return Invoke(cx, args.thisv(), target, args.length(), args.array(), args.rval());
|
||||
}
|
||||
|
||||
@ -478,7 +455,7 @@ bool
|
||||
DirectProxyHandler::construct(JSContext *cx, HandleObject proxy, const CallArgs &args)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
RootedValue target(cx, GetProxyPrivate(proxy));
|
||||
RootedValue target(cx, proxy->as<ProxyObject>().private_());
|
||||
return InvokeConstructor(cx, target, args.length(), args.array(), args.rval().address());
|
||||
}
|
||||
|
||||
@ -486,7 +463,7 @@ bool
|
||||
DirectProxyHandler::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
|
||||
CallArgs args)
|
||||
{
|
||||
args.setThis(ObjectValue(*GetProxyTargetObject(&args.thisv().toObject())));
|
||||
args.setThis(ObjectValue(*args.thisv().toObject().as<ProxyObject>().target()));
|
||||
if (!test(args.thisv())) {
|
||||
ReportIncompatible(cx, args);
|
||||
return false;
|
||||
@ -501,7 +478,7 @@ DirectProxyHandler::hasInstance(JSContext *cx, HandleObject proxy, MutableHandle
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
JSBool b;
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
if (!JS_HasInstance(cx, target, v, &b))
|
||||
return false;
|
||||
*bp = !!b;
|
||||
@ -513,15 +490,15 @@ bool
|
||||
DirectProxyHandler::objectClassIs(HandleObject proxy, ESClassValue classValue,
|
||||
JSContext *cx)
|
||||
{
|
||||
RootedObject obj(cx, GetProxyTargetObject(proxy));
|
||||
return ObjectClassIs(obj, classValue, cx);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return ObjectClassIs(target, classValue, cx);
|
||||
}
|
||||
|
||||
const char *
|
||||
DirectProxyHandler::className(JSContext *cx, HandleObject proxy)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return JSObject::className(cx, target);
|
||||
}
|
||||
|
||||
@ -530,7 +507,7 @@ DirectProxyHandler::fun_toString(JSContext *cx, HandleObject proxy,
|
||||
unsigned indent)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return fun_toStringHelper(cx, target, indent);
|
||||
}
|
||||
|
||||
@ -538,7 +515,7 @@ bool
|
||||
DirectProxyHandler::regexp_toShared(JSContext *cx, HandleObject proxy,
|
||||
RegExpGuard *g)
|
||||
{
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return RegExpToShared(cx, target, g);
|
||||
}
|
||||
|
||||
@ -546,7 +523,7 @@ bool
|
||||
DirectProxyHandler::defaultValue(JSContext *cx, HandleObject proxy, JSType hint,
|
||||
MutableHandleValue vp)
|
||||
{
|
||||
vp.set(ObjectValue(*GetProxyTargetObject(proxy)));
|
||||
vp.set(ObjectValue(*proxy->as<ProxyObject>().target()));
|
||||
if (hint == JSTYPE_VOID)
|
||||
return ToPrimitive(cx, vp);
|
||||
return ToPrimitive(cx, hint, vp);
|
||||
@ -569,7 +546,7 @@ DirectProxyHandler::has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp
|
||||
assertEnteredPolicy(cx, proxy, id);
|
||||
JS_ASSERT(!hasPrototype()); // Should never be called if there's a prototype.
|
||||
JSBool found;
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
if (!JS_HasPropertyById(cx, target, id, &found))
|
||||
return false;
|
||||
*bp = !!found;
|
||||
@ -580,7 +557,7 @@ bool
|
||||
DirectProxyHandler::hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id);
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
AutoPropertyDescriptorRooter desc(cx);
|
||||
if (!JS_GetPropertyDescriptorById(cx, target, id, 0, &desc))
|
||||
return false;
|
||||
@ -593,7 +570,7 @@ DirectProxyHandler::get(JSContext *cx, HandleObject proxy, HandleObject receiver
|
||||
HandleId id, MutableHandleValue vp)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id);
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return JSObject::getGeneric(cx, target, receiver, id, vp);
|
||||
}
|
||||
|
||||
@ -602,7 +579,7 @@ DirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver
|
||||
HandleId id, bool strict, MutableHandleValue vp)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id);
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return JSObject::setGeneric(cx, target, receiver, id, vp, strict);
|
||||
}
|
||||
|
||||
@ -610,7 +587,7 @@ bool
|
||||
DirectProxyHandler::keys(JSContext *cx, HandleObject proxy, AutoIdVector &props)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetPropertyNames(cx, target, JSITER_OWNONLY, &props);
|
||||
}
|
||||
|
||||
@ -620,21 +597,21 @@ DirectProxyHandler::iterate(JSContext *cx, HandleObject proxy, unsigned flags,
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
JS_ASSERT(!hasPrototype()); // Should never be called if there's a prototype.
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetIterator(cx, target, flags, vp);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible)
|
||||
{
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return JSObject::isExtensible(cx, target, extensible);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy)
|
||||
{
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return JSObject::preventExtensions(cx, target);
|
||||
}
|
||||
|
||||
@ -757,6 +734,21 @@ ArrayToIdVector(JSContext *cx, const Value &array, AutoIdVector &props)
|
||||
return true;
|
||||
}
|
||||
|
||||
inline HeapSlot &
|
||||
FunctionProxyObject::construct()
|
||||
{
|
||||
JS_ASSERT(slotSpan() > CONSTRUCT_SLOT);
|
||||
return getSlotRef(CONSTRUCT_SLOT);
|
||||
}
|
||||
|
||||
inline Value
|
||||
FunctionProxyObject::constructOrUndefined() const
|
||||
{
|
||||
if (slotSpan() <= CONSTRUCT_SLOT)
|
||||
return UndefinedValue();
|
||||
return getSlot(CONSTRUCT_SLOT);
|
||||
}
|
||||
|
||||
/* Derived class for all scripted indirect proxy handlers. */
|
||||
class ScriptedIndirectProxyHandler : public BaseProxyHandler
|
||||
{
|
||||
@ -845,7 +837,7 @@ ReturnedValueMustNotBePrimitive(JSContext *cx, HandleObject proxy, JSAtom *atom,
|
||||
static JSObject *
|
||||
GetIndirectProxyHandlerObject(JSObject *proxy)
|
||||
{
|
||||
return GetProxyPrivate(proxy).toObjectOrNull();
|
||||
return proxy->as<ProxyObject>().private_().toObjectOrNull();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1013,7 +1005,7 @@ bool
|
||||
ScriptedIndirectProxyHandler::call(JSContext *cx, HandleObject proxy, const CallArgs &args)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
RootedValue call(cx, GetCall(proxy));
|
||||
RootedValue call(cx, proxy->as<FunctionProxyObject>().call());
|
||||
return Invoke(cx, args.thisv(), call, args.length(), args.array(), args.rval());
|
||||
}
|
||||
|
||||
@ -1021,9 +1013,9 @@ bool
|
||||
ScriptedIndirectProxyHandler::construct(JSContext *cx, HandleObject proxy, const CallArgs &args)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
RootedValue fval(cx, GetConstruct(proxy));
|
||||
RootedValue fval(cx, proxy->as<FunctionProxyObject>().constructOrUndefined());
|
||||
if (fval.isUndefined())
|
||||
fval = GetCall(proxy);
|
||||
fval = proxy->as<FunctionProxyObject>().call();
|
||||
return InvokeConstructor(cx, fval, args.length(), args.array(), args.rval().address());
|
||||
}
|
||||
|
||||
@ -1038,9 +1030,8 @@ JSString *
|
||||
ScriptedIndirectProxyHandler::fun_toString(JSContext *cx, HandleObject proxy, unsigned indent)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
Value fval = GetCall(proxy);
|
||||
if (proxy->is<FunctionProxyObject>() &&
|
||||
(fval.isPrimitive() || !fval.toObject().is<JSFunction>())) {
|
||||
Value fval = proxy->as<FunctionProxyObject>().call();
|
||||
if (fval.isPrimitive() || !fval.toObject().is<JSFunction>()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_INCOMPATIBLE_PROTO,
|
||||
js_Function_str, js_toString_str,
|
||||
@ -1067,7 +1058,7 @@ ScriptedIndirectProxyHandler ScriptedIndirectProxyHandler::singleton;
|
||||
static JSObject *
|
||||
GetDirectProxyHandlerObject(JSObject *proxy)
|
||||
{
|
||||
return GetProxyExtra(proxy, 0).toObjectOrNull();
|
||||
return proxy->as<ProxyObject>().extra(0).toObjectOrNull();
|
||||
}
|
||||
|
||||
/* Derived class for all scripted direct proxy handlers. */
|
||||
@ -1355,7 +1346,7 @@ TrapGetOwnProperty(JSContext *cx, HandleObject proxy, HandleId id, MutableHandle
|
||||
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
|
||||
|
||||
// step 2
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
|
||||
// step 3
|
||||
RootedValue trap(cx);
|
||||
@ -1463,7 +1454,7 @@ TrapDefineOwnProperty(JSContext *cx, HandleObject proxy, HandleId id, MutableHan
|
||||
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
|
||||
|
||||
// step 2
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
|
||||
// step 3
|
||||
RootedValue trap(cx);
|
||||
@ -1668,7 +1659,7 @@ ScriptedDirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy)
|
||||
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
|
||||
|
||||
// step b
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
|
||||
// step c
|
||||
RootedValue trap(cx);
|
||||
@ -1770,7 +1761,7 @@ ScriptedDirectProxyHandler::getOwnPropertyNames(JSContext *cx, HandleObject prox
|
||||
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
|
||||
|
||||
// step b
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
|
||||
// step c
|
||||
RootedValue trap(cx);
|
||||
@ -1808,7 +1799,7 @@ ScriptedDirectProxyHandler::delete_(JSContext *cx, HandleObject proxy, HandleId
|
||||
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
|
||||
|
||||
// step 2
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
|
||||
// step 3
|
||||
RootedValue trap(cx);
|
||||
@ -1860,7 +1851,7 @@ ScriptedDirectProxyHandler::enumerate(JSContext *cx, HandleObject proxy, AutoIdV
|
||||
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
|
||||
|
||||
// step b
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
|
||||
// step c
|
||||
RootedValue trap(cx);
|
||||
@ -1903,7 +1894,7 @@ ScriptedDirectProxyHandler::has(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
|
||||
|
||||
// step 2
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
|
||||
// step 3
|
||||
RootedValue trap(cx);
|
||||
@ -1966,7 +1957,7 @@ ScriptedDirectProxyHandler::hasOwn(JSContext *cx, HandleObject proxy, HandleId i
|
||||
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
|
||||
|
||||
// step 2
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
|
||||
// step 3
|
||||
RootedValue trap(cx);
|
||||
@ -2043,7 +2034,7 @@ ScriptedDirectProxyHandler::get(JSContext *cx, HandleObject proxy, HandleObject
|
||||
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
|
||||
|
||||
// step 2
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
|
||||
// step 3
|
||||
RootedValue trap(cx);
|
||||
@ -2112,7 +2103,7 @@ ScriptedDirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject
|
||||
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
|
||||
|
||||
// step 2
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
|
||||
// step 3
|
||||
RootedValue trap(cx);
|
||||
@ -2180,7 +2171,7 @@ ScriptedDirectProxyHandler::keys(JSContext *cx, HandleObject proxy, AutoIdVector
|
||||
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
|
||||
|
||||
// step b
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
|
||||
// step c
|
||||
RootedValue trap(cx);
|
||||
@ -2229,7 +2220,7 @@ ScriptedDirectProxyHandler::call(JSContext *cx, HandleObject proxy, const CallAr
|
||||
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
|
||||
|
||||
// step 2
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
|
||||
/*
|
||||
* NB: Remember to throw a TypeError here if we change NewProxyObject so that this trap can get
|
||||
@ -2267,7 +2258,7 @@ ScriptedDirectProxyHandler::construct(JSContext *cx, HandleObject proxy, const C
|
||||
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
|
||||
|
||||
// step 2
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
|
||||
/*
|
||||
* NB: Remember to throw a TypeError here if we change NewProxyObject so that this trap can get
|
||||
@ -2315,7 +2306,7 @@ Proxy::getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
PropertyDescriptor *desc, unsigned flags)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||
BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
|
||||
desc->obj = NULL; // default result if we refuse to perform this action
|
||||
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET, true);
|
||||
if (!policy.allowed())
|
||||
@ -2348,7 +2339,7 @@ Proxy::getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
|
||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||
BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
|
||||
desc->obj = NULL; // default result if we refuse to perform this action
|
||||
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET, true);
|
||||
if (!policy.allowed())
|
||||
@ -2372,11 +2363,11 @@ bool
|
||||
Proxy::defineProperty(JSContext *cx, HandleObject proxy, HandleId id, PropertyDescriptor *desc)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||
BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
|
||||
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::SET, true);
|
||||
if (!policy.allowed())
|
||||
return policy.returnValue();
|
||||
return GetProxyHandler(proxy)->defineProperty(cx, proxy, id, desc);
|
||||
return proxy->as<ProxyObject>().handler()->defineProperty(cx, proxy, id, desc);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -2392,23 +2383,23 @@ bool
|
||||
Proxy::getOwnPropertyNames(JSContext *cx, HandleObject proxy, AutoIdVector &props)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||
BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
|
||||
AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE, BaseProxyHandler::GET, true);
|
||||
if (!policy.allowed())
|
||||
return policy.returnValue();
|
||||
return GetProxyHandler(proxy)->getOwnPropertyNames(cx, proxy, props);
|
||||
return proxy->as<ProxyObject>().handler()->getOwnPropertyNames(cx, proxy, props);
|
||||
}
|
||||
|
||||
bool
|
||||
Proxy::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||
BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
|
||||
*bp = true; // default result if we refuse to perform this action
|
||||
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::SET, true);
|
||||
if (!policy.allowed())
|
||||
return policy.returnValue();
|
||||
return GetProxyHandler(proxy)->delete_(cx, proxy, id, bp);
|
||||
return proxy->as<ProxyObject>().handler()->delete_(cx, proxy, id, bp);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
@ -2435,12 +2426,12 @@ bool
|
||||
Proxy::enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||
BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
|
||||
AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE, BaseProxyHandler::GET, true);
|
||||
if (!policy.allowed())
|
||||
return policy.returnValue();
|
||||
if (!handler->hasPrototype())
|
||||
return GetProxyHandler(proxy)->enumerate(cx, proxy, props);
|
||||
return proxy->as<ProxyObject>().handler()->enumerate(cx, proxy, props);
|
||||
if (!handler->keys(cx, proxy, props))
|
||||
return false;
|
||||
AutoIdVector protoProps(cx);
|
||||
@ -2453,7 +2444,7 @@ bool
|
||||
Proxy::has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||
BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
|
||||
*bp = false; // default result if we refuse to perform this action
|
||||
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET, true);
|
||||
if (!policy.allowed())
|
||||
@ -2474,7 +2465,7 @@ bool
|
||||
Proxy::hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||
BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
|
||||
*bp = false; // default result if we refuse to perform this action
|
||||
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET, true);
|
||||
if (!policy.allowed())
|
||||
@ -2487,7 +2478,7 @@ Proxy::get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id
|
||||
MutableHandleValue vp)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||
BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
|
||||
vp.setUndefined(); // default result if we refuse to perform this action
|
||||
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET, true);
|
||||
if (!policy.allowed())
|
||||
@ -2514,7 +2505,7 @@ Proxy::getElementIfPresent(JSContext *cx, HandleObject proxy, HandleObject recei
|
||||
if (!IndexToId(cx, index, &id))
|
||||
return false;
|
||||
|
||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||
BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
|
||||
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET, true);
|
||||
if (!policy.allowed())
|
||||
return policy.returnValue();
|
||||
@ -2530,7 +2521,7 @@ Proxy::getElementIfPresent(JSContext *cx, HandleObject proxy, HandleObject recei
|
||||
|
||||
if (hasOwn) {
|
||||
*present = true;
|
||||
return GetProxyHandler(proxy)->get(cx, proxy, receiver, id, vp);
|
||||
return proxy->as<ProxyObject>().handler()->get(cx, proxy, receiver, id, vp);
|
||||
}
|
||||
|
||||
*present = false;
|
||||
@ -2543,7 +2534,7 @@ Proxy::set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id
|
||||
MutableHandleValue vp)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||
BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
|
||||
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::SET, true);
|
||||
if (!policy.allowed())
|
||||
return policy.returnValue();
|
||||
@ -2573,7 +2564,7 @@ bool
|
||||
Proxy::keys(JSContext *cx, HandleObject proxy, AutoIdVector &props)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||
BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
|
||||
AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE, BaseProxyHandler::GET, true);
|
||||
if (!policy.allowed())
|
||||
return policy.returnValue();
|
||||
@ -2584,7 +2575,7 @@ bool
|
||||
Proxy::iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||
BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
|
||||
vp.setUndefined(); // default result if we refuse to perform this action
|
||||
if (!handler->hasPrototype()) {
|
||||
AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE,
|
||||
@ -2612,14 +2603,14 @@ bool
|
||||
Proxy::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
return GetProxyHandler(proxy)->isExtensible(cx, proxy, extensible);
|
||||
return proxy->as<ProxyObject>().handler()->isExtensible(cx, proxy, extensible);
|
||||
}
|
||||
|
||||
bool
|
||||
Proxy::preventExtensions(JSContext *cx, HandleObject proxy)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||
BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
|
||||
return handler->preventExtensions(cx, proxy);
|
||||
}
|
||||
|
||||
@ -2627,7 +2618,7 @@ bool
|
||||
Proxy::call(JSContext *cx, HandleObject proxy, const CallArgs &args)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||
BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
|
||||
|
||||
// Because vp[0] is JS_CALLEE on the way in and JS_RVAL on the way out, we
|
||||
// can only set our default value once we're sure that we're not calling the
|
||||
@ -2646,7 +2637,7 @@ bool
|
||||
Proxy::construct(JSContext *cx, HandleObject proxy, const CallArgs &args)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||
BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
|
||||
|
||||
// Because vp[0] is JS_CALLEE on the way in and JS_RVAL on the way out, we
|
||||
// can only set our default value once we're sure that we're not calling the
|
||||
@ -2669,33 +2660,33 @@ Proxy::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArg
|
||||
// Note - we don't enter a policy here because our security architecture
|
||||
// guards against nativeCall by overriding the trap itself in the right
|
||||
// circumstances.
|
||||
return GetProxyHandler(proxy)->nativeCall(cx, test, impl, args);
|
||||
return proxy->as<ProxyObject>().handler()->nativeCall(cx, test, impl, args);
|
||||
}
|
||||
|
||||
bool
|
||||
Proxy::hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||
BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
|
||||
*bp = false; // default result if we refuse to perform this action
|
||||
AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE, BaseProxyHandler::GET, true);
|
||||
if (!policy.allowed())
|
||||
return policy.returnValue();
|
||||
return GetProxyHandler(proxy)->hasInstance(cx, proxy, v, bp);
|
||||
return proxy->as<ProxyObject>().handler()->hasInstance(cx, proxy, v, bp);
|
||||
}
|
||||
|
||||
bool
|
||||
Proxy::objectClassIs(HandleObject proxy, ESClassValue classValue, JSContext *cx)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
return GetProxyHandler(proxy)->objectClassIs(proxy, classValue, cx);
|
||||
return proxy->as<ProxyObject>().handler()->objectClassIs(proxy, classValue, cx);
|
||||
}
|
||||
|
||||
const char *
|
||||
Proxy::className(JSContext *cx, HandleObject proxy)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return NULL);
|
||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||
BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
|
||||
AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE,
|
||||
BaseProxyHandler::GET, /* mayThrow = */ false);
|
||||
// Do the safe thing if the policy rejects.
|
||||
@ -2709,7 +2700,7 @@ JSString *
|
||||
Proxy::fun_toString(JSContext *cx, HandleObject proxy, unsigned indent)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return NULL);
|
||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||
BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
|
||||
AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE,
|
||||
BaseProxyHandler::GET, /* mayThrow = */ false);
|
||||
// Do the safe thing if the policy rejects.
|
||||
@ -2726,21 +2717,21 @@ bool
|
||||
Proxy::regexp_toShared(JSContext *cx, HandleObject proxy, RegExpGuard *g)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
return GetProxyHandler(proxy)->regexp_toShared(cx, proxy, g);
|
||||
return proxy->as<ProxyObject>().handler()->regexp_toShared(cx, proxy, g);
|
||||
}
|
||||
|
||||
bool
|
||||
Proxy::defaultValue(JSContext *cx, HandleObject proxy, JSType hint, MutableHandleValue vp)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
return GetProxyHandler(proxy)->defaultValue(cx, proxy, hint, vp);
|
||||
return proxy->as<ProxyObject>().handler()->defaultValue(cx, proxy, hint, vp);
|
||||
}
|
||||
|
||||
bool
|
||||
Proxy::getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject proto)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
return GetProxyHandler(proxy)->getPrototypeOf(cx, proxy, proto);
|
||||
return proxy->as<ProxyObject>().handler()->getPrototypeOf(cx, proxy, proto);
|
||||
}
|
||||
|
||||
JSObject * const Proxy::LazyProto = reinterpret_cast<JSObject *>(0x1);
|
||||
@ -2748,7 +2739,7 @@ JSObject * const Proxy::LazyProto = reinterpret_cast<JSObject *>(0x1);
|
||||
static JSObject *
|
||||
proxy_innerObject(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
return GetProxyPrivate(obj).toObjectOrNull();
|
||||
return obj->as<ProxyObject>().private_().toObjectOrNull();
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@ -3008,52 +2999,55 @@ proxy_DeleteSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, JSBool
|
||||
return proxy_DeleteGeneric(cx, obj, id, succeeded);
|
||||
}
|
||||
|
||||
static void
|
||||
proxy_TraceObject(JSTracer *trc, JSObject *obj)
|
||||
/* static */ void
|
||||
ProxyObject::trace(JSTracer *trc, JSObject *obj)
|
||||
{
|
||||
ProxyObject *proxy = &obj->as<ProxyObject>();
|
||||
|
||||
#ifdef DEBUG
|
||||
if (!trc->runtime->gcDisableStrictProxyCheckingCount && obj->isWrapper()) {
|
||||
JSObject *referent = &GetProxyPrivate(obj).toObject();
|
||||
if (referent->compartment() != obj->compartment()) {
|
||||
if (!trc->runtime->gcDisableStrictProxyCheckingCount && proxy->isWrapper()) {
|
||||
JSObject *referent = &proxy->private_().toObject();
|
||||
if (referent->compartment() != proxy->compartment()) {
|
||||
/*
|
||||
* Assert that this proxy is tracked in the wrapper map. We maintain
|
||||
* the invariant that the wrapped object is the key in the wrapper map.
|
||||
*/
|
||||
Value key = ObjectValue(*referent);
|
||||
WrapperMap::Ptr p = obj->compartment()->lookupWrapper(key);
|
||||
JS_ASSERT(*p->value.unsafeGet() == ObjectValue(*obj));
|
||||
WrapperMap::Ptr p = proxy->compartment()->lookupWrapper(key);
|
||||
JS_ASSERT(*p->value.unsafeGet() == ObjectValue(*proxy));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// NB: If you add new slots here, make sure to change
|
||||
// js::NukeChromeCrossCompartmentWrappers to cope.
|
||||
MarkCrossCompartmentSlot(trc, obj, &obj->getReservedSlotRef(JSSLOT_PROXY_PRIVATE), "private");
|
||||
MarkSlot(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_EXTRA + 0), "extra0");
|
||||
// Note: If you add new slots here, make sure to change
|
||||
// nuke() to cope.
|
||||
MarkCrossCompartmentSlot(trc, obj, proxy->slotOfPrivate(), "private");
|
||||
MarkSlot(trc, proxy->slotOfExtra(0), "extra0");
|
||||
|
||||
/*
|
||||
* The GC can use the second reserved slot to link the cross compartment
|
||||
* wrappers into a linked list, in which case we don't want to trace it.
|
||||
*/
|
||||
if (!IsCrossCompartmentWrapper(obj))
|
||||
MarkSlot(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_EXTRA + 1), "extra1");
|
||||
if (!IsCrossCompartmentWrapper(proxy))
|
||||
MarkSlot(trc, proxy->slotOfExtra(1), "extra1");
|
||||
}
|
||||
|
||||
static void
|
||||
proxy_TraceFunction(JSTracer *trc, JSObject *obj)
|
||||
{
|
||||
// NB: If you add new slots here, make sure to change
|
||||
// js::NukeChromeCrossCompartmentWrappers to cope.
|
||||
MarkCrossCompartmentSlot(trc, obj, &GetCall(obj), "call");
|
||||
MarkSlot(trc, &GetFunctionProxyConstruct(obj), "construct");
|
||||
proxy_TraceObject(trc, obj);
|
||||
// nuke() to cope.
|
||||
FunctionProxyObject *proxy = &obj->as<FunctionProxyObject>();
|
||||
MarkCrossCompartmentSlot(trc, proxy, &proxy->call(), "call");
|
||||
MarkSlot(trc, &proxy->construct(), "construct");
|
||||
ProxyObject::trace(trc, proxy);
|
||||
}
|
||||
|
||||
static JSObject *
|
||||
proxy_WeakmapKeyDelegate(JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(obj->is<ProxyObject>());
|
||||
return GetProxyHandler(obj)->weakmapKeyDelegate(obj);
|
||||
return obj->as<ProxyObject>().handler()->weakmapKeyDelegate(obj);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@ -3067,7 +3061,7 @@ static void
|
||||
proxy_Finalize(FreeOp *fop, JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(obj->is<ProxyObject>());
|
||||
GetProxyHandler(obj)->finalize(fop, obj);
|
||||
obj->as<ProxyObject>().handler()->finalize(fop, obj);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@ -3105,7 +3099,7 @@ Class js::ObjectProxyObject::class_ = {
|
||||
NULL, /* call */
|
||||
proxy_HasInstance, /* hasInstance */
|
||||
NULL, /* construct */
|
||||
proxy_TraceObject, /* trace */
|
||||
ProxyObject::trace, /* trace */
|
||||
PROXY_CLASS_EXT,
|
||||
{
|
||||
proxy_LookupGeneric,
|
||||
@ -3158,7 +3152,7 @@ Class js::OuterWindowProxyObject::class_ = {
|
||||
NULL, /* call */
|
||||
NULL, /* hasInstance */
|
||||
NULL, /* construct */
|
||||
proxy_TraceObject, /* trace */
|
||||
ProxyObject::trace, /* trace */
|
||||
{
|
||||
NULL, /* outerObject */
|
||||
proxy_innerObject,
|
||||
@ -3273,9 +3267,9 @@ Class js::FunctionProxyObject::class_ = {
|
||||
|
||||
JS_FRIEND_DATA(Class*) js::FunctionProxyClassPtr = &FunctionProxyObject::class_;
|
||||
|
||||
static JSObject *
|
||||
NewProxyObject(JSContext *cx, BaseProxyHandler *handler, HandleValue priv, TaggedProto proto_,
|
||||
JSObject *parent_, ProxyCallable callable)
|
||||
/* static */ ProxyObject *
|
||||
ProxyObject::New(JSContext *cx, BaseProxyHandler *handler, HandleValue priv, TaggedProto proto_,
|
||||
JSObject *parent_, ProxyCallable callable)
|
||||
{
|
||||
Rooted<TaggedProto> proto(cx, proto_);
|
||||
RootedObject parent(cx, parent_);
|
||||
@ -3308,65 +3302,77 @@ NewProxyObject(JSContext *cx, BaseProxyHandler *handler, HandleValue priv, Tagge
|
||||
RootedObject obj(cx, NewObjectWithGivenProto(cx, clasp, proto, parent, allocKind, newKind));
|
||||
if (!obj)
|
||||
return NULL;
|
||||
obj->initSlot(JSSLOT_PROXY_HANDLER, PrivateValue(handler));
|
||||
obj->initCrossCompartmentSlot(JSSLOT_PROXY_PRIVATE, priv);
|
||||
|
||||
Rooted<ProxyObject*> proxy(cx, &obj->as<ProxyObject>());
|
||||
proxy->initHandler(handler);
|
||||
proxy->initCrossCompartmentPrivate(priv);
|
||||
|
||||
/* Don't track types of properties of proxies. */
|
||||
if (newKind != SingletonObject)
|
||||
MarkTypeObjectUnknownProperties(cx, obj->type());
|
||||
MarkTypeObjectUnknownProperties(cx, proxy->type());
|
||||
|
||||
return obj;
|
||||
return proxy;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSObject *)
|
||||
js::NewProxyObject(JSContext *cx, BaseProxyHandler *handler, HandleValue priv, JSObject *proto_,
|
||||
JSObject *parent_, ProxyCallable callable)
|
||||
{
|
||||
return NewProxyObject(cx, handler, priv, TaggedProto(proto_), parent_, callable);
|
||||
return ProxyObject::New(cx, handler, priv, TaggedProto(proto_), parent_, callable);
|
||||
}
|
||||
|
||||
static JSObject *
|
||||
NewProxyObject(JSContext *cx, BaseProxyHandler *handler, HandleValue priv, JSObject *proto_,
|
||||
JSObject *parent_, JSObject *call_, JSObject *construct_)
|
||||
static ProxyObject *
|
||||
NewProxyObject(JSContext *cx, BaseProxyHandler *handler, HandleValue priv, JSObject *proto,
|
||||
JSObject *parent, JSObject *call, JSObject *construct)
|
||||
{
|
||||
RootedObject call(cx, call_);
|
||||
RootedObject construct(cx, construct_);
|
||||
if (!call && !construct)
|
||||
return ProxyObject::New(cx, handler, priv, TaggedProto(proto), parent, ProxyNotCallable);
|
||||
|
||||
return FunctionProxyObject::New(cx, handler, priv, proto, parent, call, construct);
|
||||
}
|
||||
|
||||
/* static */ FunctionProxyObject *
|
||||
FunctionProxyObject::New(JSContext *cx, BaseProxyHandler *handler, HandleValue priv,
|
||||
JSObject *proto, JSObject *parent, JSObject *callArg,
|
||||
JSObject *constructArg)
|
||||
{
|
||||
RootedObject call(cx, callArg);
|
||||
RootedObject construct(cx, constructArg);
|
||||
|
||||
JS_ASSERT(call || construct);
|
||||
JS_ASSERT_IF(construct, cx->compartment() == construct->compartment());
|
||||
JS_ASSERT_IF(call && cx->compartment() != call->compartment(), priv == ObjectValue(*call));
|
||||
|
||||
JSObject *proxy = NewProxyObject(cx, handler, priv, TaggedProto(proto_), parent_,
|
||||
call || construct ? ProxyIsCallable : ProxyNotCallable);
|
||||
if (!proxy)
|
||||
ProxyObject *obj = ProxyObject::New(cx, handler, priv, TaggedProto(proto), parent,
|
||||
ProxyIsCallable);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
FunctionProxyObject *proxy = &obj->as<FunctionProxyObject>();
|
||||
if (call)
|
||||
proxy->initCrossCompartmentSlot(JSSLOT_PROXY_CALL, ObjectValue(*call));
|
||||
proxy->initCrossCompartmentSlot(CALL_SLOT, ObjectValue(*call));
|
||||
if (construct)
|
||||
proxy->initCrossCompartmentSlot(JSSLOT_PROXY_CONSTRUCT, ObjectValue(*construct));
|
||||
proxy->initCrossCompartmentSlot(CONSTRUCT_SLOT, ObjectValue(*construct));
|
||||
|
||||
return proxy;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js::RenewProxyObject(JSContext *cx, JSObject *obj,
|
||||
BaseProxyHandler *handler, Value priv)
|
||||
void
|
||||
ProxyObject::renew(JSContext *cx, BaseProxyHandler *handler, Value priv)
|
||||
{
|
||||
JS_ASSERT_IF(IsCrossCompartmentWrapper(obj), IsDeadProxyObject(obj));
|
||||
JS_ASSERT(obj->getParent() == cx->global());
|
||||
JS_ASSERT(obj->getClass() == &ObjectProxyObject::class_);
|
||||
JS_ASSERT(obj->getTaggedProto().isLazy());
|
||||
JS_ASSERT_IF(IsCrossCompartmentWrapper(this), IsDeadProxyObject(this));
|
||||
JS_ASSERT(getParent() == cx->global());
|
||||
JS_ASSERT(getClass() == &ObjectProxyObject::class_);
|
||||
JS_ASSERT(getTaggedProto().isLazy());
|
||||
#ifdef DEBUG
|
||||
AutoSuppressGC suppressGC(cx);
|
||||
JS_ASSERT(!handler->isOuterWindow());
|
||||
#endif
|
||||
|
||||
obj->setSlot(JSSLOT_PROXY_HANDLER, PrivateValue(handler));
|
||||
obj->setCrossCompartmentSlot(JSSLOT_PROXY_PRIVATE, priv);
|
||||
obj->setSlot(JSSLOT_PROXY_EXTRA + 0, UndefinedValue());
|
||||
obj->setSlot(JSSLOT_PROXY_EXTRA + 1, UndefinedValue());
|
||||
|
||||
return obj;
|
||||
setSlot(HANDLER_SLOT, PrivateValue(handler));
|
||||
setCrossCompartmentSlot(PRIVATE_SLOT, priv);
|
||||
setSlot(EXTRA_SLOT + 0, UndefinedValue());
|
||||
setSlot(EXTRA_SLOT + 1, UndefinedValue());
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@ -3389,12 +3395,11 @@ proxy(JSContext *cx, unsigned argc, jsval *vp)
|
||||
return false;
|
||||
RootedObject fun(cx, target->isCallable() ? target.get() : (JSObject *) NULL);
|
||||
RootedValue priv(cx, ObjectValue(*target));
|
||||
JSObject *proxy = NewProxyObject(cx, &ScriptedDirectProxyHandler::singleton,
|
||||
priv, proto, cx->global(),
|
||||
fun, fun);
|
||||
ProxyObject *proxy = NewProxyObject(cx, &ScriptedDirectProxyHandler::singleton,
|
||||
priv, proto, cx->global(), fun, fun);
|
||||
if (!proxy)
|
||||
return false;
|
||||
SetProxyExtra(proxy, 0, ObjectOrNullValue(handler));
|
||||
proxy->setExtra(0, ObjectOrNullValue(handler));
|
||||
vp->setObject(*proxy);
|
||||
return true;
|
||||
}
|
||||
|
@ -287,32 +287,30 @@ inline bool IsProxy(JSObject *obj)
|
||||
return IsProxyClass(GetObjectClass(obj));
|
||||
}
|
||||
|
||||
/* Shared between object and function proxies. */
|
||||
/*
|
||||
* NOTE: JSSLOT_PROXY_PRIVATE is 0, because that way slot 0 is usable by API
|
||||
* These are part of the API.
|
||||
*
|
||||
* NOTE: PROXY_PRIVATE_SLOT is 0 because that way slot 0 is usable by API
|
||||
* clients for both proxy and non-proxy objects. So an API client that only
|
||||
* needs to store one slot's worth of data doesn't need to branch on what sort
|
||||
* of object it has.
|
||||
*/
|
||||
const uint32_t JSSLOT_PROXY_PRIVATE = 0;
|
||||
const uint32_t JSSLOT_PROXY_HANDLER = 1;
|
||||
const uint32_t JSSLOT_PROXY_EXTRA = 2;
|
||||
/* Function proxies only. */
|
||||
const uint32_t JSSLOT_PROXY_CALL = 4;
|
||||
const uint32_t JSSLOT_PROXY_CONSTRUCT = 5;
|
||||
const uint32_t PROXY_PRIVATE_SLOT = 0;
|
||||
const uint32_t PROXY_HANDLER_SLOT = 1;
|
||||
const uint32_t PROXY_EXTRA_SLOT = 2;
|
||||
|
||||
inline BaseProxyHandler *
|
||||
GetProxyHandler(JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(IsProxy(obj));
|
||||
return (BaseProxyHandler *) GetReservedSlot(obj, JSSLOT_PROXY_HANDLER).toPrivate();
|
||||
return (BaseProxyHandler *) GetReservedSlot(obj, PROXY_HANDLER_SLOT).toPrivate();
|
||||
}
|
||||
|
||||
inline const Value &
|
||||
GetProxyPrivate(JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(IsProxy(obj));
|
||||
return GetReservedSlot(obj, JSSLOT_PROXY_PRIVATE);
|
||||
return GetReservedSlot(obj, PROXY_PRIVATE_SLOT);
|
||||
}
|
||||
|
||||
inline JSObject *
|
||||
@ -326,14 +324,14 @@ inline const Value &
|
||||
GetProxyExtra(JSObject *obj, size_t n)
|
||||
{
|
||||
JS_ASSERT(IsProxy(obj));
|
||||
return GetReservedSlot(obj, JSSLOT_PROXY_EXTRA + n);
|
||||
return GetReservedSlot(obj, PROXY_EXTRA_SLOT + n);
|
||||
}
|
||||
|
||||
inline void
|
||||
SetProxyHandler(JSObject *obj, BaseProxyHandler *handler)
|
||||
{
|
||||
JS_ASSERT(IsProxy(obj));
|
||||
SetReservedSlot(obj, JSSLOT_PROXY_HANDLER, PrivateValue(handler));
|
||||
SetReservedSlot(obj, PROXY_HANDLER_SLOT, PrivateValue(handler));
|
||||
}
|
||||
|
||||
inline void
|
||||
@ -341,7 +339,7 @@ SetProxyExtra(JSObject *obj, size_t n, const Value &extra)
|
||||
{
|
||||
JS_ASSERT(IsProxy(obj));
|
||||
JS_ASSERT(n <= 1);
|
||||
SetReservedSlot(obj, JSSLOT_PROXY_EXTRA + n, extra);
|
||||
SetReservedSlot(obj, PROXY_EXTRA_SLOT + n, extra);
|
||||
}
|
||||
|
||||
enum ProxyCallable {
|
||||
|
@ -258,7 +258,8 @@ TryPreserveReflector(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
if (obj->getClass()->ext.isWrappedNative ||
|
||||
(obj->getClass()->flags & JSCLASS_IS_DOMJSCLASS) ||
|
||||
(obj->is<ProxyObject>() && GetProxyHandler(obj)->family() == GetDOMProxyHandlerFamily()))
|
||||
(obj->is<ProxyObject>() &&
|
||||
obj->as<ProxyObject>().handler()->family() == GetDOMProxyHandlerFamily()))
|
||||
{
|
||||
JS_ASSERT(cx->runtime()->preserveWrapperCallback);
|
||||
if (!cx->runtime()->preserveWrapperCallback(cx, obj)) {
|
||||
|
@ -47,21 +47,22 @@ JSObject *
|
||||
Wrapper::Renew(JSContext *cx, JSObject *existing, JSObject *obj, Wrapper *handler)
|
||||
{
|
||||
JS_ASSERT(!obj->isCallable());
|
||||
return RenewProxyObject(cx, existing, handler, ObjectValue(*obj));
|
||||
existing->as<ProxyObject>().renew(cx, handler, ObjectValue(*obj));
|
||||
return existing;
|
||||
}
|
||||
|
||||
Wrapper *
|
||||
Wrapper::wrapperHandler(JSObject *wrapper)
|
||||
{
|
||||
JS_ASSERT(wrapper->isWrapper());
|
||||
return static_cast<Wrapper*>(GetProxyHandler(wrapper));
|
||||
return static_cast<Wrapper*>(wrapper->as<ProxyObject>().handler());
|
||||
}
|
||||
|
||||
JSObject *
|
||||
Wrapper::wrappedObject(JSObject *wrapper)
|
||||
{
|
||||
JS_ASSERT(wrapper->isWrapper());
|
||||
return GetProxyTargetObject(wrapper);
|
||||
return wrapper->as<ProxyObject>().target();
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSObject *)
|
||||
@ -71,7 +72,7 @@ js::UncheckedUnwrap(JSObject *wrapped, bool stopAtOuter, unsigned *flagsp)
|
||||
while (wrapped->isWrapper() &&
|
||||
!JS_UNLIKELY(stopAtOuter && wrapped->getClass()->ext.innerObject)) {
|
||||
flags |= Wrapper::wrapperHandler(wrapped)->flags();
|
||||
wrapped = GetProxyPrivate(wrapped).toObjectOrNull();
|
||||
wrapped = wrapped->as<ProxyObject>().private_().toObjectOrNull();
|
||||
}
|
||||
if (flagsp)
|
||||
*flagsp = flags;
|
||||
@ -836,20 +837,8 @@ js::NewDeadProxyObject(JSContext *cx, JSObject *parent)
|
||||
bool
|
||||
js::IsDeadProxyObject(JSObject *obj)
|
||||
{
|
||||
return obj->is<ProxyObject>() && GetProxyHandler(obj) == &DeadObjectProxy::singleton;
|
||||
}
|
||||
|
||||
static void
|
||||
NukeSlot(JSObject *wrapper, uint32_t slot, Value v)
|
||||
{
|
||||
Value old = wrapper->getSlot(slot);
|
||||
if (old.isMarkable()) {
|
||||
Zone *zone = ZoneOfValue(old);
|
||||
AutoMarkInDeadZone amd(zone);
|
||||
wrapper->setReservedSlot(slot, v);
|
||||
} else {
|
||||
wrapper->setReservedSlot(slot, v);
|
||||
}
|
||||
return obj->is<ProxyObject>() &&
|
||||
obj->as<ProxyObject>().handler() == &DeadObjectProxy::singleton;
|
||||
}
|
||||
|
||||
void
|
||||
@ -859,16 +848,7 @@ js::NukeCrossCompartmentWrapper(JSContext *cx, JSObject *wrapper)
|
||||
|
||||
NotifyGCNukeWrapper(wrapper);
|
||||
|
||||
NukeSlot(wrapper, JSSLOT_PROXY_PRIVATE, NullValue());
|
||||
SetProxyHandler(wrapper, &DeadObjectProxy::singleton);
|
||||
|
||||
if (wrapper->is<FunctionProxyObject>()) {
|
||||
NukeSlot(wrapper, JSSLOT_PROXY_CALL, NullValue());
|
||||
NukeSlot(wrapper, JSSLOT_PROXY_CONSTRUCT, NullValue());
|
||||
}
|
||||
|
||||
NukeSlot(wrapper, JSSLOT_PROXY_EXTRA + 0, NullValue());
|
||||
NukeSlot(wrapper, JSSLOT_PROXY_EXTRA + 1, NullValue());
|
||||
wrapper->as<ProxyObject>().nuke(&DeadObjectProxy::singleton);
|
||||
|
||||
JS_ASSERT(IsDeadProxyObject(wrapper));
|
||||
}
|
||||
|
@ -112,6 +112,7 @@ CPP_SOURCES += [
|
||||
'Probes.cpp',
|
||||
'Profilers.cpp',
|
||||
'PropertyKey.cpp',
|
||||
'ProxyObject.cpp',
|
||||
'RegExp.cpp',
|
||||
'RegExpObject.cpp',
|
||||
'RegExpStatics.cpp',
|
||||
|
@ -2099,7 +2099,8 @@ Debugger::construct(JSContext *cx, unsigned argc, Value *vp)
|
||||
|
||||
/* Add the initial debuggees, if any. */
|
||||
for (unsigned i = 0; i < argc; i++) {
|
||||
Rooted<GlobalObject*> debuggee(cx, &GetProxyPrivate(&args[i].toObject()).toObject().global());
|
||||
Rooted<GlobalObject*>
|
||||
debuggee(cx, &args[i].toObject().as<ProxyObject>().private_().toObject().global());
|
||||
if (!dbg->addDebuggeeGlobal(cx, debuggee))
|
||||
return false;
|
||||
}
|
||||
|
60
js/src/vm/ProxyObject.cpp
Normal file
60
js/src/vm/ProxyObject.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
/* -*- 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 "vm/ProxyObject.h"
|
||||
|
||||
#include "jsgcinlines.h"
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
#include "gc/Barrier-inl.h"
|
||||
#include "vm/ObjectImpl-inl.h"
|
||||
|
||||
using namespace js;
|
||||
|
||||
void
|
||||
ProxyObject::initCrossCompartmentPrivate(HandleValue priv)
|
||||
{
|
||||
initCrossCompartmentSlot(PRIVATE_SLOT, priv);
|
||||
}
|
||||
|
||||
void
|
||||
ProxyObject::initHandler(BaseProxyHandler *handler)
|
||||
{
|
||||
initSlot(HANDLER_SLOT, PrivateValue(handler));
|
||||
}
|
||||
|
||||
static void
|
||||
NukeSlot(ProxyObject *proxy, uint32_t slot)
|
||||
{
|
||||
Value old = proxy->getSlot(slot);
|
||||
if (old.isMarkable()) {
|
||||
Zone *zone = ZoneOfValue(old);
|
||||
AutoMarkInDeadZone amd(zone);
|
||||
proxy->setReservedSlot(slot, NullValue());
|
||||
} else {
|
||||
proxy->setReservedSlot(slot, NullValue());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ProxyObject::nuke(BaseProxyHandler *handler)
|
||||
{
|
||||
NukeSlot(this, PRIVATE_SLOT);
|
||||
setHandler(handler);
|
||||
|
||||
NukeSlot(this, EXTRA_SLOT + 0);
|
||||
NukeSlot(this, EXTRA_SLOT + 1);
|
||||
|
||||
if (is<FunctionProxyObject>())
|
||||
as<FunctionProxyObject>().nukeExtra();
|
||||
}
|
||||
|
||||
void
|
||||
FunctionProxyObject::nukeExtra()
|
||||
{
|
||||
NukeSlot(this, CALL_SLOT);
|
||||
NukeSlot(this, CONSTRUCT_SLOT);
|
||||
}
|
@ -16,12 +16,88 @@ namespace js {
|
||||
// instantiated.
|
||||
class ProxyObject : public JSObject
|
||||
{
|
||||
// These are just local renamings of the slot constants that are part of
|
||||
// the API in jsproxy.h.
|
||||
static const uint32_t PRIVATE_SLOT = PROXY_PRIVATE_SLOT;
|
||||
static const uint32_t HANDLER_SLOT = PROXY_HANDLER_SLOT;
|
||||
static const uint32_t EXTRA_SLOT = PROXY_EXTRA_SLOT;
|
||||
|
||||
public:
|
||||
static ProxyObject *New(JSContext *cx, BaseProxyHandler *handler, HandleValue priv,
|
||||
TaggedProto proto_, JSObject *parent_, ProxyCallable callable);
|
||||
|
||||
const Value &private_() {
|
||||
return GetReservedSlot(this, PRIVATE_SLOT);
|
||||
}
|
||||
|
||||
void initCrossCompartmentPrivate(HandleValue priv);
|
||||
|
||||
HeapSlot *slotOfPrivate() {
|
||||
return &getReservedSlotRef(PRIVATE_SLOT);
|
||||
}
|
||||
|
||||
JSObject *target() const {
|
||||
return const_cast<ProxyObject*>(this)->private_().toObjectOrNull();
|
||||
}
|
||||
|
||||
BaseProxyHandler *handler() {
|
||||
return static_cast<BaseProxyHandler*>(GetReservedSlot(this, HANDLER_SLOT).toPrivate());
|
||||
}
|
||||
|
||||
void initHandler(BaseProxyHandler *handler);
|
||||
|
||||
void setHandler(BaseProxyHandler *handler) {
|
||||
SetReservedSlot(this, HANDLER_SLOT, PrivateValue(handler));
|
||||
}
|
||||
|
||||
static size_t offsetOfHandler() {
|
||||
return getFixedSlotOffset(HANDLER_SLOT);
|
||||
}
|
||||
|
||||
const Value &extra(size_t n) const {
|
||||
JS_ASSERT(n == 0 || n == 1);
|
||||
return GetReservedSlot(const_cast<ProxyObject*>(this), EXTRA_SLOT + n);
|
||||
}
|
||||
|
||||
void setExtra(size_t n, const Value &extra) {
|
||||
JS_ASSERT(n == 0 || n == 1);
|
||||
SetReservedSlot(this, EXTRA_SLOT + n, extra);
|
||||
}
|
||||
|
||||
private:
|
||||
HeapSlot *slotOfExtra(size_t n) {
|
||||
JS_ASSERT(n == 0 || n == 1);
|
||||
return &getReservedSlotRef(EXTRA_SLOT + n);
|
||||
}
|
||||
|
||||
public:
|
||||
static unsigned grayLinkSlot(JSObject *obj);
|
||||
|
||||
void renew(JSContext *cx, BaseProxyHandler *handler, Value priv);
|
||||
|
||||
static void trace(JSTracer *trc, JSObject *obj);
|
||||
|
||||
void nuke(BaseProxyHandler *handler);
|
||||
};
|
||||
|
||||
class FunctionProxyObject : public ProxyObject
|
||||
{
|
||||
static const uint32_t CALL_SLOT = 4;
|
||||
static const uint32_t CONSTRUCT_SLOT = 5;
|
||||
|
||||
public:
|
||||
static Class class_;
|
||||
|
||||
static FunctionProxyObject *New(JSContext *cx, BaseProxyHandler *handler, HandleValue priv,
|
||||
JSObject *proto, JSObject *parent, JSObject *call,
|
||||
JSObject *construct);
|
||||
|
||||
HeapSlot &call() { return getSlotRef(CALL_SLOT); }
|
||||
|
||||
inline HeapSlot &construct();
|
||||
inline Value constructOrUndefined() const;
|
||||
|
||||
void nukeExtra();
|
||||
};
|
||||
|
||||
class ObjectProxyObject : public ProxyObject
|
||||
|
@ -1549,36 +1549,38 @@ DebugScopeObject::create(JSContext *cx, ScopeObject &scope, HandleObject enclosi
|
||||
return NULL;
|
||||
|
||||
JS_ASSERT(!enclosing->is<ScopeObject>());
|
||||
SetProxyExtra(obj, ENCLOSING_EXTRA, ObjectValue(*enclosing));
|
||||
SetProxyExtra(obj, SNAPSHOT_EXTRA, NullValue());
|
||||
|
||||
return &obj->as<DebugScopeObject>();
|
||||
DebugScopeObject *debugScope = &obj->as<DebugScopeObject>();
|
||||
debugScope->setExtra(ENCLOSING_EXTRA, ObjectValue(*enclosing));
|
||||
debugScope->setExtra(SNAPSHOT_EXTRA, NullValue());
|
||||
|
||||
return debugScope;
|
||||
}
|
||||
|
||||
ScopeObject &
|
||||
DebugScopeObject::scope() const
|
||||
{
|
||||
return GetProxyTargetObject(const_cast<DebugScopeObject*>(this))->as<ScopeObject>();
|
||||
return target()->as<ScopeObject>();
|
||||
}
|
||||
|
||||
JSObject &
|
||||
DebugScopeObject::enclosingScope() const
|
||||
{
|
||||
return GetProxyExtra(const_cast<DebugScopeObject*>(this), ENCLOSING_EXTRA).toObject();
|
||||
return extra(ENCLOSING_EXTRA).toObject();
|
||||
}
|
||||
|
||||
JSObject *
|
||||
DebugScopeObject::maybeSnapshot() const
|
||||
{
|
||||
JS_ASSERT(!scope().as<CallObject>().isForEval());
|
||||
return GetProxyExtra(const_cast<DebugScopeObject*>(this), SNAPSHOT_EXTRA).toObjectOrNull();
|
||||
return extra(SNAPSHOT_EXTRA).toObjectOrNull();
|
||||
}
|
||||
|
||||
void
|
||||
DebugScopeObject::initSnapshot(JSObject &o)
|
||||
{
|
||||
JS_ASSERT(maybeSnapshot() == NULL);
|
||||
SetProxyExtra(this, SNAPSHOT_EXTRA, ObjectValue(o));
|
||||
setExtra(SNAPSHOT_EXTRA, ObjectValue(o));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1592,7 +1594,7 @@ bool
|
||||
js_IsDebugScopeSlow(ObjectProxyObject *proxy)
|
||||
{
|
||||
JS_ASSERT(proxy->hasClass(&ObjectProxyObject::class_));
|
||||
return GetProxyHandler(proxy) == &DebugScopeProxy::singleton;
|
||||
return proxy->handler() == &DebugScopeProxy::singleton;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
Loading…
Reference in New Issue
Block a user