зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1663365
- Move DOM proxy-related details (including expand support) to separate headers out of jsfriendapi.h. r=jandem
Differential Revision: https://phabricator.services.mozilla.com/D89336
This commit is contained in:
Родитель
45d8047ca9
Коммит
933368cb18
|
@ -3,6 +3,7 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_Document_h___
|
||||
#define mozilla_dom_Document_h___
|
||||
|
||||
|
@ -55,6 +56,7 @@
|
|||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include <bitset> // for member
|
||||
#include "js/friend/DOMProxy.h" // JS::ExpandoAndGeneration
|
||||
|
||||
// XXX We need to include this here to ensure that DefaultDeleter for Servo
|
||||
// types is specialized before the template is instantiated. Probably, this
|
||||
|
@ -5084,7 +5086,7 @@ class Document : public nsINode,
|
|||
|
||||
public:
|
||||
// Needs to be public because the bindings code pokes at it.
|
||||
js::ExpandoAndGeneration mExpandoAndGeneration;
|
||||
JS::ExpandoAndGeneration mExpandoAndGeneration;
|
||||
|
||||
bool HasPendingInitialTranslation();
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "mozilla/dom/BindingUtils.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "js/friend/DOMProxy.h" // JS::DOMProxyShadowsResult, JS::ExpandoAndGeneration, JS::SetDOMProxyInformation
|
||||
#include "js/Object.h" // JS::GetCompartment
|
||||
|
||||
using namespace JS;
|
||||
|
@ -28,39 +29,43 @@ bool DefineStaticJSVals(JSContext* cx) {
|
|||
|
||||
const char DOMProxyHandler::family = 0;
|
||||
|
||||
js::DOMProxyShadowsResult DOMProxyShadows(JSContext* cx,
|
||||
JS::DOMProxyShadowsResult DOMProxyShadows(JSContext* cx,
|
||||
JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<jsid> id) {
|
||||
using DOMProxyShadowsResult = JS::DOMProxyShadowsResult;
|
||||
|
||||
JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
|
||||
JS::Value v = js::GetProxyPrivate(proxy);
|
||||
bool isOverrideBuiltins = !v.isObject() && !v.isUndefined();
|
||||
if (expando) {
|
||||
bool hasOwn;
|
||||
if (!JS_AlreadyHasOwnPropertyById(cx, expando, id, &hasOwn))
|
||||
return js::ShadowCheckFailed;
|
||||
return DOMProxyShadowsResult::ShadowCheckFailed;
|
||||
|
||||
if (hasOwn) {
|
||||
return isOverrideBuiltins ? js::ShadowsViaIndirectExpando
|
||||
: js::ShadowsViaDirectExpando;
|
||||
return isOverrideBuiltins
|
||||
? DOMProxyShadowsResult::ShadowsViaIndirectExpando
|
||||
: DOMProxyShadowsResult::ShadowsViaDirectExpando;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isOverrideBuiltins) {
|
||||
// Our expando, if any, didn't shadow, so we're not shadowing at all.
|
||||
return js::DoesntShadow;
|
||||
return DOMProxyShadowsResult::DoesntShadow;
|
||||
}
|
||||
|
||||
bool hasOwn;
|
||||
if (!GetProxyHandler(proxy)->hasOwn(cx, proxy, id, &hasOwn))
|
||||
return js::ShadowCheckFailed;
|
||||
return DOMProxyShadowsResult::ShadowCheckFailed;
|
||||
|
||||
return hasOwn ? js::Shadows : js::DoesntShadowUnique;
|
||||
return hasOwn ? DOMProxyShadowsResult::Shadows
|
||||
: DOMProxyShadowsResult::DoesntShadowUnique;
|
||||
}
|
||||
|
||||
// Store the information for the specialized ICs.
|
||||
struct SetDOMProxyInformation {
|
||||
SetDOMProxyInformation() {
|
||||
js::SetDOMProxyInformation((const void*)&DOMProxyHandler::family,
|
||||
JS::SetDOMProxyInformation((const void*)&DOMProxyHandler::family,
|
||||
DOMProxyShadows,
|
||||
&RemoteObjectProxyBase::sCrossOriginProxyFamily);
|
||||
}
|
||||
|
@ -88,7 +93,7 @@ static inline void CheckExpandoObject(JSObject* proxy,
|
|||
}
|
||||
|
||||
static inline void CheckExpandoAndGeneration(
|
||||
JSObject* proxy, js::ExpandoAndGeneration* expandoAndGeneration) {
|
||||
JSObject* proxy, JS::ExpandoAndGeneration* expandoAndGeneration) {
|
||||
#ifdef DEBUG
|
||||
JS::Value value = expandoAndGeneration->expando;
|
||||
if (!value.isUndefined()) CheckExpandoObject(proxy, value);
|
||||
|
@ -121,8 +126,8 @@ JSObject* DOMProxyHandler::GetAndClearExpandoObject(JSObject* obj) {
|
|||
if (v.isObject()) {
|
||||
js::SetProxyPrivate(obj, UndefinedValue());
|
||||
} else {
|
||||
js::ExpandoAndGeneration* expandoAndGeneration =
|
||||
static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
|
||||
auto* expandoAndGeneration =
|
||||
static_cast<JS::ExpandoAndGeneration*>(v.toPrivate());
|
||||
v = expandoAndGeneration->expando;
|
||||
if (v.isUndefined()) {
|
||||
return nullptr;
|
||||
|
@ -146,16 +151,14 @@ JSObject* DOMProxyHandler::EnsureExpandoObject(JSContext* cx,
|
|||
return &v.toObject();
|
||||
}
|
||||
|
||||
js::ExpandoAndGeneration* expandoAndGeneration;
|
||||
JS::ExpandoAndGeneration* expandoAndGeneration = nullptr;
|
||||
if (!v.isUndefined()) {
|
||||
expandoAndGeneration =
|
||||
static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
|
||||
static_cast<JS::ExpandoAndGeneration*>(v.toPrivate());
|
||||
CheckExpandoAndGeneration(obj, expandoAndGeneration);
|
||||
if (expandoAndGeneration->expando.isObject()) {
|
||||
return &expandoAndGeneration->expando.toObject();
|
||||
}
|
||||
} else {
|
||||
expandoAndGeneration = nullptr;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> expando(
|
||||
|
@ -299,8 +302,8 @@ JSObject* DOMProxyHandler::GetExpandoObject(JSObject* obj) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
js::ExpandoAndGeneration* expandoAndGeneration =
|
||||
static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
|
||||
auto* expandoAndGeneration =
|
||||
static_cast<JS::ExpandoAndGeneration*>(v.toPrivate());
|
||||
CheckExpandoAndGeneration(obj, expandoAndGeneration);
|
||||
|
||||
v = expandoAndGeneration->expando;
|
||||
|
@ -318,8 +321,8 @@ void ShadowingDOMProxyHandler::trace(JSTracer* trc, JSObject* proxy) const {
|
|||
// so it cannot be |undefined|.
|
||||
MOZ_ASSERT(!v.isUndefined());
|
||||
|
||||
js::ExpandoAndGeneration* expandoAndGeneration =
|
||||
static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
|
||||
auto* expandoAndGeneration =
|
||||
static_cast<JS::ExpandoAndGeneration*>(v.toPrivate());
|
||||
JS::TraceEdge(trc, &expandoAndGeneration->expando,
|
||||
"Shadowing DOM proxy expando");
|
||||
}
|
||||
|
|
|
@ -30,10 +30,10 @@ namespace dom {
|
|||
* interface is annotated with the [OverrideBuiltins] extended attribute.
|
||||
*
|
||||
* If it is, the proxy is initialized with a PrivateValue, which contains a
|
||||
* pointer to a js::ExpandoAndGeneration object; this contains a pointer to
|
||||
* pointer to a JS::ExpandoAndGeneration object; this contains a pointer to
|
||||
* the actual expando object as well as the "generation" of the object. The
|
||||
* proxy handler will trace the expando object stored in the
|
||||
* js::ExpandoAndGeneration while the proxy itself is alive.
|
||||
* JS::ExpandoAndGeneration while the proxy itself is alive.
|
||||
*
|
||||
* If it is not, the proxy is initialized with an UndefinedValue. In
|
||||
* EnsureExpandoObject, it is set to an ObjectValue that points to the
|
||||
|
@ -156,7 +156,7 @@ class DOMProxyHandler : public BaseDOMProxyHandler {
|
|||
};
|
||||
|
||||
// Class used by shadowing handlers (the ones that have [OverrideBuiltins].
|
||||
// This handles tracing the expando in ExpandoAndGeneration.
|
||||
// This handles tracing the expando in JS::ExpandoAndGeneration.
|
||||
class ShadowingDOMProxyHandler : public DOMProxyHandler {
|
||||
virtual void trace(JSTracer* trc, JSObject* proxy) const override;
|
||||
};
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "nsInterfaceHashtable.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "jsfriendapi.h" // For js::ExpandoAndGeneration
|
||||
#include "js/friend/DOMProxy.h" // JS::ExpandoAndGeneration
|
||||
|
||||
class nsIMutableArray;
|
||||
class nsIURI;
|
||||
|
@ -398,7 +398,7 @@ class HTMLFormElement final : public nsGenericHTMLElement,
|
|||
nsIContent* aForm);
|
||||
#endif
|
||||
|
||||
js::ExpandoAndGeneration mExpandoAndGeneration;
|
||||
JS::ExpandoAndGeneration mExpandoAndGeneration;
|
||||
|
||||
protected:
|
||||
virtual JSObject* WrapNode(JSContext* aCx,
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
#include "nsString.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "jsfriendapi.h" // For js::ExpandoAndGeneration
|
||||
#include "js/friend/DOMProxy.h" // JS::ExpandoAndGeneration
|
||||
#include "js/RootingAPI.h" // JS::Handle
|
||||
|
||||
namespace mozilla {
|
||||
class ErrorResult;
|
||||
|
@ -44,7 +45,7 @@ class nsDOMStringMap : public nsStubMutationObserver, public nsWrapperCache {
|
|||
void NamedDeleter(const nsAString& aProp, bool& found);
|
||||
void GetSupportedNames(nsTArray<nsString>& aNames);
|
||||
|
||||
js::ExpandoAndGeneration mExpandoAndGeneration;
|
||||
JS::ExpandoAndGeneration mExpandoAndGeneration;
|
||||
|
||||
private:
|
||||
virtual ~nsDOMStringMap();
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: set ts=8 sts=2 et sw=2 tw=80:
|
||||
* 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/. */
|
||||
|
||||
/*
|
||||
* Specify information about DOMProxy proxies in the DOM, for use by ICs.
|
||||
*
|
||||
* Embedders who don't need to define particularly high-performance proxies that
|
||||
* can have random properties added to them can ignore this header.
|
||||
*/
|
||||
|
||||
#ifndef js_friend_DOMProxy_h
|
||||
#define js_friend_DOMProxy_h
|
||||
|
||||
#include <stddef.h> // size_t
|
||||
#include <stdint.h> // uint64_t
|
||||
|
||||
#include "jstypes.h" // JS_FRIEND_API
|
||||
|
||||
#include "js/Id.h" // JS::PropertyKey
|
||||
#include "js/RootingAPI.h" // JS::Handle, JS::Heap
|
||||
#include "js/Value.h" // JS::UndefinedValue, JS::Value
|
||||
|
||||
struct JS_PUBLIC_API JSContext;
|
||||
class JS_PUBLIC_API JSObject;
|
||||
|
||||
namespace JS {
|
||||
|
||||
/*
|
||||
* The DOMProxyShadowsCheck function will be called to check if the property for
|
||||
* id should be gotten from the prototype, or if there is an own property that
|
||||
* shadows it.
|
||||
* * If ShadowsViaDirectExpando is returned, then the slot at
|
||||
* listBaseExpandoSlot contains an expando object which has the property in
|
||||
* question.
|
||||
* * If ShadowsViaIndirectExpando is returned, then the slot at
|
||||
* listBaseExpandoSlot contains a private pointer to an ExpandoAndGeneration
|
||||
* and the expando object in the ExpandoAndGeneration has the property in
|
||||
* question.
|
||||
* * If DoesntShadow is returned then the slot at listBaseExpandoSlot should
|
||||
* either be undefined or point to an expando object that would contain the
|
||||
* own property.
|
||||
* * If DoesntShadowUnique is returned then the slot at listBaseExpandoSlot
|
||||
* should contain a private pointer to a ExpandoAndGeneration, which contains
|
||||
* a JS::Value that should either be undefined or point to an expando object,
|
||||
* and a uint64 value. If that value changes then the IC for getting a
|
||||
* property will be invalidated.
|
||||
* * If Shadows is returned, that means the property is an own property of the
|
||||
* proxy but doesn't live on the expando object.
|
||||
*/
|
||||
|
||||
struct ExpandoAndGeneration {
|
||||
ExpandoAndGeneration() : expando(JS::UndefinedValue()), generation(0) {}
|
||||
|
||||
void OwnerUnlinked() { ++generation; }
|
||||
|
||||
static constexpr size_t offsetOfExpando() {
|
||||
return offsetof(ExpandoAndGeneration, expando);
|
||||
}
|
||||
|
||||
static constexpr size_t offsetOfGeneration() {
|
||||
return offsetof(ExpandoAndGeneration, generation);
|
||||
}
|
||||
|
||||
Heap<Value> expando;
|
||||
uint64_t generation;
|
||||
};
|
||||
|
||||
enum class DOMProxyShadowsResult {
|
||||
ShadowCheckFailed,
|
||||
Shadows,
|
||||
DoesntShadow,
|
||||
DoesntShadowUnique,
|
||||
ShadowsViaDirectExpando,
|
||||
ShadowsViaIndirectExpando
|
||||
};
|
||||
|
||||
using DOMProxyShadowsCheck = DOMProxyShadowsResult (*)(JSContext*,
|
||||
Handle<JSObject*>,
|
||||
Handle<JS::PropertyKey>);
|
||||
|
||||
extern JS_FRIEND_API void SetDOMProxyInformation(
|
||||
const void* domProxyHandlerFamily,
|
||||
DOMProxyShadowsCheck domProxyShadowsCheck,
|
||||
const void* domRemoteProxyHandlerFamily);
|
||||
|
||||
} // namespace JS
|
||||
|
||||
#endif // js_friend_DOMProxy_h
|
|
@ -163,7 +163,7 @@ const WHITELIST_TYPES: &'static [&'static str] = &[
|
|||
"JS::RealmOptions",
|
||||
"JS::ContextOptions",
|
||||
"js::DOMCallbacks",
|
||||
"js::DOMProxyShadowsResult",
|
||||
"JS::DOMProxyShadowsResult",
|
||||
"js::ESClass",
|
||||
"JS::ForOfIterator",
|
||||
"JS::Handle",
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "jit/SharedICHelpers.h"
|
||||
#include "jit/VMFunctions.h"
|
||||
#include "js/experimental/JitInfo.h" // JSJitInfo
|
||||
#include "js/friend/DOMProxy.h" // JS::ExpandoAndGeneration
|
||||
#include "proxy/DeadObjectProxy.h"
|
||||
#include "proxy/Proxy.h"
|
||||
#include "util/Unicode.h"
|
||||
|
@ -26,6 +27,8 @@ using namespace js::jit;
|
|||
|
||||
using mozilla::Maybe;
|
||||
|
||||
using JS::ExpandoAndGeneration;
|
||||
|
||||
namespace js {
|
||||
namespace jit {
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "jit/ICState.h"
|
||||
#include "jit/SharedICRegisters.h"
|
||||
#include "js/GCVector.h"
|
||||
#include "proxy/DOMProxy.h" // js::GetDOMProxyHandlerFamily
|
||||
#include "vm/ArrayObject.h"
|
||||
#include "vm/BytecodeUtil.h"
|
||||
#include "vm/JSContext.h"
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "jit/Ion.h" // IsIonEnabled
|
||||
#include "jit/JitContext.h"
|
||||
#include "js/experimental/JitInfo.h" // JSJitInfo
|
||||
#include "js/friend/DOMProxy.h" // JS::ExpandoAndGeneration
|
||||
#include "js/friend/WindowProxy.h" // js::IsWindow, js::IsWindowProxy, js::ToWindowIfWindowProxy
|
||||
#include "js/friend/XrayJitInfo.h" // js::jit::GetXrayJitInfo, JS::XrayJitInfo
|
||||
#include "js/ScalarType.h" // js::Scalar::Type
|
||||
|
@ -45,6 +46,9 @@ using namespace js::jit;
|
|||
using mozilla::DebugOnly;
|
||||
using mozilla::Maybe;
|
||||
|
||||
using JS::DOMProxyShadowsResult;
|
||||
using JS::ExpandoAndGeneration;
|
||||
|
||||
const char* const js::jit::CacheKindNames[] = {
|
||||
#define DEFINE_KIND(kind) #kind,
|
||||
CACHE_IR_KINDS(DEFINE_KIND)
|
||||
|
@ -271,20 +275,21 @@ static ProxyStubType GetProxyStubType(JSContext* cx, HandleObject obj,
|
|||
}
|
||||
|
||||
DOMProxyShadowsResult shadows = GetDOMProxyShadowsCheck()(cx, obj, id);
|
||||
if (shadows == ShadowCheckFailed) {
|
||||
if (shadows == DOMProxyShadowsResult::ShadowCheckFailed) {
|
||||
cx->clearPendingException();
|
||||
return ProxyStubType::None;
|
||||
}
|
||||
|
||||
if (DOMProxyIsShadowing(shadows)) {
|
||||
if (shadows == ShadowsViaDirectExpando ||
|
||||
shadows == ShadowsViaIndirectExpando) {
|
||||
if (shadows == DOMProxyShadowsResult::ShadowsViaDirectExpando ||
|
||||
shadows == DOMProxyShadowsResult::ShadowsViaIndirectExpando) {
|
||||
return ProxyStubType::DOMExpando;
|
||||
}
|
||||
return ProxyStubType::DOMShadowed;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(shadows == DoesntShadow || shadows == DoesntShadowUnique);
|
||||
MOZ_ASSERT(shadows == DOMProxyShadowsResult::DoesntShadow ||
|
||||
shadows == DOMProxyShadowsResult::DoesntShadowUnique);
|
||||
return ProxyStubType::DOMUnshadowed;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "jit/IonIC.h"
|
||||
#include "jit/SharedICHelpers.h"
|
||||
#include "jit/SharedICRegisters.h"
|
||||
#include "js/friend/DOMProxy.h" // JS::ExpandoAndGeneration
|
||||
#include "js/friend/XrayJitInfo.h" // js::jit::GetXrayJitInfo
|
||||
#include "js/ScalarType.h" // js::Scalar::Type
|
||||
#include "proxy/Proxy.h"
|
||||
|
@ -47,6 +48,8 @@ using namespace js::jit;
|
|||
using mozilla::BitwiseCast;
|
||||
using mozilla::Maybe;
|
||||
|
||||
using JS::ExpandoAndGeneration;
|
||||
|
||||
ValueOperand CacheRegisterAllocator::useValueRegister(MacroAssembler& masm,
|
||||
ValOperandId op) {
|
||||
OperandLocation& loc = operandLocations_[op.id()];
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "jit/Linker.h"
|
||||
#include "jit/SharedICHelpers.h"
|
||||
#include "jit/VMFunctions.h"
|
||||
#include "js/friend/DOMProxy.h" // JS::ExpandoAndGeneration
|
||||
#include "proxy/DeadObjectProxy.h"
|
||||
#include "proxy/Proxy.h"
|
||||
#include "util/Memory.h"
|
||||
|
@ -33,6 +34,8 @@ using namespace js::jit;
|
|||
using mozilla::DebugOnly;
|
||||
using mozilla::Maybe;
|
||||
|
||||
using JS::ExpandoAndGeneration;
|
||||
|
||||
namespace js {
|
||||
namespace jit {
|
||||
|
||||
|
|
|
@ -735,34 +735,6 @@ JS_FRIEND_API const DOMCallbacks* js::GetDOMCallbacks(JSContext* cx) {
|
|||
return cx->runtime()->DOMcallbacks;
|
||||
}
|
||||
|
||||
static const void* gDOMProxyHandlerFamily = nullptr;
|
||||
static DOMProxyShadowsCheck gDOMProxyShadowsCheck;
|
||||
static const void* gDOMRemoteProxyHandlerFamily = nullptr;
|
||||
|
||||
JS_FRIEND_API void js::SetDOMProxyInformation(
|
||||
const void* domProxyHandlerFamily,
|
||||
DOMProxyShadowsCheck domProxyShadowsCheck,
|
||||
const void* domRemoteProxyHandlerFamily) {
|
||||
gDOMProxyHandlerFamily = domProxyHandlerFamily;
|
||||
gDOMProxyShadowsCheck = domProxyShadowsCheck;
|
||||
gDOMRemoteProxyHandlerFamily = domRemoteProxyHandlerFamily;
|
||||
}
|
||||
|
||||
const void* js::GetDOMProxyHandlerFamily() { return gDOMProxyHandlerFamily; }
|
||||
|
||||
DOMProxyShadowsCheck js::GetDOMProxyShadowsCheck() {
|
||||
return gDOMProxyShadowsCheck;
|
||||
}
|
||||
|
||||
const void* js::GetDOMRemoteProxyHandlerFamily() {
|
||||
return gDOMRemoteProxyHandlerFamily;
|
||||
}
|
||||
|
||||
JS_FRIEND_API bool js::IsDOMRemoteProxyObject(JSObject* object) {
|
||||
return js::IsProxy(object) && js::GetProxyHandler(object)->family() ==
|
||||
js::GetDOMRemoteProxyHandlerFamily();
|
||||
}
|
||||
|
||||
JS_FRIEND_API void js::PrepareScriptEnvironmentAndInvoke(
|
||||
JSContext* cx, HandleObject global,
|
||||
ScriptEnvironmentPreparer::Closure& closure) {
|
||||
|
|
|
@ -600,75 +600,6 @@ extern JS_FRIEND_API bool AllowNewWrapper(JS::Compartment* target,
|
|||
|
||||
extern JS_FRIEND_API bool NukedObjectRealm(JSObject* obj);
|
||||
|
||||
/* Specify information about DOMProxy proxies in the DOM, for use by ICs. */
|
||||
|
||||
/*
|
||||
* The DOMProxyShadowsCheck function will be called to check if the property for
|
||||
* id should be gotten from the prototype, or if there is an own property that
|
||||
* shadows it.
|
||||
* * If ShadowsViaDirectExpando is returned, then the slot at
|
||||
* listBaseExpandoSlot contains an expando object which has the property in
|
||||
* question.
|
||||
* * If ShadowsViaIndirectExpando is returned, then the slot at
|
||||
* listBaseExpandoSlot contains a private pointer to an ExpandoAndGeneration
|
||||
* and the expando object in the ExpandoAndGeneration has the property in
|
||||
* question.
|
||||
* * If DoesntShadow is returned then the slot at listBaseExpandoSlot should
|
||||
* either be undefined or point to an expando object that would contain the
|
||||
* own property.
|
||||
* * If DoesntShadowUnique is returned then the slot at listBaseExpandoSlot
|
||||
* should contain a private pointer to a ExpandoAndGeneration, which contains
|
||||
* a JS::Value that should either be undefined or point to an expando object,
|
||||
* and a uint64 value. If that value changes then the IC for getting a
|
||||
* property will be invalidated.
|
||||
* * If Shadows is returned, that means the property is an own property of the
|
||||
* proxy but doesn't live on the expando object.
|
||||
*/
|
||||
|
||||
struct ExpandoAndGeneration {
|
||||
ExpandoAndGeneration() : expando(JS::UndefinedValue()), generation(0) {}
|
||||
|
||||
void OwnerUnlinked() { ++generation; }
|
||||
|
||||
static size_t offsetOfExpando() {
|
||||
return offsetof(ExpandoAndGeneration, expando);
|
||||
}
|
||||
|
||||
static size_t offsetOfGeneration() {
|
||||
return offsetof(ExpandoAndGeneration, generation);
|
||||
}
|
||||
|
||||
JS::Heap<JS::Value> expando;
|
||||
uint64_t generation;
|
||||
};
|
||||
|
||||
typedef enum DOMProxyShadowsResult {
|
||||
ShadowCheckFailed,
|
||||
Shadows,
|
||||
DoesntShadow,
|
||||
DoesntShadowUnique,
|
||||
ShadowsViaDirectExpando,
|
||||
ShadowsViaIndirectExpando
|
||||
} DOMProxyShadowsResult;
|
||||
using DOMProxyShadowsCheck = DOMProxyShadowsResult (*)(JSContext*,
|
||||
JS::HandleObject,
|
||||
JS::HandleId);
|
||||
JS_FRIEND_API void SetDOMProxyInformation(
|
||||
const void* domProxyHandlerFamily,
|
||||
DOMProxyShadowsCheck domProxyShadowsCheck,
|
||||
const void* domRemoteProxyHandlerFamily);
|
||||
|
||||
const void* GetDOMProxyHandlerFamily();
|
||||
DOMProxyShadowsCheck GetDOMProxyShadowsCheck();
|
||||
inline bool DOMProxyIsShadowing(DOMProxyShadowsResult result) {
|
||||
return result == Shadows || result == ShadowsViaDirectExpando ||
|
||||
result == ShadowsViaIndirectExpando;
|
||||
}
|
||||
|
||||
const void* GetDOMRemoteProxyHandlerFamily();
|
||||
|
||||
extern JS_FRIEND_API bool IsDOMRemoteProxyObject(JSObject* object);
|
||||
|
||||
/* Implemented in jsdate.cpp. */
|
||||
|
||||
/** Detect whether the internal date value is NaN. */
|
||||
|
|
|
@ -235,6 +235,7 @@ EXPORTS.js.experimental += [
|
|||
# a clean design. Use this only if you absolutely must, and feel free to
|
||||
# propose clean APIs to replace what's here!
|
||||
EXPORTS.js.friend += [
|
||||
'../public/friend/DOMProxy.h',
|
||||
'../public/friend/DumpFunctions.h',
|
||||
'../public/friend/ErrorMessages.h',
|
||||
'../public/friend/ErrorNumbers.msg',
|
||||
|
@ -326,6 +327,7 @@ UNIFIED_SOURCES += [
|
|||
'proxy/BaseProxyHandler.cpp',
|
||||
'proxy/CrossCompartmentWrapper.cpp',
|
||||
'proxy/DeadObjectProxy.cpp',
|
||||
'proxy/DOMProxy.cpp',
|
||||
'proxy/OpaqueCrossCompartmentWrapper.cpp',
|
||||
'proxy/Proxy.cpp',
|
||||
'proxy/ScriptedProxyHandler.cpp',
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: set ts=8 sts=2 et sw=2 tw=80:
|
||||
* 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/. */
|
||||
|
||||
/* DOM proxy-related functionality, including expando support. */
|
||||
|
||||
#include "js/friend/DOMProxy.h" // JS::DOMProxyShadowsCheck
|
||||
#include "proxy/DOMProxy.h"
|
||||
|
||||
#include "js/Proxy.h" // js::GetProxyHandler, js::IsProxy
|
||||
|
||||
using JS::DOMProxyShadowsCheck;
|
||||
|
||||
static const void* gDOMProxyHandlerFamily = nullptr;
|
||||
static DOMProxyShadowsCheck gDOMProxyShadowsCheck = nullptr;
|
||||
static const void* gDOMRemoteProxyHandlerFamily = nullptr;
|
||||
|
||||
void JS::SetDOMProxyInformation(const void* domProxyHandlerFamily,
|
||||
DOMProxyShadowsCheck domProxyShadowsCheck,
|
||||
const void* domRemoteProxyHandlerFamily) {
|
||||
gDOMProxyHandlerFamily = domProxyHandlerFamily;
|
||||
gDOMProxyShadowsCheck = domProxyShadowsCheck;
|
||||
gDOMRemoteProxyHandlerFamily = domRemoteProxyHandlerFamily;
|
||||
}
|
||||
|
||||
const void* js::GetDOMProxyHandlerFamily() { return gDOMProxyHandlerFamily; }
|
||||
|
||||
DOMProxyShadowsCheck js::GetDOMProxyShadowsCheck() {
|
||||
return gDOMProxyShadowsCheck;
|
||||
}
|
||||
|
||||
const void* js::GetDOMRemoteProxyHandlerFamily() {
|
||||
return gDOMRemoteProxyHandlerFamily;
|
||||
}
|
||||
|
||||
bool js::IsDOMRemoteProxyObject(JSObject* object) {
|
||||
return js::IsProxy(object) && js::GetProxyHandler(object)->family() ==
|
||||
js::GetDOMRemoteProxyHandlerFamily();
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: set ts=8 sts=2 et sw=2 tw=80:
|
||||
* 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/. */
|
||||
|
||||
/* DOM proxy details that don't need to be exported as friend API. */
|
||||
|
||||
#ifndef proxy_DOMProxy_h
|
||||
#define proxy_DOMProxy_h
|
||||
|
||||
#include "js/friend/DOMProxy.h" // JS::DOMProxyShadowsCheck
|
||||
|
||||
class JS_PUBLIC_API JSObject;
|
||||
|
||||
namespace js {
|
||||
|
||||
extern const void* GetDOMProxyHandlerFamily();
|
||||
|
||||
extern JS::DOMProxyShadowsCheck GetDOMProxyShadowsCheck();
|
||||
|
||||
inline bool DOMProxyIsShadowing(JS::DOMProxyShadowsResult result) {
|
||||
return result == JS::DOMProxyShadowsResult::Shadows ||
|
||||
result == JS::DOMProxyShadowsResult::ShadowsViaDirectExpando ||
|
||||
result == JS::DOMProxyShadowsResult::ShadowsViaIndirectExpando;
|
||||
}
|
||||
|
||||
extern const void* GetDOMRemoteProxyHandlerFamily();
|
||||
|
||||
extern bool IsDOMRemoteProxyObject(JSObject* object);
|
||||
|
||||
} // namespace js
|
||||
|
||||
#endif // proxy_DOMProxy_h
|
Загрузка…
Ссылка в новой задаче