Bug 5227

Summary: Array indexOf() extension for JavaScript 1.5 Core
Product: WebKit Reporter: Justin Haygood <jhaygood>
Component: JavaScriptCoreAssignee: Darin Adler <darin>
Status: RESOLVED FIXED    
Severity: Normal    
Priority: P2    
Version: 420+   
Hardware: PC   
OS: Windows XP   
URL: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf
Attachments:
Description Flags
Adds indexOf support to Array object
none
Testcase
none
Adds indexOf support to Array object
eric: review-
Fixes Complaints
eric: review-
Testcase
none
Expected Results of Testcase
none
Implements indexOf
eric: review-
implements indexof
eric: review-
Implements indexOf, addressing all concerns hopefully :-D
darin: review-
indexOf compatible with Gecko.
mjs: review-
Testcase
none
Updated Expected Results, taken using Gecko's lead
none
indexOf Compatible with Gecko, addresses concerns made by mjs, fixes style issues
darin: review-
Updated Testcase
none
Updated Expected Results (Taken using Firefox 1.4.1)
none
indexOf Compatible with Gecko
darin: review-
indexOf Compatible with Gecko
darin: review-
new patch, including the test case eric: review-

Justin Haygood
Reported 2005-10-01 18:35:23 PDT
Implements indexOf() Can't test since JSCore on Win32 is b0rked. Testcases are attatched, however they aren't in the right form. I know the geniuses there at Apple can properly format it tho!
Attachments
Adds indexOf support to Array object (2.34 KB, patch)
2005-10-01 18:46 PDT, Justin Haygood
no flags
Testcase (1.13 KB, text/html)
2005-10-01 18:47 PDT, Justin Haygood
no flags
Adds indexOf support to Array object (2.36 KB, patch)
2005-10-01 19:04 PDT, Justin Haygood
eric: review-
Fixes Complaints (2.35 KB, patch)
2005-10-02 08:52 PDT, Justin Haygood
eric: review-
Testcase (1.79 KB, text/html)
2005-10-02 08:54 PDT, Justin Haygood
no flags
Expected Results of Testcase (725 bytes, text/plain)
2005-10-02 08:54 PDT, Justin Haygood
no flags
Implements indexOf (1.97 KB, patch)
2005-10-02 12:52 PDT, Justin Haygood
eric: review-
implements indexof (1.98 KB, patch)
2005-10-02 13:00 PDT, Justin Haygood
eric: review-
Implements indexOf, addressing all concerns hopefully :-D (2.04 KB, patch)
2005-10-02 13:43 PDT, Justin Haygood
darin: review-
indexOf compatible with Gecko. (2.24 KB, patch)
2005-10-03 12:34 PDT, Justin Haygood
mjs: review-
Testcase (2.75 KB, text/plain)
2005-10-03 12:34 PDT, Justin Haygood
no flags
Updated Expected Results, taken using Gecko's lead (1.20 KB, text/plain)
2005-10-03 12:35 PDT, Justin Haygood
no flags
indexOf Compatible with Gecko, addresses concerns made by mjs, fixes style issues (2.05 KB, patch)
2005-10-06 10:51 PDT, Justin Haygood
darin: review-
Updated Testcase (2.94 KB, text/html)
2005-10-06 10:53 PDT, Justin Haygood
no flags
Updated Expected Results (Taken using Firefox 1.4.1) (1.53 KB, text/plain)
2005-10-06 10:54 PDT, Justin Haygood
no flags
indexOf Compatible with Gecko (2.03 KB, patch)
2005-10-07 14:32 PDT, Justin Haygood
darin: review-
indexOf Compatible with Gecko (2.02 KB, patch)
2005-10-09 14:17 PDT, Justin Haygood
darin: review-
new patch, including the test case (8.19 KB, patch)
2005-10-09 19:58 PDT, Darin Adler
eric: review-
Justin Haygood
Comment 1 2005-10-01 18:46:40 PDT
Created attachment 4137 [details] Adds indexOf support to Array object
Justin Haygood
Comment 2 2005-10-01 18:47:41 PDT
Created attachment 4138 [details] Testcase Testcase.. works perfectly in Firefox 1.4 (using Gecko 1.8b4)
Justin Haygood
Comment 3 2005-10-01 19:04:39 PDT
Created attachment 4139 [details] Adds indexOf support to Array object Silly rabbit, you have to break out of a case or it'll fall through!
Eric Seidel (no email)
Comment 4 2005-10-01 23:20:58 PDT
Comment on attachment 4139 [details] Adds indexOf support to Array object - Every, ForEach, Some }; + Every, ForEach, Some, IndexOf }; Has tabs instead of spaces. Please fix that first. Also, please include your test case as part of the diff (make landing easier). Also your if statements do not follow the coding guidlines (one line ifs have no {}: http://webkit.opendarwin.org/blog/?page_id=25 Please correct these small oversights and resubmit. Thanks for the patch!
Justin Haygood
Comment 5 2005-10-02 08:52:56 PDT
Created attachment 4147 [details] Fixes Complaints
Justin Haygood
Comment 6 2005-10-02 08:54:17 PDT
Created attachment 4148 [details] Testcase Testcase. I can't include it as part of the cvs diff, since I don't have a Mac to use cvs-create-patch on (it doesn't like Windows)
Justin Haygood
Comment 7 2005-10-02 08:54:57 PDT
Created attachment 4149 [details] Expected Results of Testcase
Eric Seidel (no email)
Comment 8 2005-10-02 12:29:23 PDT
Comment on attachment 4147 [details] Fixes Complaints As I said on IRC: 1. Basically all of the comments should go away. Comments rot even faster than code. The goal is to make your code as readable as possible. If you ever find it too long/too complex to be readable, we suggest using static inline functions with descriptive names. 2. if statements shoudl be broken into two lines, per our coding style guidelines: http://webkit.opendarwin.org/blog/?page_id=25 if (foo) doFoo(); should be if (foo) doFoo();
Justin Haygood
Comment 9 2005-10-02 12:52:24 PDT
Created attachment 4152 [details] Implements indexOf
Justin Haygood
Comment 10 2005-10-02 12:53:42 PDT
Comment on attachment 4152 [details] Implements indexOf * Uses a better check for equality than before (thank you MacDome!) * Follows Code Style Guidelines * Gets Rid of All Junk Comments
Justin Haygood
Comment 11 2005-10-02 13:00:24 PDT
Created attachment 4153 [details] implements indexof Bla, Forgot one if
Eric Seidel (no email)
Comment 12 2005-10-02 13:30:56 PDT
Comment on attachment 4153 [details] implements indexof We discussed this on IRC more. this one fails to return correctly when value not found. I also suggested renaming index to indexFrom, and a cleaner way to have the if statements.
Justin Haygood
Comment 13 2005-10-02 13:43:14 PDT
Created attachment 4157 [details] Implements indexOf, addressing all concerns hopefully :-D Test Case Coming Soon
Darin Adler
Comment 14 2005-10-02 20:45:15 PDT
Comment on attachment 4157 [details] Implements indexOf, addressing all concerns hopefully :-D Thanks for your work on this! There are still a few things to fix and investigate. JavaScript method implementations should almost never look at the size of the args array. That's because most methods ignore extra arguments. By checking specifically for a size of 2, this method won't ignore such extra arguments properly. We need to test Gecko with extra arguments to see what the desired behavior is for compatibility. I'd suggest simply checking args[1] to see if it's undefined, rather than looking at args.size(). The list class always gives undefined rather than doing something bad when you use an index greater than the end of the list, for just this reason. The code to call throwError should return after the call. Despite its name, throwError does not do a C++ throw, and we don't want to fall into the subsequent code. There's no need for a break after a return statement, so that should be removed. We need a test case for when indexOf is called with no arguments at all. Does it find the index of "undefined" in the test array in that case or does it do something else? What about when the looked-for thing is "null"? Does that match "undefined" or not? We also need test cases for when it's called with extra arguments. I also think it's slightly ugly to have a local variable called fromIndex yet use it for indexing through the entire array in a loop. Instead perhaps it should be named something like "i" or "index". We need a test case for when the index is a very large number, too large to fit in a 32-bit integer, and a very small number, too small to fit. Also for negative and positive infinity as well as NaN and negative 0. Note how functions like splice use a double rather than an int to hold the index when doing the range check and how they use toInteger rather than toUInt32. There's a reason for that, which is handling very large or very small numbers; toUInt32 will instead return 0 or a value that's modulo the range of 32-bit integers, which is almost certainly incorrect.
Justin Haygood
Comment 15 2005-10-03 12:32:55 PDT
(In reply to comment #14) > (From update of attachment 4157 [details] [edit]) > Thanks for your work on this! There are still a few things to fix and > investigate. > > JavaScript method implementations should almost never look at the size of the > args array. That's because most methods ignore extra arguments. By checking > specifically for a size of 2, this method won't ignore such extra arguments > properly. Changed. Gecko ignores extra arguments > > We need to test Gecko with extra arguments to see what the desired behavior is > for compatibility. > > I'd suggest simply checking args[1] to see if it's undefined, rather than > looking at args.size(). The list class always gives undefined rather than doing > something bad when you use an index greater than the end of the list, for just > this reason. > > The code to call throwError should return after the call. Despite its name, > throwError does not do a C++ throw, and we don't want to fall into the > subsequent code. > > There's no need for a break after a return statement, so that should be > removed. > > We need a test case for when indexOf is called with no arguments at all. Does > it find the index of "undefined" in the test array in that case or does it do > something else? What about when the looked-for thing is "null"? Does that match > "undefined" or not? We also need test cases for when it's called with extra > arguments. Gecko returns -1. > > I also think it's slightly ugly to have a local variable called fromIndex yet > use it for indexing through the entire array in a loop. Instead perhaps it > should be named something like "i" or "index". I originally had it index. Blame MacDome for the fromIndex suggestion. I prefer index as well. > > We need a test case for when the index is a very large number, too large to fit > in a 32-bit integer, and a very small number, too small to fit. Also for > negative and positive infinity as well as NaN and negative 0. Note how > functions like splice use a double rather than an int to hold the index when > doing the range check and how they use toInteger rather than toUInt32. There's > a reason for that, which is handling very large or very small numbers; toUInt32 > will instead return 0 or a value that's modulo the range of 32-bit integers, > which is almost certainly incorrect. > It uses double now. I have it following Gecko's lead here. Patch and TestCase coming right up.
Justin Haygood
Comment 16 2005-10-03 12:34:13 PDT
Created attachment 4182 [details] indexOf compatible with Gecko. All of Darin's suggestions have been rolled in. It also has a few safety catches to make it safer to call and not crash or do some weird thing.
Justin Haygood
Comment 17 2005-10-03 12:34:47 PDT
Created attachment 4183 [details] Testcase Updated testcase
Justin Haygood
Comment 18 2005-10-03 12:35:24 PDT
Created attachment 4184 [details] Updated Expected Results, taken using Gecko's lead
Maciej Stachowiak
Comment 19 2005-10-03 19:53:19 PDT
Throwing a range error when the from index is negative even after adding the length is wrong. Gecko docs say: "If the calculated index is less than 0, the whole array will be searched." And this matches Firefox behavior. Please fix this point and add a test case for a negative range bigger than the size of the array (since the current tests aren't covering this case). I also suggest testing a discontiguous array. And finally, one of the if statements still has spaces inside the ifs. Patch looks good, other than this one bug and the style issue.
Justin Haygood
Comment 20 2005-10-06 10:51:50 PDT
Created attachment 4236 [details] indexOf Compatible with Gecko, addresses concerns made by mjs, fixes style issues Only one problem I have with this patch. I had to remove the NaN test from the patch, since someone removed ConstantValues::NaN, so if it fails due to it not being a number, don't blame me :-D
Justin Haygood
Comment 21 2005-10-06 10:53:04 PDT
Created attachment 4237 [details] Updated Testcase It adds a testcase for that one missing item. Don't know what a discontiguous array is
Justin Haygood
Comment 22 2005-10-06 10:54:10 PDT
Created attachment 4238 [details] Updated Expected Results (Taken using Firefox 1.4.1) Taken using Firefox 1.4.1, as per the lead we want to follow.
Darin Adler
Comment 23 2005-10-06 11:40:03 PDT
Comment on attachment 4236 [details] indexOf Compatible with Gecko, addresses concerns made by mjs, fixes style issues There's a missing space after the first if before the "(" character. Must fix that. The right way to check if something is undefined is to use the isUndefined() function rather than checking != explicitly against ConstantValues::undefined. Probably OK this way, but not idiomatic. The check of args[0] against undefined could just do an early return rather than if/else. Just a suggestion: optional.
Justin Haygood
Comment 24 2005-10-07 14:32:14 PDT
Created attachment 4246 [details] indexOf Compatible with Gecko Anything else need changing?
Darin Adler
Comment 25 2005-10-07 18:05:49 PDT
Comment on attachment 4246 [details] indexOf Compatible with Gecko I'm sorry to be such a pain. This is nearly perfect, but... + if (args[1]->isUndefined() == false) { The above should be !args[1]->isUndefined() -- we don't use == false for booleans. + else + searchElement = args[0]; The above should not include the optional else; since the if case returns there's no need to have an else. Otherwise, ready to go!
Justin Haygood
Comment 26 2005-10-09 14:17:44 PDT
Created attachment 4270 [details] indexOf Compatible with Gecko Please let this be the last one!
Darin Adler
Comment 27 2005-10-09 16:00:59 PDT
Comment on attachment 4270 [details] indexOf Compatible with Gecko r=me
Darin Adler
Comment 28 2005-10-09 19:23:44 PDT
I did more testing, and this final version does not correctly match Gecko. I added more test cases to demonstrate ways it falls short and I have a revised version of my own.
Darin Adler
Comment 29 2005-10-09 19:24:29 PDT
Comment on attachment 4270 [details] indexOf Compatible with Gecko Testing this one I see that it actually crashes on the test case. I have made a revised version of both the function and the test.
Darin Adler
Comment 30 2005-10-09 19:58:52 PDT
Created attachment 4277 [details] new patch, including the test case Here's what I did: - added null and undefined elements to the test case array to test behavior in those cases - removed special case for an undefined arg0, because Gecko's behavior is to search for an undefined value - changed the length of the function from 2 to 1, because that's the length in Gecko - changed the type of the index used in the loop to unsigned, and just used double when processing the fromIndex argument, being careful to handle overflow, underflow, and NaN correctly - added a check for a null pointer for the result of getProperty, since that's what we get for missing array elements (was causing a crash) - made the early exit from the loop just use a return to eliminate the need to check index outside the loop There are still some minor loose ends I think. The test doesn't test multiple elements in the array with the same value, nor is there a good test to ensure that the comparison done by strictEqual is the right one.
Justin Haygood
Comment 31 2005-10-09 20:14:43 PDT
> There are still some minor loose ends I think. The test doesn't test multiple > elements in the array with the same value, nor is there a good test to ensure > that the comparison done by strictEqual is the right one. Well, you only need to know the address of the first element with the same value, it should return the second it finds it, so that's not a loose end.
Eric Seidel (no email)
Comment 32 2005-10-09 21:50:58 PDT
Comment on attachment 4277 [details] new patch, including the test case Personally I would have chosen something other than "d" as a variable name, as it's often used as the "private" pointer in impls (it's also not very descriptive). 2. Why set e = jsUndefined() and then check equals? Under what conditions does getProperty fail (return NULL) such that matching that index with undefined is OK? Otherwise looks good.
Darin Adler
Comment 33 2005-10-09 21:58:21 PDT
I like "d" for this -- it's used the same way elsewhere in JavaScriptCore. But I could be convinced otherwise in a pinch.
Eric Seidel (no email)
Comment 34 2005-10-09 22:10:25 PDT
Comment on attachment 4277 [details] new patch, including the test case Darin notes on IRC we're missing at least a few more tests: 1. where the array has more than one of the same value 2. where the target is another object using the array prototype 3. "===" rule vs. "==" rule. The code looks fine. Justin, please add these 3 more tests, and we'll land.
Darin Adler
Comment 35 2005-12-18 16:09:46 PST
I added the additional testing, and I'm going to land this now.
Note You need to log in before you can comment on or make changes to this bug.