B.3.1 The __proto__ pseudo property

Jeff Walden jwalden+es at MIT.EDU
Wed Apr 24 11:05:05 PDT 2013

To clarify, since I was perhaps "somewhat" terse here.  :-)

  print(eval('[{"__proto__":  17}]')[0].hasOwnProperty("__proto__"));

SunSpider uses eval() on JSONish input, so engines have to make that fast.  Most/all engines for potential JSON-looking input (wrapped in '()' or '[]') attempt to JSON-parse the string before doing a full parse.  If the JSON-parse fails (probably quickly, if it does), fall back to a full parse.  If it succeeds, yay, you probably saved a bunch of time, return the resulting value.

(It's no longer that simple, of course.  |"use strict"; eval('({"x":2,"x":4})');| must throw a SyntaxError for duplicate property, so the hack can't be used if the caller's strict.  And then http://timelessrepo.com/json-isnt-a-javascript-subset observed that JSON allows U+2028 and U+2029 where JS doesn't.  So at least SpiderMonkey does a linear search for them in the string [post-JSON-parse] and falls back to the main JS parser if either's found.)

The weird behavior is because JSON-parsing treats __proto__ as a regular old property.  (The second case isn't JSON: hex's forbidden.)  If the engine hacks JSON parsing into eval, and implements JSON.parse('{"__proto__":2}').hasOwnProperty("__proto__") correctly, you get this oddity.

The obvious workaround is to search for __proto__ in the eval-string and not JSON-parse if it's found.  I have my doubts the SunSpider-score hit for the strstr over the entire input string can be eaten, but I could be mistaken.

Summary: horrible pile of hacks for a, er, venerable benchmark.

The reason for mentioning this here/now is that if quotes-means-[[DefineOwnProperty]] were standard, using the JSON parser on eval input would be fine here, and all complexity of this quirk would disappear.  Or we could just add yet more modes of JSON-looking parsing.  Or something.  Blargh.


More information about the es-discuss mailing list