<?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>Indistinguishable from Jesse &#187; JavaScript</title>
	<atom:link href="http://www.squarefree.com/categories/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.squarefree.com</link>
	<description>Jesse Ruderman on Firefox, security, and more</description>
	<lastBuildDate>Sun, 05 Feb 2012 17:32:14 +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>Lessons from JS engine bugs</title>
		<link>http://www.squarefree.com/2011/09/01/lessons-from-js-engine-bugs/</link>
		<comments>http://www.squarefree.com/2011/09/01/lessons-from-js-engine-bugs/#comments</comments>
		<pubDate>Fri, 02 Sep 2011 00:10:22 +0000</pubDate>
		<dc:creator>Jesse Ruderman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://www.squarefree.com/?p=791</guid>
		<description><![CDATA[Last week, I asked Luke Wagner to explain some security bugs that he fixed in the past. I hoped to learn from each bug at multiple levels, in ways that could help prevent future security bugs from arising and persisting. Luke is one of the developers working on Firefox's JavaScript engine, which is currently our [...]]]></description>
			<content:encoded><![CDATA[<p>Last week, I asked <a href="http://blog.mozilla.com/luke/">Luke Wagner</a> to explain some security bugs that he fixed in the past. I hoped to <a href="http://en.wikipedia.org/wiki/Root_cause_analysis">learn from each bug at multiple levels</a>, in ways that could help prevent future security bugs from arising and persisting.</p>

<p>Luke is one of the developers working on <a href="https://developer.mozilla.org/en/SpiderMonkey">Firefox's JavaScript engine</a>, which is currently our largest source of <a href="https://wiki.mozilla.org/Security_Severity_Ratings">critical</a> security bugs.</p>

<h4>Method</h4>

<p>I imagined we would recurse in <a href="http://en.wikipedia.org/wiki/Why-Because_analysis">exhaustive breadth</a> and <a href="http://en.wikipedia.org/wiki/5_Whys">exhausting depth</a>. Instead, we recursed only on the most interesting items, and refined a checklist of starting points:</p>

<ul>
<li>What was the bug?</li>
<li>What went wrong in the developer's thinking that caused the bug to be introduced?</li>
<li>What made the bug exploitable?</li>
<li>What caused us to use especially dangerous features of C++?</li>
<li>Could a new abstraction make it possible to do this both fast and safe?</li>
<li>What caused the bug to persist? Could we have caught this earlier with improved regression tests, fuzz testing, dynamic analysis, or static analysis?</li>
</ul>

<p>Luke and I made <strong><a href="http://www.squarefree.com/lessons-from-js-bugs.html">trees for all ten bugs</a></strong>, at first on paper and later using EtherPad. Then I extracted and categorized what I thought were the most useful lessons and recommendations.</p>

<h4>Recommendations for introducing fewer bugs</h4>

<p>Casts</p>

<ul>
<li>Create centralized, type-restricted cast functions. This protects you when you change the representation of one of the types. It also protects against mistakes that cause the input type to be incorrect.</li>
</ul>

<p>Sentinel values</p>

<ul>
<li>Use tagged unions instead.</li>
<li>Use a typed wrapper (a struct containing a single value). When assigning from the underlying numeric type, convert using one of two functions: one that checks for special values, and one that explicitly does not.</li>
<li>Audit existing code paths to ensure they cannot generate the special value.</li>
</ul>

<p>Clarity of invariants</p>

<ul>
<li>Increase use of <a href="http://mxr.mozilla.org/mozilla-central/search?string=AssertInvariants">methods named AssertInvariants</a></li>
<li>Create an alias for JS_ASSERTION called JS_INVARIANT.</li>
</ul>

<p>Interacting with other developers</p>

<ul>
<li>If you're about to do something gross because someone else doesn't expose the right API/helper, maybe you should get it exposed.</li>
</ul>

<p>JS Engine specific</p>

<ul>
<li>Any patch that touches rooting should be reviewed by Igor.</li>
<li>Interpreter could have better abstraction and encapsulation for its stack.</li>
</ul>

<h4>Recommendations for catching bugs earlier</h4>

<p>Static analysis</p>

<ul>
<li>Find all casts (C-style casts, the reinterpret_cast keyword, and casts through unions) for a given type. Could be used to enforce centralization or to find things that should be centralized.</li>
<li>Be suspicious of a function with multiple return statements, all of which return the same primitive value.</li>
<li>Be suspicious of a function returning true/success in an OOM path.</li>
</ul>

<p>Dynamic analysis</p>

<ul>
<li>Ask Valgrind developers what they think of providing (in valgrind.h) a way to tie the addressability of "stacklike memory" to a variable that represents the end of the stack.</li>
</ul>

<p>Fuzzing</p>

<ul>
<li>We should fuzz <a href="https://developer.mozilla.org/En/DOM/Worker">worker threads</a> somehow.
  <ul>
  <li>In browser (slow and messy, but it's what users are running).
  <li>In thread-safe shell (--enable-threadsafe?), which has "toy workers".</li>
  </ul>
</li>
<li>We should fuzz compartments better.
  <ul>
  <li>I should ask Blake and Andreas for help with testing compartments and wrappers.</li>
  <li>I should ask Gary to run jsfunfuzz in xpcshell, where I can test both same-origin and different-origin compartments, and thus get more interesting wrappers.</li>
  </ul>
</li>
<li>We should give JS OOM fuzzing another shot.</li>
</ul>

<h4>Next steps</h4>

<p>I'm curious if others have additional ideas for what could have prevented the ten bugs we looked at. For example, someone like <a href="http://whereswalden.com/">Jeff Walden</a>, who loves to write exhaustive regression tests, might have ideas that Luke and I did not consider.</p>

<p>I'd also like to do this kind of analysis with a other developers on bugs they have fixed.</p>]]></content:encoded>
			<wfw:commentRss>http://www.squarefree.com/2011/09/01/lessons-from-js-engine-bugs/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Reducing real-world scripts</title>
		<link>http://www.squarefree.com/2009/01/11/reducing-real-world-scripts/</link>
		<comments>http://www.squarefree.com/2009/01/11/reducing-real-world-scripts/#comments</comments>
		<pubDate>Mon, 12 Jan 2009 01:33:48 +0000</pubDate>
		<dc:creator>Jesse Ruderman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Reduction]]></category>

		<guid isPermaLink="false">http://www.squarefree.com/?p=413</guid>
		<description><![CDATA[Lithium is great at reducing testcases with simple structures, such as scripts generated by jsfunfuzz. Scripts from web pages are harder to reduce, since removing a line frequently introduces a syntax error. But with a few extra tricks, Lithium can be effective against real-world scripts. For example, when Google Maps triggered a JavaScript Engine assertion, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.squarefree.com/2007/09/15/introducing-lithium-a-testcase-reduction-tool/">Lithium</a> is great at reducing testcases with simple structures, such as scripts generated by <a href="http://www.squarefree.com/2007/08/02/introducing-jsfunfuzz/">jsfunfuzz</a>.  Scripts from web pages are harder to reduce, since removing a line frequently introduces a syntax error.  But with a few extra tricks, Lithium can be effective against real-world scripts.  For example, when <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=469262">Google Maps triggered a JavaScript Engine assertion</a>, I was able to reduce the <a href="http://maps.google.com/maps?file=api&amp;v=2.x&amp;key=ABQIAAAAVxoDynPWa2CEJXU6cuGlzRQgsGl9d1P7wz7wG-itpIZ-3OQO3hRuxapOgINKQqWLiem13V54tNU3mA">40</a> <a href="http://maps.google.com/intl/en_us/mapfiles/140g/maps2.api/main.js">KB</a> of Google Maps code to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=469262#c11">five lines</a>.</p>

<p>I've reduced <a href="https://bugzilla.mozilla.org/buglist.cgi?quicksearch=464116,470719,471540">three other JavaScript engine bugs</a> using these methods, but there are <a href="https://bugzilla.mozilla.org/buglist.cgi?bug_id=457449,462091,462853,462991,465058,465131,465151,465205,466417,466659,468184,469786,471585">many more that could use help</a>.</p>

<p>Start by saving the page using <kbd>wget -E -H -k -K -p</kbd> or one of the other methods on <a href="https://developer.mozilla.org/en/Reducing_testcases">DevMo: Reducing Testcases</a>.</p>


<h3>Making Firefox exit quickly</h3>

<p>For Lithium to reduce a web page quickly, Firefox needs to exit quickly.  To make normal exits fast, install <a href="https://www.squarefree.com/extensions/quitter.xpi">Quitter</a> and make the testcase <a href="https://developer.mozilla.org/En/Code_snippets:Interaction_between_privileged_and_non-privileged_pages">send a special event</a> to Quitter after onload:</p>

<pre>
&lt;script&gt;
function quit()
{
  var evt = document.createEvent("Events");
  evt.initEvent("please-quit", true, false);
  document.dispatchEvent(evt);
}
window.addEventListener("load", function() { 
  setTimeout(quit, 1000);
}, false);
window.onerror = quit;
&lt;/script&gt;
&lt;!-- DDBEGIN --&gt;
</pre>


<h3>Making Firefox crash quickly</h3>

<p>On Mac OS X, crashes are surprisingly slow: it takes the <a href="http://developer.apple.com/technotes/tn2004/tn2123.html">OS crash reporter</a> about 40 seconds to generate a crash log for Firefox.  I don't know a general way to bypass the OS crash reporter, but there are two easy cases.  First, for crashes that are easy to anticipate at the code level, such as null dereferences, adding a conditional exit(3) should do the trick.</p>

<p>Second, as of Mac OS X 10.5, fatal assertions are treated as crashes.  To make the OS treat fatal assertions as exits rather than crashes, edit the relevant assertion-failure function (<a href="http://mxr.mozilla.org/mozilla-central/source/js/src/jsutil.cpp#54">JS_Assert</a> or <a href="http://mxr.mozilla.org/mozilla-central/source/js/src/nanojit/avmplus.cpp#45">NanoAssertFail</a>) to call "exit(3);" rather than "abort();".  To make your debug build pick up this change, <a href="https://developer.mozilla.org/en/Incremental_Build">run "make -C js/src" from the objdir</a>.</p>


<h3>Finding the scripts</h3>

<p>An initial run of Lithium should make it clear which external &lt;script&gt; tags are involved in triggering the bug.  Convert them to inline scripts so they're no longer loaded over the Web.</p>

<p>You may find that one script calls document.write to include another script.  Add this code to the script at the top to see what additional scripts are being included:</p>

<pre>document._write = document.write;
document.write = function(s) { 
  dump("document.write(" + uneval(s) + ");\n"); 
  document._write(s);
};</pre>


<h3>__noSuchMethod__</h3>

<p>You can use SpiderMonkey's nonstandard <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Object/noSuchMethod">__noSuchMethod__</a> feature to turn "no such method" errors into no-ops.  This helps Lithium reduce object-oriented scripts by allowing it to remove entire methods even before their callers have been removed.</p>

<pre>Object.prototype.__noSuchMethod__ = function(id, args) {
  dump("Missing method called: " + id + "\n");
};</pre>

<p>Note that <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=466239">__noSuchMethod__ does not work for top-level functions</a> unless they are explicitly called as "this.foo()" rather than "foo()".</p>


<h3>Pretty-printing JavaScript</h3>

<p>You can use <a href="http://jsbeautifier.org/">jsbeautifier.org</a> or the decompiler built into SpiderMonkey to transform the script into a form that is friendlier to Lithium.</p>

<p>To trigger SpiderMonkey's decompiler, wrap the entire script in an anonymous function and use <a href="https://developer.mozilla.org/En/DOM/Window.dump">dump</a> (in the browser) or print (in the shell).</p>

<p>The decompiler has two modes: toString creates one line per statement, while uneval creates one line per function declaration.  You'll probably want to run Lithium at least once for each mode, since toString makes it easy to eliminate unnecessary expression-statements while uneval makes it easy to eliminate unnecessary function declarations.</p>


<h3>Moving to the shell</h3>

<p>As soon as the script seems like it isn't too entangled with the browser DOM, try to eliminate the remaining references to the browser-specific "window" and "document" objects.  This should allow you to reproduce the bug in the <a href="https://developer.mozilla.org/en/Introduction_to_the_JavaScript_shell">standalone SpiderMonkey shell</a>, which starts <em>much</em> faster than Firefox (milliseconds rather than seconds).</p>

<p>Note that to reproduce JIT bugs in the shell, you need to use the "-j" switch.</p>


<h3>Finishing touches</h3>

<p>Lithium may have left empty "if" or "for" blocks, which can almost always be removed.  To make the remaining code as simple as possible, try replacing variables with their values and inlining functions.  If the code is object-oriented or uses <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Function/call">call</a>/<a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Function/apply">apply</a>, this might require a little thinking, but it's usually straightforward.</p>

<p><i>This post was revised 2009-07-06.</i></p>]]></content:encoded>
			<wfw:commentRss>http://www.squarefree.com/2009/01/11/reducing-real-world-scripts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Some differences between JavaScript engines</title>
		<link>http://www.squarefree.com/2008/12/23/differences/</link>
		<comments>http://www.squarefree.com/2008/12/23/differences/#comments</comments>
		<pubDate>Wed, 24 Dec 2008 03:57:36 +0000</pubDate>
		<dc:creator>Jesse Ruderman</dc:creator>
				<category><![CDATA[Fuzzing]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Mozilla]]></category>

		<guid isPermaLink="false">http://www.squarefree.com/?p=410</guid>
		<description><![CDATA[I gave my new fuzzer a break from testing TraceMonkey by asking it to look for differences between SpiderMonkey and JavaScriptCore. I have listed them below, with SpiderMonkey output above JavaScriptCore output. I have no idea how many of these are bugs (in SpiderMonkey or JavaScriptCore) and how many are ambiguous in the spec (intentionally [...]]]></description>
			<content:encoded><![CDATA[<p>I gave my new fuzzer a break from <a href="http://www.squarefree.com/2008/12/23/fuzzing-tracemonkey/">testing TraceMonkey</a> by asking it to look for differences between SpiderMonkey and JavaScriptCore.  I have listed them below, with SpiderMonkey output above JavaScriptCore output.</p>

<p>I have no idea how many of these are bugs (in SpiderMonkey or JavaScriptCore) and how many are ambiguous in the spec (intentionally or unintentionally).</p>



<h3>Early error reporting</h3>

<p>SpiderMonkey reports some errors at compile time that JavaScriptCore only reports at run time, if the code is actually hit.  The difference is most obvious (and most likely to cause compatibility problems) if the code is skipped.</p>

<pre>&gt; if (false) { --1; }
<span class="spidermonkey"  >S: SyntaxError: invalid decrement operand</span>
<span class="javascriptcore">J: (no error)</span></pre>


<pre>&gt; if (false) { return; }
<span class="spidermonkey"  >S: SyntaxError: return not in function</span>
<span class="javascriptcore">J: (no error)</span></pre>


<h3>instanceof</h3>

<p>The two engines disagree about what objects are reasonable operands for the 'instanceof' operator.</p>

<pre>&gt; ({} instanceof {a:2})
<span class="spidermonkey"  >S: typein:3: TypeError: invalid 'instanceof' operand ({a:2})</span>
<span class="javascriptcore">J: false</span></pre>


<pre>&gt; ({} instanceof eval)
<span class="spidermonkey"  >S: false</span>
<span class="javascriptcore">J: Exception: TypeError: instanceof called on an object with an invalid prototype property.</span></pre>




<h3>new with native functions</h3>

<p>SpiderMonkey allows the "new" operator to be used with some native functions that JavaScriptCore considers non-constructors.</p>


<pre>&gt; new Math.sqrt(16)
<span class="spidermonkey"  >S: 4</span>
<span class="javascriptcore">J: Exception: TypeError: Result of expression 'Math.sqrt' ... is not a constructor.</span></pre>


<pre>&gt; new ({}.toString)
<span class="spidermonkey"  >S: [object Object]</span>
<span class="javascriptcore">J: Exception: TypeError: Result of expression '({}.toString)' ... is not a constructor.</span></pre>


<pre>&gt; new eval
<span class="spidermonkey"  >S: typein:9: EvalError: function eval must be called directly, and not by way of a function of another name</span>
<span class="javascriptcore">J: Exception: TypeError: Result of expression 'eval' ... is not a constructor.</span></pre>




<h3>Converting between numbers and strings</h3>

<pre>&gt; print(+'\00000027')
<span class="spidermonkey"  >S: NaN</span>
<span class="javascriptcore">J: 0</span></pre>


<pre>&gt; (1e-10).toString(16)
<span class="spidermonkey"  >S: 0.000000006df37f675ef6ec</span>
<span class="javascriptcore">J: 0</span></pre>




<h3>const</h3>

<p>There are subtle differences in handling of this new keyword.</p>


<pre>&gt; const d; const d;
<span class="spidermonkey"  >S: TypeError: redeclaration of const d</span>
<span class="javascriptcore">J: (no error)</span></pre>


<pre>&gt; const c = 0; print(++c);
<span class="spidermonkey"  >S: 0</span>
<span class="javascriptcore">J: 1</span></pre>



<h3>Other differences</h3>


<pre>&gt; print((function(){return arguments;})());
<span class="spidermonkey"  >S: [object Object]</span>
<span class="javascriptcore">J: [object Arguments]</span></pre>


<pre>&gt; typeof /x/
<span class="spidermonkey"  >S: object</span>
<span class="javascriptcore">J: function</span></pre>

<p>See <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=61911">Mozilla bug 61911</a>, which changed this in SpiderMonkey in 2007.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.squarefree.com/2008/12/23/differences/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Fuzzing TraceMonkey</title>
		<link>http://www.squarefree.com/2008/12/23/fuzzing-tracemonkey/</link>
		<comments>http://www.squarefree.com/2008/12/23/fuzzing-tracemonkey/#comments</comments>
		<pubDate>Wed, 24 Dec 2008 01:48:09 +0000</pubDate>
		<dc:creator>Jesse Ruderman</dc:creator>
				<category><![CDATA[Fuzzing]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://www.squarefree.com/?p=409</guid>
		<description><![CDATA[Making JavaScript faster is important for the future of computer security. Faster scripts will allow computationally intensive applications to move to the Web. As messy as the Web's security model is, it beats the most popular alternative, which is to give hundreds of native applications access to your files. Faster scripts will also allow large [...]]]></description>
			<content:encoded><![CDATA[<p>Making JavaScript faster is important for the future of computer security.  Faster scripts will allow computationally intensive applications to move to the Web.  As messy as the <a href="http://code.google.com/p/browsersec/wiki/Part2">Web's security model</a> is, it beats the most popular alternative, which is to give hundreds of native applications access to your files.  Faster scripts will also allow large parts of Firefox to be written in JavaScript, a memory-safe programming language, rather than C++, a statically typed <a href="http://www.squarefree.com/2006/11/01/memory-safety-bugs-in-c-code/">footgun</a>.</p>

<p>Mozilla's ambitious <a href="http://weblogs.mozillazine.org/roadmap/archives/2008/08/tracemonkey_javascript_lightsp.html">TraceMonkey project</a> adds a <a href="http://en.wikipedia.org/wiki/Just-in-time_compilation">just-in-time compiler</a> to Firefox's JavaScript engine, making many scripts 3 to 30 times faster.  TraceMonkey takes a <a href="http://andreasgal.com/2008/08/22/tracing-the-web/">non-traditional approach</a> to JIT compilation: instead of compiling a function at a time, it compiles only a path (such as the body of a loop) at a time.  This makes it possible to optimize the native code based on the actual type of each variable, which is important for dynamic languages like JavaScript.</p>

<p>My existing JavaScript fuzzer, <a href="http://www.squarefree.com/2007/08/02/introducing-jsfunfuzz/">jsfunfuzz</a>, found a decent number of crash and assertion bugs in early versions of TraceMonkey.  I made several changes to jsfunfuzz to help it generate code to test the JIT infrastructure heavily.  For example, it now generates <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=462388">mixed-type arrays</a> in order to test how the JIT deals with unexpected type changes.</p>

<p>Andreas Gal commented that each fuzz-generated testcase saved him nearly a day of debugging: otherwise, he'd probably have to tease a testcase out of a misbehaving complex web page.  Encouraged by his comment, I looked for additional ways to help the TraceMonkey team.</p>


<h3>JIT correctness</h3>

<p>Last month, I wrote a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=465479">new fuzzer</a> designed to find correctness bugs.  It runs a randomly-generated script in two JavaScript engines (in this case, SpiderMonkey with and without the JIT) and complains if the output is different.</p>

<p>It quickly found <a href="https://bugzilla.mozilla.org/buglist.cgi?bug_id=465915,465424,465453,465460,465483,465567,465605,465902,465915,466781,466787,470176,470959,470964">13 bugs</a> where the JIT caused JavaScript code to produce incorrect results.  These bugs range from <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=465424">obvious</a> to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=466781">obscure</a> to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=465915">evil</a>.</p>

<p>It even found two security bugs that jsfunfuzz had missed.  One was a crash that involved a combination of language features that jsfunfuzz doesn't test heavily.  The other was an uninitialized-memory-read bug, which caused the output to be random when it should have been consistent.  jsfunfuzz missed the bug because it ignores most output, but the new fuzzer interpreted it as a difference between non-JIT and JIT output and brought the bug to my attention.</p>


<h3>JIT speed</h3>

<p>I set up the new fuzzer to compare the <em>time</em> needed to execute scripts and complain whenever enabling the JIT made a script run more slowly. It measures speed by letting the script run for 500ms and reporting the number of loop iterations completed in that time.</p>

<p>So far, it has found <a href="https://bugzilla.mozilla.org/buglist.cgi?bug_id=469927,469938,470737,470779">4 serious bugs where the JIT makes scripts several times slower</a>.  Two of these have already been fixed, but the other two may be difficult to fix.</p>

<p>It has also found <a href="https://bugzilla.mozilla.org/buglist.cgi?bug_id=469942,469943,470128,470133,470139,470143,470144,470735,470736,470739">10 cases where the JIT makes scripts about 10% slower</a>.  Most of these minor slowdowns are due to "trace aborts", where a piece of JavaScript is not converted to native code and stays in the interpreter.  Some trace aborts are due to bugs, while others are design decisions or cases for which conversion to native code simply hasn't been implemented yet.</p>

<p>There is some <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=470739#c3">disagreement</a> over which trace aborts are most likely to affect real web pages.  I <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=470153">asked</a> members of Mozilla's QA team to scan the web in a way that can answer this question.</p>


<h3>Interpreter speed</h3>

<p>Mostly for fun, I also looked to see which code the JIT speeds up the most.  Here's a simplified version of its answer:</p>

<pre>for (var i = 0; i &lt; 0x02000000; ++i) {
  d = 0x55555555;
  d++; d++; d++; d++; d++;
}</pre>

<p>This code runs <em>250 times faster</em> when the JIT is enabled.  The JIT is able to achieve this gigantic speedup due to the interpreter being inefficient in dealing with undeclared variables and <a href="https://bugzilla.mozilla.org/buglist.cgi?bug_id=161110,421864">numbers that can't be represented as 30-bit ints</a>.</p>



<h3>Assertions</h3>

<p>The JavaScript engine team has documented many of their assumptions as <a href="http://en.wikipedia.org/wiki/Assertion_(computing)">assertions</a> in the code.  Many of these assertions make it easier to spot dangerous bugs, because the script generated by the fuzzer doesn't have to be clever enough to actually cause a crash, only strange enough to violate an assumption.  This is similar to my <a href="http://www.squarefree.com/2007/11/27/gecko-assertions/">experience</a> with other parts of Gecko that use assertions well.</p>

<p>Other JavaScript engine assertions make it easier to find <a href="https://bugzilla.mozilla.org/buglist.cgi?quicksearch=ALL+stackTypeMap.matches+reporter:jrud">severe performance bugs</a>.  Without these assertions, I'd only find these bugs when I measure speed directly, which requires drastically slowing down the tests.</p>


<h3>More ideas</h3>

<p>One testcase generated by my fuzzer demonstrated a combination of <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=470133">a JIT performance bug</a> with a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=470129">minor bytecode generation bug</a>.  I might be able to search for similar bytecode generation bugs the same way I <a href="http://www.squarefree.com/2007/08/02/fuzzing-for-correctness/">searched for decompiler bugs</a>: by ensuring that a function does not change when round-tripping through the decompiler.  In order to do that, I'll need a new patch for <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=396512">making dis() return the disassembly instead of printing it</a>.</p>

<p>I should be able to find some performance bugs by looking at which aborts and side exits are taken.  This strategy would make some performance bugs (such as repeatedly taking a side exit) easier to spot.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.squarefree.com/2008/12/23/fuzzing-tracemonkey/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Bookmarklets updated to comply with DOM 2 rule</title>
		<link>http://www.squarefree.com/2006/11/02/bookmarklets-updated-to-comply-with-dom-2-rule/</link>
		<comments>http://www.squarefree.com/2006/11/02/bookmarklets-updated-to-comply-with-dom-2-rule/#comments</comments>
		<pubDate>Fri, 03 Nov 2006 04:33:34 +0000</pubDate>
		<dc:creator>Jesse Ruderman</dc:creator>
				<category><![CDATA[Bookmarklets]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Mozilla]]></category>

		<guid isPermaLink="false">http://www.squarefree.com/2006/11/02/bookmarklets-updated-to-comply-with-dom-2-rule/</guid>
		<description><![CDATA[DOM 2 does not allow nodes to be moved between documents -- in fact, it requires that implementations throw an error when code tries to do so. But for years, Gecko has not enforced this rule. It's a bit embarrassing that Internet Explorer gets this right and we get it wrong. Someone might think Gecko [...]]]></description>
			<content:encoded><![CDATA[<p>DOM 2 does not allow nodes to be moved between documents -- in fact, it <a href="http://www.w3.org/TR/2000/CR-DOM-Level-2-20000510/core.html#ID-184E7107">requires</a> that implementations throw an error when code tries to do so.  But for years, Gecko has <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=47903">not enforced</a> this rule.</p>

<p>It's a bit embarrassing that Internet Explorer gets this right and we get it wrong.  Someone might think Gecko is trying to <a href="http://en.wikipedia.org/wiki/Embrace,_extend_and_extinguish">embrace and extend</a> the DOM.</p>

<p>Soon, Gecko will start enforcing the rule on trunk.  But bringing Gecko in line with this aspect of the DOM spec risks breaking Gecko-specific code, such as code in extensions and bookmarklets written for Firefox.  For example, my <a href="http://www.squarefree.com/extensions/search-keys/">Search Keys</a> extension used to create some nodes in the chrome document, and some in the foreground tab, before putting them in the tab that that just loaded.  Search Keys 0.8 creates all elements in the correct document.</p>

<p>I also updated the following bookmarklets to create nodes in the correct document and/or use importNode when copying nodes between documents:</p>

<ul>
<li><a href="http://www.squarefree.com/bookmarklets/validation.html">Validation bookmarklets</a>: list alts</li>
<li><a href="http://www.squarefree.com/bookmarklets/webdevel.html">Web development bookmarklets</a>: partial source, view style sheets, view scripts</li>
<li><a href="http://www.squarefree.com/bookmarklets/pagedata.html">Text and data bookmarklets</a>: view selection</li>
<li><a href="http://www.squarefree.com/bookmarklets/testbrowsers.html">Bookmarklets for testing browsers</a>: clone document</li>
</ul>

<p>These bookmarklets previously only worked in browsers that violated the DOM spec by allowing nodes to be moved between documents without a call to importNode or adoptNode.  Maybe some of them work in IE now.</p>

<p>If you use those bookmarklets, you should grab the new versions so they won't break when you update to next week's trunk build or to Firefox 3.</p>]]></content:encoded>
			<wfw:commentRss>http://www.squarefree.com/2006/11/02/bookmarklets-updated-to-comply-with-dom-2-rule/feed/</wfw:commentRss>
		<slash:comments>359</slash:comments>
		</item>
		<item>
		<title>Finding the textarea selection</title>
		<link>http://www.squarefree.com/2006/05/06/finding-the-textarea-selection/</link>
		<comments>http://www.squarefree.com/2006/05/06/finding-the-textarea-selection/#comments</comments>
		<pubDate>Sun, 07 May 2006 02:10:15 +0000</pubDate>
		<dc:creator>Jesse Ruderman</dc:creator>
				<category><![CDATA[Bookmarklets]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Mozilla]]></category>

		<guid isPermaLink="false">http://www.squarefree.com/2006/05/06/finding-the-textarea-selection/</guid>
		<description><![CDATA[A desperate web developer emailed me asking how make a bookmarklet that does something with the selected text, where the selected text is usually in a textarea. He had tried using window.getSelection.toString(), but that doesn't work, because window.getSelection() is implemented in terms of DOM Ranges and it doesn't make much sense to have a DOM [...]]]></description>
			<content:encoded><![CDATA[<p>A desperate web developer emailed me asking how make a bookmarklet that does something with the selected text, where the selected text is usually in a textarea.</p>

<p>He had tried using <a href="http://developer.mozilla.org/en/docs/DOM:window.getSelection">window.getSelection</a>.toString(), but that <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=85686">doesn't work</a>, because window.getSelection() is implemented in terms of <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html">DOM Ranges</a> and it doesn't make much sense to have a DOM Range inside a textarea.</p>

<p>Here are some of the methods I tried:</p>

<ul>
<li>Determine focus using by tracking with onfocus or onblur events.  Works for web pages, but doesn't work for bookmarklets.</li>
<li><a href="http://www.squarefree.com/findfocus/reflectSelection.html">Determine focus using window.getSelection().getRangeAt(...) and commonAncestorContainer</a>. Doesn't work (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=336936">bug 336936</a>).</li>
<li><a href="http://www.squarefree.com/findfocus/xuliframehack.html">Determine focus using a XUL document in an iframe and commandDispatcher.focusedElement</a>. Ugly Firefox-only hack, but it works.</li>
<li>Determine focus using WhatWG's <a href="http://whatwg.org/specs/web-apps/current-work/#the-documentfocus">document.currentFocus</a>. Only a working draft, not implemented in Firefox yet (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=337631">bug 337631</a>).</li>
<li><a href="http://www.squarefree.com/findfocus/alltextareas.html">Use selectionStart / selectionEnd in <em>all</em> textareas</a>. This can return nonempty selections from multiple textareas.</li>
</ul>

<p>Am I missing a sane solution that works in current versions of Firefox?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.squarefree.com/2006/05/06/finding-the-textarea-selection/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
	</channel>
</rss>

