Must built-in prototypes also be valid instances? (Was: Why DataView.prototype object's [[Class]] is "Object"?)

Brendan Eich brendan at
Mon Oct 1 15:48:49 PDT 2012

Allen Wirfs-Brock wrote:
> On Oct 1, 2012, at 12:39 PM, Brendan Eich wrote:
>> Allen Wirfs-Brock wrote:
>>> Line 5.c.v is dealing with the ES5 requirement that "host objects" not reuse the listed [[Class]] values for anything other than the specified built-ins. This version of toStrimg extends the spirit to that restriction to all user or implementation defined tag values.  It does this by prepending a "~" in front of those values if they appear as a tag value.  Note that ES5.1 includes "Object" in this list so I also included it. But, I actually think it probably should be in the censored list.
>> This is weird.
>> ES5 wanted to help SES and similar languages use some kind of
>>   original_Object_prototype_toString_call(anyObject).slice(8,-1)
>> and not be subject to spoofing.
>> Adding @@toStringTag to enable DOM self-hosting runs directly counter to this goal.
>> Prefixing "~" to core-language built-in classes (save "Object"?) does not resolve the conflict if there are spoofing hazards in other built-ins such as DOM objects as typically implemented in browsers.
>> Mark, can you weigh in? I had not heard of this "~"-prefixing idea.
> Let me try explaining this again,

No need to rehash.

Responding to my point about other legacy "tag tests" that are not 
twiddled with "~" and so are possibly "invalidated" would be helpful. 
*Why* are the core language names sacrosanct when tag-testing of other 
class names is also potentially just as important, e.g., for SES?

> The little quicks like the "~" prefix and the exception eating are simply what is necessary

Not so fast there, Tex!

First, *something* is necessary for preserving certain names from being 
spoofed and invalidating a tag-test, but we should agree on the names 
and the reason for spoof-proofing exactly and only that set of names.

Second, eating exceptions does *not* follow from "what is necessary" 
even if I agree with your set of names! Eating exceptions is bad on 
principle. Why do you do it here? A host object might throw on attempt 
to get a novel property name such as @@toStringTag but is that an actual 

Also, I'm assuming the "???" strings are just place-holders. True?

>   to formalize this extensibility model while still preserving the behavior of existing code that depends upon object.prototype.toString as a reliable mechanism to test for instances of the ES<=5.1 built-ins.

Adding new internal method calls with novel ids might add new exception 
throws. That's part of the package deal.

Implementors control their host objects in general and can tame any that 
might throw on @@toStringTag [[Get]]. Suppose an implementation has a 
bug where such a throw happens, for any reason (could be the novel 
symbol property-name, or could be some other reason). Suppressing 
prevents anyone (implementor, developer, us) from knowing what is going on.

I'm laboring over this because in JS1 I suppressed exceptions trying 
toString and valueOf and that bit back. [[DefaultValue]] uses 
ReturnIfAbrupt which propagates the abrupt completion rather than 
dropping it on the floor.


More information about the es-discuss mailing list