To clarify, since I was perhaps "somewhat" terse here. :-)
print(eval('[{"__proto__": 17}]')[0].hasOwnProperty("__proto__"));
print(eval('[{"__proto__":0x17}]')[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.
Jeff
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss