mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 07:13:20 +00:00
Bug 1694040 - Use JSObject::is<ProxyObject> in more places. r=jandem
Also replace JSClass::isProxy with isProxyObject and clarify that the flag indicates primarily that the JSObject is of type js::ProxyObject. In DOM binding code, prefer checks for NativeObject rather than !ProxyObject where that is what we really meant. Differential Revision: https://phabricator.services.mozilla.com/D105884
This commit is contained in:
parent
4f0b11e2f5
commit
bf2062a7c7
@ -1144,14 +1144,15 @@ bool TryPreserveWrapper(JS::Handle<JSObject*> obj) {
|
||||
|
||||
// The addProperty hook for WebIDL classes does wrapper preservation, and
|
||||
// nothing else, so call it, if present.
|
||||
const DOMJSClass* domClass = GetDOMClass(obj);
|
||||
const JSClass* clasp = domClass->ToJSClass();
|
||||
JSAddPropertyOp addProperty = clasp->getAddProperty();
|
||||
|
||||
const JSClass* clasp = JS::GetClass(obj);
|
||||
const DOMJSClass* domClass = GetDOMClass(clasp);
|
||||
|
||||
// We expect all proxies to be nsISupports.
|
||||
MOZ_RELEASE_ASSERT(!clasp->isProxy(),
|
||||
MOZ_RELEASE_ASSERT(clasp->isNativeObject(),
|
||||
"Should not call addProperty for proxies.");
|
||||
|
||||
JSAddPropertyOp addProperty = clasp->getAddProperty();
|
||||
if (!addProperty) {
|
||||
return true;
|
||||
}
|
||||
@ -1172,10 +1173,11 @@ bool HasReleasedWrapper(JS::Handle<JSObject*> obj) {
|
||||
if (nsISupports* native = UnwrapDOMObjectToISupports(obj)) {
|
||||
CallQueryInterface(native, &cache);
|
||||
} else {
|
||||
const DOMJSClass* domClass = GetDOMClass(obj);
|
||||
const JSClass* clasp = JS::GetClass(obj);
|
||||
const DOMJSClass* domClass = GetDOMClass(clasp);
|
||||
|
||||
// We expect all proxies to be nsISupports.
|
||||
MOZ_RELEASE_ASSERT(!domClass->ToJSClass()->isProxy(),
|
||||
MOZ_RELEASE_ASSERT(clasp->isNativeObject(),
|
||||
"Should not call getWrapperCache for proxies.");
|
||||
|
||||
WrapperCacheGetter getter = domClass->mWrapperCacheGetter;
|
||||
|
@ -94,7 +94,7 @@ inline bool IsDOMClass(const JSClass* clasp) {
|
||||
|
||||
// Return true if the JSClass is used for non-proxy DOM objects.
|
||||
inline bool IsNonProxyDOMClass(const JSClass* clasp) {
|
||||
return IsDOMClass(clasp) && !clasp->isProxy();
|
||||
return IsDOMClass(clasp) && clasp->isNativeObject();
|
||||
}
|
||||
|
||||
// Returns true if the JSClass is used for DOM interface and interface
|
||||
|
@ -163,8 +163,7 @@ class ShadowingDOMProxyHandler : public DOMProxyHandler {
|
||||
};
|
||||
|
||||
inline bool IsDOMProxy(JSObject* obj) {
|
||||
const JSClass* clasp = JS::GetClass(obj);
|
||||
return clasp->isProxy() &&
|
||||
return js::IsProxy(obj) &&
|
||||
js::GetProxyHandler(obj)->family() == &DOMProxyHandler::family;
|
||||
}
|
||||
|
||||
|
@ -790,7 +790,19 @@ struct alignas(js::gc::JSClassAlignBytes) JSClass {
|
||||
*/
|
||||
static const uint32_t NON_NATIVE = JSCLASS_INTERNAL_FLAG2;
|
||||
|
||||
// A JSObject created from a JSClass extends from one of:
|
||||
// - js::NativeObject
|
||||
// - js::ProxyObject
|
||||
//
|
||||
// While it is possible to introduce new families of objects, it is strongly
|
||||
// discouraged. The JITs would be entirely unable to optimize them and testing
|
||||
// coverage is low. The existing NativeObject and ProxyObject are extremely
|
||||
// flexible and are able to represent the entire Gecko embedding requirements.
|
||||
//
|
||||
// NOTE: Internal to SpiderMonkey, there is an experimental js::TypedObject
|
||||
// object family for future WASM features.
|
||||
bool isNativeObject() const { return !(flags & NON_NATIVE); }
|
||||
bool isProxyObject() const { return flags & JSCLASS_IS_PROXY; }
|
||||
|
||||
bool hasPrivate() const { return !!(flags & JSCLASS_HAS_PRIVATE); }
|
||||
|
||||
@ -799,14 +811,12 @@ struct alignas(js::gc::JSClassAlignBytes) JSClass {
|
||||
bool isJSFunction() const { return this == js::FunctionClassPtr; }
|
||||
|
||||
bool nonProxyCallable() const {
|
||||
MOZ_ASSERT(!isProxy());
|
||||
MOZ_ASSERT(!isProxyObject());
|
||||
return isJSFunction() || getCall();
|
||||
}
|
||||
|
||||
bool isGlobal() const { return flags & JSCLASS_IS_GLOBAL; }
|
||||
|
||||
bool isProxy() const { return flags & JSCLASS_IS_PROXY; }
|
||||
|
||||
bool isDOMClass() const { return flags & JSCLASS_IS_DOMJSCLASS; }
|
||||
|
||||
bool shouldDelayMetadataBuilder() const {
|
||||
|
@ -371,7 +371,7 @@ class JS_FRIEND_API BaseProxyHandler {
|
||||
extern JS_FRIEND_DATA const JSClass ProxyClass;
|
||||
|
||||
inline bool IsProxy(const JSObject* obj) {
|
||||
return JS::GetClass(obj)->isProxy();
|
||||
return JS::GetClass(obj)->isProxyObject();
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
@ -546,7 +546,7 @@ static MOZ_ALWAYS_INLINE JSString* GetBuiltinTagFast(JSObject* obj,
|
||||
const JSClass* clasp,
|
||||
JSContext* cx) {
|
||||
MOZ_ASSERT(clasp == obj->getClass());
|
||||
MOZ_ASSERT(!clasp->isProxy());
|
||||
MOZ_ASSERT(!clasp->isProxyObject());
|
||||
|
||||
// Optimize the non-proxy case to bypass GetBuiltinClass.
|
||||
if (clasp == &PlainObject::class_) {
|
||||
@ -674,7 +674,7 @@ bool js::obj_toString(JSContext* cx, unsigned argc, Value* vp) {
|
||||
// When |obj| is a non-proxy object, compute |builtinTag| only when needed.
|
||||
RootedString builtinTag(cx);
|
||||
const JSClass* clasp = obj->getClass();
|
||||
if (MOZ_UNLIKELY(clasp->isProxy())) {
|
||||
if (MOZ_UNLIKELY(clasp->isProxyObject())) {
|
||||
builtinTag = GetBuiltinTagSlow(cx, obj);
|
||||
if (!builtinTag) {
|
||||
return false;
|
||||
|
@ -826,7 +826,7 @@ bool CDataArrayProxyHandler::set(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
}
|
||||
|
||||
static JSObject* MaybeUnwrapArrayWrapper(JSObject* obj) {
|
||||
if (IsProxy(obj) &&
|
||||
if (obj->is<ProxyObject>() &&
|
||||
obj->as<ProxyObject>().handler() == &CDataArrayProxyHandler::singleton) {
|
||||
return obj->as<ProxyObject>().target();
|
||||
}
|
||||
|
@ -411,8 +411,8 @@ JSObject* js::Nursery::allocateObject(JSContext* cx, size_t size,
|
||||
MOZ_ASSERT(size >= sizeof(RelocationOverlay));
|
||||
|
||||
// Sanity check the finalizer.
|
||||
MOZ_ASSERT_IF(clasp->hasFinalize(),
|
||||
CanNurseryAllocateFinalizedClass(clasp) || clasp->isProxy());
|
||||
MOZ_ASSERT_IF(clasp->hasFinalize(), CanNurseryAllocateFinalizedClass(clasp) ||
|
||||
clasp->isProxyObject());
|
||||
|
||||
auto* obj = reinterpret_cast<JSObject*>(
|
||||
allocateCell(cx->zone(), size, JS::TraceKind::Object));
|
||||
|
@ -36,7 +36,8 @@ static inline AllocKind GetGCObjectKind(const JSClass* clasp) {
|
||||
return AllocKind::FUNCTION;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!clasp->isProxy(), "Proxies should use GetProxyGCObjectKind");
|
||||
MOZ_ASSERT(!clasp->isProxyObject(),
|
||||
"Proxies should use GetProxyGCObjectKind");
|
||||
|
||||
uint32_t nslots = JSCLASS_RESERVED_SLOTS(clasp);
|
||||
if (clasp->flags & JSCLASS_HAS_PRIVATE) {
|
||||
|
@ -1005,7 +1005,7 @@ static bool CanAttachDOMCall(JSContext* cx, JSJitInfo::OpType type,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type != JSJitInfo::Method && clasp->isProxy()) {
|
||||
if (type != JSJitInfo::Method && clasp->isProxyObject()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1319,7 +1319,7 @@ static bool GetXrayExpandoShapeWrapper(JSContext* cx, HandleObject xray,
|
||||
AttachDecision GetPropIRGenerator::tryAttachXrayCrossCompartmentWrapper(
|
||||
HandleObject obj, ObjOperandId objId, HandleId id,
|
||||
ValOperandId receiverId) {
|
||||
if (!IsProxy(obj)) {
|
||||
if (!obj->is<ProxyObject>()) {
|
||||
return AttachDecision::NoAction;
|
||||
}
|
||||
|
||||
@ -1357,7 +1357,7 @@ AttachDecision GetPropIRGenerator::tryAttachXrayCrossCompartmentWrapper(
|
||||
cx_->clearPendingException();
|
||||
return AttachDecision::NoAction;
|
||||
}
|
||||
if (!holder || !IsProxy(holder) ||
|
||||
if (!holder || !holder->is<ProxyObject>() ||
|
||||
!info->isCrossCompartmentXray(GetProxyHandler(holder))) {
|
||||
return AttachDecision::NoAction;
|
||||
}
|
||||
@ -5809,7 +5809,7 @@ AttachDecision CallIRGenerator::tryAttachHasClass(HandleFunction callee,
|
||||
MOZ_ASSERT(args_[0].isObject());
|
||||
|
||||
// Only optimize when the object isn't a proxy.
|
||||
if (isPossiblyWrapped && IsProxy(&args_[0].toObject())) {
|
||||
if (isPossiblyWrapped && args_[0].toObject().is<ProxyObject>()) {
|
||||
return AttachDecision::NoAction;
|
||||
}
|
||||
|
||||
|
@ -5223,7 +5223,7 @@ MDefinition* MGuardIsNotProxy::foldsTo(TempAllocator& alloc) {
|
||||
return this;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!GetObjectKnownJSClass(object())->isProxy());
|
||||
MOZ_ASSERT(!GetObjectKnownJSClass(object())->isProxyObject());
|
||||
AssertKnownClass(alloc, this, object());
|
||||
return object();
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ MCall* WarpBuilderShared::makeCall(CallInfo& callInfo, bool needsThisCheck,
|
||||
if (clasp->isNativeObject()) {
|
||||
objKind = DOMObjectKind::Native;
|
||||
} else {
|
||||
MOZ_ASSERT(clasp->isProxy());
|
||||
MOZ_ASSERT(clasp->isProxyObject());
|
||||
objKind = DOMObjectKind::Proxy;
|
||||
}
|
||||
}
|
||||
|
@ -432,7 +432,7 @@ bool js::GetObjectProto(JSContext* cx, JS::Handle<JSObject*> obj,
|
||||
JS::MutableHandle<JSObject*> proto) {
|
||||
cx->check(obj);
|
||||
|
||||
if (IsProxy(obj)) {
|
||||
if (obj->is<ProxyObject>()) {
|
||||
return JS_GetPrototype(cx, obj, proto);
|
||||
}
|
||||
|
||||
@ -453,7 +453,7 @@ JS_FRIEND_API bool js::GetRealmOriginalEval(JSContext* cx,
|
||||
|
||||
void JS::detail::SetReservedSlotWithBarrier(JSObject* obj, size_t slot,
|
||||
const Value& value) {
|
||||
if (IsProxy(obj)) {
|
||||
if (obj->is<ProxyObject>()) {
|
||||
obj->as<ProxyObject>().setReservedSlot(slot, value);
|
||||
} else {
|
||||
obj->as<NativeObject>().setSlot(slot, value);
|
||||
|
@ -236,7 +236,7 @@ inline bool JSObject::hasAllFlags(js::BaseShape::Flag flags) const {
|
||||
}
|
||||
|
||||
inline bool JSObject::nonProxyIsExtensible() const {
|
||||
MOZ_ASSERT(!uninlinedIsProxy());
|
||||
MOZ_ASSERT(!uninlinedIsProxyObject());
|
||||
|
||||
// [[Extensible]] for ordinary non-proxy objects is an object flag.
|
||||
return !hasAllFlags(js::BaseShape::NOT_EXTENSIBLE);
|
||||
|
@ -1467,7 +1467,7 @@ bool js::ObjectMayBeSwapped(const JSObject* obj) {
|
||||
// WindowProxy, Wrapper, DeadProxyObject, DOMProxy, and DOMClass (non-global)
|
||||
// types may be swapped. It is hard to detect DOMProxy from shell, so target
|
||||
// proxies in general.
|
||||
return clasp->isProxy() || clasp->isDOMClass();
|
||||
return clasp->isProxyObject() || clasp->isDOMClass();
|
||||
}
|
||||
|
||||
[[nodiscard]] static bool CopyProxyValuesBeforeSwap(
|
||||
@ -1500,7 +1500,7 @@ bool js::ObjectMayBeSwapped(const JSObject* obj) {
|
||||
|
||||
bool ProxyObject::initExternalValueArrayAfterSwap(
|
||||
JSContext* cx, const HandleValueVector values) {
|
||||
MOZ_ASSERT(getClass()->isProxy());
|
||||
MOZ_ASSERT(getClass()->isProxyObject());
|
||||
|
||||
size_t nreserved = numReservedSlots();
|
||||
|
||||
@ -3322,7 +3322,7 @@ bool JSObject::hasSameRealmAs(JSContext* cx) const {
|
||||
return nonCCWRealm() == cx->realm();
|
||||
}
|
||||
|
||||
bool JSObject::uninlinedIsProxy() const { return is<ProxyObject>(); }
|
||||
bool JSObject::uninlinedIsProxyObject() const { return is<ProxyObject>(); }
|
||||
|
||||
bool JSObject::uninlinedNonProxyIsExtensible() const {
|
||||
return nonProxyIsExtensible();
|
||||
@ -3637,7 +3637,7 @@ js::gc::AllocKind JSObject::allocKindForTenure(
|
||||
}
|
||||
|
||||
// Proxies that are CrossCompartmentWrappers may be nursery allocated.
|
||||
if (IsProxy(this)) {
|
||||
if (is<ProxyObject>()) {
|
||||
return as<ProxyObject>().allocKindForTenure();
|
||||
}
|
||||
|
||||
@ -3924,7 +3924,7 @@ void JSObject::debugCheckNewObject(ObjectGroup* group, Shape* shape,
|
||||
JSCLASS_FOREGROUND_FINALIZE | JSCLASS_BACKGROUND_FINALIZE;
|
||||
uint32_t flags = clasp->flags;
|
||||
uint32_t finalizeFlags = flags & FinalizeMask;
|
||||
if (clasp->hasFinalize() && !clasp->isProxy()) {
|
||||
if (clasp->hasFinalize() && !clasp->isProxyObject()) {
|
||||
MOZ_ASSERT(finalizeFlags == JSCLASS_FOREGROUND_FINALIZE ||
|
||||
finalizeFlags == JSCLASS_BACKGROUND_FINALIZE);
|
||||
MOZ_ASSERT((finalizeFlags == JSCLASS_BACKGROUND_FINALIZE) ==
|
||||
@ -3936,7 +3936,7 @@ void JSObject::debugCheckNewObject(ObjectGroup* group, Shape* shape,
|
||||
MOZ_ASSERT_IF(clasp->hasFinalize(),
|
||||
heap == gc::TenuredHeap ||
|
||||
CanNurseryAllocateFinalizedClass(clasp) ||
|
||||
clasp->isProxy());
|
||||
clasp->isProxyObject());
|
||||
|
||||
MOZ_ASSERT(!group->realm()->hasObjectPendingMetadata());
|
||||
|
||||
@ -3944,7 +3944,7 @@ void JSObject::debugCheckNewObject(ObjectGroup* group, Shape* shape,
|
||||
// slotSpan are always 0. Note that proxy classes can have reserved slots
|
||||
// but they're also not included in numFixedSlots/slotSpan.
|
||||
if (!clasp->isNativeObject()) {
|
||||
MOZ_ASSERT_IF(!clasp->isProxy(), JSCLASS_RESERVED_SLOTS(clasp) == 0);
|
||||
MOZ_ASSERT_IF(!clasp->isProxyObject(), JSCLASS_RESERVED_SLOTS(clasp) == 0);
|
||||
MOZ_ASSERT(!clasp->hasPrivate());
|
||||
MOZ_ASSERT_IF(shape, shape->numFixedSlots() == 0);
|
||||
MOZ_ASSERT_IF(shape, shape->slotSpan() == 0);
|
||||
|
@ -299,7 +299,7 @@ class JSObject
|
||||
|
||||
js::TaggedProto taggedProto() const { return group()->proto(); }
|
||||
|
||||
bool uninlinedIsProxy() const;
|
||||
bool uninlinedIsProxyObject() const;
|
||||
|
||||
JSObject* staticPrototype() const {
|
||||
MOZ_ASSERT(hasStaticPrototype());
|
||||
@ -319,7 +319,7 @@ class JSObject
|
||||
// the wrapper/wrappee [[Prototype]]s consistent.)
|
||||
bool hasDynamicPrototype() const {
|
||||
bool dynamic = taggedProto().isDynamic();
|
||||
MOZ_ASSERT_IF(dynamic, uninlinedIsProxy());
|
||||
MOZ_ASSERT_IF(dynamic, uninlinedIsProxyObject());
|
||||
return dynamic;
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ using namespace js;
|
||||
static gc::AllocKind GetProxyGCObjectKind(const JSClass* clasp,
|
||||
const BaseProxyHandler* handler,
|
||||
const Value& priv) {
|
||||
MOZ_ASSERT(clasp->isProxy());
|
||||
MOZ_ASSERT(clasp->isProxyObject());
|
||||
|
||||
uint32_t nreserved = JSCLASS_RESERVED_SLOTS(clasp);
|
||||
|
||||
@ -73,7 +73,7 @@ ProxyObject* ProxyObject::New(JSContext* cx, const BaseProxyHandler* handler,
|
||||
Rooted<TaggedProto> proto(cx, proto_);
|
||||
|
||||
MOZ_ASSERT(!clasp->isNativeObject());
|
||||
MOZ_ASSERT(clasp->isProxy());
|
||||
MOZ_ASSERT(clasp->isProxyObject());
|
||||
MOZ_ASSERT(isValidProxyClass(clasp));
|
||||
MOZ_ASSERT(clasp->shouldDelayMetadataBuilder());
|
||||
MOZ_ASSERT_IF(proto.isObject(),
|
||||
|
@ -122,7 +122,7 @@ class ProxyObject : public JSObject {
|
||||
|
||||
// Proxy classes are not allowed to have call or construct hooks directly.
|
||||
// Their callability is instead decided by handler()->isCallable().
|
||||
return clasp->isProxy() && clasp->isTrace(ProxyObject::trace) &&
|
||||
return clasp->isProxyObject() && clasp->isTrace(ProxyObject::trace) &&
|
||||
!clasp->getCall() && !clasp->getConstruct();
|
||||
}
|
||||
|
||||
@ -138,8 +138,6 @@ class ProxyObject : public JSObject {
|
||||
void nuke();
|
||||
};
|
||||
|
||||
inline bool IsProxyClass(const JSClass* clasp) { return clasp->isProxy(); }
|
||||
|
||||
bool IsDerivedProxyObject(const JSObject* obj,
|
||||
const js::BaseProxyHandler* handler);
|
||||
|
||||
|
@ -117,7 +117,7 @@
|
||||
MOZ_ALWAYS_INLINE size_t JSSLOT_FREE(const JSClass* clasp) {
|
||||
// Proxy classes have reserved slots, but proxies manage their own slot
|
||||
// layout.
|
||||
MOZ_ASSERT(!clasp->isProxy());
|
||||
MOZ_ASSERT(!clasp->isProxyObject());
|
||||
return JSCLASS_RESERVED_SLOTS(clasp);
|
||||
}
|
||||
|
||||
@ -1284,7 +1284,7 @@ class Shape : public gc::CellWithTenuredGCPointer<gc::TenuredCell, BaseShape> {
|
||||
// Proxy classes have reserved slots, but proxies manage their own slot
|
||||
// layout. This means all non-native object shapes have nfixed == 0 and
|
||||
// slotSpan == 0.
|
||||
uint32_t free = clasp->isProxy() ? 0 : JSSLOT_FREE(clasp);
|
||||
uint32_t free = clasp->isProxyObject() ? 0 : JSSLOT_FREE(clasp);
|
||||
return hasMissingSlot() ? free : std::max(free, maybeSlot() + 1);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user