JavaScript:New to SpiderMonkey
This is a page to help new member of the JS team or new contributors to SpiderMonkey to orient themselves. It's maintained by Paul Biggar (pbiggar@mozilla.com), who is currently new to SpiderMonkey. Please help by telling me what you found useful when you were new.
Tutorial: your first patch
The first step to getting involved with SpiderMonkey is to make your first patch. This guides you through it, and at the end you should have learnt a lot of the procedures and formalisms involved in getting things done here.
We'll assume you're on a Unix-y platform, and that you know what you're doing. We'll ignore nearly all details.
Get the code
We work out of the "tracemonkey" branch of the Mozilla Mercurial repository. Download it:
hg clone http://hg.mozilla.org/tracemonkey
Build the js shell
Most of the time, you'll be working with the Javascript shell, instead of the full Firefox browser. So build the shell:
cd tracemonkey/js/src autoconf2.13 mkdir build_DBG.OBJ cd build_DBG.OBJ ../configure --enable-debug --disable-optimize
If you're having trouble or are missing dependencies, refer to Building SpiderMonkey Tip.
Fix something
At this point, you're ready to make your first fix.
TODO: something useless. Maybe adding a datemicrosecond function.
Building your changes
Having made the change, build the shell again.
cd build_DBG.OBJ make
Testing your changes
It builds. Hurray. Time to run the tests to check you haven't broken anything.
python trace-tests/trace-test.py build_DBG.OBJ/js
The trace tests are pretty quick, and should give you an idea if you've gotten something wrong. Assuming nothing goes wrong, try the ref-tests:
cd build_DBG.OBJ python ../tests/jstests.py ./js --args="-j"
Benchmark your changes
Tests all pass. Congrats, you didn't break anything. Now, did you make it faster or slower? We benchmark using the v8 and SunSpider benchmarks. Get the benchmarks:
svn checkout http://svn.webkit.org/repository/webkit/trunk/SunSpider
And now run them:
cd SunSpider ./sunspider --args="-j" --shell=../build_DBG.OBJ/js --run=30 --suite=sunspider-0.9.1 cd ..
Optimized build
Whoops, we benchmarked the debug version. Let's make an optimized build to test instead.
mkdir build_OPT.OBJ cd build_OPT.OBJ ../configure --disable-debug --enable-optimize make cd ..
Repeat the sunspider steps above, and take note of the line that looks like:
Results are located at sunspider-0.9.1-results/sunspider-results-2010-08-07-17.56.48.js
You'll need that later.
Baseline version / Mercurial Queues
We need to time our optimized version against the baseline version. This calls for a brief introduction to mercurial queues, which most people think is a pretty good way of managing their SpiderMonkey workflow:
hg qinit hg qnew my_first_patch -f hg qrefresh
This puts your current work into a patch, managed by Mercurial, symbolically called my_first_patch. To pop the patch off:
hg qpop
And we're back to our pristine version.
Compare
Build again and rerun SunSpider again. You should now have two files like:
sunspider-0.9.1-results/sunspider-results-2010-08-07-17.56.48.js
Compare them using the compare script:
cd SunSpider sunspider-compare-results --shell=build_DBG.OBJ/js FILE1 FILE2
Get a real bug
At this point, you've seen nearly everything you need to do hack on SpiderMonkey. So it's time to get a real bug to work on. Go to the IRC channel, #jsapi on irc.mozilla.org, and say the magic words:
"I'm a beginner who wants to hack on SpiderMonkey. Can anyone give me a starter bug?"
I'm hoping that works, I haven't tried it myself.
Fix the bug, updating the bug report with your progress. When it's done, repeat all the steps above. Then it's time to get your patch into the tree.
Submit a patch
To get the patch from mercurial, use:
hg qdiff # if you're using queues or hg diff # if you're not
Add it to the bug as an attachment.
Get a review
Nothing gets into the tree without a review, so you'll need one. The easiest way to get a review is to go to the #jsapi IRC channel on irc.mozilla.org and ask for a volunteer. Point them to the bug. In all likelyhood, they'll give you a review and ask you to change something. Fix what they ask, resubmit the patch to bugzilla, and ask for another review. After you repeat this step a few times, they'll say something like "review=me" meaning it's now good to commit.
Try server
On your first commit, you're likely to be a little wary of breaking things. Mozilla has a "tryserver" where you can send a patch, and it'll be built on tons of machines which will report back to you.
The guide for getting "level 1" access, which you need for the try server, is here. Ask your reviewer to vouch for you, and send in the paperwork ASAP.
TODO: Move this elsewhere. Level 1 access can take ages.
https://wiki.mozilla.org/Build:TryServer
Commit
You can't commit until you have "level 2" access, and you don't have level 2 access (at time of writing, I don't have level 2 access), so you'll need someone to do this for you. The volunteer from IRC may do this, otherwise you'll need a new volunteer.
After committing, a large series of tests will be run to make sure you didn't break anything. You'll need to hang around to make sure you didn't break something. Check http://tests.themasta.com/tinderboxpushlog/?tree=TraceMonkey for red marks.
TODO: we don't want them worrying about false positives either, since there are plenty.
Overview of the JS engine
The JS engine is a swiftly moving target. The most detailed information is available at https://developer.mozilla.org/en/SpiderMonkey. Here are some particularly interesting, mostly up-to-date resources:
High level overviews
http://hacks.mozilla.org/2010/03/a-quick-note-on-javascript-engine-components/
https://developer.mozilla.org/En/SpiderMonkey/Internals
http://users.alliedmods.net/~dvander/jm_presentation.pdf
http://hacks.mozilla.org/2009/07/tracemonkey-overview/
Medium level documentation
jsapi.h: http://hg.mozilla.org/tracemonkey/file/tip/js/src/jsapi.h
Mapping JS idioms to SpiderMonkey code: https://developer.mozilla.org/En/SpiderMonkey/JSAPI_Phrasebook
Detailed documentation
Build: https://developer.mozilla.org/en/SpiderMonkey/Build_Documentation
Testing: https://developer.mozilla.org/en/SpiderMonkey/Running_Automated_JavaScript_Tests
Shell: https://developer.mozilla.org/En/SpiderMonkey/Introduction_to_the_JavaScript_shell
Function reference: https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference
Collaboration and teamwork
Communication (in descending order of information content)
Nearly all communication is handled through [bugzilla.mozilla.org Bugzilla]. All bugs, feature requests, issues, enhancements, etc, are all referred to as bugs. No code may enter the Mozilla repository without being a patch attached to a bugzilla bug first. To follow all SpiderMonkey related bugs:
Go to email preferences Watch the user general@spidermonkey.bugs
SpiderMonkey contributors generally hang out in the very active #jsapi IRC channel. You might also find the #static channel (discussions about static analysis in Mozilla) interesting.
Some team members blog about SpiderMonkey, though infrequently:
David Anderson Rob Sayre Jason Orendorff David Mandelin Nicholas Nethercote
The Mozilla platform team has a public weekly meeting where SpiderMonkey progress is discussed.
The js-engine mailing list is generally used for communicating with people who embed SpiderMonkey, such as asking questions and announcing API changes. No actual development happens on the list.
The Mozilla Status Board allows team members to give brief overviews of their recent work. At the moment, it is seldom used, but we are trying to encourage team members to post there.
Code considerations
Repository
Most active work on SpiderMonkey is done in the [1] branch of the mozilla repository. Currently, there is also work in the JaegerMonkey branch, but this should be merged back to Tracemonkey very soon. The main Mozilla branch is Mozilla-central, to which sayrer merges our code each week.
Coding Style
For many years, SpiderMonkey was written in C, and is gradually moving to C++. We still avoid many features such as run-time type information and virtual functions, but have come around to the glory of templates and namespaces relatively recently. Read the JavaScript:SpiderMonkey:C++ Coding Style. Do NOT read the older coding guidelines, which I will not link to, since they are very out of date.
Workflow
As stated above, everything goes through bugzilla. We find a bug or have an idea, then submit it to bugzilla, then file patches to solve it. When it is solved, the patch is reviewed by team members, and is then committed to the tracemonkey repository. Commit links are added as comments.
Bugs which are fixed in tracemonkey are marked as 'fixed-in-tracemonkey' on the bugzilla whiteboard for the bug. When sayrer merges the code into mozilla-central, those bugs are marked as fixed.
Sample Workflows
Policy
- patch policy - commit access - checkin needed - reviewers
.hgrc file
Mercurial Queues
Since most of our lives revolve around patches, and we use Mercurial, nearly everybody uses Mercurial queues.
Queues are based on the idea of patch management. Each queue consists of a series of patches, applied sequentially. The aim of the game is to split potential commits into simple, bite-sized chunks which are easy to review. This also makes it simple to experiment without polluting your existing work on a bug, to spin parts off into new bugs, and to rapidly apply and unapply patches (as demonstrated in the tutorial above).
Enabling
Add the following snippet to your .hgrc file to enable MQ
[extensions] mq =
Example MQ workflow
Clone the repository to deal with a bug:
hg clone http://hg.mozilla.org/tracemonkey
Initialize your queue:
hg qinit -c
Create a new patch, with some name:
hg qnew first_attempt
Work on the patch, try to fix the bug, test, compile, etc.
Refresh (save your work into the patch):
hg qrefresh
Repeat a few times.
Rename the patch (because your first name wasn't appliable):
hg qrename refactor_the_whatsit
Create a new patch to try a logically separate part of the same bug:
hg qnew rip_out_the_old_thing
Repeat the process a few times, until you have solved the problem. During this time, it can often be useful to go back and forth between patches:
hg qpop # unapply a patch hg qpush # reapply a patch hg qpop -a # unapply all patches hg qpush -a # reapply all patches
Combine all the patches into a single patch, which you submit to bugzilla:
hg qpush -a hg qdiff --rev qparent:. > my_wonderful_patch.patch
Commit the patches to your local patch repository, in case you make a mistake (You might do this periodically):
hg qcommit -m "Some message. Doesn't have to be good, this won't be committed to the repository, it's just for you"
Go back to the old patches and fiddle with them based on feedback:
hg qpop hg qrefresh etc
There are some more complex techniques that we won't go into in detail. You can enable only some patches using qguard and qselect, and you can reorder the patches by manually editing the .hg/patches/series file. But be careful!
Help make this better
Please make corrections as you see fit, or email pbiggar@mozilla.com to tell me what made life difficult when you were a newbie.
If you're a newbie, and have a question you'd like answered or topic you'd like addressed, please ask, and then add it to this page.
If you'd like to help newbies out by offering to review patches or answer newbie-level questions, please add your email address, name or IRC handle below:
Will review patches, commit code:
Will answer newbie questions:
Paul Biggar - pbiggar - pbiggar@mozilla.com