I would have still preferred the explicit Handle<T> notation, but not
enough to argue the point. I'd rather have the matter settled.

To recap my arguments, for no particular reason:

- The main choice between template vs typedef is whether the information
being hidden is relevant or not. To me, the fact that Handle<T> has
roughly the same relationship to T for all T *is* relevant (because of
the particular relationship, not in general). HandleObject and
HandleValue could be two entirely different types. Handle<T> enables you
to read it as "pointer to a rooted T", at which point much of the
confusion over how this stuff works drops away.

- Handle<T> feels like introducing one new type. HandleObject,
HandleValue, HandleScript, etc. feels like introducing a dozen.

- Handle<T> feels more hackable. It tells you that you can add stuff to
all of these types at once by adding stuff to Handle, and of course that
you can use template instantation to get the appropriate Handle type
when needed.

- Forward declaration is easier

And my counter to the arguments for the typedefs:

- JS::Handle<JS::Value> is indeed ugly. But you can't compare to
HandleValue; it'd still be JS::HandleValue. It sounds like people aren't
crazy about 'using namespace JS' or 'using JS::Value', so it's probably
"JS::Handle<JS::Value> vs JS::HandleValue" or "Handle<JS::Value> vs
HandleValue". A difference, but not a huge one.

- Luke's breakdown of cases of different programmers' understanding of
handles is a little oversimplified. The set of programmers who already
understand Handles is pretty close to the empty set, or at least it
oscillates between the empty set and something very small. I mostly
understand handles, but keep forgetting the details. And I've mentally
tried out several different ways of thinking about them before settling
on "pointer to rooted T".

Luke's category B argument, though, makes sense -- knowing that
HandleValue is a templatized Handle<Value> doesn't get you very far in
understand that specific specialization. And it isn't the only
specialization that differs from the default. That's the strongest
argument in favor of the typedefs in my mind.

Ok, got that off my chest. I'm done now. :-)

Oh, wait, not quite. What's the policy on Rooted and Handle types within
.cpp files, for one-offs or rarely-used types? We have a number of
these, mostly for Rooted, and it seems weird to use a local typedef when
you're probably only using it to avoid losing type information in the
first place (eg using a Handle<JSLinearString*> instead of a
HandleString because the callee wants to know it's dealing with a
JSLinearString.) Is it mandatory to use a typedef to match the standard
style? Encouraged? Discouraged? I guess it's ok to leave it to the coder
and reviewer, but we already know that this is an area with widely
divergent opinions on aesthetic gut-feel...

% egrep 'typedef Handle<' **/*.cpp
frontend/Parser.cpp:typedef Handle<StaticBlockObject*>
HandleStaticBlockObject;
jsstr.cpp:typedef Handle<JSLinearString*> HandleLinearString;
% egrep 'typedef.*Rooted<' **/*.cpp         
ctypes/Library.cpp:typedef Rooted<JSFlatString*>    RootedFlatString;
frontend/Parser.cpp:typedef Rooted<StaticBlockObject*>
RootedStaticBlockObject;
jsiter.cpp:typedef Rooted<PropertyIteratorObject*>
RootedPropertyIteratorObject;
jsscript.cpp:typedef Rooted<GlobalObject *> RootedGlobalObject;
vm/ScopeObject.cpp:typedef Rooted<ArgumentsObject *> RootedArgumentsObject;

_______________________________________________
dev-tech-js-engine-internals mailing list
dev-tech-js-engine-internals@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-js-engine-internals

Reply via email to