To put this upfront: this issue affects JavaScriptCore on iOS 8.0 and Mac OS X 10.10. The functionality in question works on iOS 2-7 and OS X 10.5-9. I was told by an Apple engineer at WWDC to file a bug here and start the summary with "REGRESSION". I attempted to replicate this issue in a browser, and it seems my attempt "fails" on older versions (iOS 6/7, OS X 10.8/9), but I could see many (maybe silly/wrong) reasons why this might be different. So, here's an example interaction (using a JavaScript REPL that runs everything through JavaScriptCore). I am going to assign the prototype of the global object and then walk to a variable. My REPL prints objects using JSObjectCopyPropertyNames, but I have also provided code using a for/in loop to get the same data into an array (note the REPL shows the array as an object). Note that I am using the global object: the scenario works for other objects. I have filed two separate bugs because I was asked to do so by Oliver. This bug is in relation to iterating the properties inherited by prototype (here shown using a for/in loop). Here is the working behavior from the old version of JavaScriptCore: cy# a = {}; this.__proto__ = a; a.f = 5; this {a:{f:5},f:5} cy# this.f 5 cy# c = []; for (x in this) c.push(x); c {0:"a",1:"c",2:"f"} Here is the broken behavior from the new version of JavaScriptCore: cy# a = {}; this.__proto__ = a; a.f = 5; this {a:{f:5}} cy# this.f 5 cy# c = []; for (x in this) c.push(x); c {0:"a",1:"c"} FWIW, if there is some different way of doing this, if this was never supposed to have worked, etc. I would be more than happy to be told "do something different". I don't see myself why this shouldn't work, however, and I've been doing this without issue now on JavaScriptCore for over five years.
To make certain this is clear when this bug is evaluated (due to some confusion on #133531), the behavior in my code is to use JSContextGetGlobalObject to get the global object (which I guess is now a JSProxy?), then use JSObjectGetPrototype in a loop to find the top-most prototype, and finally to use JSObjectSetPrototype on the final not-NULL result. I demonstrated the change in behavior using JavaScript in this bug, but I am actually working at the level of JavaScriptCore's API.