Exotic OBJECT?

Allen Wirfs-Brock allen at wirfs-brock.com
Tue Aug 12 15:16:24 PDT 2014


On Aug 12, 2014, at 2:17 PM, Garrett Smith wrote:

> On 8/12/14, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
>> 
>>> 
>>> 
>>> Since calling `Function.prototype.toString` with OBJECT as the this
>>> value results in a TypeError, it appears that the OBJECT does not
>>> implement [[Call]] and thus the only explanation is that the OBJECT is
>>> exotic. Did I get that right? Or is there another explanation?
>>> 
> 
> I based this conclusion off of the latest ES6 draft, at:
> http://people.mozilla.org/~jorendorff/es6-draft.html#sec-function.prototype.tostring
> 
> "throws a TypeError exception if its this value does not have a
> [[Call]] internal method"

Hmm, that's a change from the ES5 spec. (which is what I would optimsitically hope browsers now support).
I also thing that change is a bug that needs to be reverted.  Function.prototype.toString does things that requires intimate knowledge of the internal structure of its this value.   I don't see how it could possibly workk for any possible object with a [[Call]] internal method. 


>> ...
>> The ES5 spec. clearly says that F.p.toString is called with a this value
>> that is not a "Function object".  Note this usage of "Function object"
>> means an actual instance of the built-in Function constructor and not the
>> more general, any object that isCallable.
>> 
> 
> ES5, in a few places, vascillates between the terms "function object"

but, not that in F.p.toString it is capital-F "Function object" and that has a specific meaning.

> and isCallable. E.g. "When the [[Call]] internal method for a Function
> object..." yet there is no description of what happens when [[Call]]
> is called on any object that implements [[Call]] but is not a function
> (non-function host objects). Such objects not only exist but are
> mentioned under the definition of the typeof operator:-
> 
> Object (implements [[Call]])     "function
> 
> There is also the failure of ES5 to differentiate between the two
> types of host objects: native, and non-native, as I brought up and as
> we discussed over 4 years ago. This differentiation is explained in
> the ES6 draft as "exotic objects".

right, all address in ES6

> 
> The ES6 replaces "function object" with "isCallable" and "implements
> [[Call]]" in many places, and the place that is of concern here is the
> description of Function.prototype.toString:
> 
> | Function.prototype.toString
> | ...
> |
> | The toString function is not generic; it throws a
> | TypeError exception if its this value does not have
> | a [[Call]] internal method. Therefore, it cannot be
> | transferred to other kinds of objects for use as a method.

This is a spec, bug. should probably be expressed as does not have a [[Code]] internal slot.

> 
> Do you agree or disagree with the fact that the OBJECT implements
> [[Call]]? And if you disagree, please explain.

Here is what my test shows in FF33:
Function.prototype.call.call(document.createElement("object"))
/*
Exception: 
@Scratchpad/1:1:0
*/

Function.prototype.call.call({})
/*
Exception: Function.prototype.call called on incompatible Object
@Scratchpad/1:2:1
*/

Clearly, OBJECT is doing something different for [[Ca]] than what an ordinary object does.


> 
> Are you proposing that the definition of Function.prototype.toString
> needs to be reverted to once again use "function object"? If not, what
> is your proposal?

It would be "Function object", but that isn't precise enough.  [[Code]] (the built-in function brand check) is what needs to be used.

Allen

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140812/19182a91/attachment-0001.html>


More information about the es-discuss mailing list