<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>28117</bug_id>
          
          <creation_ts>2009-08-08 21:02:10 -0700</creation_ts>
          <short_desc>Native JSON.stringify does not omit functions</short_desc>
          <delta_ts>2009-08-13 13:27:24 -0700</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>JavaScriptCore</component>
          <version>528+ (Nightly build)</version>
          <rep_platform>Mac (Intel)</rep_platform>
          <op_sys>OS X 10.5</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc>http://lucassmith.name/pub/JSON-test-suite/test.html</bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords>HasReduction, InRadar</keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>0</everconfirmed>
          <reporter name="Luke Smith">lsmith</reporter>
          <assigned_to name="Nobody">webkit-unassigned</assigned_to>
          <cc>brendan</cc>
    
    <cc>kangax</cc>
    
    <cc>oliver</cc>
    
    <cc>rspeyer</cc>
    
    <cc>ryan</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>138465</commentid>
    <comment_count>0</comment_count>
    <who name="Luke Smith">lsmith</who>
    <bug_when>2009-08-08 21:02:10 -0700</bug_when>
    <thetext>JSON does not define functions.  They should be treated in the same manner as undefined, omitted in objects and replaced by null in arrays.

Nightly r46919 stringifies functions as objects.

JSON.stringify({fn:function () {}}) should return &apos;{}&apos; but returns &apos;{&quot;fn&quot;:{}}&apos; in the nightly.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>138547</commentid>
    <comment_count>1</comment_count>
    <who name="Mark Rowe (bdash)">mrowe</who>
    <bug_when>2009-08-09 13:36:52 -0700</bug_when>
    <thetext>&lt;rdar://problem/7129375&gt;</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>138551</commentid>
    <comment_count>2</comment_count>
    <who name="Oliver Hunt">oliver</who>
    <bug_when>2009-08-09 13:44:14 -0700</bug_when>
    <thetext>This is a bug in firefox.  Functions are an object, and therefore should be emitted, per section 15.12.3 of es262-5</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>138553</commentid>
    <comment_count>3</comment_count>
    <who name="Oliver Hunt">oliver</who>
    <bug_when>2009-08-09 13:57:10 -0700</bug_when>
    <thetext>https://bugzilla.mozilla.org/show_bug.cgi?id=509339</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>138584</commentid>
    <comment_count>4</comment_count>
    <who name="Luke Smith">lsmith</who>
    <bug_when>2009-08-09 20:31:50 -0700</bug_when>
    <thetext>Per the final draft of the ECMA 5 spec located at http://www.ecma-international.org/publications/files/drafts/tc39-2009-025.pdf

Section 15.12.3 states in the definition of the Str abstract function
4. If value is null then return &quot;null&quot;. 
5. If value is true then return &quot;true&quot;. 
6. If value is false then return &quot;false&quot;. 
7. If Type(value) is object then, 
a. If the [[Class]] internal property of value is &quot;Number&quot; then, 
i. Let value be ToNumber(value). 
b. Else if the [[Class]] internal property of value is &quot;String&quot; then, 
i. Let value be ToString(value). 
8. If Type(value) is string, then return the result of calling the abstract operation Quote with argument 
value. 
9. If Type(value) is number 
a. If value is finite then return ToString(value). 
b. else, return &quot;null&quot;. 
10. If Type(value) is object, and IsCallable(value) is false 
a. If the [[Class]] internal property of value is &quot;Array&quot; then 
i. Return the result of calling the abstract operation JA with argument value. 
b. Return the result of calling the abstract operation JO with argument value. 
11. Return undefined.


Note 10. and IsCallable(value) is false

Also, every implementation of JSON including the reference implementation by Douglas Crockford treats functions as it would undefined.

From Crockford&apos;s http://json.org/json2.js
&quot;Values that do not have JSON representations, such as undefined or
functions, will not be serialized. Such values in objects will be
dropped; in arrays they will be replaced with null. You can use
a replacer function to replace those with JSON values.
JSON.stringify(undefined) returns undefined.&quot;

From http://json.org/js.html
&quot;Values that do not have a representation in JSON (such as functions and undefined) are excluded.&quot;</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>138585</commentid>
    <comment_count>5</comment_count>
    <who name="Oliver Hunt">oliver</who>
    <bug_when>2009-08-09 20:47:54 -0700</bug_when>
    <thetext>Ah indeed.  That makes me sad.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>139228</commentid>
    <comment_count>6</comment_count>
      <attachid>34637</attachid>
    <who name="Oliver Hunt">oliver</who>
    <bug_when>2009-08-11 21:43:54 -0700</bug_when>
    <thetext>Created attachment 34637
Patch v1</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>139230</commentid>
    <comment_count>7</comment_count>
    <who name="Oliver Hunt">oliver</who>
    <bug_when>2009-08-11 21:57:36 -0700</bug_when>
    <thetext>Committed r47086</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>139257</commentid>
    <comment_count>8</comment_count>
      <attachid>34637</attachid>
    <who name="Darin Adler">darin</who>
    <bug_when>2009-08-11 22:54:33 -0700</bug_when>
    <thetext>Comment on attachment 34637
Patch v1

Why not use inherits(&amp;InternalFunction::info) instead of calling getCallData and then special-casing JSArray?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>139261</commentid>
    <comment_count>9</comment_count>
    <who name="Oliver Hunt">oliver</who>
    <bug_when>2009-08-11 23:04:59 -0700</bug_when>
    <thetext>(In reply to comment #8)
&gt; (From update of attachment 34637 [details])
&gt; Why not use inherits(&amp;InternalFunction::info) instead of calling getCallData
&gt; and then special-casing JSArray?

The uses the IsCallable internal function -- inheriting from InternalFunction is not a sufficient check, but now i&apos;ve tested firefox with a regex, /a/, they clearly are ignoring IsCallable
*yay*</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>139373</commentid>
    <comment_count>10</comment_count>
    <who name="Luke Smith">lsmith</who>
    <bug_when>2009-08-12 09:49:26 -0700</bug_when>
    <thetext>What was the test against FF?  RegExp should return false to IsCallable.  Safari and webkit have been incorrectly reporting typeof /a/ === &apos;function&apos; for several versions.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>139444</commentid>
    <comment_count>11</comment_count>
    <who name="Oliver Hunt">oliver</who>
    <bug_when>2009-08-12 11:27:45 -0700</bug_when>
    <thetext>(In reply to comment #10)
&gt; What was the test against FF?  RegExp should return false to IsCallable. 
&gt; Safari and webkit have been incorrectly reporting typeof /a/ === &apos;function&apos; for
&gt; several versions.

RegExps are callable -- eg. /b/(&quot;abc&quot;) -- the regex is callable, that means that the internal property IsCallable() must return true, which means that regexps should not be serialised.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>139718</commentid>
    <comment_count>12</comment_count>
    <who name="Luke Smith">lsmith</who>
    <bug_when>2009-08-12 21:45:52 -0700</bug_when>
    <thetext>I was unaware of this feature until reading your comment.  This behavior is not in the spec.

section 9.11 specifies IsCallable
If the argument object has an [[Call]] internal method, then return true, otherwise return false.

The only references in the spec to setting the [[Call]] internal method are
13.2 Creating Function objects
13.2.3 The [[ThrowTypeError]] Function Object
15.3.4.5 Function.prototype.bind (thisArg [, arg1 [, arg2, …]])

Section 15.10.6, defining RegExp, states
The value of the [[Prototype]] internal property of the RegExp prototype object is the standard built-in 
Object prototype object (15.2.4)

I found that /a/(&quot;abc&quot;) is implemented (inconsistently) in Firefox 3.0, Firefox 3.5, Safari 3.2.1,  Safari 4, Opera 9.6.3, Opera 10 beta2, Chrome 3 beta, and the WebKit nightlies.  It is not implemented in IE6, IE7, IE8, or Chrome 2.

Mozilla identifies this feature as a JavaScript extension
https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/RegExp#RegExp_instances

I infer that such is the case for the others, WebKit included.  The difference here being that the other browser vendors prevent the spec deviation from rippling through their implementation to (at least) typeof and recently to JSON.stringify.

Currently native JSON support is present in Firefox 3.5, IE8, Chrome 3 beta, and recent WebKit nightlies.  All three of the other currently implementing browsers agree both that typeof /a/ == &apos;object&apos; and JSON.stringify(/a/) == &apos;{}&apos;.  There is value in interoperability.  If not typeof, please at least stringify RegExp instances as objects for the sake of convention.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>139728</commentid>
    <comment_count>13</comment_count>
    <who name="Oliver Hunt">oliver</who>
    <bug_when>2009-08-12 22:26:10 -0700</bug_when>
    <thetext>&gt; Currently native JSON support is present in Firefox 3.5, IE8, Chrome 3 beta,
&gt; and recent WebKit nightlies.  All three of the other currently implementing
&gt; browsers agree both that typeof /a/ == &apos;object&apos; and JSON.stringify(/a/) ==
&gt; &apos;{}&apos;.  There is value in interoperability.  If not typeof, please at least
&gt; stringify RegExp instances as objects for the sake of convention.

RegExps are callable -- breaking this would break compatibility with json2.js, and the bug is in mozilla for not correctly treating a callable object as callable.

We cannot reasonably serialise regexps as standard objects -- the bug is in firefox, not webkit.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>139737</commentid>
    <comment_count>14</comment_count>
    <who name="Luke Smith">lsmith</who>
    <bug_when>2009-08-12 23:26:37 -0700</bug_when>
    <thetext>&gt; breaking this would break compatibility with json2.js

Can you explain this?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>139738</commentid>
    <comment_count>15</comment_count>
    <who name="Raphael Speyer">rspeyer</who>
    <bug_when>2009-08-12 23:45:40 -0700</bug_when>
    <thetext>(In reply to comment #13)
&gt; RegExps are callable -- breaking this would break compatibility with json2.js,
&gt; and the bug is in mozilla for not correctly treating a callable object as
&gt; callable.

I think there is an important distinction between a vendor extension to EcmaScript to allow an object to be treated as a function, and the meaning of IsCallable in the spec.

As Luke mentioned above, according to the spec, a IsCallable is false for RegExp&apos;s, and thus they should be serialised by JSON.stringify, in 15.12.3 step 10.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>139739</commentid>
    <comment_count>16</comment_count>
    <who name="Raphael Speyer">rspeyer</who>
    <bug_when>2009-08-12 23:48:32 -0700</bug_when>
    <thetext>(In reply to comment #15)

&gt; As Luke mentioned above, according to the spec, a IsCallable is false for
&gt; RegExp&apos;s, and thus they should be serialised by JSON.stringify, in 15.12.3 step
&gt; 10.

That is, step 10 of the Str operation.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>139742</commentid>
    <comment_count>17</comment_count>
    <who name="Oliver Hunt">oliver</who>
    <bug_when>2009-08-13 00:19:20 -0700</bug_when>
    <thetext>(In reply to comment #16)
&gt; (In reply to comment #15)
&gt; 
&gt; &gt; As Luke mentioned above, according to the spec, a IsCallable is false for
&gt; &gt; RegExp&apos;s, and thus they should be serialised by JSON.stringify, in 15.12.3 step
&gt; &gt; 10.
&gt; 
&gt; That is, step 10 of the Str operation.

json2.js uses typeof holder === &quot;function&quot; to determine whether an object IsCallable, and regexp instances have the type &quot;function&quot;.  This is correct behaviour, per ES5 (from ES262, v5, 11.4.3)
Object (native and doesn‘t implement  [[Call]])  -&gt; &quot;object&quot; 
Object (native or host and implements  [[Call]]) -&gt; &quot;function&quot; 

IsCallable is defined in section 9.11:
If the argument object has an [[Call]] internal method, then return true, otherwise 
return false. 

In other words, a RegExp instance has [[Call]] so typeof should be &quot;function&quot;, and [[IsCallable]] is true.

You seem to believe that there is value in serialising a regexp object, when there is not -- a serialised regexp object is either undefined (in conforming implementations in which regexps are callable) or as the empty object {} (in conforming implementations in whichs regexps are not callable).

Firefox is not conforming in this regard.  Arguing will not accopmlish anything as it is pointless to add a slow check which will break behaviour relative to json2, just to handle the specific case of RegExps, when there are numerous other disagreements between different runtimes as to which objects are callable (NodeLists anyone?), especially given the serialisation of RegExps is unhelpful in either case.

If you feel really strongly about this, i suggest you go to http://bugs.mozilla.org and file a bug on the spidermonkey RegExp object incorrectly reporting typeof as &quot;object&quot; and claiming not to be callable.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>139746</commentid>
    <comment_count>18</comment_count>
    <who name="Raphael Speyer">rspeyer</who>
    <bug_when>2009-08-13 00:56:17 -0700</bug_when>
    <thetext>(In reply to comment #17)
&gt; 
&gt; json2.js uses typeof holder === &quot;function&quot; to determine whether an object
&gt; IsCallable, 

That seems reasonable to me.

&gt; and regexp instances have the type &quot;function&quot;.  

I think this is the crux of the issue. I know that webkit gives typeof /a/ ===
&apos;function&apos;, but I don&apos;t understand why. The spec does not say anywhere that a RegExp defines the internal property [[Call]].

&gt; This is correct
&gt; behaviour, per ES5 (from ES262, v5, 11.4.3)
&gt; Object (native and doesn‘t implement  [[Call]])  -&gt; &quot;object&quot; 
&gt; Object (native or host and implements  [[Call]]) -&gt; &quot;function&quot; 
&gt; 

Exactly. So, wouldn&apos;t RegExp&apos;s fall into the first category? Yes, they can be treated as functions, but that&apos;s a particular vendor extension, it&apos;s not how RegExp instances are specified to behave.

&gt; IsCallable is defined in section 9.11:
&gt; If the argument object has an [[Call]] internal method, then return true,
&gt; otherwise 
&gt; return false. 

Right, and again, as per the spec, a RegExp does not have a [[Call]] internal method.

&gt; 
&gt; In other words, a RegExp instance has [[Call]] so typeof should be &quot;function&quot;,
&gt; and [[IsCallable]] is true.
&gt; 

I think we forked back at /a/(&apos;a&apos;) implying that at a specification level, [[Call]] is defined for RegExp&apos;s.

&gt; You seem to believe that there is value in serialising a regexp object, when
&gt; there is not -- a serialised regexp object is either undefined (in conforming
&gt; implementations in which regexps are callable) or as the empty object {} (in
&gt; conforming implementations in whichs regexps are not callable).
&gt; 

Granted, it&apos;s not going to be typical, and I can&apos;t actually think of a very good use case for it myself. However enumerable properties can be defined on RegExp&apos;s or their prototype, as can the toJSON method. I think this is more about conformance with the spec.

&gt; Firefox is not conforming in this regard.  Arguing will not accopmlish anything
&gt; as it is pointless to add a slow check which will break behaviour relative to
&gt; json2, just to handle the specific case of RegExps, when there are numerous
&gt; other disagreements between different runtimes as to which objects are callable
&gt; (NodeLists anyone?), especially given the serialisation of RegExps is unhelpful
&gt; in either case.
&gt; 
&gt; If you feel really strongly about this, i suggest you go to
&gt; http://bugs.mozilla.org and file a bug on the spidermonkey RegExp object
&gt; incorrectly reporting typeof as &quot;object&quot; and claiming not to be callable.

Well, as I said above, as far as I can tell, the spec says that RegExp is not callable, in the sense that the internal [[Call]] property is not defined, IsCallable will return false and thus at the language level, typeof should return &apos;object&apos;, and stringify should not ignore it.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>139795</commentid>
    <comment_count>19</comment_count>
    <who name="kangax">kangax</who>
    <bug_when>2009-08-13 04:40:09 -0700</bug_when>
    <thetext>(In reply to comment #18)
&gt; (In reply to comment #17)
[...]
&gt; &gt; Firefox is not conforming in this regard.  Arguing will not accopmlish anything
&gt; &gt; as it is pointless to add a slow check which will break behaviour relative to
&gt; &gt; json2, just to handle the specific case of RegExps, when there are numerous
&gt; &gt; other disagreements between different runtimes as to which objects are callable
&gt; &gt; (NodeLists anyone?), especially given the serialisation of RegExps is unhelpful
&gt; &gt; in either case.
&gt; &gt; 
&gt; &gt; If you feel really strongly about this, i suggest you go to
&gt; &gt; http://bugs.mozilla.org and file a bug on the spidermonkey RegExp object
&gt; &gt; incorrectly reporting typeof as &quot;object&quot; and claiming not to be callable.
&gt; 
&gt; Well, as I said above, as far as I can tell, the spec says that RegExp is not
&gt; callable, in the sense that the internal [[Call]] property is not defined,
&gt; IsCallable will return false and thus at the language level, typeof should
&gt; return &apos;object&apos;, and stringify should not ignore it.

Yes, at the &quot;language level&quot; `RegExp` objects don&apos;t have [[Call]], but don&apos;t forget that ES3 allows implementations to extend language and still be considered conforming. Quoting section 2:

| A conforming implementation of ECMAScript is permitted to provide 
| additional types, values, objects, properties, and functions beyond those
| described in this specification. In particular, a conforming implementation
| of ECMAScript is permitted to provide properties not described in this
| specification, and values for those properties, for objects that are
| described in this specification.

So here we are with a conforming implementation that adds [[Call]] to RegExp objects. Note that nowhere does ES3 explicitly disallow for `RegExp` objects to have [[Call]] as it does for, say, `Math` or &quot;Global object&quot;.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>139832</commentid>
    <comment_count>20</comment_count>
    <who name="Raphael Speyer">rspeyer</who>
    <bug_when>2009-08-13 07:20:53 -0700</bug_when>
    <thetext>(In reply to comment #19)
&gt; (In reply to comment #18)
&gt; &gt; (In reply to comment #17)
&gt; [...]
&gt; &gt; 
&gt; &gt; Well, as I said above, as far as I can tell, the spec says that RegExp is not
&gt; &gt; callable, in the sense that the internal [[Call]] property is not defined,
&gt; &gt; IsCallable will return false and thus at the language level, typeof should
&gt; &gt; return &apos;object&apos;, and stringify should not ignore it.
&gt; 
&gt; Yes, at the &quot;language level&quot; `RegExp` objects don&apos;t have [[Call]], but don&apos;t
&gt; forget that ES3 allows implementations to extend language and still be
&gt; considered conforming. Quoting section 2:
&gt; 
&gt; | A conforming implementation of ECMAScript is permitted to provide 
&gt; | additional types, values, objects, properties, and functions beyond those
&gt; | described in this specification. In particular, a conforming implementation
&gt; | of ECMAScript is permitted to provide properties not described in this
&gt; | specification, and values for those properties, for objects that are
&gt; | described in this specification.
&gt; 
&gt; So here we are with a conforming implementation that adds [[Call]] to RegExp
&gt; objects. Note that nowhere does ES3 explicitly disallow for `RegExp` objects to
&gt; have [[Call]] as it does for, say, `Math` or &quot;Global object&quot;.

Good points. I guess to some extent it&apos;s a matter of interpretation here.

To me /a/(&apos;abc&apos;) just looks like syntactic sugar for /a/.exec(&apos;abc&apos;). /a/ is certainly not a member of the &quot;function&quot; objects described in section 13 or 15.3 of the spec. The view that it&apos;s simply (unspecified) syntactic sugar, and doesn&apos;t change anything about the runtime behaviour seems to be Mozilla&apos;s approach.

On the other hand, WebKit seem to have taken it as both additional syntax and also a semantic change such that while a RegExp instance is not a function as in &quot;/a/ instanceof Function&quot;, it does have an internal [[Call]] property, which is called by this new syntax. Perhaps that view is just as valid, but it does alter the behaviour of syntactically identical programs. It&apos;s hard to tell who&apos;s right because this behaviour was never specified to begin with.

I guess there&apos;s not much more for me I can say here. This sort of thing is best clarified, and specified (or explicitly not specified) by the TC39 commitee.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>139875</commentid>
    <comment_count>21</comment_count>
    <who name="Brendan Eich">brendan</who>
    <bug_when>2009-08-13 09:34:57 -0700</bug_when>
    <thetext>I cited these Mozilla bug reports to Ollie over IRC:

https://bugzilla.mozilla.org/show_bug.cgi?id=61911
https://bugzilla.mozilla.org/show_bug.cgi?id=289933

We fixed the higher-numbered one first, making typeof /a/ == &quot;function&quot;. But then we retreated in 61911 due to complaints and (I seem to recall; it&apos;s hard to find evidence at the moment) real web compatibility problems.

The complaints weren&apos;t all from spec-purists who did not like the extension in SpiderMonkey that allows /a/(s) as shorthand for /a/.exec(s). I remember more than a few places where real code was flummoxed by typeof /a/ == &quot;function&quot;. This confusing result broke code, whether or not such code expected (this would have been Mozilla-specific code, originally) to be able to call a regexp as shorthand for exec&apos;ing it.

Anyway, we threw in the towel with the resolution of 61911. The only further retreat for us is to remove callability, but that may be hard. We may be stuck. We can&apos;t easily go back to typeof /a/ == &quot;function&quot;, in any event.

/be</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>139909</commentid>
    <comment_count>22</comment_count>
    <who name="Brendan Eich">brendan</who>
    <bug_when>2009-08-13 10:16:38 -0700</bug_when>
    <thetext>I&apos;ve re-raised this issue (it has been beaten around before) on es-discuss:

https://mail.mozilla.org/pipermail/es-discuss/2009-August/009718.html

/be</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>139938</commentid>
    <comment_count>23</comment_count>
    <who name="Oliver Hunt">oliver</who>
    <bug_when>2009-08-13 11:13:13 -0700</bug_when>
    <thetext>&gt; &gt; and regexp instances have the type &quot;function&quot;.  
&gt; 
&gt; I think this is the crux of the issue. I know that webkit gives typeof /a/ ===
&gt; &apos;function&apos;, but I don&apos;t understand why. The spec does not say anywhere that a
&gt; RegExp defines the internal property [[Call]].
&gt; 
&gt; &gt; This is correct
&gt; &gt; behaviour, per ES5 (from ES262, v5, 11.4.3)
&gt; &gt; Object (native and doesn‘t implement  [[Call]])  -&gt; &quot;object&quot; 
&gt; &gt; Object (native or host and implements  [[Call]]) -&gt; &quot;function&quot; 
&gt; &gt; 
&gt; 
&gt; Exactly. So, wouldn&apos;t RegExp&apos;s fall into the first category? Yes, they can be
&gt; treated as functions, but that&apos;s a particular vendor extension, it&apos;s not how
&gt; RegExp instances are specified to behave.
&gt; 
&gt; &gt; IsCallable is defined in section 9.11:
&gt; &gt; If the argument object has an [[Call]] internal method, then return true,
&gt; &gt; otherwise 
&gt; &gt; return false. 
&gt; 
&gt; Right, and again, as per the spec, a RegExp does not have a [[Call]] internal
&gt; method.
And you can take that up with mozilla who decided to give RegExp are

If an object can be called it is by definition callable.  To be called an
object must provide [[Call]] -- if you look at section 11.2.3 you will see that
a function call will throw an exception if IsCallable(func) returns false. 
Therefore by definition IsCallable must be true.

&gt; 
&gt; &gt; 
&gt; &gt; In other words, a RegExp instance has [[Call]] so typeof should be &quot;function&quot;,
&gt; &gt; and [[IsCallable]] is true.
&gt; &gt; 
&gt; 
&gt; I think we forked back at /a/(&apos;a&apos;) implying that at a specification level,
&gt; [[Call]] is defined for RegExp&apos;s.
Mozilla extended the spec by saying RegExps were callable, thus forcing us to
implement this extension or be broken.  [[Call]] is defined on on RegExp as an
extension, but that does not make it not present.

&gt; Well, as I said above, as far as I can tell, the spec says that RegExp is not
&gt; callable, in the sense that the internal [[Call]] property is not defined,
&gt; IsCallable will return false and thus at the language level, typeof should
&gt; return &apos;object&apos;, and stringify should not ignore it.
[[Call]] is defined, IsCallable is true, typeof is function, and serialisation
should skip it.  If you want to argue this more, please provide a logical
explanation beyond &quot;firefox violates spec here, so should you&quot;

Once again, the fact that /a/(&quot;a&quot;) does not throw an exception demonstrates
that IsCallable(/a/) must be true in firefox</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>139950</commentid>
    <comment_count>24</comment_count>
    <who name="Brendan Eich">brendan</who>
    <bug_when>2009-08-13 11:40:16 -0700</bug_when>
    <thetext>Ollie, could you point me to bugs or URLs showing where you had to follow the SpiderMonkey extension of callable regexps &quot;or be broken&quot;? Thanks,

/be</thetext>
  </long_desc>
      
          <attachment
              isobsolete="0"
              ispatch="1"
              isprivate="0"
          >
            <attachid>34637</attachid>
            <date>2009-08-11 21:43:54 -0700</date>
            <delta_ts>2009-08-11 22:54:33 -0700</delta_ts>
            <desc>Patch v1</desc>
            <filename>bug-28117-20090811214353.patch</filename>
            <type>text/plain</type>
            <size>6005</size>
            <attacher name="Oliver Hunt">oliver</attacher>
            
              <data encoding="base64">ZGlmZiAtLWdpdCBhL0phdmFTY3JpcHRDb3JlL0NoYW5nZUxvZyBiL0phdmFTY3JpcHRDb3JlL0No
YW5nZUxvZwppbmRleCA5NjJlNDZlLi5mM2I2N2I4IDEwMDY0NAotLS0gYS9KYXZhU2NyaXB0Q29y
ZS9DaGFuZ2VMb2cKKysrIGIvSmF2YVNjcmlwdENvcmUvQ2hhbmdlTG9nCkBAIC0xLDUgKzEsMTgg
QEAKIDIwMDktMDgtMTEgIE9saXZlciBIdW50ICA8b2xpdmVyQGFwcGxlLmNvbT4KIAorICAgICAg
ICBSZXZpZXdlZCBieSBOT0JPRFkoT09QUykuCisKKyAgICAgICAgTmF0aXZlIEpTT04uc3RyaW5n
aWZ5IGRvZXMgbm90IG9taXQgZnVuY3Rpb25zCisgICAgICAgIGh0dHBzOi8vYnVncy53ZWJraXQu
b3JnL3Nob3dfYnVnLmNnaT9pZD0yODExNworCisgICAgICAgIE9iamVjdHMgdGhhdCBhcmUgY2Fs
bGFibGUgc2hvdWxkIGJlIHRyZWF0ZWQgYXMgdW5kZWZpbmVkIHdoZW4KKyAgICAgICAgc2VyaWFs
aXNpbmcgdG8gSlNPTi4KKworICAgICAgICAqIHJ1bnRpbWUvSlNPTk9iamVjdC5jcHA6CisgICAg
ICAgIChKU0M6OlN0cmluZ2lmaWVyOjphcHBlbmRTdHJpbmdpZmllZFZhbHVlKToKKworMjAwOS0w
OC0xMSAgT2xpdmVyIEh1bnQgIDxvbGl2ZXJAYXBwbGUuY29tPgorCiAgICAgICAgIFJldmlld2Vk
IGJ5IEdlb2ZmIEdhcmVuLgogCiAgICAgICAgIFJFR1JFU1NJT046IEhhbmcvY3Jhc2ggaW4gQnl0
ZWNvZGVHZW5lcmF0b3I6OmNvbnN0UmVnaXN0ZXJGb3IgbG9hZGluZyBzaW1wbGUgcGFnZQpkaWZm
IC0tZ2l0IGEvSmF2YVNjcmlwdENvcmUvcnVudGltZS9KU09OT2JqZWN0LmNwcCBiL0phdmFTY3Jp
cHRDb3JlL3J1bnRpbWUvSlNPTk9iamVjdC5jcHAKaW5kZXggZDY0MzgwOC4uZmVkOWZjMyAxMDA2
NDQKLS0tIGEvSmF2YVNjcmlwdENvcmUvcnVudGltZS9KU09OT2JqZWN0LmNwcAorKysgYi9KYXZh
U2NyaXB0Q29yZS9ydW50aW1lL0pTT05PYmplY3QuY3BwCkBAIC0zODEsNiArMzgxLDE1IEBAIFN0
cmluZ2lmaWVyOjpTdHJpbmdpZnlSZXN1bHQgU3RyaW5naWZpZXI6OmFwcGVuZFN0cmluZ2lmaWVk
VmFsdWUoU3RyaW5nQnVpbGRlciYKIAogICAgIEpTT2JqZWN0KiBvYmplY3QgPSBhc09iamVjdCh2
YWx1ZSk7CiAKKyAgICBDYWxsRGF0YSBjYWxsRGF0YTsKKyAgICBpZiAob2JqZWN0LT5nZXRDYWxs
RGF0YShjYWxsRGF0YSkgIT0gQ2FsbFR5cGVOb25lKSB7CisgICAgICAgIGlmIChob2xkZXItPmlu
aGVyaXRzKCZKU0FycmF5OjppbmZvKSkgeworICAgICAgICAgICAgYnVpbGRlci5hcHBlbmQoIm51
bGwiKTsKKyAgICAgICAgICAgIHJldHVybiBTdHJpbmdpZnlTdWNjZWVkZWQ7CisgICAgICAgIH0K
KyAgICAgICAgcmV0dXJuIFN0cmluZ2lmeUZhaWxlZER1ZVRvVW5kZWZpbmVkVmFsdWU7CisgICAg
fQorCiAgICAgLy8gSGFuZGxlIGN5Y2xlIGRldGVjdGlvbiwgYW5kIHB1dCB0aGUgaG9sZGVyIG9u
IHRoZSBzdGFjay4KICAgICBpZiAoIW1faG9sZGVyQ3ljbGVEZXRlY3Rvci5hZGQob2JqZWN0KS5z
ZWNvbmQpIHsKICAgICAgICAgdGhyb3dFcnJvcihtX2V4ZWMsIFR5cGVFcnJvciwgIkpTT04uc3Ry
aW5naWZ5IGNhbm5vdCBzZXJpYWxpemUgY3ljbGljIHN0cnVjdHVyZXMuIik7CmRpZmYgLS1naXQg
YS9MYXlvdXRUZXN0cy9DaGFuZ2VMb2cgYi9MYXlvdXRUZXN0cy9DaGFuZ2VMb2cKaW5kZXggMWM2
MzcyMS4uMGJmNTAyMCAxMDA2NDQKLS0tIGEvTGF5b3V0VGVzdHMvQ2hhbmdlTG9nCisrKyBiL0xh
eW91dFRlc3RzL0NoYW5nZUxvZwpAQCAtMSwzICsxLDE4IEBACisyMDA5LTA4LTExICBPbGl2ZXIg
SHVudCAgPG9saXZlckBhcHBsZS5jb20+CisKKyAgICAgICAgUmV2aWV3ZWQgYnkgTk9CT0RZIChP
T1BTISkuCisKKyAgICAgICAgTmF0aXZlIEpTT04uc3RyaW5naWZ5IGRvZXMgbm90IG9taXQgZnVu
Y3Rpb25zCisgICAgICAgIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0y
ODExNworCisgICAgICAgIFRlc3Qgc2VyaWFsaXNhdGlvbiBvZiBmdW5jdGlvbiBvYmplY3RzLgor
CisgICAgICAgICogZmFzdC9qcy9KU09OLXN0cmluZ2lmeS1leHBlY3RlZC50eHQ6CisgICAgICAg
ICogZmFzdC9qcy9KU09OLXN0cmluZ2lmeS1yZXBsYWNlci1leHBlY3RlZC50eHQ6CisgICAgICAg
ICogZmFzdC9qcy9yZXNvdXJjZXMvSlNPTi1zdHJpbmdpZnktcmVwbGFjZXIuanM6CisgICAgICAg
ICogZmFzdC9qcy9yZXNvdXJjZXMvSlNPTi1zdHJpbmdpZnkuanM6CisgICAgICAgIChjcmVhdGVU
ZXN0cy5yZXN1bHQucHVzaC4pOgorCiAyMDA5LTA4LTExICBCcmFkeSBFaWRzb24gIDxiZWlkc29u
QGFwcGxlLmNvbT4KIAogICAgICAgICBSdWJiZXJzdGFtcGVkIGJ5IE1hcmsgUm93ZS4KZGlmZiAt
LWdpdCBhL0xheW91dFRlc3RzL2Zhc3QvanMvSlNPTi1zdHJpbmdpZnktZXhwZWN0ZWQudHh0IGIv
TGF5b3V0VGVzdHMvZmFzdC9qcy9KU09OLXN0cmluZ2lmeS1leHBlY3RlZC50eHQKaW5kZXggMDA0
YTAxMS4uMTFlZjdiOCAxMDA2NDQKLS0tIGEvTGF5b3V0VGVzdHMvZmFzdC9qcy9KU09OLXN0cmlu
Z2lmeS1leHBlY3RlZC50eHQKKysrIGIvTGF5b3V0VGVzdHMvZmFzdC9qcy9KU09OLXN0cmluZ2lm
eS1leHBlY3RlZC50eHQKQEAgLTM1Miw2ICszNTIsMTQgQEAgZnVuY3Rpb24gKGpzb25PYmplY3Qp
IHsKICAgICB9CiBQQVNTIHRlc3RzW2ldKG5hdGl2ZUpTT04pIGlzIHRlc3RzW2ldKEpTT04pCiBm
dW5jdGlvbiAoanNvbk9iamVjdCkgeworICAgICAgICByZXR1cm4ganNvbk9iamVjdC5zdHJpbmdp
Znkoe2E6e3RvSlNPTjpmdW5jdGlvbigpeyByZXR1cm4gZnVuY3Rpb24oKXt9OyB9fX0pOworICAg
IH0KK1BBU1MgdGVzdHNbaV0obmF0aXZlSlNPTikgaXMgdGVzdHNbaV0oSlNPTikKK2Z1bmN0aW9u
IChqc29uT2JqZWN0KSB7CisgICAgICAgIHJldHVybiBqc29uT2JqZWN0LnN0cmluZ2lmeSh7YTpm
dW5jdGlvbigpe319KTsKKyAgICB9CitQQVNTIHRlc3RzW2ldKG5hdGl2ZUpTT04pIGlzIHRlc3Rz
W2ldKEpTT04pCitmdW5jdGlvbiAoanNvbk9iamVjdCkgewogICAgICAgICB2YXIgZGVlcE9iamVj
dCA9IHt9OwogICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDIwNDg7IGkrKykKICAgICAgICAg
ICAgIGRlZXBPYmplY3QgPSB7bmV4dDpkZWVwT2JqZWN0fTsKZGlmZiAtLWdpdCBhL0xheW91dFRl
c3RzL2Zhc3QvanMvSlNPTi1zdHJpbmdpZnktcmVwbGFjZXItZXhwZWN0ZWQudHh0IGIvTGF5b3V0
VGVzdHMvZmFzdC9qcy9KU09OLXN0cmluZ2lmeS1yZXBsYWNlci1leHBlY3RlZC50eHQKaW5kZXgg
OGYyYjhmMS4uYTA1ZTZkOSAxMDA2NDQKLS0tIGEvTGF5b3V0VGVzdHMvZmFzdC9qcy9KU09OLXN0
cmluZ2lmeS1yZXBsYWNlci1leHBlY3RlZC50eHQKKysrIGIvTGF5b3V0VGVzdHMvZmFzdC9qcy9K
U09OLXN0cmluZ2lmeS1yZXBsYWNlci1leHBlY3RlZC50eHQKQEAgLTExLDYgKzExLDggQEAgUEFT
UyBKU09OLnN0cmluZ2lmeShvYmplY3QsIHJldHVybkFycmF5Rm9yMSkgaXMgJ3siMCI6MCwiMSI6
W10sIjIiOjJ9JwogUEFTUyBKU09OLnN0cmluZ2lmeShhcnJheSwgcmV0dXJuQXJyYXlGb3IxKSBp
cyAnWzAsW10sMixudWxsXScKIFBBU1MgSlNPTi5zdHJpbmdpZnkob2JqZWN0LCByZXR1cm5VbmRl
ZmluZWRGb3IxKSBpcyAneyIwIjowLCIyIjoyfScKIFBBU1MgSlNPTi5zdHJpbmdpZnkoYXJyYXks
IHJldHVyblVuZGVmaW5lZEZvcjEpIGlzICdbMCxudWxsLDIsbnVsbF0nCitQQVNTIEpTT04uc3Ry
aW5naWZ5KG9iamVjdCwgcmV0dXJuRnVuY3Rpb25Gb3IxKSBpcyAneyIwIjowLCIyIjoyfScKK1BB
U1MgSlNPTi5zdHJpbmdpZnkoYXJyYXksIHJldHVybkZ1bmN0aW9uRm9yMSkgaXMgJ1swLG51bGws
MixudWxsXScKIFBBU1MgSlNPTi5zdHJpbmdpZnkob2JqZWN0LCByZXR1cm5OdWxsRm9yMSkgaXMg
J3siMCI6MCwiMSI6bnVsbCwiMiI6Mn0nCiBQQVNTIEpTT04uc3RyaW5naWZ5KGFycmF5LCByZXR1
cm5OdWxsRm9yMSkgaXMgJ1swLG51bGwsMixudWxsXScKIFBBU1MgSlNPTi5zdHJpbmdpZnkob2Jq
ZWN0LCByZXR1cm5TdHJpbmdGb3JVbmRlZmluZWQpIGlzICd7IjAiOjAsIjEiOjEsIjIiOjIsIjMi
OiJ1bmRlZmluZWQgdmFsdWUifScKZGlmZiAtLWdpdCBhL0xheW91dFRlc3RzL2Zhc3QvanMvcmVz
b3VyY2VzL0pTT04tc3RyaW5naWZ5LXJlcGxhY2VyLmpzIGIvTGF5b3V0VGVzdHMvZmFzdC9qcy9y
ZXNvdXJjZXMvSlNPTi1zdHJpbmdpZnktcmVwbGFjZXIuanMKaW5kZXggMmI1Yzg3Mi4uMGZkMTc1
MyAxMDA2NDQKLS0tIGEvTGF5b3V0VGVzdHMvZmFzdC9qcy9yZXNvdXJjZXMvSlNPTi1zdHJpbmdp
ZnktcmVwbGFjZXIuanMKKysrIGIvTGF5b3V0VGVzdHMvZmFzdC9qcy9yZXNvdXJjZXMvSlNPTi1z
dHJpbmdpZnktcmVwbGFjZXIuanMKQEAgLTMzLDYgKzMzLDExIEBAIGZ1bmN0aW9uIHJldHVybkN5
Y2xlQXJyYXlGb3IxKGssIHYpIHsKICAgICAgICAgcmV0dXJuIGFycmF5OwogICAgIHJldHVybiB2
OwogfQorZnVuY3Rpb24gcmV0dXJuRnVuY3Rpb25Gb3IxKGssIHYpIHsKKyAgICBpZiAoayA9PSAi
MSIpCisgICAgICAgIHJldHVybiBmdW5jdGlvbigpe307CisgICAgcmV0dXJuIHY7Cit9CiBmdW5j
dGlvbiByZXR1cm5TdHJpbmdGb3JVbmRlZmluZWQoaywgdikgewogICAgIGlmICh2ID09PSB1bmRl
ZmluZWQpCiAgICAgICAgIHJldHVybiAidW5kZWZpbmVkIHZhbHVlIjsKQEAgLTUxLDYgKzU2LDkg
QEAgc2hvdWxkQmUoIkpTT04uc3RyaW5naWZ5KGFycmF5LCByZXR1cm5BcnJheUZvcjEpIiwgJ1wn
WzAsW10sMixudWxsXVwnJyk7CiBzaG91bGRCZSgiSlNPTi5zdHJpbmdpZnkob2JqZWN0LCByZXR1
cm5VbmRlZmluZWRGb3IxKSIsICdcJ3siMCI6MCwiMiI6Mn1cJycpOwogc2hvdWxkQmUoIkpTT04u
c3RyaW5naWZ5KGFycmF5LCByZXR1cm5VbmRlZmluZWRGb3IxKSIsICdcJ1swLG51bGwsMixudWxs
XVwnJyk7CiAKK3Nob3VsZEJlKCJKU09OLnN0cmluZ2lmeShvYmplY3QsIHJldHVybkZ1bmN0aW9u
Rm9yMSkiLCAnXCd7IjAiOjAsIjIiOjJ9XCcnKTsKK3Nob3VsZEJlKCJKU09OLnN0cmluZ2lmeShh
cnJheSwgcmV0dXJuRnVuY3Rpb25Gb3IxKSIsICdcJ1swLG51bGwsMixudWxsXVwnJyk7CisKIHNo
b3VsZEJlKCJKU09OLnN0cmluZ2lmeShvYmplY3QsIHJldHVybk51bGxGb3IxKSIsICdcJ3siMCI6
MCwiMSI6bnVsbCwiMiI6Mn1cJycpOwogc2hvdWxkQmUoIkpTT04uc3RyaW5naWZ5KGFycmF5LCBy
ZXR1cm5OdWxsRm9yMSkiLCAnXCdbMCxudWxsLDIsbnVsbF1cJycpOwogCmRpZmYgLS1naXQgYS9M
YXlvdXRUZXN0cy9mYXN0L2pzL3Jlc291cmNlcy9KU09OLXN0cmluZ2lmeS5qcyBiL0xheW91dFRl
c3RzL2Zhc3QvanMvcmVzb3VyY2VzL0pTT04tc3RyaW5naWZ5LmpzCmluZGV4IGU0MDIzMTMuLmYw
MjRiN2UgMTAwNjQ0Ci0tLSBhL0xheW91dFRlc3RzL2Zhc3QvanMvcmVzb3VyY2VzL0pTT04tc3Ry
aW5naWZ5LmpzCisrKyBiL0xheW91dFRlc3RzL2Zhc3QvanMvcmVzb3VyY2VzL0pTT04tc3RyaW5n
aWZ5LmpzCkBAIC0zMTYsNiArMzE2LDEyIEBAIGZ1bmN0aW9uIGNyZWF0ZVRlc3RzKCkgewogICAg
ICAgICByZXR1cm4ganNvbk9iamVjdC5zdHJpbmdpZnkoe2E6e3RvSlNPTjpmdW5jdGlvbigpeyBy
ZXR1cm4gbnVsbDsgfX19KTsKICAgICB9KTsKICAgICByZXN1bHQucHVzaChmdW5jdGlvbihqc29u
T2JqZWN0KXsKKyAgICAgICAgcmV0dXJuIGpzb25PYmplY3Quc3RyaW5naWZ5KHthOnt0b0pTT046
ZnVuY3Rpb24oKXsgcmV0dXJuIGZ1bmN0aW9uKCl7fTsgfX19KTsKKyAgICB9KTsKKyAgICByZXN1
bHQucHVzaChmdW5jdGlvbihqc29uT2JqZWN0KXsKKyAgICAgICAgcmV0dXJuIGpzb25PYmplY3Qu
c3RyaW5naWZ5KHthOmZ1bmN0aW9uKCl7fX0pOworICAgIH0pOworICAgIHJlc3VsdC5wdXNoKGZ1
bmN0aW9uKGpzb25PYmplY3QpewogICAgICAgICB2YXIgZGVlcE9iamVjdCA9IHt9OwogICAgICAg
ICBmb3IgKHZhciBpID0gMDsgaSA8IDIwNDg7IGkrKykKICAgICAgICAgICAgIGRlZXBPYmplY3Qg
PSB7bmV4dDpkZWVwT2JqZWN0fTs=
</data>
<flag name="review"
          id="18787"
          type_id="1"
          status="+"
          setter="barraclough"
    />
          </attachment>
      

    </bug>

</bugzilla>