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