Bug 81588

Summary: Array.prototype.toString should be generic
Product: WebKit Reporter: Erik Arvidsson <arv>
Component: JavaScriptCoreAssignee: Gavin Barraclough <barraclough>
Status: RESOLVED FIXED    
Severity: Normal CC: abarth, andersca, barraclough, hojong.han, oliver, webkit.review.bot
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Unspecified   
Bug Depends on: 83967    
Bug Blocks: 81573, 83787    
Attachments:
Description Flags
Patch
none
Patch
none
Patch
none
Patch
none
partial patch
none
Patch
none
Patch
none
Patch
none
Fix
none
Fix inc layout test changes! sam: review+

Erik Arvidsson
Reported 2012-03-19 16:26:19 PDT
The following fails in JSC Array.prototype.toString.call(document.getElementsByTagName('*')) with a TypeError. The spec is pretty clear here that the above should work. 15.4.4.2 Array.prototype.toString ( ) NOTE The toString function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method. Whether the toString function can be applied successfully to a host object is implementation-dependent.
Attachments
Patch (1.65 KB, patch)
2012-03-29 22:09 PDT, Hojong Han
no flags
Patch (2.29 KB, patch)
2012-04-02 05:26 PDT, Hojong Han
no flags
Patch (4.17 KB, patch)
2012-04-04 03:04 PDT, Hojong Han
no flags
Patch (4.11 KB, patch)
2012-04-04 03:13 PDT, Hojong Han
no flags
partial patch (2.78 KB, patch)
2012-04-07 19:47 PDT, Gavin Barraclough
no flags
Patch (8.17 KB, patch)
2012-04-09 02:45 PDT, Hojong Han
no flags
Patch (7.65 KB, patch)
2012-04-09 03:58 PDT, Hojong Han
no flags
Patch (7.54 KB, patch)
2012-04-09 04:26 PDT, Hojong Han
no flags
Fix (3.75 KB, patch)
2012-04-16 16:35 PDT, Gavin Barraclough
no flags
Fix inc layout test changes! (10.39 KB, patch)
2012-04-16 16:36 PDT, Gavin Barraclough
sam: review+
Hojong Han
Comment 1 2012-03-29 22:09:15 PDT
Erik Arvidsson
Comment 2 2012-03-30 11:09:33 PDT
Comment on attachment 134723 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=134723&action=review Please add tests that ensures the correct behavior. var obj = {__proto__: Array.prototype, 0: 'a', 1: 'b', 2: 'c', length: 3} shouldBeEqualToString('obj.toString()', 'a,b,c'); var join = {join: function() { return 'join' }} shouldBeEqualToString('Array.prototype.toString.call(join)', 'join') shouldBeEqualToString('Array.prototype.toString.call(new Date)', '[object Date]') > Source/JavaScriptCore/runtime/ArrayPrototype.cpp:260 > + JSValue value = thisValue.asCell()->toPrimitive(exec, PreferString); This does not look correct. How does this check for "join" etc?
Hojong Han
Comment 3 2012-04-01 20:24:59 PDT
(In reply to comment #2) > (From update of attachment 134723 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=134723&action=review > > Please add tests that ensures the correct behavior. > > var obj = {__proto__: Array.prototype, 0: 'a', 1: 'b', 2: 'c', length: 3} > shouldBeEqualToString('obj.toString()', 'a,b,c'); > > var join = {join: function() { return 'join' }} > shouldBeEqualToString('Array.prototype.toString.call(join)', 'join') > > shouldBeEqualToString('Array.prototype.toString.call(new Date)', '[object Date]') > > > Source/JavaScriptCore/runtime/ArrayPrototype.cpp:260 > > + JSValue value = thisValue.asCell()->toPrimitive(exec, PreferString); > > This does not look correct. How does this check for "join" etc? Could you explain how Array.prototype.toString.call(join) results join , not [object Object]? (and also Array.prototype.toString.call(new Date) results [object Date], not current date information like Mon Apr 02 2012 12:24:05 GMT+0900 (KST))
Erik Arvidsson
Comment 4 2012-04-01 21:11:58 PDT
The spec is pretty clear here. (Sorry for the brevity, I'm using my phone)
Hojong Han
Comment 5 2012-04-01 23:03:20 PDT
(In reply to comment #4) > The spec is pretty clear here. (Sorry for the brevity, I'm using my phone) I did misunderstand the spec. It's clear now. thanks, Erik.
Hojong Han
Comment 6 2012-04-02 05:26:33 PDT
Darin Adler
Comment 7 2012-04-02 07:49:43 PDT
Comment on attachment 135074 [details] Patch A bug fix like this needs test cases. And it needs performance testing.
Darin Adler
Comment 8 2012-04-02 07:50:20 PDT
Comment on attachment 135074 [details] Patch Please submit a new patch that adds tests for all the new code paths.
Erik Arvidsson
Comment 9 2012-04-02 09:55:01 PDT
Comment on attachment 135074 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=135074&action=review > Source/JavaScriptCore/runtime/ArrayPrototype.cpp:270 > + return JSValue::encode(jsMakeNontrivialString(exec, "[object ", thisObject->methodTable()->className(thisObject), "]")); This does not seem right. You should call the original Object.prototype.toString instead of duplicating its implementation. ...and add tests
Hojong Han
Comment 10 2012-04-02 18:00:55 PDT
(In reply to comment #9) > (From update of attachment 135074 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=135074&action=review > > Source/JavaScriptCore/runtime/ArrayPrototype.cpp:270 > > + return JSValue::encode(jsMakeNontrivialString(exec, "[object ", thisObject->methodTable()->className(thisObject), "]")); > This does not seem right. You should call the original Object.prototype.toString instead of duplicating its implementation. > ...and add tests Thanks for reveiw. I'll apply what you recommend and tests to the new patch.
Hojong Han
Comment 11 2012-04-04 03:04:13 PDT
Early Warning System Bot
Comment 12 2012-04-04 03:08:19 PDT
Early Warning System Bot
Comment 13 2012-04-04 03:12:46 PDT
Hojong Han
Comment 14 2012-04-04 03:13:28 PDT
Erik Arvidsson
Comment 15 2012-04-05 16:00:55 PDT
Olli, Gavin: This bug is blocking 81573 so your feedback is highly appreciated.
Erik Arvidsson
Comment 16 2012-04-06 15:19:37 PDT
The reason why this is blocking 81573 is that NodeList now has Array.prototype on its prototype chain. This will cause toString on a NodeList to call Array.prototype.toString which throws in JSC. I'm tempted to submit 81573 without waiting for this but the JSC behavior until this one is fixed is pretty much unacceptable.
Erik Arvidsson
Comment 17 2012-04-06 15:26:04 PDT
I think this patch might not be sufficient. If someone overrides Array.prototype.join, arrays need to reflect that. For example: Array.prototype.join = function() { return 'join' } shouldBeEqualToString('[0, 1, 2].toString()', 'join'); It seems like the right thing to do is to not special case real arrays and always call join as the spec says.
Hojong Han
Comment 18 2012-04-07 07:35:44 PDT
(In reply to comment #17) > I think this patch might not be sufficient. If someone overrides Array.prototype.join, arrays need to reflect that. For example: > > Array.prototype.join = function() { return 'join' } > shouldBeEqualToString('[0, 1, 2].toString()', 'join'); > > It seems like the right thing to do is to not special case real arrays and always call join as the spec says. I think you are right on the basic principle. It'd better call join as your explanation. but some considerations, such as arguments, will be necessay if join were called in toString. I'll patch again with these.
Gavin Barraclough
Comment 19 2012-04-07 19:44:07 PDT
(In reply to comment #17) > I think this patch might not be sufficient. If someone overrides Array.prototype.join, arrays need to reflect that. For example: > > Array.prototype.join = function() { return 'join' } > shouldBeEqualToString('[0, 1, 2].toString()', 'join'); Agreed - please add this test case. Also, due to the 'if (thisValue.isCell()) {'check, I think this will do the wrong think for non-cell this values, e.g.: Number.prototype.join = function() { return "number join"; } Array.prototype.toString.call(42); > It seems like the right thing to do is to not special case real arrays and always call join as the spec says. From a quick glance it looks like toString is more optimized that join, we could look at similarly optimizing join, but without doing so we wouldn't want to ditch the optimization from toString, and changing functionality and introducing optimizations in the same patch is a bad plan. So it would be best for this patch to fix toString without either removing optimizations from toString or introducing them to join. The 'inherits' check in the current patch is also bogus (not all functions inherit from JSFunction). If we did need to check for functions, the right thing to do would be to would be to check .isFunction - however in this case the spec does not ask for the value to be a function, rather that it is callable (these may be one and the same for objects defined in the ES spec, but is not the same thing in the DOM). The way to check for this is to check the returned CallType for CallTypeNone. Rather than creating a new Identifier every time toString is called, one should be added to CommonIdentifiers. The function call is passing undefined as the this value, this is also wrong. When implementing something like this, I'd suggest the easiest way is to start by copying the text from the spec, and using this a comments to follow, to help make sure your steps are all correct!
Gavin Barraclough
Comment 20 2012-04-07 19:47:09 PDT
Created attachment 136143 [details] partial patch Thought I'd try to help, think this might be a useful starting point. I haven't run the existing regression tests, the new tests from your patch, Erik's proposed test case, or the one I suggest from my patch. So there may be bugs. :-) But hope this is useful.
Hojong Han
Comment 21 2012-04-09 02:45:26 PDT
Hojong Han
Comment 22 2012-04-09 03:20:58 PDT
(In reply to comment #20) > Created an attachment (id=136143) [details] > partial patch > > Thought I'd try to help, think this might be a useful starting point. I haven't run the existing regression tests, the new tests from your patch, Erik's proposed test case, or the one I suggest from my patch. So there may be bugs. :-) But hope this is useful. Thanks a lot, Gavin. I patched by steps you'd taught.
Hojong Han
Comment 23 2012-04-09 03:58:10 PDT
Hojong Han
Comment 24 2012-04-09 04:26:06 PDT
Erik Arvidsson
Comment 25 2012-04-09 09:30:08 PDT
Comment on attachment 136211 [details] Patch This looks pretty good to me. I'll let Gavin or someone else that knows JSC take care of the r+
Erik Arvidsson
Comment 26 2012-04-11 18:47:08 PDT
[ArrayClass] landed so when this lands JSC ports need some rebaselines
Hojong Han
Comment 27 2012-04-11 19:59:40 PDT
(In reply to comment #26) > [ArrayClass] landed so when this lands JSC ports need some rebaselines When was it landed? I cannot find any landed codes affects this latest patch.
Adam Barth
Comment 28 2012-04-11 23:07:43 PDT
> > [ArrayClass] landed so when this lands JSC ports need some rebaselines > > When was it landed? I cannot find any landed codes affects this latest patch. http://trac.webkit.org/changeset/113931
Erik Arvidsson
Comment 29 2012-04-11 23:11:17 PDT
The following tests probably needs rebaselines: LayoutTests/fast/dom/HTMLSelectElement/named-options.html LayoutTests/fast/dom/NodeList/node-list-array-class.html LayoutTests/fast/dom/NodeList/nodelist-item-call-as-function.html since they depend on the toString behavior of NodeList.
Erik Arvidsson
Comment 30 2012-04-13 12:32:18 PDT
This is now causing Gmail to not working when building with JSC.
WebKit Review Bot
Comment 31 2012-04-13 17:26:40 PDT
Comment on attachment 136211 [details] Patch Clearing flags on attachment: 136211 Committed r114185: <http://trac.webkit.org/changeset/114185>
WebKit Review Bot
Comment 32 2012-04-13 17:26:46 PDT
All reviewed patches have been landed. Closing bug.
Anders Carlsson
Comment 33 2012-04-13 18:23:07 PDT
Unfortunately, this broke a bunch of JavaScript tests on the Mac bots (probably more bots as well): fast/dom/HTMLSelectElement/named-options.html fast/dom/NodeList/nodelist-item-call-as-function.html fast/dom/everything-to-string.html fast/js/array-functions-non-arrays.html fast/js/array-prototype-properties.html fast/js/recursion-limit-equal.html fast/js/toString-overrides.html inspector/console/command-line-api.html inspector/console/console-dir.html inspector/console/console-format-collections.html jquery/traversing.html sputnik/Conformance/15_Native_Objects/15.4_Array/15.4.4/15.4.4.2_Array_prototype_toString/S15.4.4.2_A2_T1.html sputnik/Conformance/15_Native_Objects/15.4_Array/15.4.4/15.4.4.3_Array_prototype_toLocaleString/S15.4.4.3_A1_T1.html I don't know if all of them are progressions so I'm going to roll out the patch.
Alexey Proskuryakov
Comment 34 2012-04-15 00:03:35 PDT
This fix was rolled out in <http://trac.webkit.org/changeset/114195>, so reopening.
Hojong Han
Comment 35 2012-04-15 18:21:49 PDT
(In reply to comment #30) > This is now causing Gmail to not working when building with JSC. Erik, could you let me know which one is "This", patch or bug? Layout test has not been run under my development environmen so that I've not been able to update the patch with rebaseline... Sorry for this.
Gavin Barraclough
Comment 36 2012-04-16 10:02:05 PDT
(In reply to comment #35) > Layout test has not been run under my development environmen If you want to contribute patches to WebKit, we do require that you run the regression tests on your changes.
Gavin Barraclough
Comment 37 2012-04-16 16:35:37 PDT
Gavin Barraclough
Comment 38 2012-04-16 16:36:59 PDT
Created attachment 137430 [details] Fix inc layout test changes!
Hojong Han
Comment 39 2012-04-16 17:03:23 PDT
(In reply to comment #36) > (In reply to comment #35) > > Layout test has not been run under my development environmen > > If you want to contribute patches to WebKit, we do require that you run the regression tests on your changes. Yes, of course. What I meant is that my system had some problems while running layout tests for rebaseline so that I couldn't patch right away. I should have let people know this before landing.
Gavin Barraclough
Comment 40 2012-04-17 11:59:15 PDT
Fixed in r114405
Note You need to log in before you can comment on or make changes to this bug.