<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Where&#039;s Walden? &#187; es5</title>
	<atom:link href="http://whereswalden.com/tag/es5/feed/" rel="self" type="application/rss+xml" />
	<link>http://whereswalden.com</link>
	<description>Mozilla, politics, economics, law, backpacking, cycling, and other random desiderata</description>
	<lastBuildDate>Wed, 25 Jan 2012 18:17:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>I feel the need&#8230;the need for JSON parsing correctness and speed!</title>
		<link>http://whereswalden.com/2011/06/06/i-feel-the-need-the-need-for-json-parsing-correctness-and-speed/</link>
		<comments>http://whereswalden.com/2011/06/06/i-feel-the-need-the-need-for-json-parsing-correctness-and-speed/#comments</comments>
		<pubDate>Mon, 06 Jun 2011 23:17:34 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[ecma-262]]></category>
		<category><![CDATA[ecmascript]]></category>
		<category><![CDATA[es5]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[json.parse]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[speed]]></category>
		<category><![CDATA[spidermonkey]]></category>

		<guid isPermaLink="false">http://whereswalden.com/?p=3149</guid>
		<description><![CDATA[JSON and SpiderMonkey JSON is a handy serialization format for passing data between servers and browsers and between independent, cooperating web pages. It&#8217;s increasingly the format of choice for website APIs. ECMAScript 5 (the standard underlying JavaScript) includes built-in support for producing and parsing JSON. SpiderMonkey has included such support since before ES5 added it. [...]]]></description>
			<content:encoded><![CDATA[<h2><a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/JSON"><abbr title="JavaScript Object Notation">JSON</abbr></a> and SpiderMonkey</h2>
<p>JSON is a handy <a href="http://www.ietf.org/rfc/rfc4627.txt">serialization format</a> for passing data between servers and browsers and between independent, cooperating web pages.  It&#8217;s increasingly <a href="http://blog.programmableweb.com/2011/05/25/1-in-5-apis-say-bye-xml/">the format of choice</a> for website <abbr title="application programming interfaces">APIs</abbr>.</p>
<p>ECMAScript 5 (the standard underlying JavaScript) includes built-in support for producing and parsing JSON.  SpiderMonkey has included such support since before <abbr title="ECMAScript 5">ES5</abbr> added it.</p>
<p>SpiderMonkey&#8217;s support, because it predated ES5, hasn&#8217;t always agreed with ES5.  Also, because JSON support was added before it became ubiquitous on the web, it wasn&#8217;t written with raw speed in mind.</p>
<h2>Improving <code>JSON.parse</code></h2>
<p>We&#8217;ve now improved JSON parsing in Firefox 5 to be fast and fully conformant with ES5.  For awhile we&#8217;ve made <a href="http://whereswalden.com/2010/09/08/spidermonkey-json-change-trailing-commas-no-longer-accepted/">improvements</a> to JSON by piecemeal change.  This worked for small bug fixes, and it probably would have worked to fix the remaining conformance bugs.  But performance is different: to improve performance we needed to parse in a fundamentally different way.  It was time for a <a href="http://www.joelonsoftware.com/articles/fog0000000069.html">rewrite</a>.</p>
<h2>What parsing bugs got fixed?</h2>
<p>The bugs the new parser fixes are quite small and generally shouldn&#8217;t affect sites, in part because other browsers overwhelmingly don&#8217;t have these bugs.  We&#8217;ve had no compatibility reports for these fixes in the month and a half they&#8217;ve been in the tree:</p>
<ul>
<li>The number syntax is properly stricter:
<ul>
<li>Octal numbers are now syntax errors.</li>
<li>Numbers containing a decimal point must now include a fractional component (<abbr title="id est, that is" lang="la">i.e.</abbr> <code>1.</code> is no longer accepted).</li>
</ul>
</li>
<li><code>JSON.parse("this")</code> now throws a <code>SyntaxError</code> rather than evaluate to <code>true</code>, due to a mistake reusing our keyword parser.  (Hysterically, because we used our JSON parser to optimize <code>eval</code> in certain cases, this change means that <code>eval("(this)")</code> will no longer evaluate to <code>true</code>.)</li>
<li>Strings can&#8217;t contain tab characters: <code>JSON.parse('"\t"')</code> now properly throws a <code>SyntaxError</code>.</li>
</ul>
<p>This list of changes <em>should</em> be complete, but it&#8217;s possible I&#8217;ve missed others.  Parsing might be a solved problem in the compiler literature, but it&#8217;s still pretty complicated.  I could have missed lurking bugs in the old parser, and it&#8217;s possible (although I think less likely) that I&#8217;ve introduced bugs in the new parser.</p>
<h2>What about speed?</h2>
<p>The new parser is much faster than the old one.  Exactly how fast depends on the data you&#8217;re parsing.  For example, on Opera&#8217;s <a href="http://testsuites.opera.com/JSON/performance/001.html">simple parse</a> test, I get around 156000 times/second in Firefox 4, but in Firefox 5 with the new JSON parser I get around 339000 times/second (bigger is better).  On a second testcase, <a href="http://krakenbenchmark.mozilla.org/">Kraken&#8217;s</a> <code>JSON.parse</code> test (json-parse-financial, to be precise), I get a 4.0 time of around 140ms and a 5.0 time of around 100ms (smaller is better).  (In both cases I&#8217;m comparing builds containing far more JavaScript changes than just the new parser, to be sure.  But I&#8217;m pretty sure the bulk of the performance improvements in these two cases are due to the new parser.)  The new JSON parser puts us solidly in the center of the browser pack.</p>
<p>It&#8217;ll only get better in the future as we wring even more speed out of SpiderMonkey.  After all, on the same system used to generate the above numbers, IE gets around 510000 times/second.  I expect further speedup will happen during more generalized performance improvements: improving the speed of defining new properties, improving the speed with which objects are allocated, improving the speed of creating a property name from a string, and so on.  As we perform such streamlining, we&#8217;ll parse JSON even faster.</p>
<h2>Side benefit: better error messages</h2>
<p>The parser rewrite also gives <code>JSON.parse</code> better error messages.  With the old parser it would have been difficult to provide useful feedback, but in the new parser it&#8217;s easy to briefly describe the reason for syntax errors.</p>
<pre>
js&gt; JSON.parse('{ foo: 17 }'); // unquoted property name
(old) typein:1: SyntaxError: JSON.parse
(new) typein:1: SyntaxError: JSON.parse: expected property name or '}'
</pre>
<p>We can definitely <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=507998">do more here</a>, perhaps by including context for the error from the provided string, but this is nevertheless a marked improvement over the old parser&#8217;s error messages.</p>
<h2>Bottom line</h2>
<p><code>JSON.parse</code> in Firefox 5 is faster, follows the spec, and tells you what went wrong if you give it bad data.  &#8217;nuff said.</p>
]]></content:encoded>
			<wfw:commentRss>http://whereswalden.com/2011/06/06/i-feel-the-need-the-need-for-json-parsing-correctness-and-speed/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>JavaScript change for Firefox 5 (not 4): class, enum, export, extends, import, and super are once again reserved words per ECMAScript 5</title>
		<link>http://whereswalden.com/2011/03/16/javascript-change-for-firefox-5-not-4-class-enum-export-extends-import-and-super-are-once-again-reserved-words-per-ecmascript-5/</link>
		<comments>http://whereswalden.com/2011/03/16/javascript-change-for-firefox-5-not-4-class-enum-export-extends-import-and-super-are-once-again-reserved-words-per-ecmascript-5/#comments</comments>
		<pubDate>Wed, 16 Mar 2011 16:53:50 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[ecmascript]]></category>
		<category><![CDATA[enum]]></category>
		<category><![CDATA[es5]]></category>
		<category><![CDATA[export]]></category>
		<category><![CDATA[extends]]></category>
		<category><![CDATA[import]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[keyword]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[reserved word]]></category>
		<category><![CDATA[super]]></category>

		<guid isPermaLink="false">http://whereswalden.com/?p=2865</guid>
		<description><![CDATA[Most programming languages have keywords or reserved words: names which can&#8217;t be used to name variables. Keywords have special meaning, so using them as variable names would conflict with such use. Reserved words are keywords of the future: names which might eventually be given special meaning, so they can&#8217;t be used now to ease future [...]]]></description>
			<content:encoded><![CDATA[<p>Most programming languages have <dfn>keywords</dfn> or <dfn>reserved words</dfn>: names which can&#8217;t be used to name variables.  Keywords have special meaning, so using them as variable names would conflict with such use.  Reserved words are keywords of the future: names which might eventually be given special meaning, so they can&#8217;t be used now to ease future adoption.</p>
<p>JavaScript and the ECMAScript standard that underlie it historically have had an excessively large set of keywords and reserved words &#8220;inherited&#8221; from Java.  <abbr title="ECMAScript 5">ES5</abbr> partially loosened <abbr title="ECMAScript 3">ES3</abbr>&#8216;s past keyword restrictions.  For example, <code>byte</code>, <code>char</code>, and <code>int</code> were reserved in ES3 but aren&#8217;t in ES5.</p>
<p>Many years ago, before work started on ECMAScript after ES3, a few browsers stopped reserving all of ES3&#8242;s reserved words.  In response browsers generally started to un-reserve many of these names.  As it turned out this un-reservation went too far: ES5 un-reserved many of these words, but it didn&#8217;t un-reserve all of them.  In particular, while some implementations un-reserved the names <code>class</code>, <code>enum</code>, <code>export</code>, <code>extends</code>, <code>import</code>, and <code>super</code>, ES5 did not.</p>
<p>Firefox un-reserved these names then along with some other browsers.  But as ES5 corrects the over-reservation of ES3 without un-reserving these names, we are moving to align with ES5 by re-reserving <code>class</code>, <code>enum</code>, <code>export</code>, <code>extends</code>, <code>import</code>, and <code>super</code> in all code.  (Firefox 4 reserves these names only in strict mode code.)</p>
<p>You can experiment with a version of Firefox with these changes by downloading a <a href="http://nightly.mozilla.org/js-preview.html">TraceMonkey nightly build</a>.  Trunk&#8217;s still locked down for Firefox 4, so it hasn&#8217;t picked up these changes just yet.  (Don’t forget to <a href="http://support.mozilla.com/en-US/kb/Managing+profiles">use the profile manager</a> if you want to keep the settings you use with your primary Firefox installation pristine.)</p>
]]></content:encoded>
			<wfw:commentRss>http://whereswalden.com/2011/03/16/javascript-change-for-firefox-5-not-4-class-enum-export-extends-import-and-super-are-once-again-reserved-words-per-ecmascript-5/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>JavaScript change in Firefox 5 (not 4), and in other browsers: regular expressions can&#8217;t be called like functions</title>
		<link>http://whereswalden.com/2011/03/06/javascript-change-in-firefox-5-not-4-and-in-other-browsers-regular-expressions-cant-be-called-like-functions/</link>
		<comments>http://whereswalden.com/2011/03/06/javascript-change-in-firefox-5-not-4-and-in-other-browsers-regular-expressions-cant-be-called-like-functions/#comments</comments>
		<pubDate>Mon, 07 Mar 2011 01:44:08 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[callable]]></category>
		<category><![CDATA[ecmascript]]></category>
		<category><![CDATA[es5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[regular expression]]></category>
		<category><![CDATA[spidermonkey]]></category>

		<guid isPermaLink="false">http://whereswalden.com/?p=2829</guid>
		<description><![CDATA[Callable regular expressions Way back in the day when Netscape implemented regular expressions in JavaScript, it made them callable. If you slapped an argument list after a regular expression, it&#8217;d act as if you called RegExp.prototype.exec on it with the provided arguments. var r = /abc/, res; res = r("abc"); assert(res.length === 1); res = [...]]]></description>
			<content:encoded><![CDATA[<h2>Callable regular expressions</h2>
<p>Way back in the day when Netscape implemented regular expressions in JavaScript, it made them callable.  If you slapped an argument list after a regular expression, it&#8217;d act as if you called <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/RegExp/exec"><code>RegExp.prototype.exec</code></a> on it with the provided arguments.</p>
<pre class="code" data-language="javascript">
var r = /abc/, res;

res = r("abc");
assert(res.length === 1);

res = r("def");
assert(res === null);
</pre>
<p>Why?  Beats me.  I&#8217;d have thought <code>.exec</code> was easy enough to type and clearer to boot, myself.  Hopefully readers familiar with the history can explain in comments.</p>
<h2>Problems</h2>
<p>Callable regular expressions present one immediate problem to a &#8220;naive&#8221; implementation: their behavior with <a href="https://developer.mozilla.org/en/JavaScript/Reference/Operators/Special/typeof"><code>typeof</code></a>.  According to ECMAScript, the <code>typeof</code> for any object which is callable should be <code>"function"</code>, and Netscape and Mozilla for a long time faithfully implemented this.  This tended to cause <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=61911">much confusion</a> in practice, so browsers that implemented callable regular expressions eventually changed <code>typeof</code> to arguably &#8220;lie&#8221; for regular expressions and return <code>"object"</code>.  In SpiderMonkey the &#8220;fix&#8221; was an utterly inelegant hack which distinguished callables as either regular expressions or not, to determine <code>typeof</code> behavior.</p>
<p>Past this, callable regular expressions complicate implementing callability and optimizations of it.  Implementations supporting getters and setters (once purely as an extension, now standardized in <abbr title="ECMAScript 5th edition">ES5</abbr>) must consider the case where the getter or setter is a regular expression and do something appropriate.  And of course they must handle regular old calls, qualified (<code>/a/()</code>) and unqualified (<code>({ p: /a/ }).p()</code>) both.  Mozilla&#8217;s had a solid trickle of bugs involving callable regular expressions, almost always filed as a result of <a href="http://squarefree.com/">Jesse</a>&#8216;s evil fuzzers (and not due to actual sites breaking).</p>
<p>It&#8217;s also hard to justify callable regular expressions as an extension.  While ECMAScript explicitly permits extensions, it generally prefers extensions to be new methods or properties of existing objects.  Regular expression callability is neither of these: instead it&#8217;s adding an internal hook to regular expressions to make them callable.  This might not technically be contrary to the spec, but it goes against its spirit.</p>
<h2>Regular expressions won&#8217;t be callable in Firefox 5</h2>
<p>No one&#8217;s ever really used callable regular expressions.  They&#8217;re non-standard, not all browsers implement them, and they unnecessarily complicate implementations.  So, in concert with other browser engines like <a href="https://bugs.webkit.org/show_bug.cgi?id=28285">WebKit</a>, we&#8217;re making regular expressions non-callable in Firefox 5.  (Regular expressions are callable in Firefox 4, but of course don&#8217;t rely on this.)</p>
<p>You can experiment with a version of Firefox with these changes by downloading a <a href="http://nightly.mozilla.org/js-preview.html">TraceMonkey nightly build</a>.  Trunk&#8217;s still locked down for Firefox 4, so it won&#8217;t pick up the change until Firefox 4 branches and trunk reopens for changes targeted at the next release.  (Don’t forget to <a href="http://support.mozilla.com/en-US/kb/Managing+profiles">use the profile manager</a> if you want to keep the settings you use with your primary Firefox installation pristine.)</p>
]]></content:encoded>
			<wfw:commentRss>http://whereswalden.com/2011/03/06/javascript-change-in-firefox-5-not-4-and-in-other-browsers-regular-expressions-cant-be-called-like-functions/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>The proper way to call parseInt (tl;dr: parseInt(str, radix))</title>
		<link>http://whereswalden.com/2011/02/26/the-proper-way-to-call-parseint-tldr-parseintstr-radix/</link>
		<comments>http://whereswalden.com/2011/02/26/the-proper-way-to-call-parseint-tldr-parseintstr-radix/#comments</comments>
		<pubDate>Sun, 27 Feb 2011 03:04:02 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[decimal]]></category>
		<category><![CDATA[ecmascript]]></category>
		<category><![CDATA[es5]]></category>
		<category><![CDATA[hexadecimal]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[octal]]></category>
		<category><![CDATA[parseInt]]></category>

		<guid isPermaLink="false">http://whereswalden.com/?p=2793</guid>
		<description><![CDATA[Introduction Allen Wirfs-Brock recently discussed the impedance mismatch when functions accepting optional arguments are incompatibly combined, considering in particular combining parseInt and Array.prototype.map. In doing so he makes this comment: The most common usage of parseInt passes only a single argument Allen Wirfs-Brock, A JavaScript Optional Argument Hazard Code-quality systems like JSLint routinely warn about [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p><a href="http://www.wirfs-brock.com/allen/">Allen Wirfs-Brock</a> recently discussed the impedance mismatch when functions accepting optional arguments are incompatibly combined, considering in particular combining <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/parseInt"><code>parseInt</code></a> and <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/map"><code>Array.prototype.map</code></a>.  In doing so he makes this comment:</p>
<blockquote cite="http://www.wirfs-brock.com/allen/posts/166"><p>The most common usage of parseInt passes only a single argument</p>
</blockquote>
<div class="attribution">Allen Wirfs-Brock, <a href="http://www.wirfs-brock.com/allen/posts/166">A JavaScript Optional Argument Hazard</a></div>
<p>Code-quality systems like <a href="http://www.jslint.com/">JSLint</a> routinely warn about <code>parseInt</code> without an explicit radix.  Most uses might well pass only a single argument, but I could easily imagine this going the other way.</p>
<p>This raises an interesting question: <em>why</em> do lints warn about using <code>parseInt</code> without a radix?</p>
<h2><code>parseInt</code> and radixes</h2>
<p>Like much of JavaScript, <code>parseInt</code> tries to be helpful when called without an explicitly specified radix.  It attempts to guess a suitable radix:</p>
<pre class="code" data-language="javascript">
assertEq(parseInt("+17"), 17);
assertEq(parseInt("42"), 42);
assertEq(parseInt("-0x42"), -66);
// assertEq(parseInt("0755"), ???); // we'll get back to this
</pre>
<p>If the string (after optional leading whitespace and <code>+</code> or <code>-</code>) starts with a non-zero decimal digit, it&#8217;s parsed as decimal.  But if the string begins with <code>0</code>, things get wacky.  If the next character is <code>x</code> or <code>X</code>, the number is parsed in base-16: hexadecimal.  Last, if the next character isn&#8217;t <code>x</code> or <code>X</code>&#8230;hold that thought.  I&#8217;ll return to it in a moment.</p>
<p>Thus the behavior of <code>parseInt</code> without a radix depends not just on the numeric contents of the string but also upon its internal structure, entirely separate from its contents.  This alone is reason enough to always specify a radix: specify a radix <code>2 &le; r &le; 36</code> and it will be used, no guessing, no uncertain behavior in the face of varying strings.  (Although, to be sure, there&#8217;s still a very slight wrinkle: if <code>r === 16</code> and your string begins with <code>0x</code> or <code>0X</code>, they&#8217;ll be skipped when determining the integer to return.  But this is a pretty far-out edge case where you might want to parse a hexadecimal string without a prefix and would also want to process one <em>with</em> a prefix as just <code>0</code>.)</p>
<h2>But wait!  There&#8217;s more</h2>
<p>Beyond cuteness lies another concern.  Let&#8217;s return to the leading-zero-but-not-hexadecimal case:</p>
<pre class="code" data-language="javascript">
parseInt("0755");
</pre>
<p>In some programming languages a leading zero (that&#8217;s not part of a hexadecimal prefix) means the number is base-8: octal.  So maybe JavaScript infers this to be an octal number, returning <code>7 × 8 × 8 + 5 × 8 + 5 === 493</code>.</p>
<p>On the other hand, as I noted <a href="https://developer.mozilla.org/en/JavaScript/Strict_mode">in Mozilla&#8217;s <abbr title="ECMAScript 5th edition">ES5</abbr> strict mode documentation</a>, there&#8217;s some evidence that people use leading zeroes as alignment devices, thinking they have no semantic effect.  So maybe leading zero is decimal instead.</p>
<h2>The wonderful thing about standards is that there are so many of them to choose from</h2>
<p>According to <abbr title="ECMAScript 3rd edition">ES3</abbr>, a leading zero with no explicit radix is either decimal <em>or</em>, if octal extensions have been implemented, octal.  So what happens depends on who wrote the ES3 implementation, and what choice they made.  But what if it&#8217;s an ES5 implementation?  ES5 explicitly forbids octal and says this is interpreted as decimal.  Therefore, <code>parseInt("0755")</code> is <code>755</code> in bog-standard ES3 implementations, <code>493</code> in ES3 implementations which have implemented octal extensions, and <code>755</code> in conforming ES5 implementations.  Isn&#8217;t it great?</p>
<h2>What do browsers actually do?</h2>
<p>On the web everyone implements the octal extensions, so you&#8217;ll have to look hard to find an ES3 browser that doesn&#8217;t make <code>parseInt("0755") === 493</code>.  But ES3 is old and busted, and ES5 is the new hotness.  What do ES5 implementations do, especially as the change in ES5 isn&#8217;t backwards-compatible?</p>
<p>Surprisingly browsers aren&#8217;t all playing chicken here, waiting to see that they can change without breaking sites.  On this particular point <abbr title="Internet Explorer 9">IE9</abbr> leads the way (in standards mode code only), implementing <code>parseInt("0755") === 755</code> despite having implemented <code>parseInt("0755") === 493</code> in the past.  Before I saw IE9 implemented this (although I hasten to note they have not shipped a release with it yet), I expected no browser would implement it due to the possibility of breaking sites.  After seeing IE9&#8242;s example, I&#8217;m less certain.  Hopefully their experience will shed light on the decision for the other browser vendors.</p>
<h2>Conclusion</h2>
<p>Precise details of browser and specification inconsistencies aside, the point remains that <code>parseInt(str)</code> tries to be cute when parsing <code>str</code>.  That cuteness can make <code>parseInt(str)</code> unpredictable if inputs vary sufficiently.  Avoid edge-case bugs and use <code>parseInt(str, radix)</code> instead.</p>
]]></content:encoded>
			<wfw:commentRss>http://whereswalden.com/2011/02/26/the-proper-way-to-call-parseint-tldr-parseintstr-radix/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Working on the JS engine, Episode IV</title>
		<link>http://whereswalden.com/2011/02/03/working-on-the-js-engine-episode-iv/</link>
		<comments>http://whereswalden.com/2011/02/03/working-on-the-js-engine-episode-iv/#comments</comments>
		<pubDate>Fri, 04 Feb 2011 05:58:59 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[ecmascript]]></category>
		<category><![CDATA[es3]]></category>
		<category><![CDATA[es5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[spidermonkey]]></category>
		<category><![CDATA[why blacklisting is a fool's errand]]></category>
		<category><![CDATA[working on the js engine]]></category>

		<guid isPermaLink="false">http://whereswalden.com/?p=2750</guid>
		<description><![CDATA[A testcase submitted to us today: ([][(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]()+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]()+[])[!+[]+!+[]] The result according to ES3, plus a common implementation-specific behavior, is the string "job". The result according to ES5, plus a common implementation-specific behavior, is a thrown TypeError.]]></description>
			<content:encoded><![CDATA[<p>A testcase submitted to us today:</p>
<pre class="code" data-language="javascript">
([][(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]()+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]()+[])[!+[]+!+[]]
</pre>
<p>The result according to <abbr title="ECMAScript, 3rd edition">ES3</abbr>, plus a common implementation-specific behavior, is the string <code>"job"</code>.</p>
<p>The result according to <abbr title="ECMAScript, 5th edition">ES5</abbr>, plus a common implementation-specific behavior, is a thrown <code>TypeError</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://whereswalden.com/2011/02/03/working-on-the-js-engine-episode-iv/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>New ES5 strict mode requirement: function statements not at top level of a program or function are prohibited</title>
		<link>http://whereswalden.com/2011/01/24/new-es5-strict-mode-requirement-function-statements-not-at-top-level-of-a-program-or-function-are-prohibited/</link>
		<comments>http://whereswalden.com/2011/01/24/new-es5-strict-mode-requirement-function-statements-not-at-top-level-of-a-program-or-function-are-prohibited/#comments</comments>
		<pubDate>Mon, 24 Jan 2011 17:01:43 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[compatibility]]></category>
		<category><![CDATA[ecmascript]]></category>
		<category><![CDATA[es5]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[function statement]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[spidermonkey]]></category>
		<category><![CDATA[strict mode]]></category>

		<guid isPermaLink="false">http://whereswalden.com/?p=2688</guid>
		<description><![CDATA[Function statements in ECMAScript What&#8217;s the effect of this program according to ECMAScript? function foo() { } If you said that it defines a function as a property of the global object, congratulations! You&#8217;ve mastered a basic part of JavaScript syntax. Let&#8217;s go a little trickier: what is the effect of the function defined in [...]]]></description>
			<content:encoded><![CDATA[<h2>Function statements in ECMAScript</h2>
<p>What&#8217;s the effect of this program according to ECMAScript?</p>
<pre data-language="javascript" class="code">
function foo() { }
</pre>
<p>If you said that it defines a function as a property of the global object, congratulations!  You&#8217;ve mastered a basic part of JavaScript syntax.</p>
<p>Let&#8217;s go a little trickier: what is the effect of the function defined in this program according to ECMAScript?</p>
<pre data-language="javascript" class="code">
function foo()
{
  return g;
  function g() { }
}
</pre>
<p>This function, when called, defines a local variable <code>g</code> whose value is the specified function.  Then it returns that function as the value of that variable.  If you knew this as well, give yourself a gold star.</p>
<p>Now let&#8217;s try something even harder: what&#8217;s the effect of these programs?</p>
<pre data-language="javascript" class="code">
if (true)
  function bar() { }
</pre>
<pre data-language="javascript" class="code">
function g() { }
function foo()
{
  if (true)
    function g() { }
  return g;
}
</pre>
<h2>Shenanigans!</h2>
<p>Trick question!  They fail to run due to syntax errors.</p>
<p>ECMAScript permits function statements in exactly two places: directly within the list of statements that make up a program, and directly within the list of statements that make up the contents of a function body.  These are the first two examples.  (A function statement also looks like an expression, but if it appears in expression context it&#8217;s a function expression, not a function statement.)  Engines which permit a function statement anywhere else &mdash; as the child of a block statement enclosed by curly braces, as the child of a loop or condition, as the child of a <code>with</code>, or as the child of a <code>case</code> or <code>default</code> in a <code>switch</code> statement &mdash; do so by extending <abbr title="ECMAScript 5th edition">ES5</abbr>.</p>
<p>Spec requirements aside, what are the semantics of extensionland function statements?</p>
<h2>Now you&#8217;re just messing with me</h2>
<p><em>Which</em> semantics?</p>
<p>Browsers all implement extensionland function statements differently, with different semantics.  Use them just so and they&#8217;ll work the same way across browsers.  Use them in any way where the function statement conditionally executes, or where you start capturing the binding for the function in different locations, and you&#8217;ll find any semblance of cross-browser compatibility disappears.  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=385264#c2">This example by Rich Dougherty</a>, used with permission, demonstrates some of the incompatibilities (and I wonder whether function statements in <code>with</code> might present more):</p>
<pre data-language="javascript" class="code">
var result = [];
result.push(f());
function f() { return 1; }
result.push(f());
if (1)
{
  result.push(f());
  function f() { return 2; }
  result.push(f());
}
result.push(f());
function y()
{
  result.push(g());
  function g() { return 3; }
  result.push(g());
  if (1)
  {
    result.push(g());
    function g() { return 4; }
    result.push(g());
  }
  result.push(g());
}
y();
print(result);
</pre>
<p>Results in different browsers vary a fair bit, although there&#8217;s a little more consensus on behavior now than at the time this example was originally written:</p>
<table class="border-1">
<tr>
<th>Browser</th>
<th>Output</th>
</tr>
<tr>
<td>Firefox 1.5 and 2</td>
<td>1,1,1,2,2,3,3,3,3,3</td>
</tr>
<tr>
<td>Firefox 4</td>
<td>1,1,1,2,2,3,3,3,4,4</td>
</tr>
<tr>
<td>Opera</td>
<td>2,2,2,2,2,4,4,4,4,4</td>
</tr>
<tr>
<td>Internet Explorer 7</td>
<td>2,2,2,2,2,4,4,4,4,4</td>
</tr>
<tr>
<td>Safari 3</td>
<td>1,1,2,2,2,3,3,4,4,4</td>
</tr>
<tr>
<td>Safari 4</td>
<td>2,2,2,2,2,4,4,4,4,4</td>
</tr>
<tr>
<td>Chrome</td>
<td>2,2,2,2,2,4,4,4,4,4</td>
</tr>
</table>
<h2>Why not specify semantics?</h2>
<p>Blindly specifying some particular behavior won&#8217;t work.  Many sites these days (and different browser-specific implementations of those sites) rely on engine-specific behavior with user-agent-conditioned code.  Changing browser behavior breaks that pretty hard.  Specification will break any browsers not already implementing it at time of specification.</p>
<h2>A way forward</h2>
<p>The next version of ECMAScript would like to specify semantics for this case &mdash; quite possibly semantics not implemented by any browser.  How to do it, if implementations irreconcilably disagree?  The solution comes in two parts.  First, &#8220;<abbr title="ECMAScript 6th edition">ES6</abbr>&#8221; will require affirmative opt-in to enable new syntax and semantics, including for currently-nonstandard function statements.  Second, in anticipation of that change, the ECMA committee recommends that non-standard function statements be forbidden in strict mode code, to open up a future path down which ES6 can walk.</p>
<p>To permit ES6 to standardize semantics, the ECMA committee <a href="http://wiki.ecmascript.org/doku.php?id=conventions:no_non_standard_strict_decls">recommends forbidding non-standard function statements in strict mode code</a>.  Thus these examples are syntax errors:</p>
<pre data-language="javascript" class="code">
"use strict";
{
  function foo() { }
}
</pre>
<pre data-language="javascript" class="code">
"use strict";
if (true)
  function bar() { }
</pre>
<pre data-language="javascript" class="code">
"use strict";
with (obj)
  function foo() { }
</pre>
<pre data-language="javascript" class="code">
"use strict";
for (;;)
  function foo() { }
</pre>
<pre data-language="javascript" class="code">
"use strict";
switch (v)
{
  case 10:
    function bar() { }
  default:
    function baz() { }
}
</pre>
<p>Both Firefox and WebKit now implement this restriction, and other engines will follow as they too implement strict mode.</p>
<h2>Conclusion</h2>
<p>In order for future versions of ECMAScript to be able to define semantics for extensionland functions, strict mode &#8220;clears the deck&#8221; and forbids them entirely.  Instead, assign functions to variables, a la <code>var f = function() { };</code>.  Semantics for this are completely defined and compatibly implemented across browsers.</p>
<p>You can experiment with a version of Firefox with these changes by downloading a <a href="http://nightly.mozilla.org/">nightly build</a>.  (Don’t forget to <a href="http://support.mozilla.com/en-US/kb/Managing+profiles">use the profile manager</a> if you want to keep the settings you use with your primary Firefox installation pristine.)</p>
]]></content:encoded>
			<wfw:commentRss>http://whereswalden.com/2011/01/24/new-es5-strict-mode-requirement-function-statements-not-at-top-level-of-a-program-or-function-are-prohibited/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>New ES5 strict mode support: new vars created by strict mode eval code are local to that code only</title>
		<link>http://whereswalden.com/2011/01/10/new-es5-strict-mode-support-new-vars-created-by-strict-mode-eval-code-are-local-to-that-code-only/</link>
		<comments>http://whereswalden.com/2011/01/10/new-es5-strict-mode-support-new-vars-created-by-strict-mode-eval-code-are-local-to-that-code-only/#comments</comments>
		<pubDate>Mon, 10 Jan 2011 22:22:08 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[ecmascript]]></category>
		<category><![CDATA[es5]]></category>
		<category><![CDATA[eval]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[runtime code generation]]></category>
		<category><![CDATA[simplicity]]></category>
		<category><![CDATA[spidermonkey]]></category>
		<category><![CDATA[strict mode]]></category>

		<guid isPermaLink="false">http://whereswalden.com/?p=2584</guid>
		<description><![CDATA[tl;dr Ideally you shouldn&#8217;t use eval, because it inhibits many optimizations and makes code run slower. new Function(argname1, argname2, ..., code) doesn&#8217;t inhibit optimizations, so it&#8217;s a better way to dynamically generate code. (This may require passing in arguments instead of using names for local variables. That&#8217;s the price you pay to play nice with [...]]]></description>
			<content:encoded><![CDATA[<h2><abbr title="too long; didn't read">tl;dr</abbr></h2>
<p>Ideally you shouldn&#8217;t use <code>eval</code>, because it inhibits many optimizations and makes code run slower.  <code>new Function(argname1, argname2, ..., code)</code> doesn&#8217;t inhibit optimizations, so it&#8217;s a better way to dynamically generate code.  (This may require passing in arguments instead of using names for local variables.  That&#8217;s the price you pay to play nice with compilers that could optimize but for <code>eval</code>.)</p>
<p>Nevertheless, it&#8217;s still possible to use <code>eval</code> in <abbr title="ECMAScript 5th edition">ES5</abbr>.  <code>eval</code> of normal code behaves as it always has.  But <code>eval</code> of strict mode code behaves differently: any variables <em>created</em> by the code being evaluated affect <em>only that code</em>, not the enclosing scope.  (The enclosing scope&#8217;s variables are still visible in the <code>eval</code> code if they aren&#8217;t shadowed.)  Firefox now correctly binds variables created by strict mode <code>eval</code> code, <a href="http://kangax.github.com/es5-compat-table/strict-mode/">completing the last major component of strict mode</a> (though bugs remain).  These programs demonstrate the idea:</p>
<pre data-language="javascript" class="code">
var x = 2, y = 3;
print(eval("var x = 9; x"));               // prints 9
print(x);                                  // prints 9
print(eval("'use strict'; var x = 5; x")); // prints 5
print(eval("'use strict'; var x = 7; x")); // prints 7
print(eval("'use strict'; y"));            // prints 3
print(x);                                  // prints 9
</pre>
<pre data-language="javascript" class="code">
"use strict";
var x = 2, y = 3;
// <abbr title="Nota bene, note well" lang="la">NB</abbr>: Strictness propagates into eval code evaluated by a
//     direct call to eval — a call occurring through an
//     expression of the form eval(...).
print(eval("var x = 5; x")); // prints 5
print(eval("var x = 7; x")); // prints 7
print(eval("y"));            // prints 3
print(x);                    // prints 2
</pre>
<p>This <em>partially</em> defangs <code>eval</code>.  But even strict mode <code>eval</code> inhibits optimizations, so you are still better off avoiding it.</p>
<h2><code>eval</code> is a double-edged sword</h2>
<p><code>eval</code> is one of the most powerful parts of JavaScript: it enables runtime code generation.  You can compile code to perform specific operations, avoiding unnecessary general-purpose overhead &mdash; <a href="http://weblogs.mozillazine.org/roc/archives/2010/11/implementing_a.html">a powerful concept</a>.  (But you&#8217;d be better off using <code>new Function(argname1, argname2, ..., code)</code>, which doesn&#8217;t inhibit optimizations and still enables code generation, at loss of the ability to capture the local scope.  Code using <code>eval</code> may see considerable speedups: for example, roc&#8217;s <abbr title="Central processing unit">CPU</abbr> emulator sped up ~14% switching from <code>eval</code> to <code>Function</code>.  Less beefy code won&#8217;t see that magnitude of win, yet why give up performance when you have a ready alternative?)</p>
<p>Yet at the same time, <code>eval</code> is <em>too</em> powerful.  As inline assembly is to <a href="http://en.wikipedia.org/wiki/C_(programming_language)">C</a> or <a href="http://en.wikipedia.org/wiki/C++">C++</a> (at least without the information <a href="http://gcc.gnu.org/">gcc</a>&#8216;s <code>asm</code> syntax requires), so is <code>eval</code> to JavaScript.  In both instances a powerful construct inhibits many optimizations.  Even if you don&#8217;t care about optimizations or performance, <code>eval</code>&#8216;s ability to introduce and delete bindings makes code that uses it much harder to reason about.</p>
<h3><code>eval</code> arbitrarily mutates variables</h3>
<p>At its simplest, <code>eval</code> can change the value of any variable:</p>
<pre data-language="javascript" class="code">
function test(code)
{
  var v = 1;
  eval(code);
  return v;
}
assert(test("v = 2") === 2);
</pre>
<p>Thus you can&#8217;t reorder or constant-fold assignments past <code>eval</code>: <code>eval</code> forces <em>everything</em> to be &#8220;written to disk&#8221; so that the <code>eval</code> code can observe it, and likewise it forces <em>everything</em> to be read back &#8220;from disk&#8221; when needed next.  Without costly analysis you can&#8217;t store <code>v</code> in a register across the call.</p>
<h3><code>eval</code> can insert bindings after compilation</h3>
<p><code>eval</code>&#8216;s ability to add bindings is worse.  This can make it impossible to say what a name refers to until runtime:</p>
<pre data-language="javascript" class="code">
var v;
function test(code)
{
  eval(code);
  return v;
}
</pre>
<p>Does the <code>v</code> in the return statement mean the global variable?  You can&#8217;t know without knowing the code <code>eval</code> will compile and run.  If that code is <code>"var v = 17;"</code> it refers to a new variable.  If that code is <code>"/* psych! */"</code> it refers to the global variable.  <code>eval</code> in a function will deoptimize any name in that function which refers to a variable in an enclosing scope.  (And don&#8217;t forget that the name <code>test</code> itself is in an enclosing scope: if the function returned <code>test</code> instead of <code>v</code>, you couldn&#8217;t say whether that <code>test</code> referred to the enclosing function or to a new variable without knowing <code>code</code>.)</p>
<h3><code>eval</code> can remove bindings added after compilation</h3>
<p>You can also <em>delete</em> bindings introduced by <code>eval</code> (but not any other variables):</p>
<pre data-language="javascript" class="code">
var v = 42;
function test(code)
{
  eval(code);
  function f(code2)
  {
    eval(code2);
    return function g(code3) { eval(code3); return v; };
  }
  return f;
}
var f = test("var v = 17;");
var g = f("var v = 8675309;");
assert(g("/* nada */") === 8675309);
assert(g("var v = 5;") === 5);
assert(g("delete v") === 17);
assert(g("delete v") === 42);
assert(g("delete v") === 42); // can't delete non-eval var (thankfully)
</pre>
<p>So not only can you not be sure what binding a name refers to given <code>eval</code>, you can&#8217;t even be sure what binding it refers to over time!  (Throw <a href="https://developer.mozilla.org/en/JavaScript/Guide/Iterators_and_Generators">generators</a> into the game and you also have to account for a scope without a binding containing that binding even after a function has &#8220;returned&#8221;.)</p>
<h3><code>eval</code> can affect enclosing scopes</h3>
<p>Worst, none of these complications (and I&#8217;ve listed only a few) are limited to purely local variables.  <code>eval</code> can affect any variable it can see at runtime, whether in its immediate function or in any enclosing function or globally.  <code>eval</code> is the <a href="http://en.wikipedia.org/wiki/Fruit_of_the_poisonous_tree">fruit of the poisonous tree</a>: it taints not just the scope containing it, but <a href="http://hg.mozilla.org/tracemonkey/file/3d9329ed0363/js/src/jsparse.cpp#l3062">all scopes containing it</a>.</p>
<h2>Save us, ES5!</h2>
<p>ES5 brings some relief from this madness: strict mode <code>eval</code> can no longer introduce or delete bindings.  (Normal <code>eval</code> remains unchanged.)  Deleting a binding is impossible in strict mode because <code>delete name</code> is a syntax error.  And instead of introducing bindings in the calling scope, <code>eval</code> of strict mode code introduces bindings <em>for that code only</em>:</p>
<pre data-language="javascript" class="code">
var x = 2, y = 3;
print(eval("var x = 9; x"));               // prints 9
print(x);                                  // prints 9
print(eval("'use strict'; var x = 5; x")); // prints 5
print(eval("'use strict'; var x = 7; x")); // prints 7
print(eval("'use strict'; y"));            // prints 3
print(x);                                  // prints 9
</pre>
<p>This works best if you have strict mode <a href="http://en.wikipedia.org/wiki/Turtles_all_the_way_down">all the way down</a>, so that <code>eval</code> can never affect the bindings of any scope (and so you don&#8217;t need <code>"use strict"</code> at the start of every <code>eval</code> code):</p>
<pre data-language="javascript" class="code">
"use strict";
var x = 2, y = 3;
// <abbr title="Nota bene, note well" lang="la">NB</abbr>: Strictness propagates into eval code evaluated by a
//     direct call to eval — a call occurring through an
//     expression of the form eval(...).
print(eval("var x = 5; x")); // prints 5
print(eval("var x = 7; x")); // prints 7
print(eval("y"));            // prints 3
print(x);                    // prints 2
</pre>
<p>Names in strict mode code can thus be associated without having to worry about <code>eval</code> in strict mode code altering bindings, preserving additional optimization opportunities.</p>
<p>Firefox now correctly implements strict mode <code>eval</code> code binding semantics (modulo bugs, of course).</p>
<h2>So if I write strict mode code, should I use <code>eval</code>?</h2>
<p><code>eval</code>&#8216;s worst aspects are gone in strict mode, but using it still isn&#8217;t a good idea.  It can still change variables in ways the JavaScript compiler can&#8217;t detect, so strict mode <code>eval</code> still generally forces every variable to be saved before it occurs and to be reloaded when needed.  This deoptimization is unavoidable if runtime code generation can affect dynamically-determined local variables.  It&#8217;s still better to use <code>Function</code> than to use <code>eval</code>.</p>
<p>Also, as a temporary SpiderMonkey-specific concern, we don&#8217;t perform many of the binding optimizations strict mode <code>eval</code> enables.  Binding semantics <em>might</em> (I haven&#8217;t tested, and it&#8217;s entirely possible the extra work is unnoticeable in practice) slow down strict <code>eval</code> compared to normal <code>eval</code>.  Strict mode <code>eval</code> performance in SpiderMonkey won&#8217;t be much better than that of regular <code>eval</code>, and it <em>might</em> be slightly worse.  We&#8217;ll fix this over time, but for now don&#8217;t expect strict mode <code>eval</code> to improve performance.  (If you really need performance, don&#8217;t use <code>eval</code>.)</p>
<h2>Conclusion</h2>
<p><code>eval</code> is powerful &mdash; arguably too powerful.  ES5&#8242;s strict mode blunts <code>eval</code>&#8216;s sharpest corners to simplify it and permit typical optimizations in code using it.  But while strict mode <code>eval</code> is better than regular <code>eval</code>, <code>Function</code> is still the best way to generate code at runtime.  If you must use <code>eval</code>, consider using strict mode <code>eval</code> for a simpler binding model and eventual performance benefits.</p>
<p>You can experiment with a version of Firefox with these changes by downloading a <a href="http://nightly.mozilla.org/">nightly build</a>.  (Don’t forget to <a href="http://support.mozilla.com/en-US/kb/Managing+profiles">use the profile manager</a> if you want to keep the settings you use with your primary Firefox installation pristine.)</p>
]]></content:encoded>
			<wfw:commentRss>http://whereswalden.com/2011/01/10/new-es5-strict-mode-support-new-vars-created-by-strict-mode-eval-code-are-local-to-that-code-only/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>New ES5 requirement: getters and setters in object literals must not conflict with each other or with data properties, even outside strict mode</title>
		<link>http://whereswalden.com/2011/01/09/new-es5-requirement-getters-and-setters-in-object-literals-must-not-conflict-with-each-other-or-with-data-properties-even-outside-strict-mode/</link>
		<comments>http://whereswalden.com/2011/01/09/new-es5-requirement-getters-and-setters-in-object-literals-must-not-conflict-with-each-other-or-with-data-properties-even-outside-strict-mode/#comments</comments>
		<pubDate>Sun, 09 Jan 2011 20:57:22 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[ecmascript]]></category>
		<category><![CDATA[es5]]></category>
		<category><![CDATA[getter]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[setter]]></category>
		<category><![CDATA[spidermonkey]]></category>
		<category><![CDATA[strict mode]]></category>
		<category><![CDATA[syntax]]></category>

		<guid isPermaLink="false">http://whereswalden.com/?p=2590</guid>
		<description><![CDATA[Conflicting properties in object literals Object literals in ECMAScript can contain the same property multiple times: var obj = { prop: 42, prop: 17 }; How does this behave? The object, when fully initialized, has that property with its last assigned value: var obj = { prop: 17 }; // same effect The expression 42 [...]]]></description>
			<content:encoded><![CDATA[<h2>Conflicting properties in object literals</h2>
<p>Object literals in ECMAScript can contain the same property multiple times:</p>
<pre data-language="javascript" class="code">
var obj = { prop: 42, prop: 17 };
</pre>
<p>How does this behave?  The object, when fully initialized, has that property with its last assigned value:</p>
<pre data-language="javascript" class="code">
var obj = { prop: 17 }; // same effect
</pre>
<p>The expression <code>42</code> is still evaluated in source order, but that value isn&#8217;t found in the final object when construction and initialization completes.</p>
<h2>Are conflicting properties desirable?</h2>
<p>Duplicating property names is at best innocuous, but at worst it&#8217;s the source of bugs.  Repeated assignment of the same side effect-free expression is aesthetically unpleasing but harmless.  But what if that expression has side effects?  Or what if the two expressions are ever made to differ?  (This needn&#8217;t be purely human error.  For example, a conflict might be the result of a bad <a href="http://en.wikipedia.org/wiki/Merge_%28revision_control%29">merge</a> of your changes with changes made by others.)  What if a developer accidentally changes the first instance of a property but doesn&#8217;t notice the second?  You can see how this might cause bugs.</p>
<h2>Compatibility</h2>
<p>ES5 generally avoids breaking compatibility with ES3.  For the sake of existing code, duplicate property names are a syntax error <em>only in strict mode code</em>.</p>
<pre data-language="javascript" class="code">
function good() { return { p: 1, p: 2 }; } // okay
function bad() { "use strict"; return { p: 1, p: 2 }; } // ERROR
</pre>
<h2>What about getters and setters?</h2>
<p>ES5 standardizes syntax for <a href="https://developer.mozilla.org/en/JavaScript/Reference/Operators/Special/get">getters</a> and <a href="https://developer.mozilla.org/en/JavaScript/Reference/Operators/Special/set">setters</a> in object literals.  Using getters and setters you can write properties which <em>lazily</em> compute their values only when asked.  You can also write properties which post-process values assigned to them: to validate them, to transform them at time of assignment, and so on.  Getters and setters are new in ES5, so they don&#8217;t present compatibility concerns.</p>
<p>Conflicts with accessors are worse than conflicts with data properties.  What if a setter and a data property conflict?  <a href="https://developer.mozilla.org/web-tech/2009/04/29/object-and-array-initializers-should-not-invoke-setters-when-evaluated/">Properties in an initializer don&#8217;t invoke setters</a>, so a conflicting data property might blow away an accessor pair entirely!  Also, since getters and setters quite often involve side effects, or reliance on object structure and internals, errant fixes of one of a pair of getters or setters are likely to cause worse problems than conflicting data properties.</p>
<p>Therefore ES5 prohibits conflicting property getters and setters, either with each other or with existing data properties.  You can&#8217;t have both an accessor and a data property, and you can&#8217;t have multiple getters or multiple setters for the same property.  <em>This applies even outside strict mode!</em></p>
<pre data-language="javascript" class="code">
/* syntax errors in any code */
({ p: 1, get p() { } });
({ get p() { }, p: 1 });
({ p: 1, set p(v) { } });
({ set p(v) { }, p: 1 });
({ get p() { }, get p() { } });
({ set p(v) { }, set p(v) { } });
({ get p() { }, set p(v) { }, get p() { } });
({ set p(v) { }, get p() { }, set p(v) { } });

/* syntax error only in strict mode code */
function fail() { "use strict"; ({ p: 1, p: 2 }); }
</pre>
<h2>SpiderMonkey and Firefox no longer permit conflicts involving accessor properties in object literals</h2>
<p>Firefox 4 nightlies now reject any property-name conflicts in object literals. The only exception is when the object literal is outside strict mode and all assignments are for data properties.  Previously we implemented accessor conflict detection only in strict mode, but now Firefox 4 fully conforms to the ES5 specification when parsing object literals.  (While I&#8217;m here let me give a brief hat-tip to the <a href="http://es5conform.codeplex.com/">ECMAScript 5 Conformance Suite</a> for revealing this mistake, the result of spec misreading by multiple SpiderMonkey hackers.)</p>
<p>If you ever have conflicting properties in an object literal, odds are they were a mistake.  If you&#8217;ve done this only with data properties, no sweat now &mdash; but you&#8217;ll have to fix that if you ever opt your code into strict mode.  If you&#8217;ve done this with accessor properties (previously a non-standard, implementation-specific feature), you&#8217;ll need to change your code to eliminate the conflict.  Conflicts are reported as syntax errors (but note the bug that syntax errors aren&#8217;t reported for <a href="https://developer.mozilla.org/en/how_to_build_an_xpcom_component_in_javascript">JavaScript <abbr title="Cross-platform component-object model">XPCOM</abbr> components</a>), and they should be easy to fix.</p>
<h2>Conclusion</h2>
<p>Object literals containing the same property multiple times are bug-prone, as only one of the properties will actually be respected when the code executes.  That mistake can&#8217;t be fixed for data properties in normal code, but ES5 can prohibit new conflicts involving accessor properties; Firefox now properly treats such conflicts as syntax errors.  You can experiment with a version of Firefox with these changes by downloading a <a href="http://nightly.mozilla.org/">nightly build</a>.  (Don’t forget to <a href="http://support.mozilla.com/en-US/kb/Managing+profiles">use the profile manager</a> if you want to keep the settings you use with your primary Firefox installation pristine.)</p>
]]></content:encoded>
			<wfw:commentRss>http://whereswalden.com/2011/01/09/new-es5-requirement-getters-and-setters-in-object-literals-must-not-conflict-with-each-other-or-with-data-properties-even-outside-strict-mode/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SpiderMonkey JSON change: trailing commas no longer accepted</title>
		<link>http://whereswalden.com/2010/09/08/spidermonkey-json-change-trailing-commas-no-longer-accepted/</link>
		<comments>http://whereswalden.com/2010/09/08/spidermonkey-json-change-trailing-commas-no-longer-accepted/#comments</comments>
		<pubDate>Thu, 09 Sep 2010 05:57:01 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[ecma-262]]></category>
		<category><![CDATA[ecmascript]]></category>
		<category><![CDATA[es5]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[spidermonkey]]></category>
		<category><![CDATA[trailing comma]]></category>

		<guid isPermaLink="false">http://whereswalden.com/?p=2200</guid>
		<description><![CDATA[Historically, SpiderMonkey&#8217;s JSON implementation has accepted input containing trailing commas: JSON.parse('[1, 2, 3, ]'); JSON.parse('{ "1": 2, }"); We did so because the JSON RFC permitted implementations to accept extensions, and trailing commas are nice for humans to be able to use. The down side is that accepting extra syntax like this makes interoperability harder: [...]]]></description>
			<content:encoded><![CDATA[<p>Historically, SpiderMonkey&#8217;s <abbr title="JavaScript object notation">JSON</abbr> implementation has accepted input containing trailing commas:</p>
<pre class="code" data-language="javascript">
JSON.parse('[1, 2, 3, ]');
JSON.parse('{ "1": 2, }");
</pre>
<p>We did so because the <a href="http://www.ietf.org/rfc/rfc4627.txt">JSON <abbr title="request for comments">RFC</abbr></a> permitted implementations to accept extensions, and trailing commas are nice for humans to be able to use.  The down side is that accepting extra syntax like this makes interoperability harder: implementations which don&#8217;t implement the same extension, for reasons every bit as valid as those of implementations allowing the extension, are disadvantaged.  <abbr title="ECMAScript, 5th edition">ES5</abbr> weighed these concerns and chose to precisely specify permissible JSON syntax, putting everyone on the same page: trailing commas are not permitted.  Therefore, the examples above should throw a <code>SyntaxError</code> per ES5.</p>
<p>SpiderMonkey has now been changed to conform to ES5 on this point: trailing commas are syntax errors.  If you still need to accept trailing commas, you should use a custom implementation that accepts them &mdash; but best would be for you to adjust the processes that produce JSON strings including trailing commas to not include them.  (If you are an extension or are in privileged code, for the moment you can use <code>nsIJSON.legacyDecode</code> to continue to accept trailing commas.  However, note that we have added it only to accommodate legacy code in the process of being updated to no longer generate faulty input, and it will be removed sometime in the future.)</p>
<p>You can experiment with a version of Firefox with this change by downloading a <a href="http://nightly.mozilla.org/js-preview.html">TraceMonkey branch nightly</a>; this change should also make its way into <a href="http://nightly.mozilla.org/">mozilla-central nightlies</a> shortly, if you&#8217;d rather stick to trunk builds.  (Don’t forget to <a href="http://support.mozilla.com/en-US/kb/Managing+profiles">use the profile manager</a> if you want to keep the settings you use with your primary Firefox installation pristine.)</p>
]]></content:encoded>
			<wfw:commentRss>http://whereswalden.com/2010/09/08/spidermonkey-json-change-trailing-commas-no-longer-accepted/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>New ES5 strict mode support: now with poison pills!</title>
		<link>http://whereswalden.com/2010/09/08/new-es5-strict-mode-support-now-with-poison-pills/</link>
		<comments>http://whereswalden.com/2010/09/08/new-es5-strict-mode-support-now-with-poison-pills/#comments</comments>
		<pubDate>Thu, 09 Sep 2010 05:56:33 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[ecma-262]]></category>
		<category><![CDATA[ecmascript]]></category>
		<category><![CDATA[es5]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[introspection]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[programming language]]></category>
		<category><![CDATA[spidermonkey]]></category>
		<category><![CDATA[stack]]></category>
		<category><![CDATA[strict]]></category>
		<category><![CDATA[strict mode]]></category>

		<guid isPermaLink="false">http://whereswalden.com/?p=2150</guid>
		<description><![CDATA[tl;dr Don&#8217;t try to use the arguments or caller properties of functions created in strict mode code. Don&#8217;t try to use the callee or caller properties of arguments objects corresponding to invocations of functions in strict mode code. Don&#8217;t try to use the caller property of a function if it might be called from strict [...]]]></description>
			<content:encoded><![CDATA[<h2><abbr title="too long; didn't read">tl;dr</abbr></h2>
<p>Don&#8217;t try to use the <code>arguments</code> or <code>caller</code> properties of functions created in strict mode code.  Don&#8217;t try to use the <code>callee</code> or <code>caller</code> properties of <code>arguments</code> objects corresponding to invocations of functions in strict mode code.  Don&#8217;t try to use the <code>caller</code> property of a function if it might be called from strict mode code.  You are in for an unpleasant surprise (a thrown <code>TypeError</code>) if you do.</p>
<pre data-language="javascript" class="code">
function strict() { "use strict"; return arguments; }
function outer() { "use strict"; return inner(); }
function inner() { return inner.caller; }

strict.caller;    // !!! BAD IDEA
strict.arguments; // !!! BAD IDEA
strict().caller;  // !!! BAD IDEA
strict().callee;  // !!! BAD IDEA
outer();          // !!! BAD IDEA
</pre>
<p>Really, it&#8217;s best not to access the caller of a function, the current function (except by naming it), or the arguments for a given function (except via <code>arguments</code> or by use of the named parameter) at all.</p>
<h2><abbr title="ECMAScript 5th edition">ES5</abbr> strict mode: self-limitation, not wish fulfillment</h2>
<p>ES5 introduces the curious concept of strict mode.  Strict mode, whose name and concept derive from the similar feature in Perl, is a new feature in ES5 whose purpose is to deliberately <em>reduce</em> the things you can do in JavaScript.  Instead of a feature, it&#8217;s really more the <em>absence</em> of several features, within the scope of the strict-annotated code: <code>with</code>, particularly intrusive forms of <code>eval</code>, silent failure of writes to non-writable properties, silent failure of deletions of non-configurable properties, implicit creation of global-object properties, and so on.  The goal of these removals is to simplify both the reasoning necessary to understand such code and the implementation of it in JavaScript engines: to sand away some rough edges in the language.</p>
<h2>Magical stack-introspective properties of functions and arguments</h2>
<p>Consider this code, and note the expected behavior (expected per the web, but not as part of <abbr title="ECMAScript 3rd edition">ES3</abbr>):</p>
<pre data-language="javascript" class="code">
function getSelf() { return arguments.callee; }
assertEq(getSelf(), getSelf); // arguments.callee is the enclosing function

function outer()
{
  function inner() { return arguments.callee.caller; } // inner.caller === outer
  return inner();
}
assertEq(outer(), outer); // fun.caller === nearest function in stack that called fun, or null

function args2()
{
  return args2.arguments;
}
assertEq(args2(17)[0], 17); // fun.arguments === arguments object for nearest call to fun in stack, or null
</pre>
<p>Real-world JavaScript implementations take many shortcuts for top performance.  These shortcuts are not (supposed to be) observable, except by timing the relevant functionality.  Two common optimizations are <dfn>function inlining</dfn> and <dfn>avoiding creating an <code>arguments</code> object</dfn>.  The above &#8220;features&#8221; play havoc with both of these optimizations (as well as others, one of which will be the subject of a forthcoming post).</p>
<p>Inlining a function should conceptually be equivalent to splatting the function&#8217;s contents in that location in the calling function and doing some <a href="http://en.wikipedia.org/wiki/AlphaRenaming">α-renaming</a> to ensure no names in the splatted body conflict with the surrounding code.  The ability to access the calling function defeats this: there&#8217;s no function being invoked any more, so what does it even mean to ask for the function&#8217;s caller?  (Don&#8217;t simply say you&#8217;d hard-code the surrounding function: how do you know which property lookups in the inlined code will occur upon precisely the function being called, looking for precisely the <code>caller</code> property?)  It is also possible to access a function&#8217;s arguments through <code>fun.arguments</code>.  While the &#8220;proper&#8221; behavior here is more obvious, implementing it would be a large hassle: either the arguments would have to be created when the function was inlined (in the general case where you can&#8217;t be sure the function will never be used this way), or you&#8217;d have to inline code in such a way as to be able to &#8220;work backward&#8221; to the argument values.</p>
<p>Speaking of <code>arguments</code>, in offering access to the corresponding function via <code>arguments.callee</code> it has the same problems as <code>fun.caller</code>.  It also presents one further problem: in (some, mostly old) engines, <code>arguments.caller</code> provides access to the variables declared <em>within</em> that function when it was most recently called.  (If you&#8217;re thinking <a href="http://stuff.mit.edu/iap/2008/facebook/">security/integrity/optimization hazard</a>, well, you now know why engines no longer support it.)</p>
<p>In sum these features are bad for optimization.  Further, since they&#8217;re a form of dynamic scoping, they&#8217;re basically bad style in many other languages already.</p>
<h2>Per ES5, SpiderMonkey no longer supports this stack-inspecting magic when it interacts with strict mode</h2>
<p>As of the most recent Firefox nightly, SpiderMonkey now rejects code like that given above when it occurs in strict mode (more or less).  (The properties in question are now generally implemented through a so-called &#8220;poison pill&#8221; mechanism, an immutable accessor property which throws a <code>TypeError</code> when retrieved or set.)  The specific scenarios which we reject are as follows.</p>
<p>First, attempts to access the caller or arguments (except by directly naming the object) of a strict mode function throw a <code>TypeError</code>, because these properties are poison pills:</p>
<pre data-language="javascript" class="code">
function strict()
{
  "use strict";
  strict.caller;    // !!! TypeError
  strict.arguments; // !!! TypeError
  return arguments; // direct name: perfectly cromulent
}
strict();
</pre>
<p>Second, attempts to access the enclosing function or caller variables via the <code>arguments</code> of a strict mode function throw a <code>TypeError</code>.  These properties too are poison pills:</p>
<pre data-language="javascript" class="code">
function strict()
{
  "use strict";
  arguments.callee; // !!! TypeError
  arguments.caller; // !!! TypeError
}
strict();
</pre>
<p>Third (and most trickily, because non-strict code is affected), attempts to access a function&#8217;s caller when that caller is in strict mode will throw a <code>TypeError</code>.  This isn&#8217;t a poison pill, because if the <code>"use strict"</code> directive weren&#8217;t there it would still &#8220;work&#8221;:</p>
<pre data-language="javascript" class="code">
function outer()
{
  "use strict";
  return inner();
}
function inner()
{
  return inner.caller; // !!! TypeError
}
outer();
</pre>
<p>But if there&#8217;s no strict mode in sight, nothing will throw exceptions, and what worked before will still work:</p>
<pre data-language="javascript" class="code">
function fun()
{
  assertEq(fun.caller, null); // global scope
  assertEq(fun.arguments, arguments);
  assertEq(arguments.callee, fun);
  arguments.caller; // won't throw, won't do anything special
  return arguments;
}
fun();
</pre>
<h2>Conclusion</h2>
<p>With these changes, which are required by ES5, stack inspection is slowly going the way of the dodo.  Don&#8217;t use it or rely on it!  Even if you never use strict mode, beware the third change, for it still might affect you if you provide methods for other code to call.  (But don&#8217;t expect to be able to avoid strict mode forever: I expect all JavaScript libraries will adopt strict mode in short order, given its benefits.)</p>
<p>(For those curious about <code>new Error().stack</code>, we&#8217;re still considering what to do about it.  Regrettably, we may need to kill it for information-privacy reasons too, or at least censor it to something less useful.  Nothing&#8217;s certain yet; stay tuned for further announcements should we make changes.)</p>
<p>You can experiment with a version of Firefox with these changes by downloading a <a href="http://nightly.mozilla.org/js-preview.html">TraceMonkey branch nightly</a>; these changes should also make their way into <a href="http://nightly.mozilla.org/">mozilla-central nightlies</a> shortly, if you&#8217;d rather stick to trunk builds.  (Don’t forget to <a href="http://support.mozilla.com/en-US/kb/Managing+profiles">use the profile manager</a> if you want to keep the settings you use with your primary Firefox installation pristine.)</p>
]]></content:encoded>
			<wfw:commentRss>http://whereswalden.com/2010/09/08/new-es5-strict-mode-support-now-with-poison-pills/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

