Catchall proposal
Brendan Eich
brendan at mozilla.com
Wed May 6 09:10:33 PDT 2009
On May 6, 2009, at 8:22 AM, David-Sarah Hopwood wrote:
> The ability to define 'has', 'get', and 'invoke' handlers for the
> case where the property exists, is definitely needed IMHO. Suppressing
> the visibility of a property is potentially as useful as creating a
> "virtual" property, especially for the secure JS subsets.
Good feedback. What do other secure subsetters say?
> (Defining both the "always" and "missing" versions of a handler
> in the descriptor is not useful, and could be an error.)
Does the has : get :: add : set approach have any advantages in your
view? I could see allowing both has and get, and add and set.
> This means that "throw e", where e might have come from an unknown
> source, has to be avoided in a handler in favour of something like
> "throw e === DefaultAction ? new Error() : e". Yuck.
The same problem exists for a return value encoding "DefaultAction".
There's always a pigeon-hole problem somewhere, but exceptions are
less used than return values, and a singleton exception object
constant is less likely to be misused, as well as being efficient to
handle in the VM.
> # Runaway prevention: should a catchall, while its call is active,
> # be automatically suppressed from re-entering itself for the given
> # id on the target object?
>
> I think that all catchalls on a given object O, not just those for
> the same id, should be suppressed when handling a catchall for O.
> If you want the behaviour that would occur as a result of triggering
> a catchall for another property, then it is easy to inline that
> behaviour in the handler. But if you want to suppress the catchall
> behaviour for another property while in a handler, then it would be
> difficult to do so under the semantics suggested above.
Why would you want to suppress the catchall behavior for another
property while handling the first property? I'm looking for real-world
use-cases.
Both inlining and suppressing an otherwise-nesting catchall seem
plausible. Our experience with internal catchall APIs in SpiderMonkey
has favored suppressing (obj, id), not just obj.
One hard case is bootstrapping the Object and Function built-in
constructors lazily. You have to do both at the same time, since
Function.prototype's proto is Object.prototype but Object is an
instance of Function. Yet a script could mention either Object or
Function (or define or express a function) in either order. We inline
some logic to handle the coupled nature of the two, but we rely on the
suppression using (obj, id) to detect what action by the script
triggered the lazy initialization.
Either way could be "coded around", but the (obj, id) way let the
runtime share the suppression machinery in a detectable way for use by
others. I believe we have lazy DOM init code that always benefits from
not requiring inlining.
I know of no case where we want an otherwise-nesting catchall to be
suppressed.
> (Also the per-object suppression is easier to specify; it just
> requires an [[InCatchall]] flag on each object.)
True (although optimizing VMs have few bits for such things and may
use a hash table, so storing the id too is less of a burden).
/be
More information about the es-discuss
mailing list