Bug 751377 - Add handles to all the new meta-object APIs. r=bhackett

--HG--
extra : rebase_source : 879302249be14da57c6945899961e63a08375279
This commit is contained in:
Jeff Walden 2012-06-14 19:13:34 -07:00
parent 457cf0d407
commit 54f304976b
2 changed files with 97 additions and 79 deletions

View File

@ -291,7 +291,7 @@ js::ObjectImpl::markChildren(JSTracer *trc)
} }
bool bool
DenseElementsHeader::getOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t index, DenseElementsHeader::getOwnElement(JSContext *cx, Handle<ObjectImpl*> obj, uint32_t index,
unsigned resolveFlags, PropDesc *desc) unsigned resolveFlags, PropDesc *desc)
{ {
MOZ_ASSERT(this == &obj->elementsHeader()); MOZ_ASSERT(this == &obj->elementsHeader());
@ -313,7 +313,7 @@ DenseElementsHeader::getOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t inde
} }
bool bool
SparseElementsHeader::getOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t index, SparseElementsHeader::getOwnElement(JSContext *cx, Handle<ObjectImpl*> obj, uint32_t index,
unsigned resolveFlags, PropDesc *desc) unsigned resolveFlags, PropDesc *desc)
{ {
MOZ_ASSERT(this == &obj->elementsHeader()); MOZ_ASSERT(this == &obj->elementsHeader());
@ -338,7 +338,7 @@ ElementToValue(const uint8_clamped &u)
template<typename T> template<typename T>
bool bool
TypedElementsHeader<T>::getOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t index, TypedElementsHeader<T>::getOwnElement(JSContext *cx, Handle<ObjectImpl*> obj, uint32_t index,
unsigned resolveFlags, PropDesc *desc) unsigned resolveFlags, PropDesc *desc)
{ {
MOZ_ASSERT(this == &obj->elementsHeader()); MOZ_ASSERT(this == &obj->elementsHeader());
@ -354,7 +354,7 @@ TypedElementsHeader<T>::getOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t i
} }
bool bool
ArrayBufferElementsHeader::getOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t index, ArrayBufferElementsHeader::getOwnElement(JSContext *cx, Handle<ObjectImpl*> obj, uint32_t index,
unsigned resolveFlags, PropDesc *desc) unsigned resolveFlags, PropDesc *desc)
{ {
MOZ_ASSERT(this == &obj->elementsHeader()); MOZ_ASSERT(this == &obj->elementsHeader());
@ -364,7 +364,7 @@ ArrayBufferElementsHeader::getOwnElement(JSContext *cx, ObjectImpl *obj, uint32_
} }
bool bool
SparseElementsHeader::defineElement(JSContext *cx, ObjectImpl *obj, uint32_t index, SparseElementsHeader::defineElement(JSContext *cx, Handle<ObjectImpl*> obj, uint32_t index,
const PropDesc &desc, bool shouldThrow, unsigned resolveFlags, const PropDesc &desc, bool shouldThrow, unsigned resolveFlags,
bool *succeeded) bool *succeeded)
{ {
@ -375,7 +375,7 @@ SparseElementsHeader::defineElement(JSContext *cx, ObjectImpl *obj, uint32_t ind
} }
bool bool
DenseElementsHeader::defineElement(JSContext *cx, ObjectImpl *obj, uint32_t index, DenseElementsHeader::defineElement(JSContext *cx, Handle<ObjectImpl*> obj, uint32_t index,
const PropDesc &desc, bool shouldThrow, unsigned resolveFlags, const PropDesc &desc, bool shouldThrow, unsigned resolveFlags,
bool *succeeded) bool *succeeded)
{ {
@ -450,7 +450,7 @@ DenseElementsHeader::defineElement(JSContext *cx, ObjectImpl *obj, uint32_t inde
} }
static JSObject * static JSObject *
ArrayBufferDelegate(JSContext *cx, ObjectImpl *obj) ArrayBufferDelegate(JSContext *cx, Handle<ObjectImpl*> obj)
{ {
MOZ_ASSERT(obj->hasClass(&ArrayBufferClass)); MOZ_ASSERT(obj->hasClass(&ArrayBufferClass));
if (obj->getPrivate()) if (obj->getPrivate())
@ -462,7 +462,7 @@ ArrayBufferDelegate(JSContext *cx, ObjectImpl *obj)
template <typename T> template <typename T>
bool bool
TypedElementsHeader<T>::defineElement(JSContext *cx, ObjectImpl *obj, TypedElementsHeader<T>::defineElement(JSContext *cx, Handle<ObjectImpl*> obj,
uint32_t index, const PropDesc &desc, bool shouldThrow, uint32_t index, const PropDesc &desc, bool shouldThrow,
unsigned resolveFlags, bool *succeeded) unsigned resolveFlags, bool *succeeded)
{ {
@ -476,20 +476,20 @@ TypedElementsHeader<T>::defineElement(JSContext *cx, ObjectImpl *obj,
} }
bool bool
ArrayBufferElementsHeader::defineElement(JSContext *cx, ObjectImpl *obj, ArrayBufferElementsHeader::defineElement(JSContext *cx, Handle<ObjectImpl*> obj,
uint32_t index, const PropDesc &desc, bool shouldThrow, uint32_t index, const PropDesc &desc, bool shouldThrow,
unsigned resolveFlags, bool *succeeded) unsigned resolveFlags, bool *succeeded)
{ {
MOZ_ASSERT(this == &obj->elementsHeader()); MOZ_ASSERT(this == &obj->elementsHeader());
JSObject *delegate = ArrayBufferDelegate(cx, obj); Rooted<JSObject*> delegate(cx, ArrayBufferDelegate(cx, obj));
if (!delegate) if (!delegate)
return false; return false;
return DefineElement(cx, delegate, index, desc, shouldThrow, resolveFlags, succeeded); return DefineElement(cx, delegate, index, desc, shouldThrow, resolveFlags, succeeded);
} }
bool bool
js::GetOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t index, unsigned resolveFlags, js::GetOwnElement(JSContext *cx, Handle<ObjectImpl*> obj, uint32_t index, unsigned resolveFlags,
PropDesc *desc) PropDesc *desc)
{ {
ElementsHeader &header = obj->elementsHeader(); ElementsHeader &header = obj->elementsHeader();
@ -525,27 +525,29 @@ js::GetOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t index, unsigned resol
} }
bool bool
js::GetElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, uint32_t index, js::GetElement(JSContext *cx, Handle<ObjectImpl*> obj, Handle<ObjectImpl*> receiver, uint32_t index,
unsigned resolveFlags, Value *vp) unsigned resolveFlags, Value *vp)
{ {
NEW_OBJECT_REPRESENTATION_ONLY(); NEW_OBJECT_REPRESENTATION_ONLY();
do { Rooted<ObjectImpl*> current(cx, obj);
MOZ_ASSERT(obj);
if (static_cast<JSObject *>(obj)->isProxy()) { // XXX do {
MOZ_ASSERT(current);
if (Downcast(current)->isProxy()) {
MOZ_NOT_REACHED("NYI: proxy [[GetP]]"); MOZ_NOT_REACHED("NYI: proxy [[GetP]]");
return false; return false;
} }
PropDesc desc; PropDesc desc;
if (!GetOwnElement(cx, obj, index, resolveFlags, &desc)) if (!GetOwnElement(cx, current, index, resolveFlags, &desc))
return false; return false;
/* No property? Recur or bottom out. */ /* No property? Recur or bottom out. */
if (desc.isUndefined()) { if (desc.isUndefined()) {
obj = obj->getProto(); current = current->getProto();
if (obj) if (current)
continue; continue;
vp->setUndefined(); vp->setUndefined();
@ -572,7 +574,7 @@ js::GetElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, uint32_t in
/* Push get, receiver, and no args. */ /* Push get, receiver, and no args. */
args.calleev() = get; args.calleev() = get;
args.thisv() = ObjectValue(*receiver); args.thisv() = ObjectValue(*current);
bool ok = Invoke(cx, args); bool ok = Invoke(cx, args);
*vp = args.rval(); *vp = args.rval();
@ -589,20 +591,23 @@ js::GetElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, uint32_t in
} }
bool bool
js::HasElement(JSContext *cx, ObjectImpl *obj, uint32_t index, unsigned resolveFlags, bool *found) js::HasElement(JSContext *cx, Handle<ObjectImpl*> obj, uint32_t index, unsigned resolveFlags,
bool *found)
{ {
NEW_OBJECT_REPRESENTATION_ONLY(); NEW_OBJECT_REPRESENTATION_ONLY();
do { Rooted<ObjectImpl*> current(cx, obj);
MOZ_ASSERT(obj);
if (static_cast<JSObject *>(obj)->isProxy()) { // XXX do {
MOZ_ASSERT(current);
if (Downcast(current)->isProxy()) {
MOZ_NOT_REACHED("NYI: proxy [[HasProperty]]"); MOZ_NOT_REACHED("NYI: proxy [[HasProperty]]");
return false; return false;
} }
PropDesc prop; PropDesc prop;
if (!GetOwnElement(cx, obj, index, resolveFlags, &prop)) if (!GetOwnElement(cx, current, index, resolveFlags, &prop))
return false; return false;
if (!prop.isUndefined()) { if (!prop.isUndefined()) {
@ -610,8 +615,8 @@ js::HasElement(JSContext *cx, ObjectImpl *obj, uint32_t index, unsigned resolveF
return true; return true;
} }
obj = obj->getProto(); current = current->getProto();
if (obj) if (current)
continue; continue;
*found = false; *found = false;
@ -623,7 +628,7 @@ js::HasElement(JSContext *cx, ObjectImpl *obj, uint32_t index, unsigned resolveF
} }
bool bool
js::DefineElement(JSContext *cx, ObjectImpl *obj, uint32_t index, const PropDesc &desc, js::DefineElement(JSContext *cx, Handle<ObjectImpl*> obj, uint32_t index, const PropDesc &desc,
bool shouldThrow, unsigned resolveFlags, bool *succeeded) bool shouldThrow, unsigned resolveFlags, bool *succeeded)
{ {
NEW_OBJECT_REPRESENTATION_ONLY(); NEW_OBJECT_REPRESENTATION_ONLY();
@ -674,9 +679,9 @@ js::DefineElement(JSContext *cx, ObjectImpl *obj, uint32_t index, const PropDesc
} }
bool bool
SparseElementsHeader::setElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, SparseElementsHeader::setElement(JSContext *cx, Handle<ObjectImpl*> obj,
uint32_t index, const Value &v, unsigned resolveFlags, Handle<ObjectImpl*> receiver, uint32_t index, const Value &v,
bool *succeeded) unsigned resolveFlags, bool *succeeded)
{ {
MOZ_ASSERT(this == &obj->elementsHeader()); MOZ_ASSERT(this == &obj->elementsHeader());
@ -685,9 +690,9 @@ SparseElementsHeader::setElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *rec
} }
bool bool
DenseElementsHeader::setElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, DenseElementsHeader::setElement(JSContext *cx, Handle<ObjectImpl*> obj,
uint32_t index, const Value &v, unsigned resolveFlags, Handle<ObjectImpl*> receiver, uint32_t index, const Value &v,
bool *succeeded) unsigned resolveFlags, bool *succeeded)
{ {
MOZ_ASSERT(this == &obj->elementsHeader()); MOZ_ASSERT(this == &obj->elementsHeader());
@ -697,9 +702,9 @@ DenseElementsHeader::setElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *rece
template <typename T> template <typename T>
bool bool
TypedElementsHeader<T>::setElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, TypedElementsHeader<T>::setElement(JSContext *cx, Handle<ObjectImpl*> obj,
uint32_t index, const Value &v, unsigned resolveFlags, Handle<ObjectImpl*> receiver, uint32_t index, const Value &v,
bool *succeeded) unsigned resolveFlags, bool *succeeded)
{ {
MOZ_ASSERT(this == &obj->elementsHeader()); MOZ_ASSERT(this == &obj->elementsHeader());
@ -739,9 +744,9 @@ TypedElementsHeader<T>::setElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *r
} }
bool bool
ArrayBufferElementsHeader::setElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, ArrayBufferElementsHeader::setElement(JSContext *cx, Handle<ObjectImpl*> obj,
uint32_t index, const Value &v, unsigned resolveFlags, Handle<ObjectImpl*> receiver, uint32_t index, const Value &v,
bool *succeeded) unsigned resolveFlags, bool *succeeded)
{ {
MOZ_ASSERT(this == &obj->elementsHeader()); MOZ_ASSERT(this == &obj->elementsHeader());
@ -752,21 +757,23 @@ ArrayBufferElementsHeader::setElement(JSContext *cx, ObjectImpl *obj, ObjectImpl
} }
bool bool
js::SetElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, uint32_t index, js::SetElement(JSContext *cx, Handle<ObjectImpl*> obj, Handle<ObjectImpl*> receiver,
const Value &v, unsigned resolveFlags, bool *succeeded) uint32_t index, const Value &v, unsigned resolveFlags, bool *succeeded)
{ {
NEW_OBJECT_REPRESENTATION_ONLY(); NEW_OBJECT_REPRESENTATION_ONLY();
do { Rooted<ObjectImpl*> current(cx, obj);
MOZ_ASSERT(obj);
if (static_cast<JSObject *>(obj)->isProxy()) { // XXX do {
MOZ_ASSERT(current);
if (Downcast(current)->isProxy()) {
MOZ_NOT_REACHED("NYI: proxy [[SetP]]"); MOZ_NOT_REACHED("NYI: proxy [[SetP]]");
return false; return false;
} }
PropDesc ownDesc; PropDesc ownDesc;
if (!GetOwnElement(cx, obj, index, resolveFlags, &ownDesc)) if (!GetOwnElement(cx, current, index, resolveFlags, &ownDesc))
return false; return false;
if (!ownDesc.isUndefined()) { if (!ownDesc.isUndefined()) {
@ -776,7 +783,7 @@ js::SetElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, uint32_t in
return true; return true;
} }
if (receiver == obj) { if (receiver == current) {
PropDesc updateDesc = PropDesc::valueOnly(v); PropDesc updateDesc = PropDesc::valueOnly(v);
return DefineElement(cx, receiver, index, updateDesc, false, resolveFlags, return DefineElement(cx, receiver, index, updateDesc, false, resolveFlags,
succeeded); succeeded);
@ -799,7 +806,7 @@ js::SetElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, uint32_t in
/* Push set, receiver, and v as the sole argument. */ /* Push set, receiver, and v as the sole argument. */
args.calleev() = setter; args.calleev() = setter;
args.thisv() = ObjectValue(*receiver); args.thisv() = ObjectValue(*current);
args[0] = v; args[0] = v;
*succeeded = true; *succeeded = true;
@ -810,8 +817,8 @@ js::SetElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, uint32_t in
return false; return false;
} }
obj = obj->getProto(); current = current->getProto();
if (obj) if (current)
continue; continue;
PropDesc newDesc(v, PropDesc::Writable, PropDesc::Enumerable, PropDesc::Configurable); PropDesc newDesc(v, PropDesc::Writable, PropDesc::Enumerable, PropDesc::Configurable);

View File

@ -408,14 +408,15 @@ class DenseElementsHeader : public ElementsHeader
return ElementsHeader::length; return ElementsHeader::length;
} }
bool getOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t index, unsigned resolveFlags, bool getOwnElement(JSContext *cx, Handle<ObjectImpl*> obj, uint32_t index,
PropDesc *desc); unsigned resolveFlags, PropDesc *desc);
bool defineElement(JSContext *cx, ObjectImpl *obj, uint32_t index, const PropDesc &desc, bool defineElement(JSContext *cx, Handle<ObjectImpl*> obj, uint32_t index,
bool shouldThrow, unsigned resolveFlags, bool *succeeded); const PropDesc &desc, bool shouldThrow, unsigned resolveFlags,
bool *succeeded);
bool setElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, uint32_t index, bool setElement(JSContext *cx, Handle<ObjectImpl*> obj, Handle<ObjectImpl*> receiver,
const Value &v, unsigned resolveFlags, bool *succeeded); uint32_t index, const Value &v, unsigned resolveFlags, bool *succeeded);
private: private:
inline bool isDenseElements() const MOZ_DELETE; inline bool isDenseElements() const MOZ_DELETE;
@ -438,14 +439,15 @@ class SparseElementsHeader : public ElementsHeader
return ElementsHeader::length; return ElementsHeader::length;
} }
bool getOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t index, unsigned resolveFlags, bool getOwnElement(JSContext *cx, Handle<ObjectImpl*> obj, uint32_t index,
PropDesc *desc); unsigned resolveFlags, PropDesc *desc);
bool defineElement(JSContext *cx, ObjectImpl *obj, uint32_t index, const PropDesc &desc, bool defineElement(JSContext *cx, Handle<ObjectImpl*> obj, uint32_t index,
bool shouldThrow, unsigned resolveFlags, bool *succeeded); const PropDesc &desc, bool shouldThrow, unsigned resolveFlags,
bool *succeeded);
bool setElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, uint32_t index, bool setElement(JSContext *cx, Handle<ObjectImpl*> obj, Handle<ObjectImpl*> receiver,
const Value &v, unsigned resolveFlags, bool *succeeded); uint32_t index, const Value &v, unsigned resolveFlags, bool *succeeded);
private: private:
inline bool isSparseElements() const MOZ_DELETE; inline bool isSparseElements() const MOZ_DELETE;
@ -563,14 +565,15 @@ class TypedElementsHeader : public ElementsHeader
return ElementsHeader::length; return ElementsHeader::length;
} }
bool getOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t index, unsigned resolveFlags, bool getOwnElement(JSContext *cx, Handle<ObjectImpl*> obj, uint32_t index,
PropDesc *desc); unsigned resolveFlags, PropDesc *desc);
bool defineElement(JSContext *cx, ObjectImpl *obj, uint32_t index, const PropDesc &desc, bool defineElement(JSContext *cx, Handle<ObjectImpl*> obj, uint32_t index,
bool shouldThrow, unsigned resolveFlags, bool *succeeded); const PropDesc &desc, bool shouldThrow, unsigned resolveFlags,
bool *succeeded);
bool setElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, uint32_t index, bool setElement(JSContext *cx, Handle<ObjectImpl*> obj, Handle<ObjectImpl*> receiver,
const Value &v, unsigned resolveFlags, bool *succeeded); uint32_t index, const Value &v, unsigned resolveFlags, bool *succeeded);
private: private:
TypedElementsHeader(const TypedElementsHeader &other) MOZ_DELETE; TypedElementsHeader(const TypedElementsHeader &other) MOZ_DELETE;
@ -723,14 +726,15 @@ class Uint8ClampedElementsHeader : public TypedElementsHeader<uint8_clamped>
class ArrayBufferElementsHeader : public ElementsHeader class ArrayBufferElementsHeader : public ElementsHeader
{ {
public: public:
bool getOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t index, unsigned resolveFlags, bool getOwnElement(JSContext *cx, Handle<ObjectImpl*> obj, uint32_t index,
PropDesc *desc); unsigned resolveFlags, PropDesc *desc);
bool defineElement(JSContext *cx, ObjectImpl *obj, uint32_t index, const PropDesc &desc, bool defineElement(JSContext *cx, Handle<ObjectImpl*> obj, uint32_t index,
bool shouldThrow, unsigned resolveFlags, bool *succeeded); const PropDesc &desc, bool shouldThrow, unsigned resolveFlags,
bool *succeeded);
bool setElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, uint32_t index, bool setElement(JSContext *cx, Handle<ObjectImpl*> obj, Handle<ObjectImpl*> receiver,
const Value &v, unsigned resolveFlags, bool *succeeded); uint32_t index, const Value &v, unsigned resolveFlags, bool *succeeded);
private: private:
inline bool isArrayBufferElements() const MOZ_DELETE; inline bool isArrayBufferElements() const MOZ_DELETE;
@ -1302,26 +1306,33 @@ ObjectValue(ObjectImpl &obj)
return v; return v;
} }
inline Handle<JSObject*>
Downcast(Handle<ObjectImpl*> obj)
{
return Handle<JSObject*>::fromMarkedLocation(reinterpret_cast<JSObject* const*>(obj.address()));
}
bool bool
GetOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t index, unsigned resolveFlags, GetOwnElement(JSContext *cx, Handle<ObjectImpl*> obj, uint32_t index, unsigned resolveFlags,
PropDesc *desc); PropDesc *desc);
/* Proposed default [[GetP]](Receiver, P) method. */ /* Proposed default [[GetP]](Receiver, P) method. */
extern bool extern bool
GetElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, uint32_t index, GetElement(JSContext *cx, Handle<ObjectImpl*> obj, Handle<ObjectImpl*> receiver, uint32_t index,
unsigned resolveFlags, Value *vp); unsigned resolveFlags, Value *vp);
extern bool extern bool
DefineElement(JSContext *cx, ObjectImpl *obj, uint32_t index, const PropDesc &desc, DefineElement(JSContext *cx, Handle<ObjectImpl*> obj, uint32_t index, const PropDesc &desc,
bool shouldThrow, unsigned resolveFlags, bool *succeeded); bool shouldThrow, unsigned resolveFlags, bool *succeeded);
/* Proposed default [[SetP]](Receiver, P, V) method. */ /* Proposed default [[SetP]](Receiver, P, V) method. */
extern bool extern bool
SetElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, uint32_t index, const Value &v, SetElement(JSContext *cx, Handle<ObjectImpl*> obj, Handle<ObjectImpl*> receiver, uint32_t index,
unsigned resolveFlags, bool *succeeded); const Value &v, unsigned resolveFlags, bool *succeeded);
extern bool extern bool
HasElement(JSContext *cx, ObjectImpl *obj, uint32_t index, unsigned resolveFlags, bool *found); HasElement(JSContext *cx, Handle<ObjectImpl*> obj, uint32_t index, unsigned resolveFlags,
bool *found);
} /* namespace js */ } /* namespace js */