2015-05-03 22:32:37 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2012-05-22 17:46:20 +04:00
|
|
|
/* 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/. */
|
|
|
|
|
2013-08-24 06:42:39 +04:00
|
|
|
#include "mozilla/dom/DOMJSProxyHandler.h"
|
2012-05-22 17:46:20 +04:00
|
|
|
#include "xpcpublic.h"
|
|
|
|
#include "xpcprivate.h"
|
|
|
|
#include "XPCWrapper.h"
|
|
|
|
#include "WrapperFactory.h"
|
|
|
|
#include "nsWrapperCacheInlines.h"
|
|
|
|
#include "mozilla/dom/BindingUtils.h"
|
|
|
|
|
|
|
|
#include "jsapi.h"
|
|
|
|
|
|
|
|
using namespace JS;
|
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace dom {
|
|
|
|
|
2013-12-17 06:27:43 +04:00
|
|
|
jsid s_length_id = JSID_VOID;
|
2012-05-22 17:46:20 +04:00
|
|
|
|
|
|
|
bool
|
|
|
|
DefineStaticJSVals(JSContext* cx)
|
|
|
|
{
|
2015-06-30 17:58:31 +03:00
|
|
|
return AtomizeAndPinJSString(cx, s_length_id, "length");
|
2012-05-22 17:46:20 +04:00
|
|
|
}
|
|
|
|
|
2014-08-28 04:09:06 +04:00
|
|
|
const char DOMProxyHandler::family = 0;
|
2012-05-22 17:46:20 +04:00
|
|
|
|
2013-06-06 22:32:26 +04:00
|
|
|
js::DOMProxyShadowsResult
|
2013-06-21 17:12:46 +04:00
|
|
|
DOMProxyShadows(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id)
|
2013-04-29 17:17:59 +04:00
|
|
|
{
|
2015-02-26 20:30:02 +03:00
|
|
|
JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
|
2017-04-28 15:12:28 +03:00
|
|
|
JS::Value v = js::GetProxyPrivate(proxy);
|
2015-02-26 20:30:02 +03:00
|
|
|
bool isOverrideBuiltins = !v.isObject() && !v.isUndefined();
|
|
|
|
if (expando) {
|
2013-08-09 02:53:04 +04:00
|
|
|
bool hasOwn;
|
2015-02-26 20:30:02 +03:00
|
|
|
if (!JS_AlreadyHasOwnPropertyById(cx, expando, id, &hasOwn))
|
2013-04-29 17:17:59 +04:00
|
|
|
return js::ShadowCheckFailed;
|
|
|
|
|
2015-02-26 20:30:02 +03:00
|
|
|
if (hasOwn) {
|
|
|
|
return isOverrideBuiltins ?
|
|
|
|
js::ShadowsViaIndirectExpando : js::ShadowsViaDirectExpando;
|
|
|
|
}
|
2013-04-29 17:17:59 +04:00
|
|
|
}
|
|
|
|
|
2015-02-26 20:30:02 +03:00
|
|
|
if (!isOverrideBuiltins) {
|
|
|
|
// Our expando, if any, didn't shadow, so we're not shadowing at all.
|
2013-04-29 17:17:59 +04:00
|
|
|
return js::DoesntShadow;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool hasOwn;
|
|
|
|
if (!GetProxyHandler(proxy)->hasOwn(cx, proxy, id, &hasOwn))
|
|
|
|
return js::ShadowCheckFailed;
|
|
|
|
|
|
|
|
return hasOwn ? js::Shadows : js::DoesntShadowUnique;
|
|
|
|
}
|
|
|
|
|
2012-08-24 20:32:26 +04:00
|
|
|
// Store the information for the specialized ICs.
|
2013-06-06 22:32:26 +04:00
|
|
|
struct SetDOMProxyInformation
|
2012-08-24 20:32:26 +04:00
|
|
|
{
|
2013-06-06 22:32:26 +04:00
|
|
|
SetDOMProxyInformation() {
|
2014-08-28 04:09:06 +04:00
|
|
|
js::SetDOMProxyInformation((const void*) &DOMProxyHandler::family,
|
2017-04-28 15:12:28 +03:00
|
|
|
DOMProxyShadows);
|
2012-08-24 20:32:26 +04:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-06-06 22:32:26 +04:00
|
|
|
SetDOMProxyInformation gSetDOMProxyInformation;
|
2012-08-24 20:32:26 +04:00
|
|
|
|
2013-04-16 21:02:57 +04:00
|
|
|
// static
|
|
|
|
JSObject*
|
|
|
|
DOMProxyHandler::GetAndClearExpandoObject(JSObject* obj)
|
|
|
|
{
|
2013-04-20 20:04:09 +04:00
|
|
|
MOZ_ASSERT(IsDOMProxy(obj), "expected a DOM proxy object");
|
2017-04-28 15:12:28 +03:00
|
|
|
JS::Value v = js::GetProxyPrivate(obj);
|
2013-04-20 20:04:09 +04:00
|
|
|
if (v.isUndefined()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (v.isObject()) {
|
2017-04-28 15:12:28 +03:00
|
|
|
js::SetProxyPrivate(obj, UndefinedValue());
|
2012-12-12 06:45:36 +04:00
|
|
|
} else {
|
|
|
|
js::ExpandoAndGeneration* expandoAndGeneration =
|
|
|
|
static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
|
|
|
|
v = expandoAndGeneration->expando;
|
|
|
|
if (v.isUndefined()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-09-15 22:04:56 +03:00
|
|
|
// We have to expose v to active JS here. The reason for that is that we
|
|
|
|
// might be in the middle of a GC right now. If our proxy hasn't been
|
|
|
|
// traced yet, when it _does_ get traced it won't trace the expando, since
|
|
|
|
// we're breaking that link. But the Rooted we're presumably being placed
|
|
|
|
// into is also not going to trace us, because Rooted marking is done at
|
|
|
|
// the very beginning of the GC. In that situation, we need to manually
|
|
|
|
// mark the expando as live here. JS::ExposeValueToActiveJS will do just
|
|
|
|
// that for us.
|
|
|
|
//
|
|
|
|
// We don't need to do this in the non-expandoAndGeneration case, because
|
|
|
|
// in that case our value is stored in a slot and slots will already mark
|
|
|
|
// the old thing live when the value in the slot changes.
|
|
|
|
JS::ExposeValueToActiveJS(v);
|
2012-12-12 06:45:36 +04:00
|
|
|
expandoAndGeneration->expando = UndefinedValue();
|
2013-04-20 20:04:09 +04:00
|
|
|
}
|
|
|
|
|
2012-12-12 06:45:36 +04:00
|
|
|
|
2013-04-20 20:04:09 +04:00
|
|
|
return &v.toObject();
|
2013-04-16 21:02:57 +04:00
|
|
|
}
|
2012-08-24 20:32:26 +04:00
|
|
|
|
2012-05-22 17:46:20 +04:00
|
|
|
// static
|
|
|
|
JSObject*
|
2013-05-04 03:29:09 +04:00
|
|
|
DOMProxyHandler::EnsureExpandoObject(JSContext* cx, JS::Handle<JSObject*> obj)
|
2012-05-22 17:46:20 +04:00
|
|
|
{
|
|
|
|
NS_ASSERTION(IsDOMProxy(obj), "expected a DOM proxy object");
|
2017-04-28 15:12:28 +03:00
|
|
|
JS::Value v = js::GetProxyPrivate(obj);
|
2013-04-20 20:04:09 +04:00
|
|
|
if (v.isObject()) {
|
|
|
|
return &v.toObject();
|
|
|
|
}
|
2012-05-22 17:46:20 +04:00
|
|
|
|
2013-04-20 20:04:09 +04:00
|
|
|
js::ExpandoAndGeneration* expandoAndGeneration;
|
|
|
|
if (!v.isUndefined()) {
|
|
|
|
expandoAndGeneration = static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
|
|
|
|
if (expandoAndGeneration->expando.isObject()) {
|
|
|
|
return &expandoAndGeneration->expando.toObject();
|
2013-05-05 03:27:20 +04:00
|
|
|
}
|
2013-04-20 20:04:09 +04:00
|
|
|
} else {
|
|
|
|
expandoAndGeneration = nullptr;
|
|
|
|
}
|
2013-04-20 20:04:09 +04:00
|
|
|
|
2013-05-08 06:34:56 +04:00
|
|
|
JS::Rooted<JSObject*> expando(cx,
|
2015-05-14 00:07:34 +03:00
|
|
|
JS_NewObjectWithGivenProto(cx, nullptr, nullptr));
|
2013-04-20 20:04:09 +04:00
|
|
|
if (!expando) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2013-04-20 20:04:09 +04:00
|
|
|
|
2013-05-17 19:04:08 +04:00
|
|
|
nsISupports* native = UnwrapDOMObject<nsISupports>(obj);
|
|
|
|
nsWrapperCache* cache;
|
|
|
|
CallQueryInterface(native, &cache);
|
2017-05-17 07:52:52 +03:00
|
|
|
cache->PreserveWrapper(native);
|
|
|
|
|
2013-05-17 19:04:08 +04:00
|
|
|
if (expandoAndGeneration) {
|
|
|
|
expandoAndGeneration->expando.setObject(*expando);
|
|
|
|
return expando;
|
|
|
|
}
|
|
|
|
|
2017-04-28 15:12:28 +03:00
|
|
|
js::SetProxyPrivate(obj, ObjectValue(*expando));
|
2013-04-20 20:04:09 +04:00
|
|
|
|
2012-05-22 17:46:20 +04:00
|
|
|
return expando;
|
|
|
|
}
|
|
|
|
|
2013-03-23 06:43:03 +04:00
|
|
|
bool
|
2015-02-04 21:01:01 +03:00
|
|
|
DOMProxyHandler::preventExtensions(JSContext* cx, JS::Handle<JSObject*> proxy,
|
|
|
|
JS::ObjectOpResult& result) const
|
2013-03-23 06:43:03 +04:00
|
|
|
{
|
2013-06-29 01:01:09 +04:00
|
|
|
// always extensible per WebIDL
|
2015-02-04 21:01:01 +03:00
|
|
|
return result.failCantPreventExtensions();
|
2013-03-23 06:43:03 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2014-10-21 22:40:04 +04:00
|
|
|
DOMProxyHandler::isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *extensible) const
|
2013-03-23 06:43:03 +04:00
|
|
|
{
|
2014-10-21 22:40:04 +04:00
|
|
|
*extensible = true;
|
2014-10-19 12:18:43 +04:00
|
|
|
return true;
|
2013-03-23 06:43:03 +04:00
|
|
|
}
|
|
|
|
|
2014-08-02 07:37:14 +04:00
|
|
|
bool
|
|
|
|
BaseDOMProxyHandler::getOwnPropertyDescriptor(JSContext* cx,
|
|
|
|
JS::Handle<JSObject*> proxy,
|
|
|
|
JS::Handle<jsid> id,
|
2016-01-28 13:28:04 +03:00
|
|
|
MutableHandle<PropertyDescriptor> desc) const
|
2014-08-02 07:37:14 +04:00
|
|
|
{
|
|
|
|
return getOwnPropDescriptor(cx, proxy, id, /* ignoreNamedProps = */ false,
|
|
|
|
desc);
|
|
|
|
}
|
|
|
|
|
2012-05-22 17:46:20 +04:00
|
|
|
bool
|
2013-03-22 02:23:48 +04:00
|
|
|
DOMProxyHandler::defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
2016-01-28 13:28:04 +03:00
|
|
|
Handle<PropertyDescriptor> desc,
|
2015-01-30 20:37:07 +03:00
|
|
|
JS::ObjectOpResult &result, bool *defined) const
|
2012-05-22 17:46:20 +04:00
|
|
|
{
|
|
|
|
if (xpc::WrapperFactory::IsXrayWrapper(proxy)) {
|
2015-01-30 20:37:07 +03:00
|
|
|
return result.succeed();
|
2012-05-22 17:46:20 +04:00
|
|
|
}
|
|
|
|
|
2015-05-30 00:48:26 +03:00
|
|
|
JS::Rooted<JSObject*> expando(cx, EnsureExpandoObject(cx, proxy));
|
2012-05-22 17:46:20 +04:00
|
|
|
if (!expando) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-05-30 00:48:26 +03:00
|
|
|
if (!JS_DefinePropertyById(cx, expando, id, desc, result)) {
|
2015-01-30 20:37:07 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
*defined = true;
|
|
|
|
return true;
|
2012-05-22 17:46:20 +04:00
|
|
|
}
|
|
|
|
|
2014-04-26 00:07:18 +04:00
|
|
|
bool
|
Bug 1142794 - Change 'receiver' argument to SetProperty functions and ProxyHandler::set methods to be a HandleValue. r=Waldo.
Also: Change signature of these functions and methods to all have the same arguments in the same order: (cx, obj, id, v, receiver). Also change v from MutableHandleValue to HandleValue.
There is no change in behavior.
In fact the new error message `JSMSG_SET_NON_OBJECT_RECEIVER` is
impossible to trigger from scripts for now, I think (after re-reading
the whole patch with this in mind). JS_ForwardSetPropertyTo is the only
way to get a non-object receiver into the engine, but no caller
currently does so.
We're installing new pipes here, and they should work, but for now it's
the same cold water flowing through as before. Actually hooking up the
hot water is left for another bug (one with tests, not to put too fine a
point on it).
Notes:
* InvokeGetterOrSetter had to be split into two functions:
InvokeGetter takes a MutableHandleValue out-param,
InvokeSetter a HandleValue in-param.
* Watchpoints can still tamper with values being assigned. So can
JSSetterOps. I'm pleased we can support this craziness in a way that
doesn't have to spread via the type system to encompass the entire
codebase.
* Change in GlobalObject::setIntrinsicValue is not really a change.
Yes, it asserted before, but an exception thrown during self-hosting
initialization is not going to go unnoticed either.
* Since the receiver argument to js::SetProperty() is at the end now, it
makes sense for it to be optional. Some callers look nicer.
--HG--
extra : rebase_source : e89f916fe267800bc73890e11aceef5c4855b272
2015-03-01 22:16:19 +03:00
|
|
|
DOMProxyHandler::set(JSContext *cx, Handle<JSObject*> proxy, Handle<jsid> id,
|
|
|
|
Handle<JS::Value> v, Handle<JS::Value> receiver,
|
|
|
|
ObjectOpResult &result) const
|
2014-04-26 00:07:18 +04:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
|
|
|
|
"Should not have a XrayWrapper here");
|
|
|
|
bool done;
|
Bug 1142794 - Change 'receiver' argument to SetProperty functions and ProxyHandler::set methods to be a HandleValue. r=Waldo.
Also: Change signature of these functions and methods to all have the same arguments in the same order: (cx, obj, id, v, receiver). Also change v from MutableHandleValue to HandleValue.
There is no change in behavior.
In fact the new error message `JSMSG_SET_NON_OBJECT_RECEIVER` is
impossible to trigger from scripts for now, I think (after re-reading
the whole patch with this in mind). JS_ForwardSetPropertyTo is the only
way to get a non-object receiver into the engine, but no caller
currently does so.
We're installing new pipes here, and they should work, but for now it's
the same cold water flowing through as before. Actually hooking up the
hot water is left for another bug (one with tests, not to put too fine a
point on it).
Notes:
* InvokeGetterOrSetter had to be split into two functions:
InvokeGetter takes a MutableHandleValue out-param,
InvokeSetter a HandleValue in-param.
* Watchpoints can still tamper with values being assigned. So can
JSSetterOps. I'm pleased we can support this craziness in a way that
doesn't have to spread via the type system to encompass the entire
codebase.
* Change in GlobalObject::setIntrinsicValue is not really a change.
Yes, it asserted before, but an exception thrown during self-hosting
initialization is not going to go unnoticed either.
* Since the receiver argument to js::SetProperty() is at the end now, it
makes sense for it to be optional. Some callers look nicer.
--HG--
extra : rebase_source : e89f916fe267800bc73890e11aceef5c4855b272
2015-03-01 22:16:19 +03:00
|
|
|
if (!setCustom(cx, proxy, id, v, &done)) {
|
2014-04-26 00:07:18 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (done) {
|
2015-02-04 04:51:40 +03:00
|
|
|
return result.succeed();
|
2014-04-26 00:07:18 +04:00
|
|
|
}
|
2014-08-02 07:37:14 +04:00
|
|
|
|
|
|
|
// Make sure to ignore our named properties when checking for own
|
|
|
|
// property descriptors for a set.
|
2016-01-28 13:28:04 +03:00
|
|
|
JS::Rooted<PropertyDescriptor> ownDesc(cx);
|
2014-08-02 07:37:14 +04:00
|
|
|
if (!getOwnPropDescriptor(cx, proxy, id, /* ignoreNamedProps = */ true,
|
2015-05-04 21:27:02 +03:00
|
|
|
&ownDesc)) {
|
2014-08-02 07:37:14 +04:00
|
|
|
return false;
|
|
|
|
}
|
2015-05-04 21:27:02 +03:00
|
|
|
return js::SetPropertyIgnoringNamedGetter(cx, proxy, id, v, receiver, ownDesc, result);
|
2014-04-26 00:07:18 +04:00
|
|
|
}
|
|
|
|
|
2012-05-22 17:46:20 +04:00
|
|
|
bool
|
2013-03-22 02:23:48 +04:00
|
|
|
DOMProxyHandler::delete_(JSContext* cx, JS::Handle<JSObject*> proxy,
|
2015-02-04 19:20:04 +03:00
|
|
|
JS::Handle<jsid> id, JS::ObjectOpResult &result) const
|
2012-05-22 17:46:20 +04:00
|
|
|
{
|
2013-05-04 03:29:09 +04:00
|
|
|
JS::Rooted<JSObject*> expando(cx);
|
2012-05-22 17:46:20 +04:00
|
|
|
if (!xpc::WrapperFactory::IsXrayWrapper(proxy) && (expando = GetExpandoObject(proxy))) {
|
2015-02-04 19:20:04 +03:00
|
|
|
return JS_DeletePropertyById(cx, expando, id, result);
|
2012-05-22 17:46:20 +04:00
|
|
|
}
|
|
|
|
|
2015-02-04 19:20:04 +03:00
|
|
|
return result.succeed();
|
2012-05-22 17:46:20 +04:00
|
|
|
}
|
|
|
|
|
2014-04-16 06:58:44 +04:00
|
|
|
bool
|
2014-09-27 00:16:36 +04:00
|
|
|
BaseDOMProxyHandler::ownPropertyKeys(JSContext* cx,
|
|
|
|
JS::Handle<JSObject*> proxy,
|
|
|
|
JS::AutoIdVector& props) const
|
2014-04-16 06:58:44 +04:00
|
|
|
{
|
2014-10-07 01:42:33 +04:00
|
|
|
return ownPropNames(cx, proxy, JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, props);
|
2014-04-16 06:58:44 +04:00
|
|
|
}
|
|
|
|
|
2016-04-30 05:59:40 +03:00
|
|
|
bool
|
|
|
|
BaseDOMProxyHandler::getPrototypeIfOrdinary(JSContext* cx, JS::Handle<JSObject*> proxy,
|
|
|
|
bool* isOrdinary,
|
|
|
|
JS::MutableHandle<JSObject*> proto) const
|
|
|
|
{
|
|
|
|
*isOrdinary = true;
|
|
|
|
proto.set(GetStaticPrototype(proxy));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-04-16 06:58:44 +04:00
|
|
|
bool
|
2014-10-09 07:01:55 +04:00
|
|
|
BaseDOMProxyHandler::getOwnEnumerablePropertyKeys(JSContext* cx,
|
|
|
|
JS::Handle<JSObject*> proxy,
|
|
|
|
JS::AutoIdVector& props) const
|
2014-04-16 06:58:44 +04:00
|
|
|
{
|
|
|
|
return ownPropNames(cx, proxy, JSITER_OWNONLY, props);
|
|
|
|
}
|
|
|
|
|
2014-04-26 00:07:18 +04:00
|
|
|
bool
|
|
|
|
DOMProxyHandler::setCustom(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
Bug 1142794 - Change 'receiver' argument to SetProperty functions and ProxyHandler::set methods to be a HandleValue. r=Waldo.
Also: Change signature of these functions and methods to all have the same arguments in the same order: (cx, obj, id, v, receiver). Also change v from MutableHandleValue to HandleValue.
There is no change in behavior.
In fact the new error message `JSMSG_SET_NON_OBJECT_RECEIVER` is
impossible to trigger from scripts for now, I think (after re-reading
the whole patch with this in mind). JS_ForwardSetPropertyTo is the only
way to get a non-object receiver into the engine, but no caller
currently does so.
We're installing new pipes here, and they should work, but for now it's
the same cold water flowing through as before. Actually hooking up the
hot water is left for another bug (one with tests, not to put too fine a
point on it).
Notes:
* InvokeGetterOrSetter had to be split into two functions:
InvokeGetter takes a MutableHandleValue out-param,
InvokeSetter a HandleValue in-param.
* Watchpoints can still tamper with values being assigned. So can
JSSetterOps. I'm pleased we can support this craziness in a way that
doesn't have to spread via the type system to encompass the entire
codebase.
* Change in GlobalObject::setIntrinsicValue is not really a change.
Yes, it asserted before, but an exception thrown during self-hosting
initialization is not going to go unnoticed either.
* Since the receiver argument to js::SetProperty() is at the end now, it
makes sense for it to be optional. Some callers look nicer.
--HG--
extra : rebase_source : e89f916fe267800bc73890e11aceef5c4855b272
2015-03-01 22:16:19 +03:00
|
|
|
JS::Handle<JS::Value> v, bool *done) const
|
2014-04-26 00:07:18 +04:00
|
|
|
{
|
|
|
|
*done = false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-08-28 04:09:06 +04:00
|
|
|
//static
|
|
|
|
JSObject *
|
|
|
|
DOMProxyHandler::GetExpandoObject(JSObject *obj)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(IsDOMProxy(obj), "expected a DOM proxy object");
|
2017-04-28 15:12:28 +03:00
|
|
|
JS::Value v = js::GetProxyPrivate(obj);
|
2014-08-28 04:09:06 +04:00
|
|
|
if (v.isObject()) {
|
|
|
|
return &v.toObject();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (v.isUndefined()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
js::ExpandoAndGeneration* expandoAndGeneration =
|
|
|
|
static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
|
|
|
|
v = expandoAndGeneration->expando;
|
|
|
|
return v.isUndefined() ? nullptr : &v.toObject();
|
|
|
|
}
|
|
|
|
|
2016-07-22 23:19:52 +03:00
|
|
|
void
|
|
|
|
ShadowingDOMProxyHandler::trace(JSTracer* trc, JSObject* proxy) const
|
|
|
|
{
|
|
|
|
DOMProxyHandler::trace(trc, proxy);
|
|
|
|
|
|
|
|
MOZ_ASSERT(IsDOMProxy(proxy), "expected a DOM proxy object");
|
2017-04-28 15:12:28 +03:00
|
|
|
JS::Value v = js::GetProxyPrivate(proxy);
|
2016-07-22 23:19:52 +03:00
|
|
|
MOZ_ASSERT(!v.isObject(), "Should not have expando object directly!");
|
|
|
|
|
2017-04-28 15:12:28 +03:00
|
|
|
// The proxy's private slot is set when we allocate the proxy,
|
|
|
|
// so it cannot be |undefined|.
|
|
|
|
MOZ_ASSERT(!v.isUndefined());
|
2016-07-22 23:19:52 +03:00
|
|
|
|
|
|
|
js::ExpandoAndGeneration* expandoAndGeneration =
|
|
|
|
static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
|
|
|
|
JS::TraceEdge(trc, &expandoAndGeneration->expando,
|
|
|
|
"Shadowing DOM proxy expando");
|
|
|
|
}
|
|
|
|
|
2012-05-22 17:46:20 +04:00
|
|
|
} // namespace dom
|
|
|
|
} // namespace mozilla
|