<?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>Chris Pitchin&#039; Hey</title>
	<atom:link href="http://blog.mozilla.org/cjones/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.mozilla.org/cjones</link>
	<description>Mozilla hacks and suchlike</description>
	<lastBuildDate>Tue, 15 Nov 2011 05:30:12 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Great work coming out of Mozilla&#8217;s Taiwan office</title>
		<link>http://blog.mozilla.org/cjones/2011/11/14/great-work-coming-out-of-mozillas-taiwan-office/</link>
		<comments>http://blog.mozilla.org/cjones/2011/11/14/great-work-coming-out-of-mozillas-taiwan-office/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 05:30:12 +0000</pubDate>
		<dc:creator>cjones</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/cjones/?p=117</guid>
		<description><![CDATA[You knew that Mozilla has an office in Taipei now, right? We&#8217;ve got a great engineering manager and three great engineers working out of Taipei, so far mostly on Boot2Gecko. I want to briefly call out what they&#8217;ve been working on lately. They&#8217;ve all just started within the last couple of months and are already [...]]]></description>
				<content:encoded><![CDATA[<p>You knew that Mozilla has an office in Taipei now, right? <img src='http://blog.mozilla.org/cjones/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>We&#8217;ve got a great engineering manager and three great engineers working out of Taipei, so far mostly on Boot2Gecko.  I want to briefly call out what they&#8217;ve been working on lately.  They&#8217;ve all just started within the last couple of months and are already kicking butt!</p>
<p>Shian-Yow Wu (shianyow on IRC): Shian-Yow fixed a long-standing bug preventing Wifi from working on b2g phones.  He&#8217;s lately been hacking on virtual qemu devices that will allow us to test new hardware-interaction DOM APIs, and he continues to debug nasty issues; most recently an infinite loop in a stack dumper and a media crash on startup.</p>
<p>Thinker Lee (thinker): Thinker hit the ground running at Mozilla by setting up a qemu build that runs Firefox on Android (and b2g).  He went on to add a fall-back path to our WebGL home screen that lets it work when WebGL isn&#8217;t available (uses 2D canvas instead).  Lately he&#8217;s been implementing the lower-level parts of a proposed DOM &#8220;Sensor&#8221; API, allowing web apps to access proximity and ambient-light sensors, possibly among others.</p>
<p>Kan-Ru Chen (kanru): Kan-Ru jumped right into porting <a href="https://github.com/apitrace/apitrace">apitrace</a>, a GL tracing debugger, to Android/EGL.  He&#8217;s got it up and running already!  Now he&#8217;s working on getting it working with Firefox for Android <img src='http://blog.mozilla.org/cjones/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>And last but not least, James Ho has been managing our team in Taiwan, and continuously finding more good folks for Mozilla to hire in Taipei.</p>
<p>Please join me in welcoming our Taipei office, if you haven&#8217;t already.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/cjones/2011/11/14/great-work-coming-out-of-mozillas-taiwan-office/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>pdf.js reached its first milestone</title>
		<link>http://blog.mozilla.org/cjones/2011/07/03/pdf-js-first-milestone/</link>
		<comments>http://blog.mozilla.org/cjones/2011/07/03/pdf-js-first-milestone/#comments</comments>
		<pubDate>Mon, 04 Jul 2011 03:17:40 +0000</pubDate>
		<dc:creator>cjones</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/cjones/?p=96</guid>
		<description><![CDATA[Last Friday, pdf.js reached the state we wanted to it to be in before announcing it loudly: it renders the Tracemonkey paper perfectly*. So, we&#8217;re announcing it! Try out version 0.2. We&#8217;re very excited about the progress since the cat was let out of the bag two weeks ago. Below is a comparison of some [...]]]></description>
				<content:encoded><![CDATA[<p>Last Friday, <a href="http://andreasgal.com/2011/06/15/pdf-js/">pdf.js</a> reached <a href="http://andreasgal.github.com/pdf.js/multi_page_viewer.html">the state</a> we wanted to it to be in before announcing it loudly: it renders the <a href="http://people.mozilla.org/~gal/compressed.tracemonkey-pldi-09.pdf">Tracemonkey paper</a> perfectly<sup><a href="#*">*</a></sup>.  So, we&#8217;re announcing it!</p>
<p><a href="http://andreasgal.github.com/pdf.js/multi_page_viewer.html">Try out version 0.2</a>.</p>
<p>We&#8217;re very excited about the progress since the <a href="http://news.ycombinator.com/item?id=2657684">cat was let out of the bag</a> two weeks ago.  Below is a comparison of some pages as rendered by the <a href="http://people.mozilla.org/~gal/test.html">version of pdf.js</a> initially covered by the press and our <a href="http://andreasgal.github.com/pdf.js/multi_page_viewer.html">v0.2 release</a>.  In each pair of screenshots, the rendering of the older version is on top, and the rendering of 0.2 is on the bottom.</p>
<p><a href="http://people.mozilla.com/~cjones/pdf.js/caps/tm/0.1-0.2-page1.png"><img src="http://people.mozilla.com/~cjones/pdf.js/caps/tm/0.1-0.2-page1.png-thumb.jpg"></img></a></p>
<p>This is the most dramatic demonstration of <a href="https://github.com/andreasgal/pdf.js">pdf.js</a>&#8216;s biggest feature in 0.2: loading Type 1 fonts.  (In fact, the difference between the captures above <em>should</em> have been even more dramatic, except that we hard-coded into <a href="https://github.com/andreasgal/pdf.js">pdf.js</a> selection of the font used for most body text in the paper, so that we could more easily focus on other unimplemented features.)  Dynamically loading Type 1 fonts into a web application was a big challenge.  We&#8217;re trying to get <a href="http://vingtetun.org/blog/">Vivien</a> to write about it; stay tuned.  It&#8217;s hard to overstate how important this feature is for <a href="https://github.com/andreasgal/pdf.js">pdf.js</a>.</p>
<p><a href="http://people.mozilla.com/~cjones/pdf.js/caps/tm/0.1-0.2-page2.png"><img src="http://people.mozilla.com/~cjones/pdf.js/caps/tm/0.1-0.2-page2.png-thumb.jpg"></img></a></p>
<p>Figure 2 on this page shows off several parts of <a href="https://github.com/andreasgal/pdf.js">pdf.js</a>&#8216;s renderer</p>
<ul>
<li>The very obvious improvement in the labels on elements in the figure in 0.2 is due to pdf.js loading TrueType fonts properly.</li>
<li>The shadows under the rounded boxes are masked images, which <a href="https://sbarman.wordpress.com/">Shaon</a> implemented.</li>
<li>The dashed lines are drawn using a new API we&#8217;ve added to Firefox&#8217;s &lt;canvas&gt; and are in the process of standardizing.</li>
</ul>
<p><a href="http://people.mozilla.com/~cjones/pdf.js/caps/tm/0.1-0.2-page3.png"><img src="http://people.mozilla.com/~cjones/pdf.js/caps/tm/0.1-0.2-page3.png-thumb.jpg"></img></a></p>
<p>Figure 4 is another dramatic demonstration of the difference made by loading Type 1 fonts and measuring them accurately.</p>
<p><a href="http://people.mozilla.com/~cjones/pdf.js/caps/tm/0.1-0.2-page11.png"><img src="http://people.mozilla.com/~cjones/pdf.js/caps/tm/0.1-0.2-page11.png-thumb.jpg"></img></a></p>
<p>The prettily colored, filled bars in Figure 10 are also thanks to <a href="https://sbarman.wordpress.com/">Shaon</a>; they&#8217;re &#8220;shading patterns&#8221; (custom, parameterized functions) that pdf.js evaluates all in JS, drawing resulting pixel values to canvas.  These particular bars are &#8220;axial shading&#8221; patterns, aka &#8220;linear gradients&#8221;.  The text in the description of Figure 10 also looks vastly better in 0.2, as it mixes several font faces that are now being loaded thanks to Vivien.</p>
<p><a href="http://people.mozilla.com/~cjones/pdf.js/caps/tm/0.1-0.2-page13.png"><img src="http://people.mozilla.com/~cjones/pdf.js/caps/tm/0.1-0.2-page13.png-thumb.jpg"></img></a></p>
<p>In Figure 12, we see a nice demonstration of a couple more new features in 0.2: the labels in the figure are being drawn because <a href="https://github.com/andreasgal/pdf.js">pdf.js</a> now loads TrueType fonts.  The hatched segments of bars in the graph are being rendered faithfully now because <a href="https://sbarman.wordpress.com/">Shaon</a> implemented tiled fills of patterns.</p>
<p><a href="http://people.mozilla.com/~cjones/pdf.js/caps/tm/0.1-0.2-nav.png"><img src="http://people.mozilla.com/~cjones/pdf.js/caps/tm/0.1-0.2-nav.png-thumb.jpg"></img></a></p>
<p>And last but not least, tt&#8217;s obvious in all the screenshots above that the user interface in version 0.2 is much more usable and prettier than in the initial version.  That&#8217;s the work of  <a href="https://github.com/justindarc">justindarc</a>.  This sceenshot shows off a really cool new feature of <a href="https://github.com/andreasgal/pdf.js">pdf.js</a>&#8216;s new viewer: a &#8220;preview panel&#8221;, that pops out when the mouse hovers over the dark bar on the left side of the page.  You&#8217;ll also notice the lower screenshot, from 0.2, shows the viewer straddling two pages; the first version, shown above, could only display one page at a time.</p>
<p>We chose the pixel-perfect rendering of this paper as our first milestone  because getting there required solving some hard problems, and it&#8217;s easier to focus attention on one target.  We want to prove that a competitive HTML5 PDF renderer really is feasible, and not just fun talk.  Many more hard problems remain, but we haven&#8217;t come across any so far that  are so much harder than what we&#8217;ve already solved to make us rethink the viability of pdf.js.</p>
<h3>Community</h3>
<p>pdf.js has a great and growing community.  As we noted above, <a href="https://github.com/justindarc">justindarc</a> totally overhauled the viewer UI.  <a href="https://github.com/notmasteryet">notmasteryet</a> implemented support for encrypted PDFs and embedded JPEGs (among other things).   <a href="https://github.com/jviereck">jvierek</a> added a Web Workers backend (among other things) that will be one of the biggest features of our next milestone.  <a href="https://github.com/sayrer">sayrer</a> has greatly improved our testing infrastructure.  Everyone has done their fair share bug fixing.  The list of contributors will probably have grown between the time we write this and the time you read it, so be sure to check out the <a href="https://github.com/andreasgal/pdf.js/contributors">current list</a>.</p>
<h3>More browsers/OSes, more problems</h3>
<p>We intend pdf.js to work in all HTML5-compliant browsers.  And that, by definition, means pdf.js should work equally well on all operating systems that those browsers run on.</p>
<p><a name="*"></a>Reality is different.  pdf.js produces different results on pretty much every element in the browser&times;OS matrix.  We said above that pdf.js renders the Tracemonkey paper &#8220;perfectly&#8221; &#8230; if you&#8217;re running a <a href="http://nightly.mozilla.org/">Firefox nightly</a>.  On a Windows 7 machine where Firefox can use Direct2D and DirectWrite.  If you ignore what appears to be a bug in DirectWrite&#8217;s font hinting.</p>
<p>The paper is rendered less well on other platforms and in older FIrefoxen, and even worse in other browsers.  But such is life on the bleeding edge of the web platform.</p>
<p>pdf.js has now reached the point where a significant portion of its issues are actually <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=667947">browser</a>-<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=664077">rendering</a>-<a href="https://github.com/andreasgal/pdf.js/issues/131">engine</a> <a href="http://code.google.com/p/chromium/issues/detail?id=82402">bugs</a>, or <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=471915">missing features</a>.  Finding these gaps and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=655926">filling</a> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=662038">some</a> of <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=664884">them</a> has been one of the biggest returns on our investment in pdf.js so far.</p>
<h3>What&#8217;s next?</h3>
<p>For our next release, we have two big goals: first is to continue adding features needed to render PDFs (of course!).  Our next target is a bit more ambitious: pixel-perfect rendering of the <a href="http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/pdf_reference_1-7.pdf">PDF 1.7 specification</a> itself.  Work has already begun on this, during the stabilization period for the 0.2 release.  Second is to improve pdf.js&#8217;s architecture.  This itself has two parts: use Web Workers to parallelize computationally-intensive tasks, and allow pdf.js&#8217;s main-thread computations to be interrupted to improve UI responsiveness.  (Ideally the web platform would allow us to do all computationally-intensive tasks like drawing to &lt;canvas&gt; off the UI thread, but that&#8217;s a hard and unsolved problem.)</p>
<p>We can keep moving fast towards rendering the PDF spec because we&#8217;re not worried about regressions, thanks mostly to sayrer&#8217;s work on testing.</p>
<h3>Contribute!</h3>
<p>We want <a href="https://github.com/andreasgal/pdf.js">pdf.js</a> to be a community driven and governed open-source project. We want to use it for  Firefox, but we think there are many cool applications for it. We would love to see it embedded in other browsers or web applications; because it’s written only in standards-compliant web technologies, the code will run in any compliant browser. <a href="https://github.com/andreasgal/pdf.js">pdf.js</a> is licensed under a very liberal 3-clause BSD license and we welcome external contributors.  We are looking forward to your ideas or code to make pdf.js better!  Take a look at our <a href="https://github.com/andreasgal/pdf.js">github and our <a href="https://wiki.mozilla.org/PDF.js">wiki</a>, talk to us on IRC in <a href="irc://irc.mozilla.org/pdfjs">#pdfjs</a>, and sign up for our <a href="https://lists.mozilla.org/listinfo/dev-pdf-js">mailing list</a>.</p>
<p>Andreas Gal and Chris Jones (and the pdf.js team)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/cjones/2011/07/03/pdf-js-first-milestone/feed/</wfw:commentRss>
		<slash:comments>39</slash:comments>
		</item>
		<item>
		<title>Overview of pdf.js guts</title>
		<link>http://blog.mozilla.org/cjones/2011/06/15/overview-of-pdf-js-guts/</link>
		<comments>http://blog.mozilla.org/cjones/2011/06/15/overview-of-pdf-js-guts/#comments</comments>
		<pubDate>Thu, 16 Jun 2011 02:21:22 +0000</pubDate>
		<dc:creator>cjones</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/cjones/?p=82</guid>
		<description><![CDATA[Andreas posted a general overview of pdf.js. I&#8217;d like to briefly cover some more-technical parts of the renderer. pdf.js (currently) parses raw arrays of bytes into streams of PDF &#8220;bytecode&#8221;, compiles the bytecode into JavaScript programs, then executes the programs. (Yes, it&#8217;s a sort of PDF JIT . The side effect of those programs is [...]]]></description>
				<content:encoded><![CDATA[<p>Andreas <a href="http://andreasgal.com/2011/06/15/pdf-js">posted</a> a general overview of pdf.js.  I&#8217;d like to briefly cover some more-technical parts of the renderer.</p>
<p>pdf.js (currently) parses raw arrays of bytes into streams of PDF &#8220;bytecode&#8221;, compiles the bytecode into JavaScript programs, then executes the programs.  (Yes, it&#8217;s a sort of PDF JIT <img src='http://blog.mozilla.org/cjones/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .  The side effect of those programs is to draw on an HTML5 &lt;canvas&gt;.  The commands in the bytecode include simple things like &#8220;draw a curve&#8221;, &#8220;draw this text here&#8221;, and more complicated things like filling areas with &#8220;shading patterns&#8221; specified by custom functions (see <a href="http://sbarman.wordpress.com">Shaon&#8217;s post</a>).  Additionally, the stream of commands itself, and other data embedded within like fonts and images, might be compressed and/or encrypted in the raw byte array.  pdf.js has basic support to decompress some of these streams, all the code written in JavaScript.</p>
<p>The rendering of fonts embedded in PDFs using web technologies is a big enough topic to merit its own blog post.  A post might eventually appear on <a href="http://vingtetun.org/blog/">Vivien&#8217;s</a>, but if not, somewhere else <img src='http://blog.mozilla.org/cjones/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p>There are several ways to write a PDF renderer on top of the web platform; pdf.js&#8217;s current implementation, drawing to a &lt;canvas&gt;, is just one way.  We chose canvas initially because it is (should be) the fastest way for us to draw to the screen.  We want the first-paint of pages to be quick so that pdf.js startup feels zippy, and users can start reading content ASAP.  Canvas is great for this.</p>
<p>Canvas has problems though.  First, it&#8217;s missing many features needed to render PDFs.  We&#8217;ve starting adding some of these to the <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=655926">web</a> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=662038">platform</a>, when it makes sense to do so, and there&#8217;s more to<br />
come.  A second, and much bigger problem, is that while canvas&#8217;s immediate-mode design allows us to render with minimal overhead, it means that the user agent doesn&#8217;t have enough information to allow users to select text, or navigate using accessibility interfaces (through a screen reader, e.g.).  Printing canvases with high fidelity is another issue.</p>
<p>The web platform already offers a (potential) solution to these problems, however: SVG.  SVG is richly featured, retained-mode, and has its own DOM.  In theory, user agents should have text-selection, a11y, and printing support for SVG.  (If they don&#8217;t, it needs to be added.)  So, SVG provides (in theory) the features missing from &lt;canvas&gt;, just at a higher cost in the form of more overhead.</p>
<p>Putting all this together, we currently plan on doing a fast first-paint of pages using canvas, concurrently building an SVG document for the page in the background, and when the SVG document is ready, switching to that.  Or if that doesn&#8217;t work well, we could implement text-selection (and hopefully a11y) in pdf.js itself, on top of canvas, possibly creating new web APIs along the way.  Or if, say, font loading dominates the critical path to first-paint, we might only use SVG and forget canvas.  It&#8217;s great to have these options available.</p>
<p>There&#8217;s a ton of work left on pdf.js, from implementing features to improving the user interface to exploring crazy ideas (like for example using WebGL to speed up rendering).  The project is open and the code is libre: we&#8217;d love for you to get involved!  Have a look at <a href="https://github.com/andreasgal/pdf.js">our github</a> and <a href="https://wiki.mozilla.org/PDF.js">our wiki</a>, or talk to us on <a href="irc://irc.mozilla.org/pdfjs">IRC in #pdfjs</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/cjones/2011/06/15/overview-of-pdf-js-guts/feed/</wfw:commentRss>
		<slash:comments>31</slash:comments>
		</item>
		<item>
		<title>Followup to: Filter your tryserver builds, a bit more easily</title>
		<link>http://blog.mozilla.org/cjones/2010/08/12/followup-to-filter-your-tryserver-builds-a-bit-more-easily/</link>
		<comments>http://blog.mozilla.org/cjones/2010/08/12/followup-to-filter-your-tryserver-builds-a-bit-more-easily/#comments</comments>
		<pubDate>Thu, 12 Aug 2010 19:59:54 +0000</pubDate>
		<dc:creator>cjones</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/cjones/?p=66</guid>
		<description><![CDATA[I made a mistake in not hosting this script from an hg repository; it&#8217;s already changed a few times since I originally posted. So, I fixed that. Now one can hg clone http://hg.mozilla.org/users/cjones_mozilla.com/tryselect cd $repo ../tryselect/tryselect Permissions and so forth should be set correctly. (Protip: I symlinked tryselect/tryselect into a directory in my $PATH.) If [...]]]></description>
				<content:encoded><![CDATA[<p>I made a mistake in not hosting this script from an hg repository; it&#8217;s already changed a few times since I originally posted.  So, I fixed that.  Now one can</p>
<pre>
hg clone http://hg.mozilla.org/users/cjones_mozilla.com/tryselect
cd $repo
../tryselect/tryselect
</pre>
<p>Permissions and so forth should be set correctly.  (Protip: I symlinked <code>tryselect/tryselect</code> into a directory in my <code>$PATH</code>.)</p>
<p>If you find bugs, please fix them!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/cjones/2010/08/12/followup-to-filter-your-tryserver-builds-a-bit-more-easily/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Filter your tryserver builds, a bit more easily</title>
		<link>http://blog.mozilla.org/cjones/2010/08/10/filter-your-tryserver-builds-a-bit-more-easily/</link>
		<comments>http://blog.mozilla.org/cjones/2010/08/10/filter-your-tryserver-builds-a-bit-more-easily/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 07:42:18 +0000</pubDate>
		<dc:creator>cjones</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/cjones/?p=63</guid>
		<description><![CDATA[(Next in my series of posts designed to make this the most boring blog on p.m.o .) The new tryserver has the (awesome!) ability to customize builds for each platform, using mozconfig-extra-$platform scripts. For me (and most others?), the common case will be to use the extra files to disable builds for platforms I don&#8217;t [...]]]></description>
				<content:encoded><![CDATA[<p>(Next in my series of posts designed to make this the most boring blog on p.m.o <img src='http://blog.mozilla.org/cjones/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  .)</p>
<p>The <a href="https://wiki.mozilla.org/Build:TryServer">new tryserver</a> has the (awesome!) ability to customize builds for each platform, using <code>mozconfig-extra-$platform</code> scripts.  For me (and most others?), the common case will be to use the extra files to disable builds for platforms I don&#8217;t care about.  However, keeping a <code>tryserver-filter</code> patch or patches in my mq, and customizing for each filtered push, didn&#8217;t appeal to me.  So instead, I wrote a little <a href="http://people.mozilla.com/~cjones/tryselect">bash script</a> to automate the process for me.</p>
<p>To use it, download the script linked above to somewhere in your <code>$PATH</code>, then <code>chmod +x tryselect</code>.  The script expects you to have an <code>try = ssh://[user]@hg.mozilla.org/try</code> alias in your <code>.hgrc</code>, which you probably already do.  Then, change directory to your tree, apply all the patches you want to push, then run <code>tryselect</code>.  The script will ask you to list the platforms you want tryserver to build, then confirms those that it will disable.  If all goes well, you should see something like the following (which submitted a tryserver job I only wanted built on win32).</p>
<pre>
$ tryselect
Enter platforms to build, out of android-r7 linux linux64 macosx macosx64 maemo4 maemo5-gtk maemo5-qt win32
win32
Disabling  android-r7  linux  linux64  macosx  macosx64  maemo4  maemo5-gtk  maemo5-qt , is that right? (y/n): y
pushing to ssh://cjones@mozilla.com@hg.mozilla.org/try
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 12 changesets with 1 changes to 27 files
remote: Trying to insert into pushlog.
remote: Please do not interrupt...
remote: Inserted into the pushlog db sucessfully.
now at: 582057-use-createchild
</pre>
<p>The usual caveat about this script possibly eating your mq and/or your children, and my lack of liability thereof, applies.  Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/cjones/2010/08/10/filter-your-tryserver-builds-a-bit-more-easily/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Print nsTArrays in gdb</title>
		<link>http://blog.mozilla.org/cjones/2010/04/30/print-nstarrays-in-gdb/</link>
		<comments>http://blog.mozilla.org/cjones/2010/04/30/print-nstarrays-in-gdb/#comments</comments>
		<pubDate>Fri, 30 Apr 2010 23:09:06 +0000</pubDate>
		<dc:creator>cjones</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/cjones/?p=60</guid>
		<description><![CDATA[This code was shamelessly stolen and modified from the pvector command from Dan Marinescu&#8217;s et al. gdb-stl-views. ## ## nsTArray ## define ptarray if $argc == 0 help ptarray else set $size = $arg0.mHdr->mLength set $capacity = $arg0.mHdr->mCapacity set $size_max = $size - 1 set $elts = $arg0.Elements() end if $argc == 1 set $i [...]]]></description>
				<content:encoded><![CDATA[<p>This code was shamelessly stolen and modified from the <code>pvector</code> command from Dan Marinescu&#8217;s et al. <a href="http://sourceware.org/gdb/wiki/STLSupport">gdb-stl-views</a>.</p>
<pre>
##
## nsTArray
##
define ptarray
	if $argc == 0
		help ptarray
	else
		set $size = $arg0.mHdr->mLength
		set $capacity = $arg0.mHdr->mCapacity
		set $size_max = $size - 1
                set $elts = $arg0.Elements()
	end
	if $argc == 1
		set $i = 0
		while $i < $size
			printf "elem[%u]: ", $i
			p *($elts + $i)
			set $i++
		end
	end
	if $argc == 2
		set $idx = $arg1
		if $idx < 0 || $idx > $size_max
			printf "idx1, idx2 are not in acceptable range: [0..%u].\n", $size_max
		else
			printf "elem[%u]: ", $idx
			p *($elts + $idx)
		end
	end
	if $argc == 3
	  set $start_idx = $arg1
	  set $stop_idx = $arg2
	  if $start_idx > $stop_idx
	    set $tmp_idx = $start_idx
	    set $start_idx = $stop_idx
	    set $stop_idx = $tmp_idx
	  end
	  if $start_idx < 0 || $stop_idx < 0 || $start_idx > $size_max || $stop_idx > $size_max
	    printf "idx1, idx2 are not in acceptable range: [0..%u].\n", $size_max
	  else
	    set $i = $start_idx
		while $i <= $stop_idx
			printf "elem[%u]: ", $i
			p *($elts + $i)
			set $i++
		end
	  end
	end
	if $argc > 0
		printf "nsTArray length = %u\n", $size
		printf "nsTArray capacity = %u\n", $capacity
		printf "Element "
		whatis *$elts
	end
end

document ptarray
	Prints nsTArray<T> information.
	Syntax: ptarray <tarray> <idx1> <idx2>
	Note: idx, idx1 and idx2 must be in acceptable range [0..<tarray>.size()-1].
	Examples:
	ptarray a - Prints tarray content, size, capacity and T typedef
	ptarray a 0 - Prints element[idx] from tarray
	ptarray a 1 2 - Prints elements in range [idx1..idx2] from tarray
end 
</pre>
<p>Example session</p>
<pre>
(gdb) ptarray arr
elem[0]: $1 = 1
elem[1]: $2 = 2
elem[2]: $3 = 3
nsTArray length = 3
nsTArray capacity = 4
Element type = int
(gdb) ptarray arr 1
elem[1]: $4 = 2
nsTArray length = 3
nsTArray capacity = 4
Element type = int
(gdb) ptarray arr 1 2
elem[1]: $5 = 2
elem[2]: $6 = 3
nsTArray length = 3
nsTArray capacity = 4
Element type = int
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/cjones/2010/04/30/print-nstarrays-in-gdb/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Save yourself some license template copypasta (in emacs)</title>
		<link>http://blog.mozilla.org/cjones/2010/03/24/save-yourself-some-license-template-copypasta-in-emacs/</link>
		<comments>http://blog.mozilla.org/cjones/2010/03/24/save-yourself-some-license-template-copypasta-in-emacs/#comments</comments>
		<pubDate>Thu, 25 Mar 2010 03:17:04 +0000</pubDate>
		<dc:creator>cjones</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/cjones/?p=54</guid>
		<description><![CDATA[Add this to your .emacs (defun insert-mpl-tri-license () (interactive) (insert "/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n" " * vim: sw=2 ts=8 et :\n" " */\n" "/* ***** BEGIN LICENSE BLOCK *****\n" " * Version: MPL 1.1/GPL 2.0/LGPL 2.1\n" " *\n" " * The contents of this file are subject to [...]]]></description>
				<content:encoded><![CDATA[<p>Add this to your .emacs</p>
<pre>
(defun insert-mpl-tri-license () (interactive)
  (insert 
"/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-\n"
" * vim: sw=2 ts=8 et :\n"
" */\n"
"/* ***** BEGIN LICENSE BLOCK *****\n"
" * Version: MPL 1.1/GPL 2.0/LGPL 2.1\n"
" *\n"
" * The contents of this file are subject to the Mozilla Public License Version\n"
" * 1.1 (the \"License\"); you may not use this file except in compliance with\n"
" * the License. You may obtain a copy of the License at:\n"
" * http://www.mozilla.org/MPL/\n"
" *\n"
" * Software distributed under the License is distributed on an \"AS IS\" basis,\n"
" * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n"
" * for the specific language governing rights and limitations under the\n"
" * License.\n"
" *\n"
" * The Original Code is Mozilla Code.\n"
" *\n"
" * The Initial Developer of the Original Code is\n"
" *   The Mozilla Foundation\n"
" * Portions created by the Initial Developer are Copyright (C) 2010\n"
" * the Initial Developer. All Rights Reserved.\n"
" *\n"
" * Contributor(s):\n"
" *   [YOUR NAME/EMAIL HERE]\n"
" *\n"
" * Alternatively, the contents of this file may be used under the terms of\n"
" * either the GNU General Public License Version 2 or later (the \"GPL\"), or\n"
" * the GNU Lesser General Public License Version 2.1 or later (the \"LGPL\"),\n"
" * in which case the provisions of the GPL or the LGPL are applicable instead\n"
" * of those above. If you wish to allow use of your version of this file only\n"
" * under the terms of either the GPL or the LGPL, and not to allow others to\n"
" * use your version of this file under the terms of the MPL, indicate your\n"
" * decision by deleting the provisions above and replace them with the notice\n"
" * and other provisions required by the GPL or the LGPL. If you do not delete\n"
" * the provisions above, a recipient may use your version of this file under\n"
" * the terms of any one of the MPL, the GPL or the LGPL.\n"
" *\n"
" * ***** END LICENSE BLOCK ***** */\n"))
(global-set-key "\C-xg" 'insert-mpl-tri-license)
</pre>
<p>(replacing &#8220;[YOUR NAME/EMAIL HERE]&#8221; of course), then &#8220;C-x g&#8221; to victory.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/cjones/2010/03/24/save-yourself-some-license-template-copypasta-in-emacs/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Helping ld link libxul more quickly</title>
		<link>http://blog.mozilla.org/cjones/2009/11/25/helping-ld-link-libxul-more-quickly/</link>
		<comments>http://blog.mozilla.org/cjones/2009/11/25/helping-ld-link-libxul-more-quickly/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 19:28:29 +0000</pubDate>
		<dc:creator>cjones</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/cjones/?p=45</guid>
		<description><![CDATA[I used to do most of my development in a Linux virtual machine with 1.5GB of RAM. There, &#8211;enable-libxul builds were &#8230; painful: linking libxul itself took about 2 minutes and 30 seconds. Ideally, ld or gold would know how to re-link incrementally, and the problem would vanish. But until then, you can help ld [...]]]></description>
				<content:encoded><![CDATA[<p>I used to do most of my development in a Linux virtual machine with 1.5GB of RAM.  There, &#8211;enable-libxul builds were &#8230; painful: linking libxul itself took about 2 minutes and 30 seconds.  Ideally, ld or gold would know how to re-link incrementally, and the problem would vanish.  But until then, you can help ld out by adding a flag in your mozconfig</p>
<pre>
...
export LDFLAGS="-Wl,--no-keep-memory"
</pre>
<p>This tells ld to optimize for memory usage rather than speed.  On my 1.5GB VM, this made a big difference because it kept ld from hitting swap as much; the link time went from ~2:30 to ~1:30.  Also see https://bugzilla.mozilla.org/show_bug.cgi?id=494068.</p>
<p>CAVEAT EMPTOR: if you have a machine with &#8220;lots of RAM&#8221;, this flag might actually <strong>hurt</strong> link times.  Also, it&#8217;s worth pointing out that the best way to speed up libxul link times is to add more RAM to your build machine, if possible.  (My bright shiny new build machine can link libxul in about 5 seconds, so I don&#8217;t use &#8211;no-keep-memory anymore.)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/cjones/2009/11/25/helping-ld-link-libxul-more-quickly/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing porky.py: Low-fat pork</title>
		<link>http://blog.mozilla.org/cjones/2009/08/04/introducing-porky-py-low-fat-pork/</link>
		<comments>http://blog.mozilla.org/cjones/2009/08/04/introducing-porky-py-low-fat-pork/#comments</comments>
		<pubDate>Tue, 04 Aug 2009 21:16:09 +0000</pubDate>
		<dc:creator>cjones</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/cjones/?p=23</guid>
		<description><![CDATA[Porky.py (pronounced &#8220;porky pie&#8221;) is a simple C++ rewriting tool built on top of pork. Porky.py aims to make pork usable for a larger class of code rewriting problems by lowering pork&#8217;s high learning curve and making it easier to code up rewrite passes. If you want to skip the exposition and play with the [...]]]></description>
				<content:encoded><![CDATA[<p>Porky.py (pronounced &#8220;porky pie&#8221;) is a simple C++ rewriting tool built on top of <a href="https://developer.mozilla.org/en/Pork">pork</a>.  Porky.py aims to make pork usable for a larger class of code rewriting problems by lowering pork&#8217;s high learning curve and making it easier to code up rewrite passes.</p>
<p>If you want to skip the exposition and play with the code, it&#8217;s available <a href="http://hg.mozilla.org/rewriting-and-analysis/pork/">here</a>.  Just follow the <a href="https://developer.mozilla.org/en/Installing_Pork">pork install instructions</a> to get started.</p>
<h4>Background</h4>
<p>Porky.py started back in April when I wanted to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=486606">rewrite a bunch of code</a>.  I was (well, am still, sigh) replacing a C API with a new C++ API.  Basically, code that looked like this</p>
<pre>
PRLock* lock = PR_NewLock();
PR_Lock(lock);
PR_Unlock(lock);
PR_DestroyLock(lock);
</pre>
<p>was going to be changed into this</p>
<pre>
Mutex* lock = new Mutex();
lock->Lock();
lock->Unlock();	
delete lock;
</pre>
<p>I quickly estimated that these old APIs were used in O(1000) places in our code, which was way more than I wanted to edit by hand.  (I&#8217;m <a href="http://www.c2.com/cgi/wiki?LazinessImpatienceHubris">lazy</a>, so sue me.)  So I wanted an automated tool.  However, this rewrite task is just beyond the reach of regular-expression-based tools like sed; existing code could do something like <code>PR_Lock(GetStruct().GetPRLock())</code>, which causes sed to barf.  Of course there&#8217;s the pork tool, which can eat this kind of rewrite for breakfast, but looking at existing pork tools convinced me that, for this relatively simple rewrite, it was going to be a waste of work to (i) learn pork&#8217;s AST classes; (ii) learn its AST visitor idioms; (iii) learn the non-standard utility libraries pork depends on (sm::string, FakeList, &#8230;); (iv) learn pork&#8217;s patch generation library; (v) code the tool in C++ &#8230; sigh.</p>
<p>So I was stuck with either doing a half-assed rewrite with sed and spending a few days fixing up its mistakes, or wasting a week or so coding a pork tool.  Half-assed rewrites suck.  But in the <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=486606">bug report</a> I filed, I realized that I was naturally describing the rewrite in a way that an automated tool could understand.  I have some background in programming languages, so in the spirit of Terence Parr</p>
<blockquote><p>
&#8220;Why program by hand in five days what you can spend five <strike>years</strike>days of your life automating?&#8221;
</p></blockquote>
<p>I decided to write my own tool on top of pork.</p>
<h4>Porky.py&#8217;s specification language</h4>
<p>Porky.py&#8217;s domain-specific language (DSL) for rewrites was designed with this use case in mind</p>
<ul>
<li>a C++ developer not familiar with porky.py wants to do something like my API rewrite example above</li>
<li>doesn&#8217;t want to spend several days learning pork</li>
<li>and doesn&#8217;t want to learn an obscure DSL</li>
<li>(it&#8217;d be nice if the tool were fast, too)</li>
</ul>
<p>So these requirements to me implied that, first, the porky.py DSL should be &#8220;minimal&#8221; in the sense of minimal additional syntax beyond C++&#8217;s &#8212; less to learn.  And second, porky.py should target expression-level rewrites (as API changes usually are) rather than statement level.  Statement-level rewrites complicate things.</p>
<p>Below is a working porky.py solution to the rewrite problem posed above.  You can decide for yourself whether it meets my criteria.</p>
<pre>
rewrite SyncPrimitiveUpgrade {
  type PRLock* => Mutex*
  call PR_NewLock() => new Mutex()
  call PR_Lock(lock) => lock->Lock()
  call PR_Unlock(lock) => lock->Unlock()
  call PR_DestroyLock(lock) => delete lock
}
</pre>
<p>The rewrite rule <code>type PRLock* => Mutex*</code> means: everywhere the type &#8220;PRLock*&#8221; appears, change it into &#8220;Mutex*&#8221;.  The second kind of rule here, <code>PR_Lock(lock) => lock->Lock()</code> is more interesting; it means that, at any callsite matching</p>
<pre>PR_Lock($lock$)</pre>
<p>where <code>$lock$</code> is any expression, change this line into</p>
<pre>$lock$->Lock()</pre>
<p>These kinds of rules are porky.py&#8217;s big advantage over sed et al.: because pork.py has access to a C++ AST through pork, it can match patterns that require strictly more power than regular expressions provide.  One can write rules like <code>call Foo(a, b, c) => c.Method(b, a)</code>, and the rule will rewrite call sites like <code>Foo(x().y().z(), r(s(t)), u.v.w())</code> into <code>u.v.w().Method(r(s(t)), x().y().z())</code>.</p>
<p>And finally, porky.py provides the creature comfort of one-liner shell invocations for really simple rewrites</p>
<pre>porkyc -e 'call SomeFun(a, b) => OtherFun(b, a)'</pre>
<p>After which the compiled pork tool can be invoked.  (Docs forthcoming on MDC.)</p>
<h4>Code rewriting workflow when using porky.py</h4>
<p>After writing porky.py, I used it to edit a large quantity of code in a couple of hours.  These patches haven&#8217;t all made it into mozilla-central yet (for a variety of reasons), but I wanted to show the steps I took to generate them.  This will eventually find its way into an MDC guide.</p>
<pre>
$ porkyc -m sync_primitive_upgrade.porky
  (outputs and compiles code in |SyncPrimitiveUpgrade.code/|)
$ SyncPrimitiveUpgrade.code/dorewrite ~/mozilla-code/*.ii -x *nspr* > mozilla-code.patch
   (does n-way parallel rewrite on matching files; n depends on your system)
   (doesn't include files matching the pattern *nspr* in the patch)
   (writes patch to stdout)
</pre>
<p>Next, I would apply this patch and compile, fixing up problems by hand (hey, porky.py is a prototype).  Then it was <code>hg qdiff</code> and the patch was up for review.  I could generate these patches <em>much</em> faster than they would have been able to be reviewed; this ended up being the bottleneck.</p>
<h4>Eventual goal for porky.py</h4>
<p>I&#8217;d like it to support this rewrite</p>
<pre>
rewrite FooToBar {
  class Foo => Bar {
    member mMember => member_
    method Method(a1, a2) => method(a2, a1)
  }
}
</pre>
<p>which would entail</p>
<ul>
<li>rename <code>class Foo</code> into <code>class Bar</code></li>
<li>rename type &#8220;Foo&#8221; into type &#8220;Bar&#8221; (including <code>Foo*</code>, <code>Foo&#038;</code>, &#8230;)</li>
<li>change calls to Foo constructors into Bar constructors</li>
<li>rename declaration of <code>Foo.mMember</code> into <code>Bar.member_</code></li>
<li>convert accesses of <code>((Foo)inst).mMember</code> into <code>((Bar)inst).member_</code>, (and similary for <code>inst->mMember</code>, &#8230;)</li>
<li>rename declaration of <code>Foo::Method</code> into <code>Bar::method</code></li>
<li>rename implementation of <code>Foo::Method</code> into <code>Bar::method</code></li>
<li>convert calls to <code>((Foo)inst).Method(a1, a2)</code> into <code>((Bar)inst).method(a2, a1)</code> (and similary for <code>inst->Method(a1, a2)</code>, &#8230; and similary for subclasses of Foo &#8230;)</li>
</ul>
<p>I should note that having porky.py rewrite <em>declarations</em> and <em>definitions</em> is not so important (though it would be nice!): there is only one declaration/definition.  Rewriting <em>uses</em> is much more important, since there are any number of uses.</p>
<p>I won&#8217;t implement this kind of rewrite until I need it.  Sorry!  But please feel free to dive in to the porky.py code and do it yourself!</p>
<h4>How porky.py fits into the &#8220;rewrite tool space&#8221;</h4>
<p>Rewrite tools have to trade off several factors.  It&#8217;s good to have a small, familiar DSL, as these are easier to learn and remember.  But it&#8217;s also good to have a large and expressive DSL, for raw rewrite power.  The table below is my attempt to fit porky.py into the space of relevant rewrite approaches I&#8217;m aware of.  It compares porky.py with</p>
<ul>
<li><em>pork</em>.  Rewrites specs are written in C++, which is not obscure to C++ programmers.  Rewrite specs are very verbose.  Any possible rewrite of C++ code can be expressed in pork.  Pork is very fast.
<li><em>XML+XSLT</em>.  Rewrite specs are written in XML/XSLT modeled on a particular C++ AST; very obscure.  Rewrite specs are relatively concise.  Any possible rewrite can be expressed.  Very slow.</li>
<li><em>Tree transformation</em> (e.g. in <a href="http://www.antlr2.org/doc/sor.html">ANTLR</a>).  Very obscure DSL.  Rewrite specs are relatively concise.  Can express (usually) any possible rewrite.  Usually relatively slow.</li>
<li><em><a href="http://coccinelle.lip6.fr/">Coccinelle/SmPl</a></em>.  DSL relatively familiar.  Rewrite specs concise.  Can express most statement-level rewrites.  Can be fast.</li>
<li><em>porky.py</em>.  DSL familiar.  Rewrite specs concise.  Express some expression-level rewrites.  Fast.</li>
<li><em>sed</em>.  DSL familiar.  Specs concise.  Extremely limited power.  Very fast.</li>
</ul>
<pre>
  	            <---- More LoC(bad) ----- Fewer LoC (good) --->
                    <-- Less obscure(good) -- More obscure(bad) -->

	               No DSL  |  Some DSL  |  More DSL  |  All DSL
                     +---------+------------+------------+-----------
        All possible |  Pork   |    ???     |    ???     |  XML+XSLT/tree trans.
	  ~Statement |         |            |coccinelle* |
	 ~Expression |         |  porky.py  |            |
	       Names |         |            |            |
 Crappy rename hacks | sed**   |            |            |
	-------------
 	 * only works for C code
	 ** assumption: regular expressions are well-known enough that 
	    negative "DSL" connontations don't apply.
</pre>
<p>To be honest, the biggest lesson I learned from this project is that pork can be a good lower-level &#8220;engine&#8221; for higher-level tools.  I didn&#8217;t know about Coccinelle when I wrote porky.py; if I had, I might have tried retargeting it to pork instead of starting from scratch.  I prefer some of porky&#8217;s syntax/semantics to Coccinelle&#8217;s, but I think the additional complexity of SmPL adds a compelling amount of power over porky.py&#8217;s simpler DSL.  Upgrading SmPL to parse C++ and retargeting it to pork might be a good project for someone else.</p>
<p>But of course, since Coccinelle doesn&#8217;t understand C++, we&#8217;re &#8220;stuck&#8221; with porky.py for the foreseeable future <img src='http://blog.mozilla.org/cjones/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<h4>Porky.py for language nerds</h4>
<p>Porky.py is implemented as a relatively simple source-to-source translator written in Python.  It converts porky.py specifications into a C++ header containing rewrite rules defined in a sort of &#8220;bytecode.&#8221;  This header is included by a general porky.py C++ tool that uses pork.  This tool &#8220;interprets&#8221; the rules, and if a rule matches part of the C++ AST, the tool generates a patch hunk according to the porky.py spec.  This is fairly similar to how a regular expression engine would implement a &#8220;replace&#8221; function, although the matching is obviously fairly different.</p>
<p>There were a few interesting problems that arose while I designed the porky.py language.  The first was what the semantics of rule matching should be.  The issue is that multiple rules can match the same program text.  For example, in the spec</p>
<pre>
call Foo => Bar
  (means "rewrite all calls to Foo into Bar, regardless of arguments")
call Foo(a, b) => Bar(b, a)
  (means "rewrite only the two-argument version of Foo into Bar, reverse the args")
</pre>
<p>both rules will match <code>Foo(1, 2)</code>.  Which should be used?.  My solution was use the most &#8220;specific&#8221; rule.  I defined what &#8220;specific&#8221; meant by the following rules.  First, a <code>call</code> pattern with arguments is &#8220;more specific than&#8221; a <code>call</code> pattern without arguments.  And second, a &#8220;literal&#8221; pattern is &#8220;more specific than&#8221; a wildcard pattern.  For example, <code>Foo::kSomething</code> is more specific than <code>f</code>.  Porky.py implements these heuristics by ordering all the rewrite rules at compile time by decreasing &#8220;specificity&#8221; and then attempting matches in that order.  The first rule to match is chosen for the rewrite.</p>
<p>A second issue that arose was how rewrite specifications should express &#8220;literal&#8221; patterns &#8212; i.e., match this exact text &#8212; vs. &#8220;wildcard&#8221; patterns &#8212; i.e., match any expression in this syntactic slot.  The problem arises in this rule <code>call Foo(Bar, a) => Baz(a, Bar)</code>.  Are &#8220;Foo&#8221;, &#8220;a&#8221;, and &#8220;Bar&#8221; literals or wildcards?  I didn&#8217;t want to add special syntax for wildcards because of the &#8220;minimal DSL&#8221; design goal.  So, my solution was to be as &#8220;greedy&#8221; as possible about choosing wildcard variables; I think this is likely to be least surprising.  In the example above, &#8220;Foo&#8221; shouldn&#8217;t be a wildcard because if it were, it would match any function call with two arguments.  That would be silly.  But, both &#8220;a&#8221; and &#8220;Bar&#8221; are wildcards; in fact, <em>any</em> identifier used as a C++ &#8220;expression variable&#8221; (other than function names) are treated as wildcards.  The &#8220;escape hatch&#8221; is C++ namespace qualification; if in the first example &#8220;Bar&#8221; was meant to only match some global symbol &#8220;Bar&#8221;, then the pattern could have been written as <code>call Foo(::Bar, a)</code>.  There are numerous other heuristics possible here, and I may change porky.py&#8217;s depending on feedback.</p>
<p>A third issue was how porky.py expressions should be typed, i.e., what their C++ type should be.  For example, this porky.py rule seems innocent enough <code>call foo->Bar() => foo->Baz()</code> when one is thinking &#8220;<code>foo</code> is a Foo instance,&#8221; but how can porky.py glean that information?  (Note that this is not a problem for the RHS &#8220;foo&#8221;, since its type is already known by the time porky.py is ready to generate a patch hunk.)  My solution to this was to have porky.py programmers write these LHS method calls in desugared form; in the example above, <code>call Foo::Bar(foo) => foo->Baz()</code>.  Eventually, though, I would like to use the <code>class</code> syntax I introduced above to resolve this ambiguity.  For example: <code>class Foo { call Bar => call Baz }</code> (note, though, that this isn&#8217;t implemented yet).  C++ inheritance also complicates things here.  When implementing porky.py I punted on inheritance (hey, it was five day&#8217;s work!), but I think the problems it presents have reasonable solutions.</p>
<h4>Hacking porky.py</h4>
<p>If you&#8217;re interested in taking up any of the porky.py extensions I suggested here, or just want some porky.py technical support, send me an e-mail at cjones@mozilla.com or drop by the #static channel at irc.mozilla.org.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/cjones/2009/08/04/introducing-porky-py-low-fat-pork/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Multi-process Firefox, coming to an Internets near you</title>
		<link>http://blog.mozilla.org/cjones/2009/06/21/multi-process-firefox-coming-to-an-internets-near-you/</link>
		<comments>http://blog.mozilla.org/cjones/2009/06/21/multi-process-firefox-coming-to-an-internets-near-you/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 05:19:48 +0000</pubDate>
		<dc:creator>cjones</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[electrolysis]]></category>
		<category><![CDATA[multi-process]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/cjones/?p=20</guid>
		<description><![CDATA[Benjamin Smedberg recently discussed the motivation for splitting Firefox into multiple process, so I won&#8217;t recap that here. Instead, I want to demonstrate what we&#8217;ve accomplished so far. The video below shows our nearly Phase I-complete browser. (Back and Forward don&#8217;t work yet, but are relatively easy to add.) Sorry, your browser doesn&#8217;t support the [...]]]></description>
				<content:encoded><![CDATA[<p>Benjamin Smedberg <a href="http://benjamin.smedbergs.us/blog/2009-06-16/electrolysis-making-mozilla-faster-and-more-stable-using-multiple-processes/">recently discussed</a> the motivation for splitting Firefox into multiple process, so I won&#8217;t recap that here.  Instead, I want to demonstrate what we&#8217;ve accomplished so far.  The video below shows our nearly <a href="https://wiki.mozilla.org/Content_Processes#Phase_I:_Bootstrap">Phase I</a>-complete browser.  (Back and Forward don&#8217;t work yet, but are relatively easy to add.)</p>
<p><video src="http://people.mozilla.org/~cjones/ff-mp-demo.ogg" autobuffer controls>Sorry, your browser doesn&#8217;t support the &#8220;video&#8221; tag.  Try <a href="http://people.mozilla.org/~cjones/ff-mp-demo.ogg">clicking here</a> instead.</video></p>
<p>First, I browse around.  Nothing particularly exciting there, except that <em>two</em> Firefox programs are running &#8212; Firefox itself, and <code>gecko-iframe</code>.  The second program is new: it&#8217;s drawing the web pages to the screen.  Currently in Firefox, this is all done within the same program.</p>
<p>The fun comes when I <code>kill -9</code> this <code>gecko-iframe</code>, the &#8220;tab&#8221; containing mozilla.com.  To the non-geeky, invoking <code>kill -9</code> on a program causes it to crash IMMEDIATELY.  This simulates what would happen if, say, you tried to run a buggy plugin and it got itself into trouble.  Notice that only the &#8220;content&#8221; disappears when the page crashes; the user interface itself keeps running as if nothing happened.  This is a big step forward!  If I were to <code>kill -9</code> the current version of Firefox, everything would die, user interface and tabs.</p>
<p>With Firefox protected from buggy pages and plugins, more fun is possible.  This video shows me pressing a &#8220;Recover&#8221; button that relaunches the page that just crashed.  There are many more possibilities for recovering from these errors, and I&#8217;m excited to see what our user interface folks cook up.</p>
<p>This demo shows off a lot of hard work from Ben Turner, <a href="http://benjamin.smedbergs.us/blog">Benjamin Smedberg</a>, <a href="http://weblogs.mozillazine.org/bz/">Boris Zbarsky</a>, and <a href="http://blog.mozilla.org/joe">Joe Drew</a>.  (We also have plugins running in their own, separate processes, in an incomplete way.  However, the plugins still refuse to draw to the screen and so wouldn&#8217;t make for a very good demo.)  Drop by #content on IRC or read mozilla.dev.tech.dom if you want to find out more details of what the Electrolysis team is up to.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/cjones/2009/06/21/multi-process-firefox-coming-to-an-internets-near-you/feed/</wfw:commentRss>
		<slash:comments>58</slash:comments>
		</item>
	</channel>
</rss>
