<?xml version="1.0" encoding="us-ascii"?>
<?xml-stylesheet version="1.0" type="text/xsl" href="../../../article.xsl"?>
<page title="Coding with Spidermonkey" url="http://aoeex.com/personal/2006/06/07/coding_with_spidermonkey.php">
	<header>
		<stylesheet href="/css/personal/articles.css" />
		<stylesheet href="/css/comments/comments.css" />
	</header>
	<content xmlns:xhtml="http://www.w3.org/1999/xhtml">
		<article>
			<next href="../29/coding_with_spidermonkey_part_ii.php" title="Part II --&gt;"/>
			<body>

<xhtml:h1>Coding with Spidermonkey</xhtml:h1>

<xhtml:p>So, I'm working on learning how to use the 
<xhtml:a href="http://www.mozilla.org/js/spidermonkey/">Spidermonkey engine</xhtml:a> in my C programs 
to provide scripting support.  I actually do have an overall goal that I would like to 
achieve from learning this (and a few other things) but that's not something I want to 
share...just yet anyway.</xhtml:p>

<xhtml:p>As I work, I want to use this blog as sort of a record keeping device.  I'll blog about 
what I've learned, what I think I know, but am not sure of, what I'm having problems with, 
etc.  Perhaps someone else can make use of this information in their Spidermonkey (or maybe 
just regular C) adventures.</xhtml:p>

<xhtml:p>Well then, lets get started with some information.  I've messed with the code a while 
ago, but only recently started up again, so I had to re-learn some of the stuff I was 
working on.  Last night I managed to get the engine setup and accept a file to parse as 
the command-line argument.  I provide one custom object right now, which is the file 
object.  It allows a script to write to files, or stdout.  No reading support yet, or 
custom modes or anything, just plain, simple, writing.</xhtml:p>

<xhtml:p>I haven't bothered to create any sort of API for the file object (or any other object), 
instead I'm just adding methods on as I think of them and coding the behavior in some 
way that works and (to me) makes sense.  To express the API's that exist, I'll use C++ 
like (not real) class definitions. The API for the file object currently looks like this:</xhtml:p>

<sampleCode>
class File {
	public:
		File(string name);
		bool open();
		int write(string text);
		bool close();

		static bool open();
		static int write(string text);
		static bool close();
};
</sampleCode>

<xhtml:p>So, essentially, there is one form of a constructor use to instantiate a new object, 
and there are three methods: open, write, and close which can be used as a method on 
an instantiated class, or statically (in which case, they affect stdout).  So, here's a 
show example script showing how they can be used:</xhtml:p>

<sampleCode>
var out = new File("outfile");
if (out.open()){
	out.write("Todays date is: "+(new Date()).toGMTString());
	out.close();
	File.write("./outfile created, contains todays date.");
}
else {
	File.write("./outfile could not be opened");
}
</sampleCode>

<xhtml:p>Here's the output from running that code through my engine:</xhtml:p>
<consoleOutput>
$./engine test.js
./outfile created, contains todays date.
$cat outfile
Todays date is: Tue, 06 Jun 2006 23:18:56 GMT

<xhtml:b>--or, if ./outfile can't be opened--</xhtml:b>

$./engine test.js
./outfile could not be opened
</consoleOutput>


<xhtml:p>So, how did I get that working you may ask? Well, "simple!" I will say, though it did take 
a while to actually figure it out.  Let me start this blog serise off from the very 
beginning.  In this post, I'll cover compiling Spidermonkey on a Linux system, and then 
I'll cover making an extreamly basic program that uses the JS engine, but doesn't actually 
do anything other than start it up and then shut it down.</xhtml:p>

<xhtml:h3>Compiling Spidermonkey</xhtml:h3>
<xhtml:p>Compiling Spidermonkey on Linux is really pretty straight forward.  It's just a matter 
of running their make file using <xhtml:a href="http://www.gnu.org/software/make/">GNU Make</xhtml:a>, 
or probably any decent substitute, having tried any others myself.  Here's a little 
step-by-step instruction on what I did to build Spidermonkey and then make it usable.</xhtml:p>

<xhtml:ol>
  <xhtml:li>Obtain the Spidermonkey source code either from the official site, or you can 
	  download the version I'm using as I write this by using the link below.</xhtml:li>
  <xhtml:li>Extract js-1.5.tar.gz to a directory somewhere.  It will create a js/ sub 
	  directory.</xhtml:li>
  <xhtml:li><xhtml:code>cd js/src/</xhtml:code> to enter the source code directory.</xhtml:li>
  <xhtml:li><xhtml:code>make -f Makefile.ref</xhtml:code> to build the source.  Notice you have to use the 
	  Makefile.ref file, not the regular Makefile.  The regular Makefile is configured to 
	  build Spidermonkey as the embedded engine for the browser.  The Makefile.ref file 
	  will build the standalone library that you can use.
	  <xhtml:ul>
		<xhtml:li><xhtml:span class="articleUpdate">*Update 11/4/2006</xhtml:span> - I rebuilt my computer and installed Ubuntu Edgy Eft (6.10).  I tried installing 
			spidermonkey by following my own compile instructions here but I ended up receiving these compile errors.
				<consoleOutput>
make[1]: Circular jscpucfg.h &lt;- Linux_All_DBG.OBJ/jsautocfg.h dependency dropped.
gcc -o Linux_All_DBG.OBJ/jscpucfg.o -c -Wall -Wno-format -DGCC_OPT_BUG -g -DXP_UNIX -DSVR4 -DSYSV -D_BSD_SOURCE -DPOSIX_SOURCE -DHAVE_LOCALTIME_R -DX86_LINUX  -DDEBUG -DDEBUG_kicken -DEDITLINE -ILinux_All_DBG.OBJ  jscpucfg.c
jscpucfg.c:376: internal compiler error: in dwarf2out_finish, at dwarf2out.c:14129
Please submit a full bug report,
with preprocessed source if appropriate.
See &lt;URL:http://gcc.gnu.org/bugs.html&gt; for instructions.
For Debian GNU/Linux specific bug reporting instructions,
see &lt;URL:file:///usr/share/doc/gcc-4.1/README.Bugs&gt;.
Preprocessed source stored into /tmp/cc8xj9FF.out file, please attach this to your bugreport.
make[1]: *** [Linux_All_DBG.OBJ/jscpucfg.o] Error 1
				</consoleOutput>
			It turns out these errors were caused by the -g debugging flag when compiling jscpucfg.  I created a 
			<xhtml:a href="files/ubuntu-config.mk.patch">patch file</xhtml:a> which removes this flag 
			and fixes the build process.  Please apply the patch if you are experiencing the same problem.
		</xhtml:li>
	 </xhtml:ul>
  </xhtml:li>
  <xhtml:li>When the build is complete, look at the last few lines of the output from make, you 
	  will probably see something similar to this:
		<consoleOutput>
make[1]: `Linux_All_DBG.OBJ/jsautocfg.h' is up to date.
make[1]: `Linux_All_DBG.OBJ/jscpucfg' is up to date.
make[1]: `Linux_All_DBG.OBJ/jscpucfg.o' is up to date.
make[1]: Nothing to be done for `Linux_All_DBG.OBJ/jsmathtemp.o'.
		</consoleOutput>
	  That means the build was successful, and that the libjs.so file is stored in 
	  the <xhtml:b>Linux_All_DBG.OBJ</xhtml:b> sub-folder.  This folder name varies by 
	  platform/configuration (see the config/ directory for other names).</xhtml:li>
  <xhtml:li>Now, if you want you can just reference the source directory and that object 
	  directory using your compiler flags to build the program.  I, however, choose to 
	  put the header files into <xhtml:code>/usr/local/include/spidermonkey</xhtml:code> and the 
	  <xhtml:code>libjs.so</xhtml:code> file into <xhtml:code>/usr/local/lib</xhtml:code>.  To do that, simply issue the 
	  following simple commands (as a user with appropriate privileges, such as root):
		<consoleOutput>
cp Linux_All_DBG.OBJ/libjs.so /usr/local/lib
mkdir -p /usr/local/include/spidermonkey
cp *.h Linux_All_DBG.OBJ/jsautocfg.h *.msg /usr/local/include/spidermonkey
		</consoleOutput>
	  <xhtml:ul>
		<xhtml:li><xhtml:span class="articleUpdate">*Update 11/04/2006</xhtml:span> - I've been informed that jsautocfg.h needs copied over too.  
			I must have already done this when I wrote the article and missed it when I was recalling the steps necessary.  
			The command above has been updated to include this file in the copy process.</xhtml:li>
	  </xhtml:ul>
	  Once complete, you will have Spidermonkey successfully "installed" and ready 
	  to work.</xhtml:li>
</xhtml:ol>

<xhtml:h3>Touched by the spider(monkey)</xhtml:h3>
<xhtml:p>So, now that Spidermonkey is installed, now you get to create your first program 
using it.  To start, lets do something really, really, really simple.  That means a script 
that doesn't execute any script files.  All it does is startup the engine; print a 
message; then shuts down.  This will ensure that you have all the proper compile flags 
by introducing enough of the engine that you actually need to link with it, but leaving 
enough out that you shouldn't be overrun with possible errors in the code.</xhtml:p>

<xhtml:p>The first step to setting up the JS engine is to <xhtml:code>#include</xhtml:code> the 
<xhtml:code>jsapi.h</xhtml:code> header file.  This file defines all the public API functions for the 
Spidermonkey engine.   The basic rule of thumb, from what I understand, is that if it's 
defined in this file, it's safe to use.  If for some reason you ever find that you need to 
dig into a different header file, you probably shouldn't be using what you are.  Or, you 
need to file a bug report so that the developers can work on providing the necessary 
functionality via a public API.  Don't be eager to file bugs though, make sure you actually 
need to do what you think you need to do.  There may be another way.</xhtml:p>

<xhtml:p>The second step is to setup a new runtime environment for the JS engine though a call 
to the <apiref name="JS_NewRuntime">JS_NewRuntime</apiref>.  
This function sets up the runtime environment for the JS engine.  The 
<xhtml:span class="name">maxbytes</xhtml:span> parameter specifies how much memory the runtime will 
let fill up before it forces a call to the garbage collector to free old unused objects. 
I don't think this is an absolute cap on the memory, and I don't think it's required that 
this amount fills up before the GC runs, but I don't know the specific details.  This is 
just my interpretation of the docs.</xhtml:p>

<xhtml:p>Once you have a runtime initialized with <xhtml:code>JS_NewRuntime()</xhtml:code>, you next have to 
make a context using <apiref name="JS_NewContext">JS_NewContext</apiref>  
You can think of the context as the actual engine if you want.  A script is executed 
within a specific context, and within the context is where the scripts variables and objects 
and such are stored.  That's how I understand it to work anyway.  The context is created 
within the specified runtime, <parameter>rt</parameter>.  The context will have a stack size of 
<parameter>stacksize</parameter> bytes.  The stack size does not have to be less than the runtime's 
<parameter>maxbytes</parameter> parameter.  In fact, it should probably be much bigger.</xhtml:p>

<xhtml:p>Next, you need to create a global object.  All objects created will be a child of this 
global object.  The global object isn't directly available to the scripts you execute, but 
it could be made available if desired (which I did, to emulate `window' in browser-based 
code, but won't cover here). Before you can create this global object however, you must define it.</xhtml:p>

<xhtml:p>To define objects in Spidermonkey, you use the <xhtml:a href="http://developer.mozilla.org/en/docs/JSClass"><xhtml:code>JSClass</xhtml:code></xhtml:a> 
structure.  It's a pretty good sized structure with quite a few fields you need to setup.  Have a look at the documentation 
page for the full details.  From what I understand of the process, and from what I've seen looking at the Spidermonkey code, 
the easiest way to manage these classes seems to be just giving them unique names and declaring them as global variables in their 
respective files, then using an extern statement in the header file to let any other project files know about them.  This is the 
method I will be using for now.  If I come up with anything better later, that will be another post.</xhtml:p>

<xhtml:p>Now, the good thing about this class is that for most of the required fields, there are some methods provided by 
Spidermonkey that you can use as a default.  The optional fields can all be specified as <xhtml:code>NULL</xhtml:code> or <xhtml:code>0</xhtml:code>.
For the global object, it works nice to just use all the provided defaults, and set all of the "optionals" to null, so that is what
I will do.  Here is the code for my global object:</xhtml:p>

<sampleCode>
JSClass js_global_object_class = {
  "System",
  0,
  JS_PropertyStub,
  JS_PropertyStub,
  JS_PropertyStub,
  JS_PropertyStub,
  JS_EnumerateStub,
  JS_ResolveStub,
  JS_ConvertStub,
  JS_FinalizeStub,
  JSCLASS_NO_OPTIONAL_MEMBERS
};
</sampleCode>

<xhtml:p>So now that we have our global object's class defined, we can create the object based on this definition. 
To create a new object, you use the <apiref name="JS_NewObject">JS_NewObject</apiref> function to create a new 
global object.  There are other functions to create objects as well, but they are for use later when you are defining objects 
that you want your scripts to be able to use.  As you can see from the parameter list, defining an object is fairly simple. 
You have to tell it what context to create the object in by passing in the <xhtml:code>JSContext</xhtml:code> variable we created above 
as the <xhtml:span class="name">cx</xhtml:span> parameter.  Next you pass a pointer to the object definition that we created above 
as the <xhtml:span class="name">clasp</xhtml:span> parameter.  The last two parameters, <xhtml:span class="name">proto</xhtml:span> and 
<xhtml:span class="name">parent</xhtml:span> can be specified as NULL for this case.  I'm not well versed on what these parameters 
are really for, but what I understand from the documentation and experience is that the <xhtml:span class="name">proto</xhtml:span> 
(prototype) parameter is used as a base object for the new object.  The object will inherit the members that are defined 
on the prototype object.  Also, the new object's <xhtml:code>.__proto__</xhtml:code> property will point to the prototype object.  The 
<xhtml:span class="parent">parent</xhtml:span> argument specifies to which object the new object will be a child.  This will set the 
<xhtml:code>.__parent__</xhtml:code> property of the new object to the passed in parent.  I'm guessing that this also means if the parent 
object gets collected by the garbage collector, that the child object will also be collected.</xhtml:p>

<xhtml:p>And finally, the last step in initializing the JS engine is to initialize all the standard, built-in Javascript classes 
such as the Date, Math, and String classes.  You do this using the <apiref name="JS_InitStandardClasses">JS_InitStandardClasses</apiref> function.  
You have to pass into this function the context to use, via the <xhtml:span class="name">cx</xhtml:span> parameter, and the global object, via 
the <xhtml:span class="name">obj</xhtml:span> parameter.  This function is what actually sets <xhtml:span class="name">obj</xhtml:span> as the 
global object.  Prior to this, the object would be the same as any ordinary object you declared.  If, for some reason, you wanted 
to use the JS engine without defining the standard classes, you could set your global object using the 
<apiref name="JS_SetGlobalObject">JS_SetGlobal</apiref> function, but 
I cannot see any point in doing this right now.</xhtml:p>

<xhtml:p>Yay! Now the JS engine is up and running.  So now what?  Ordinarily now you would go through defining your own 
application-specific objects, like my file object outlined above, and proceed to execute scripts.  However, 
to keep this simple we will do nothing.  All I'm going to do is check to see if a file was passed on the command line. 
If one was, I'll show a message stating that we would run the file.  If not, I'll show the usage text for the program.</xhtml:p>

<sampleCode>
if (fileToRun){
	printf("At this point, we would run the file %s if we were developed more.\n", fileToRun);
}
else {
	printf("Usage: %s file\n", argv[0]);
}
</sampleCode>

<xhtml:p>Now, as with most programs, the Javascript engine has to be properly shutdown when you are done with it.  This will typically 
be at program exit, but not necessarily, depending upon your program's design.  Engine shutdown is a pretty simple process.  
There are two functions that you use to destroy the context's that you have created, and then destroy the runtime object.  To 
destroy all the created contexts, you use the <apiref name="JS_DestroyContext">JS_DestroyContext</apiref> function.  To 
destroy the runtime object, you use the <apiref name="JS_DestroyRuntime">JS_DestroyRuntime</apiref>.  
Pretty simple, huh?</xhtml:p>

<xhtml:h3>Compiling your beast</xhtml:h3>
<xhtml:p>Yay!  Now we should have a program that is ready to be compiled and run.  Embedding the Spidermonkey engine does 
make compiling a little more difficult than the simple <xhtml:code>gcc -ofile file.c</xhtml:code> command line that some people 
may be used to.  Don't panic though; it's not that much more difficult.  Basically all you need to do is use the 
<xhtml:code>-I</xhtml:code> and <xhtml:code>-L</xhtml:code> flags to tell the preprocessor where to find the header files, and the linker 
file where to find the library files.  Then you use the <xhtml:code>-ljs</xhtml:code> flag to tell the linker it needs to 
include <xhtml:code>libjs.so</xhtml:code> in the linking process.</xhtml:p>
  
<xhtml:p>You also have to define a constant for your platform.  You can do this using either the <xhtml:code>-D</xhtml:code> 
command line switch, or using a <xhtml:code>#define</xhtml:code> directive directly in the source code, prior to the 
<xhtml:code>#include &lt;jsapi.h&gt;</xhtml:code> directive.  I have opted to do the former.  There are a number of platform 
constants from which to choose.  For a Unix/Linux platform the constant to use is <xhtml:code>XP_UNIX</xhtml:code>.  For other 
platforms you need to choose one of the following: <xhtml:code>XP_BEOS</xhtml:code>, <xhtml:code>XP_MAC</xhtml:code>, <xhtml:code>XP_OS2</xhtml:code>, or
<xhtml:code>XP_WIN</xhtml:code>.  Should you forget to define this constant, you will get many error messages from the files regarding 
undefined objects, parser errors, warnings, etc.  At the top of the output though, you should see these lines:</xhtml:p>

<consoleOutput>
In file included from /usr/local/include/spidermonkey/jspubtd.h:45,
				 from /usr/local/include/spidermonkey/jsapi.h:47,
				 from engine.c:2:
/usr/local/include/spidermonkey/jstypes.h:224:6: #error "Must define one of XP_BEOS, XP_MAC, XP_OS2, XP_WIN or XP_UNIX"
/usr/local/include/spidermonkey/jstypes.h:240:2: #error No suitable type for JSInt8/JSUint8
/usr/local/include/spidermonkey/jstypes.h:253:2: #error No suitable type for JSInt16/JSUint16
/usr/local/include/spidermonkey/jstypes.h:273:2: #error No suitable type for JSInt32/JSUint32
</consoleOutput>

<xhtml:p>For reference, below is the command line I used to compile the engine, and a summary of the options I used and why 
I used them.</xhtml:p>

<consoleOutput>
$gcc -I/usr/local/include/spidermonkey -L/usr/local/lib -ljs -DXP_UNIX -O0 -g \
-Wall -pedantic -Wno-long-long -o engine engine.c
</consoleOutput>
<xhtml:ul>
  <xhtml:li><xhtml:strong class="monospace">-I/usr/local/include/Spidermonkey</xhtml:strong> -- Add the path <xhtml:code>/usr/local/include/spidermonkey</xhtml:code> 
	  to the C Pre-processors search path.  This way it knows where to find the <xhtml:code>jsapi.h</xhtml:code> file.</xhtml:li>
  <xhtml:li><xhtml:strong class="monospace">-L/usr/local/lib</xhtml:strong> -- Add the path <xhtml:code>/usr/local/lib</xhtml:code> to the linkers search path.  This is needed so that the 
	  linker can find the libjs.so file.</xhtml:li>
  <xhtml:li><xhtml:strong class="monospace">-ljs</xhtml:strong> -- Tells the linker that it in addition to the standard libraries, it needs to link against libjs.so</xhtml:li>
  <xhtml:li><xhtml:strong class="monospace">-DXP_UNIX</xhtml:strong> -- Tells the compiler to define the constant <xhtml:code>XP_UNIX</xhtml:code> which tells Spidermonkey we are on a 
	  UNIX or UNIX-like (Linux/BSD) operating system.</xhtml:li>
  <xhtml:li><xhtml:strong class="monospace">-O0</xhtml:strong> -- Disables optimizations made by the compiler.  I do this as I find that often when the optimizations 
	  are enabled debugging with GDB becomes nearly impossible.  GDB no longer is able to associate which line of the 
	  source file is being executed and often will do mini loops through the lines.  Cycling between two lines for a while, 
	  then advancing a line and repeating.</xhtml:li>
  <xhtml:li><xhtml:strong class="monospace">-g</xhtml:strong> -- Enables debugging symbols to make debugging with GDB easier.</xhtml:li>
  <xhtml:li><xhtml:strong class="monospace">-Wall</xhtml:strong> -- Enables nearly all warning messages in order to help highlight possible problems.</xhtml:li>
  <xhtml:li><xhtml:strong class="monospace">-pedantic</xhtml:strong> -- Enables even more strict checking.  Highlights things such as using a double-slash (<xhtml:code>//</xhtml:code>)
	  comment in C.  That style of commenting came about in C++ and not C, though GCC still accepts it in C files.</xhtml:li>
  <xhtml:li><xhtml:strong class="monospace">-Wno-long-long</xhtml:strong> -- Disable warning about 'long long' not being supported in ISO C90.  I have yet to determine if 
	  this causes any actual problems, but so far everything is working so I am just ignoring it.</xhtml:li>
  <xhtml:li><xhtml:strong class="monospace">-o engine</xhtml:strong> -- Sets the output file to be <xhtml:code>engine</xhtml:code>
	  <xhtml:ul><xhtml:li><xhtml:span class="articleUpdate">*Update 11/6/2006</xhtml:span> - I used to show this 
			flag as being <xhtml:strong>-oengine</xhtml:strong>, all one word without a space.  It would appear as 
			though some versions of gcc do not like this format though.  Since the version I use also accepts a space 
			as well as this, I will include the space to be more compatible.</xhtml:li>
	  </xhtml:ul>
  </xhtml:li>
  <xhtml:li><xhtml:strong class="monospace">engine.c</xhtml:strong> -- The input file.</xhtml:li>
</xhtml:ul>

<xhtml:p>Well, that's it.  You should now have a program which successfully initiates the Spidermonkey engine, prints a message, then 
shutdown the engine.  This is only the beginning to far greater things.  Enjoy!</xhtml:p>

				<author>
					<name>Keith Maika</name>
					<homepage>http://www.aoeex.com</homepage>
					<email username="keithm" domain="aoeex.com" />
				</author>
			</body>
			<attachments>
				<attachment href="./files/js-1.5.tar.gz" title="js-1.5.tar.gz">Here's the 1.5 version of the Spidermonkey code, straight from the 
					Mozilla servers.  This is the version I'm using as I write this post.</attachment>
				<attachment href="./files/engine.c" title="engine.c">This is the program I created for this post.  All this program does is startup 
					the engine, print out a message about how it can't actually do anything, then shutdown the engine.</attachment>
				<attachment href="./files/ubuntu-config.mk.patch" title="ubuntu-config.mk.patch">A patch for ubuntu edgy eft systems which disables the -g flag
					when compiling allowing the compile to complete.</attachment>
			</attachments>
			<apiPrototypes>
				<function name="JS_DestroyContext" return="void" docs="http://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_DestroyContext">
					<parameter type="JSContext *" name="cx" />
				</function>
				<function name="JS_DestroyRuntime" return="void" docs="http://developer.mozilla.org/en/docs/JS_DestroyRuntime">
					<parameter type="JSRuntime *" name="rt" />
				</function>
				<function name="JS_SetGlobalObject" return="void" docs="http://developer.mozilla.org/en/docs/JS_SetGlobalObject">
					<parameter type="JSContext *" name="cx" />
					<parameter type="JSObject *" name="obj" />
				</function>
				<function name="JS_InitStandardClasses" return="void" docs="http://developer.mozilla.org/en/docs/JS_InitStandardClasses">
					<parameter type="JSContext *" name="cx" /> 
					<parameter type="JSObject *" name="obj" />
				</function>
				<function name="JS_NewObject" return="JSObject *" docs="http://developer.mozilla.org/en/docs/JS_NewObject">
					<parameter type="JSContext *" name="cx"/> 
					<parameter type="JSClass *" name="clasp"/> 
					<parameter type="JSObject *" name="proto"/>
					<parameter type="JSObject *" name="parent"/>
				</function>
				<function name="JS_NewContext" return="JSContext *">
					<parameter type="JSRuntime *" name="rt" />
					<parameter type="size_t" name="stacksize" />
				</function>
				<function name="JS_NewRuntime" return="JSRuntime" docs="http://developer.mozilla.org/en/docs/JS_NewRuntime">
					<parameter type="uint32" name="maxbytes" />
				</function>
			</apiPrototypes>

			<comments pageId="2" showForm="true">
				<comment visitor="nancy" email="05120451 -(@)- bjtu -(.)- edu -(.)- cn"><![CDATA[Thank you very much for your step-by-step instruction.
But I meet some troubles,can you help me?
when I set up spidermonkey-0.0.1a whith the command"
python setup.py build",I get the error "error: command 'gcc' failed with exit status 1". 

redhat linux system
gcc version 3.4.6 20060404
js-1.5.tar.gz 
Pyrex-0.9.8.5.tar.gz]]></comment>
			</comments>
		</article>
	</content>
</page>