Bug 776635 - Allow use of JSRootedObject using only external headers. r=billm

Currently, JS::Rooted<JSObject*> requires the full definition of JSObject to be available (due to RootMethods<JSObject*>::kind() calling JSObject::rootKind()). This patch switches to using a RootKind<T> template that is explicitly specialized in jspubtd.h for externally-visible pointer types, but still falls back on T::rootKind() for other pointer types so that we don't need to explicitly specialize on eg all subclasses of JSString or JSObject.

--HG--
extra : rebase_source : 138a859babc1aac60e61fe6f08089d8dbb4995d2
This commit is contained in:
Steve Fink 2012-07-18 14:32:39 -07:00
parent 6ed1505aa3
commit 6f2dea22ee
3 changed files with 26 additions and 1 deletions

View File

@ -221,11 +221,19 @@ class MutableHandle : public MutableHandleBase<T>
typedef MutableHandle<JSObject*> MutableHandleObject;
typedef MutableHandle<Value> MutableHandleValue;
/*
* By default, pointers should use the inheritance hierarchy to find their
* ThingRootKind. Some pointer types are explicitly set in jspubtd.h so that
* Rooted<T> may be used without the class definition being available.
*/
template <typename T>
struct RootKind<T *> { static ThingRootKind rootKind() { return T::rootKind(); }; };
template <typename T>
struct RootMethods<T *>
{
static T *initial() { return NULL; }
static ThingRootKind kind() { return T::rootKind(); }
static ThingRootKind kind() { return RootKind<T *>::rootKind(); }
static bool poisoned(T *v) { return IsPoisonedPtr(v); }
};

View File

@ -240,6 +240,20 @@ enum ThingRootKind
THING_ROOT_LIMIT
};
template <typename T>
struct RootKind;
/*
* Specifically mark the ThingRootKind of externally visible types, so that
* JSAPI users may use JSRooted... types without having the class definition
* available.
*/
template <> struct RootKind<JSObject *> { static ThingRootKind rootKind() { return THING_ROOT_OBJECT; }; };
template <> struct RootKind<JSString *> { static ThingRootKind rootKind() { return THING_ROOT_STRING; }; };
template <> struct RootKind<JSScript *> { static ThingRootKind rootKind() { return THING_ROOT_SCRIPT; }; };
template <> struct RootKind<jsid> { static ThingRootKind rootKind() { return THING_ROOT_ID; }; };
template <> struct RootKind<Value> { static ThingRootKind rootKind() { return THING_ROOT_VALUE; }; };
struct ContextFriendFields {
JSRuntime *const runtime;

View File

@ -1182,6 +1182,9 @@ MarkNonNativePropertyFound(HandleObject obj, MutableHandleShape propp);
namespace JS {
template<> class AnchorPermitted<js::Shape *> { };
template<> class AnchorPermitted<const js::Shape *> { };
template<> struct RootKind<js::Shape *> { static ThingRootKind rootKind() { return THING_ROOT_SHAPE; }; };
template<> struct RootKind<js::BaseShape *> { static ThingRootKind rootKind() { return THING_ROOT_BASE_SHAPE; }; };
}
#endif /* jsscope_h___ */