mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-06-25 20:29:33 +00:00
134 lines
4.3 KiB
C++
134 lines
4.3 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef vm_ProxyObject_h
|
|
#define vm_ProxyObject_h
|
|
|
|
#include "js/Proxy.h"
|
|
#include "vm/NativeObject.h"
|
|
|
|
namespace js {
|
|
|
|
// This is the base class for the various kinds of proxy objects. It's never
|
|
// instantiated.
|
|
class ProxyObject : public JSObject
|
|
{
|
|
HeapPtrShape shape;
|
|
|
|
// GetProxyDataLayout computes the address of this field.
|
|
ProxyDataLayout data;
|
|
|
|
void static_asserts() {
|
|
static_assert(sizeof(ProxyObject) == sizeof(JSObject_Slots0),
|
|
"proxy object size must match GC thing size");
|
|
static_assert(offsetof(ProxyObject, data) == ProxyDataOffset,
|
|
"proxy object layout must match shadow interface");
|
|
}
|
|
|
|
public:
|
|
static ProxyObject* New(JSContext* cx, const BaseProxyHandler* handler, HandleValue priv,
|
|
TaggedProto proto_, const ProxyOptions& options);
|
|
|
|
const Value& private_() {
|
|
return GetProxyPrivate(this);
|
|
}
|
|
|
|
void setCrossCompartmentPrivate(const Value& priv);
|
|
void setSameCompartmentPrivate(const Value& priv);
|
|
|
|
HeapValue* slotOfPrivate() {
|
|
return reinterpret_cast<HeapValue*>(&GetProxyDataLayout(this)->values->privateSlot);
|
|
}
|
|
|
|
JSObject* target() const {
|
|
return const_cast<ProxyObject*>(this)->private_().toObjectOrNull();
|
|
}
|
|
|
|
const BaseProxyHandler* handler() const {
|
|
return GetProxyHandler(const_cast<ProxyObject*>(this));
|
|
}
|
|
|
|
void setHandler(const BaseProxyHandler* handler) {
|
|
SetProxyHandler(this, handler);
|
|
}
|
|
|
|
static size_t offsetOfValues() {
|
|
return offsetof(ProxyObject, data.values);
|
|
}
|
|
static size_t offsetOfHandler() {
|
|
return offsetof(ProxyObject, data.handler);
|
|
}
|
|
static size_t offsetOfExtraSlotInValues(size_t slot) {
|
|
MOZ_ASSERT(slot < PROXY_EXTRA_SLOTS);
|
|
return offsetof(ProxyValueArray, extraSlots) + slot * sizeof(Value);
|
|
}
|
|
|
|
const Value& extra(size_t n) const {
|
|
return GetProxyExtra(const_cast<ProxyObject*>(this), n);
|
|
}
|
|
|
|
void setExtra(size_t n, const Value& extra) {
|
|
SetProxyExtra(this, n, extra);
|
|
}
|
|
|
|
private:
|
|
HeapValue* slotOfExtra(size_t n) {
|
|
MOZ_ASSERT(n < PROXY_EXTRA_SLOTS);
|
|
return reinterpret_cast<HeapValue*>(&GetProxyDataLayout(this)->values->extraSlots[n]);
|
|
}
|
|
|
|
static bool isValidProxyClass(const Class* clasp) {
|
|
// Since we can take classes from the outside, make sure that they
|
|
// are "sane". They have to quack enough like proxies for us to belive
|
|
// they should be treated as such.
|
|
|
|
// proxy_Trace is just a trivial wrapper around ProxyObject::trace for
|
|
// friend api exposure.
|
|
|
|
// Proxy classes are not allowed to have call or construct hooks directly. Their
|
|
// callability is instead decided by handler()->isCallable().
|
|
return clasp->isProxy() &&
|
|
clasp->trace == proxy_Trace &&
|
|
!clasp->call && !clasp->construct;
|
|
}
|
|
|
|
public:
|
|
static unsigned grayLinkExtraSlot(JSObject* obj);
|
|
|
|
void renew(JSContext* cx, const BaseProxyHandler* handler, Value priv);
|
|
|
|
static void trace(JSTracer* trc, JSObject* obj);
|
|
|
|
void nuke();
|
|
|
|
// There is no class_ member to force specialization of JSObject::is<T>().
|
|
// The implementation in JSObject is incorrect for proxies since it doesn't
|
|
// take account of the handler type.
|
|
static const Class proxyClass;
|
|
};
|
|
|
|
bool IsDerivedProxyObject(const JSObject* obj, const js::BaseProxyHandler* handler);
|
|
|
|
} // namespace js
|
|
|
|
template<>
|
|
inline bool
|
|
JSObject::is<js::ProxyObject>() const
|
|
{
|
|
// Note: this method is implemented in terms of the IsProxy() friend API
|
|
// functions to ensure the implementations are tied together.
|
|
// Note 2: this specialization isn't used for subclasses of ProxyObject
|
|
// which must supply their own implementation.
|
|
return js::IsProxy(const_cast<JSObject*>(this));
|
|
}
|
|
|
|
inline bool
|
|
js::IsDerivedProxyObject(const JSObject* obj, const js::BaseProxyHandler* handler) {
|
|
return obj->is<js::ProxyObject>() && obj->as<js::ProxyObject>().handler() == handler;
|
|
}
|
|
|
|
#endif /* vm_ProxyObject_h */
|