mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 860572 - Allow JSPropertyDescriptor to use Rooted; r=jonco
This commit is contained in:
parent
fb71ffd4ce
commit
7aae601b79
@ -67,6 +67,7 @@ MarkExactStackRoot(JSTracer *trc, Rooted<void*> *rooter, ThingRootKind kind)
|
||||
case THING_ROOT_ID: MarkIdRoot(trc, (jsid *)addr, "exact-id"); break;
|
||||
case THING_ROOT_PROPERTY_ID: MarkIdRoot(trc, &((js::PropertyId *)addr)->asId(), "exact-propertyid"); break;
|
||||
case THING_ROOT_BINDINGS: ((Bindings *)addr)->trace(trc); break;
|
||||
case THING_ROOT_PROPERTY_DESCRIPTOR: ((JSPropertyDescriptor *)addr)->trace(trc); break;
|
||||
default: JS_NOT_REACHED("Invalid THING_ROOT kind"); break;
|
||||
}
|
||||
}
|
||||
@ -415,19 +416,7 @@ AutoGCRooter::trace(JSTracer *trc)
|
||||
|
||||
case DESCRIPTOR : {
|
||||
PropertyDescriptor &desc = *static_cast<AutoPropertyDescriptorRooter *>(this);
|
||||
if (desc.obj)
|
||||
MarkObjectRoot(trc, &desc.obj, "Descriptor::obj");
|
||||
MarkValueRoot(trc, &desc.value, "Descriptor::value");
|
||||
if ((desc.attrs & JSPROP_GETTER) && desc.getter) {
|
||||
JSObject *tmp = JS_FUNC_TO_DATA_PTR(JSObject *, desc.getter);
|
||||
MarkObjectRoot(trc, &tmp, "Descriptor::get");
|
||||
desc.getter = JS_DATA_TO_FUNC_PTR(JSPropertyOp, tmp);
|
||||
}
|
||||
if (desc.attrs & JSPROP_SETTER && desc.setter) {
|
||||
JSObject *tmp = JS_FUNC_TO_DATA_PTR(JSObject *, desc.setter);
|
||||
MarkObjectRoot(trc, &tmp, "Descriptor::set");
|
||||
desc.setter = JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, tmp);
|
||||
}
|
||||
desc.trace(trc);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -648,6 +637,24 @@ StackShape::AutoRooter::trace(JSTracer *trc)
|
||||
MarkIdRoot(trc, (jsid*) &shape->propid, "StackShape::AutoRooter id");
|
||||
}
|
||||
|
||||
void
|
||||
JSPropertyDescriptor::trace(JSTracer *trc)
|
||||
{
|
||||
if (obj)
|
||||
MarkObjectRoot(trc, &obj, "Descriptor::obj");
|
||||
MarkValueRoot(trc, &value, "Descriptor::value");
|
||||
if ((attrs & JSPROP_GETTER) && getter) {
|
||||
JSObject *tmp = JS_FUNC_TO_DATA_PTR(JSObject *, getter);
|
||||
MarkObjectRoot(trc, &tmp, "Descriptor::get");
|
||||
getter = JS_DATA_TO_FUNC_PTR(JSPropertyOp, tmp);
|
||||
}
|
||||
if ((attrs & JSPROP_SETTER) && setter) {
|
||||
JSObject *tmp = JS_FUNC_TO_DATA_PTR(JSObject *, setter);
|
||||
MarkObjectRoot(trc, &tmp, "Descriptor::set");
|
||||
setter = JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots)
|
||||
{
|
||||
|
@ -29,14 +29,23 @@ using namespace mozilla;
|
||||
|
||||
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
CheckNonAddressThing(uintptr_t *w, T *t)
|
||||
{
|
||||
return w >= (uintptr_t*)t && w < (uintptr_t*)(t + 1);
|
||||
}
|
||||
|
||||
JS_ALWAYS_INLINE bool
|
||||
CheckStackRootThing(uintptr_t *w, void *address, ThingRootKind kind)
|
||||
{
|
||||
if (kind != THING_ROOT_BINDINGS)
|
||||
return address == static_cast<void*>(w);
|
||||
if (kind == THING_ROOT_BINDINGS)
|
||||
return CheckNonAddressThing(w, static_cast<Bindings*>(address));
|
||||
|
||||
Bindings *bp = static_cast<Bindings*>(address);
|
||||
return w >= (uintptr_t*)bp && w < (uintptr_t*)(bp + 1);
|
||||
if (kind == THING_ROOT_PROPERTY_DESCRIPTOR)
|
||||
return CheckNonAddressThing(w, static_cast<PropertyDescriptor*>(address));
|
||||
|
||||
return address == static_cast<void*>(w);
|
||||
}
|
||||
|
||||
struct Rooter {
|
||||
|
104
js/src/jsapi.h
104
js/src/jsapi.h
@ -3326,13 +3326,115 @@ struct JSPropertyDescriptor {
|
||||
unsigned shortid;
|
||||
JSPropertyOp getter;
|
||||
JSStrictPropertyOp setter;
|
||||
jsval value;
|
||||
JS::Value value;
|
||||
|
||||
JSPropertyDescriptor() : obj(NULL), attrs(0), shortid(0), getter(NULL),
|
||||
setter(NULL), value(JSVAL_VOID)
|
||||
{}
|
||||
|
||||
void trace(JSTracer *trc);
|
||||
};
|
||||
|
||||
namespace JS {
|
||||
|
||||
template <typename Outer>
|
||||
class PropertyDescriptorOperations
|
||||
{
|
||||
const JSPropertyDescriptor * desc() const { return static_cast<const Outer*>(this)->extract(); }
|
||||
JSPropertyDescriptor * desc() { return static_cast<Outer*>(this)->extract(); }
|
||||
|
||||
public:
|
||||
bool isEnumerable() const { return desc()->attrs & JSPROP_ENUMERATE; }
|
||||
bool isReadonly() const { return desc()->attrs & JSPROP_READONLY; }
|
||||
bool isPermanent() const { return desc()->attrs & JSPROP_PERMANENT; }
|
||||
bool hasNativeAccessors() const { return desc()->attrs & JSPROP_NATIVE_ACCESSORS; }
|
||||
bool hasGetterObject() const { return desc()->attrs & JSPROP_GETTER; }
|
||||
bool hasSetterObject() const { return desc()->attrs & JSPROP_SETTER; }
|
||||
bool isShared() const { return desc()->attrs & JSPROP_SHARED; }
|
||||
bool isIndex() const { return desc()->attrs & JSPROP_INDEX; }
|
||||
bool hasShortId() const { return desc()->attrs & JSPROP_SHORTID; }
|
||||
bool hasAttributes(unsigned attrs) const { return desc()->attrs & attrs; }
|
||||
|
||||
JS::MutableHandleObject object() { return JS::MutableHandleObject::fromMarkedLocation(&desc()->obj); }
|
||||
unsigned attributes() const { return desc()->attrs; }
|
||||
unsigned shortid() const {
|
||||
MOZ_ASSERT(hasShortId());
|
||||
return desc()->shortid;
|
||||
}
|
||||
JSPropertyOp getter() const { MOZ_ASSERT(!hasGetterObject()); return desc()->getter; }
|
||||
JSStrictPropertyOp setter() const { MOZ_ASSERT(!hasSetterObject()); return desc()->setter; }
|
||||
JS::HandleObject getterObject() const {
|
||||
MOZ_ASSERT(hasGetterObject());
|
||||
return JS::HandleObject::fromMarkedLocation(reinterpret_cast<JSObject *const *>(&desc()->getter));
|
||||
}
|
||||
JS::HandleObject setterObject() const {
|
||||
MOZ_ASSERT(hasSetterObject());
|
||||
return JS::HandleObject::fromMarkedLocation(reinterpret_cast<JSObject *const *>(&desc()->setter));
|
||||
}
|
||||
JS::MutableHandleValue value() { return JS::MutableHandleValue::fromMarkedLocation(&desc()->value); }
|
||||
|
||||
void setAttributes(unsigned attrs) { desc()->attrs = attrs; }
|
||||
void setShortId(unsigned id) { desc()->shortid = id; }
|
||||
void setGetter(JSPropertyOp op) { desc()->getter = op; }
|
||||
void setSetter(JSStrictPropertyOp op) { desc()->setter = op; }
|
||||
void setGetterObject(JSObject *obj) { desc()->getter = reinterpret_cast<JSPropertyOp>(obj); }
|
||||
void setSetterObject(JSObject *obj) { desc()->setter = reinterpret_cast<JSStrictPropertyOp>(obj); }
|
||||
};
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
namespace js {
|
||||
|
||||
template <>
|
||||
struct RootMethods<JSPropertyDescriptor> {
|
||||
static JSPropertyDescriptor initial() { return JSPropertyDescriptor(); }
|
||||
static ThingRootKind kind() { return THING_ROOT_PROPERTY_DESCRIPTOR; }
|
||||
static bool poisoned(const JSPropertyDescriptor &desc) {
|
||||
return (desc.obj && JS::IsPoisonedPtr(desc.obj)) ||
|
||||
(desc.attrs & JSPROP_GETTER && desc.getter && JS::IsPoisonedPtr(desc.getter)) ||
|
||||
(desc.attrs & JSPROP_SETTER && desc.setter && JS::IsPoisonedPtr(desc.setter)) ||
|
||||
(desc.value.isGCThing() && JS::IsPoisonedPtr(desc.value.toGCThing()));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class RootedBase<JSPropertyDescriptor>
|
||||
: public JS::PropertyDescriptorOperations<JS::Rooted<JSPropertyDescriptor> >
|
||||
{
|
||||
friend class JS::PropertyDescriptorOperations<JS::Rooted<JSPropertyDescriptor> >;
|
||||
const JSPropertyDescriptor *extract() const {
|
||||
return static_cast<const JS::Rooted<JSPropertyDescriptor>*>(this)->address();
|
||||
}
|
||||
JSPropertyDescriptor *extract() {
|
||||
return static_cast<JS::Rooted<JSPropertyDescriptor>*>(this)->address();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class HandleBase<JSPropertyDescriptor>
|
||||
: public JS::PropertyDescriptorOperations<JS::Handle<JSPropertyDescriptor> >
|
||||
{
|
||||
friend class JS::PropertyDescriptorOperations<JS::Rooted<JSPropertyDescriptor> >;
|
||||
const JSPropertyDescriptor *extract() const {
|
||||
return static_cast<const JS::Handle<JSPropertyDescriptor>*>(this)->address();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class MutableHandleBase<JSPropertyDescriptor>
|
||||
: public JS::PropertyDescriptorOperations<JS::MutableHandle<JSPropertyDescriptor> >
|
||||
{
|
||||
friend class JS::PropertyDescriptorOperations<JS::Rooted<JSPropertyDescriptor> >;
|
||||
const JSPropertyDescriptor *extract() const {
|
||||
return static_cast<const JS::MutableHandle<JSPropertyDescriptor>*>(this)->address();
|
||||
}
|
||||
JSPropertyDescriptor *extract() {
|
||||
return static_cast<JS::MutableHandle<JSPropertyDescriptor>*>(this)->address();
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
/*
|
||||
* Like JS_GetPropertyAttrsGetterAndSetterById but will return a property on
|
||||
* an object on the prototype chain (returned in objp). If data->obj is null,
|
||||
|
@ -244,6 +244,7 @@ enum ThingRootKind
|
||||
THING_ROOT_VALUE,
|
||||
THING_ROOT_TYPE,
|
||||
THING_ROOT_BINDINGS,
|
||||
THING_ROOT_PROPERTY_DESCRIPTOR,
|
||||
THING_ROOT_LIMIT
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user