tag:blogger.com,1999:blog-141037622024-03-07T06:54:21.409+00:00the Jau Virtual MachineA VM in Java with tail-calls and continuationsUnknownnoreply@blogger.comBlogger19125tag:blogger.com,1999:blog-14103762.post-1130207336250440862005-10-25T03:11:00.000+01:002005-11-04T14:36:17.040+00:00A new minor release - 1.0.1That's right, I've made a maintenance release a couple of days ago.<br /><br />It corrects a minor issue that didn't manifest itself on files compiled by <code>javac</code> but that was, nevertheless, a bug since it affected legal <code>.class</code> files.<br /><br />Along with the bug-fix came new features (not big, but I believe cool): checkout the <code><a href="http://jauvm.sourceforge.net/doc/net/sf/jauvm/Continuation.html#forkThread()">forkThread</a></code> and the <code><a href="http://jauvm.sourceforge.net/doc/net/sf/jauvm/Continuation.html#saveCurrentTo(java.io.File)">saveCurrentTo</a></code> methods on the <code><a href="http://jauvm.sourceforge.net/doc/net/sf/jauvm/Continuation.html">Continuation</a></code> class. You can also load and return to a serialized continuation right from the command line, see the <code><a href="http://jauvm.sourceforge.net/doc/net/sf/jauvm/Interpreter.html#main(java.lang.String...)">main</a></code> method for details. And, as you can gather from the links, the documentation has been updated accordingly.<br /><br />All these changes have also been merged from the <code>rel-1.0-devel</code> branch (where they originated) to the main trunk.<br /><br />That's all for now, thanks!Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-14103762.post-1128555056471340962005-10-05T22:53:00.000+01:002007-01-29T17:32:12.220+00:00Is it alive?Hell, yes! Sure it is! I took a break for a couple of weeks, but development hasn't stopped - there is much to do, some will to do it, and tiny bits of free time here and there too.<br /><br />I've been back behind the keyboard for a few weeks now. The released code seems to be holding on, and I haven't found any unexpected bugs. As such, the first news is - I've just re-released version 1.0b1 re-branded as 1.0.<br /><br />Besides that, I've started implementing a couple of simple “user level” features (“user level” as in “you could have done them yourself”), namely a static method in <code>Continuation</code> that “forks” a thread much like Unix's <code>fork</code> for processes. These superficial changes will be released soon (as in, without much further testing), in something like a version 1.0.1. If curiosity bites you, these changes are happening in branch <code>rel-1.0-devel</code>, and will be merged with the trunk as soon has they're ready.<br /><br />The way I see it, these “simple” things (like the new <code>fork</code>, generators and non-determinism) are beneficent in that, being useful, they both show the potential of continuations in general, and help new comers get their mindsets around how to work with continuations (at least in the JauVM).<br /><br />I've also been revising the full source code, correcting the (not so many) shortcuts I took in order to meet Google's deadline. I'll be releasing (not so soon) something like a version 1.1, with very few visible changes on the outside, but with a revamped core, being (hopefully) more performant, and better designed (or I should say, more according to the intended design) if a bit more verbose.<br /><br />About Google and the Summer of Code, all I can say is that my mentor liked the outcome, and I'm pretty confident my project will be approved. I haven't received any official confirmation, and whatever the prize, it's still on hold thanks to IRS issues.<br /><br />All in all, it was a great experience, and more importantly <em>I</em> liked the outcome (tough I'll like the income too!).Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-14103762.post-1125551100746869712005-09-01T06:00:00.000+01:002005-09-01T06:07:29.216+01:00The final Summer of Code release - 1.0b1As promised, here it is.<br /><br />Nothing new, no new features. Just the <a href="http://jauvm.sf.net/doc/overview-summary.html">API Specification</a>, and some really minor modifications.<br /><br />So that's it, <a href="http://sf.net/project/showfiles.php?group_id=142992">download</a> it, if you will, and remember I appreciate any feed back.<br /><br />I'll rest for a few days now. Just hope I've deserved it!Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-14103762.post-1125449780569739232005-08-31T00:56:00.000+01:002005-09-01T06:01:19.930+01:00The “last” release - 0.4Hi all!<br /><br />That's right, this is it: the last modifications for the Google Summer of Code are in. From now on, and I still have until tomorrow, it'll be just writing API documentation (javadocs for the “public” classes) and bugs' squashing.<br /><br />So, are you curious about what got in, and what not?<br /><br />It pretty much covers everything on the initial <a href="http://jauvm.blogspot.com/2005/07/so-what-does-it-do.html">proposal</a>. A few things didn't make it though.<br /><br />This version introduces the serialization of continuations. I've also moved the <code>Ambivalence</code> class to a “new” <code>util</code> package. This package will host classes implementing common uses of continuations. I've also added the <code>Generator</code> class, an implementation of generators, much like <a href="http://www.python.org/peps/pep-0255.html">Python's</a>.<br /><br />And now, on to what doesn't work...<br /><br />Synchronization doesn't work, as I've explained <a href="http://jauvm.blogspot.com/2005/07/first-commit.html">before</a>. Since then I've found that this behavior (enforcing balanced locking) is <strong>optionally</strong> mandated by the <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/Threads.doc.html#22500">JVM Spec</a>, so some VMs may not even enforce it. Besides that, Sun VMs (which do enforce it) have ways to bypass it through <code>sun.misc.Unsafe</code>. So, there is hope.<br /><br />Method invocations with the <code>super</code> keyword don't work either. In general <code>invokespecial</code> can only be used to call either <code>private</code> methods or constructors in interpreted code. All other uses are disallowed by the interpreter. This is so because it is not possible to call such methods through reflection: the overriding method is always called. I have currently no solution for this issue.<br /><br />Winding protection (which was not part of the initial proposal, but had been <a href="http://jauvm.blogspot.com/2005/07/user-guide-part-four.html">promised</a> afterwards) was not implemented. The problem is that <code>continuing</code> blocks could not be implemented that way, since executing them would destructively modify their frame. Winding guards will be implemented sometime in the future in an alternative way, but designing the solution will take its time, since the way we do this affects our synchronization policy as well.<br /><br />Besides this three outstanding issues, everything <em>should</em> work - and I'd like to ear about it if it doesn't.<br /><br />That does not however mean my work is anywhere near finished. There are options to work around those issues, and a lot can still be done in terms of performance. Work will continue and feedback is welcomed.<br /><br />I'll be making another release tomorrow, either a 1.0 or something like a 1.0b1 (with which I'd be more confortable, as long as it doesn't clash with Google's goals, since the code has barely been tested).Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-14103762.post-1125079522256159082005-08-26T17:58:00.000+01:002005-08-26T20:58:20.713+01:00Another release - 0.3This release, if you've been following the blog, introduces continuations. Everything seems to work as it's supposed to, hence another release. Just don't forget it's pretty alpha, there may be serious bugs.<br /><br />Besides the code for continuations I've also added a new test exemplifying them, and I'd like to call your attention to it, as I believe it shows the great power of continuations:<br /><blockquote><pre><code>Ambivalence<Integer> amb = <b style="color:#A020F0">new</b> Ambivalence<Integer>();<br /><br /><b style="color:#A020F0">try</b> {<br /> <b style="color:#A020F0">int</b> h = amb.choose(range(1, N));<br /> <b style="color:#A020F0">int</b> a = amb.choose(range(1, h));<br /> <b style="color:#A020F0">int</b> b = amb.choose(range(a, h));<br /><br /> amb.require(sqr(h) == sqr(a) + sqr(b));<br /><br /> System.out.printf(<b style="color:#BC8F8F">"%2d^2 + %2d^2 = %2d^2\n"</b>, a, b, h);<br /><br /> amb.fail();<br />} <b style="color:#A020F0">catch</b> (Exception e) {<br />}</code></pre></blockquote><br />Let's go through it step by step.<br /><br />Firstly what is the code supposed to do? Well, the goal is to find Pythagorean Triplets, that is integer (<var>a</var>, <var>b</var>, <var>h</var>) triplets that satisfy the Pythagorean Theorem <var>a</var>²+<var>b</var>²=<var>h</var>².<br /><br />Having set its goal, the code (or at least a portion of it) is quite easy to read:<br /><ol><li>you state that <var>h</var> is to be chosen from a range of 1 through a given <var>N</var>; <small>(<var>N</var> exclusively)</small></li><li>you state that <var>a</var> is to be chosen from a range of 1 through <var>h</var>; <small>(the hypotenuse is always larger than the legs)</small></li><li>you state that <var>b</var> is to be chosen from a range of <var>a</var> through <var>h</var>; <small>(making <var>b</var> be greater than or equal to <var>a</var> removes the uninteresting solutions where <var>a</var> and <var>b</var> are interchanged)</small></li><li>you require that <var>h</var> squared is to be equal to the sum of <var>a</var> squared and <var>b</var> squared.</li></ol><br />And then you go on to printing the solution. So, basically you've set out the rules and you hope the program will automagically give the right answer, and it does - that's <code>amb</code>. You can read about non-determinism and <code>amb</code> on two great Scheme books: <a href="http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-28.html">SICP</a> and <a href="http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme-Z-H-16.html">TYS</a>.<br /><br /><code>Ambivalence</code> differs from it's Scheme's cousin in that it is not a macro, and so it evaluates it's arguments, but otherwise it's pretty much the same. Modulo that difference, it can be used in almost the same ways. It's code is part of the test, but it may be added to the general library, as a clean way to use continuations. I'll post it here for a good showcase, anyway:<br /><blockquote><pre><code><b style="color:#A020F0">public</b> <b style="color:#A020F0">final</b> <b style="color:#A020F0">class</b> Ambivalence<T> {<br /> <b style="color:#A020F0">private</b> Continuation failure;<br /><br /> <b style="color:#A020F0">public</b> @interpretable T choose(T... values) {<br /> <b style="color:#A020F0">if</b> (values.length == 0) failure.returnTo();<br /> <b style="color:#A020F0">if</b> (values.length == 1) <b style="color:#A020F0">return</b> values[0];<br /><br /> Continuation old = failure;<br /> Continuation success = <b style="color:#A020F0">new</b> Continuation();<br /><br /> <b style="color:#A020F0">for</b> (T value : values) helper(value, success);<br /><br /> failure = old;<br /> failure.returnTo();<br /><br /> <b style="color:#A020F0">return</b> <b style="color:#A020F0">null</b>;<br /> }<br /><br /> <b style="color:#A020F0">private</b> @interpretable <b style="color:#A020F0">void</b> helper(T value, Continuation success) {<br /> failure = <b style="color:#A020F0">new</b> Continuation();<br /> success.returnTo(value);<br /> }<br /><br /> <b style="color:#A020F0">public</b> @interpretable <b style="color:#A020F0">void</b> fail() {<br /> failure.returnTo();<br /> }<br /><br /> <b style="color:#A020F0">public</b> @interpretable <b style="color:#A020F0">void</b> require(<b style="color:#A020F0">boolean</b> condition) {<br /> <b style="color:#A020F0">if</b> (!condition) failure.returnTo();<br /> }<br />}</code></pre></blockquote><br />That's it for today. I'm working on <code>finally</code> and <code>continuing</code> blocks, and hope to nail them soon. Keep tuned.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-14103762.post-1124434487023612802005-08-19T07:38:00.000+01:002005-08-26T19:06:30.790+01:00New release - 0.2That's right, there's a new file release - version 0.2, see the <a href=http://sourceforge.net/project/showfiles.php?group_id=142992>downloads</a> page.<br /><br />So, what's new in so little time?<br /><br />Well everything I intended to do before going into continuations is now in place. Besides that, lot of bugs have been corrected (hopefully more than those introduced).<br /><br />Most notably in this release, exception handling is implemented, with stack-trace translation, source file and line numbers. This means debugging the interpreted code is now much easier.<br /><br />I'll move into continuations soon, then into <code>finally</code> and <code>continuing</code> blocks with continuations, and hopefully finish serialization in time. Tight schedule until September 1, but now moving steadily towards the goal - or so it seems.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-14103762.post-1124392212648233422005-08-16T22:37:00.000+01:002005-08-31T01:14:23.830+01:00The first alpha release - 0.1Following up on my last post, yesterday I made the project's first file release - alpha version 0.1, see the <a href="http://sourceforge.net/project/showfiles.php?group_id=142992">downloads</a> page.<br /><br />Now the code is most likely buggy, but at least (and modulo the unknown bugs) it already does a few things:<br /><ul><li>it is able to interpret just about everything apart from throwing and catching exceptions</li><li>and, most notably, it already does tail-calls optimization.</li></ul><br />I've also added couple of tests where added and an <code>ant</code> target was created (<code>test</code>). To test the JauVM yourself download the file (<a href="http://prdownloads.sf.net/jauvm/jauvm-0.1-src.tgz?download">jauvm-0.1-src.tgz</a>) and do the following:<br /><blockquote><pre><kbd>tar xfz jauvm-0.1-src.tgz<br />cd jauvm<br />ant test</kbd></pre></blockquote><small>Notes: you'll need a recent version of <code>ant</code> (mine is 1.6.2) and a 1.5 JDK (mine is 1.5.0_02); and, there will be some warnings about missing <code>serialVersionUID</code>s.</small><br /><br />The expected output should be amongst <code>ant</code>'s own output and is something like:<br /><blockquote><pre><samp>[echo] ========== Fib ==========<br />[java] fib(25)=121393, O(N)<br />[java] fib(25)=121393, O(log(N))<br />[java] fib(25)=121393, O(exp(N))<br />[echo] ========= Parity ========<br />[java] even(65536)?=true<br />[java] odd(65536)?=false<br />[java] even(65535)?=false<br />[java] odd(65535)?=true<br />[echo] =========================</samp></pre></blockquote><br />The sources for these tests are under the <samp>test</samp> directory, do take a look.<br /><br />The interpreter is pretty slow and memory hungry right now, but there's a lot of room for improvement though that's not a priority - features and correct behaviour come first.<br /><br />The only known issues (that are not easy problems) are synchronization (as I've said <a href="http://jauvm.blogspot.com/2005/07/first-commit.html">earlier</a>) and some method invocations, like those with the super keyword (calling virtual methods of the super-class). Other known issues have to do with class garbage collection, but seem more manageable.<br /><br />Under memory pressure the interpreter may throw a <code>NullPointerException</code> - this is being worked on. Other than that, all bug reports are welcomed.<br /><br />Work will continue on implementing exceptions throwing and handling. That's it for today!Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-14103762.post-1123726576781090212005-08-11T01:33:00.000+01:002005-08-18T20:12:17.516+01:00Wow - it's been two weeks!Indeed... But what have I been up to?<br /><br />Well, if you'd kept up with CVS, you'd know that a week ago I was dealing with symbolic name resolution as per the <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ConstantPool.doc.html#73492">JVM Spec</a>.<br /><br />I was kinda delayed by a bug in javac's compile-time field resolution. I kept testing my algorithm against javac's, and so I had to redo it to match the JVM's dynamic resolution method - which is the correct one, according to the specification. I filed a bug with Sun (no response yet) - but it's a corner case (not that important). I just wanted to get it right the first time.<br /><br />That's not the main reason for this post, though. I've just committed a version of the code that finally does something - like visible stuff.<br /><br />The interpreter now “loads” the necessary classes (that was the step following resolution), parsing the bytecode and building a structure suitable for the interpretation process.<br /><br />I was going to go with an <code>int[]</code> and the traditional <code>switch</code> interpreter, but after implementing just “a couple” of opcodes I was rapidly approaching the maximum method size limit (besides having a huge source file, but that's manageable with code folding).<br /><br />So I gave up, and I'm using an <code>Insn[]</code> - that's an “instructions” array. <code>Insn</code>s are objects that represent an instruction and all its arguments, and which have an <code>execute(...)</code> virtual method.<br /><br />The interpreter cycle is now just this (code which I believe explains itself):<br /><blockquote><pre><code><b style="color:#A020F0">while</b> (<b style="color:#A020F0">this</b>.frame != <b style="color:#A020F0">null</b>) <b style="color:#A020F0">this</b>.code[<b style="color:#A020F0">this</b>.cp++].execute(<b style="color:#A020F0">this</b>);</code></pre></blockquote><br />I've implemented a couple of opcodes already, quite enough for dear “Hello World!” - which was in fact the initial goal:<br /><ul><li>static and virtual, interpreted and native invocations;</li><li>static and instance field getting and setting;</li><li>local variable loading and storing</li><li>constant loading;</li><li>simple stack operations.</li></ul><br />It's not much (no math yet, amongst other things) but as I said enough to test.<br /><br />Want to give it a try? Easy steps then:<br /><blockquote><pre><kbd>cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/jauvm login<br />cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/jauvm co -P jauvm<br />cd jauvm<br />ant dist</kbd></pre></blockquote><small>Notes: leave the password blank; you'll need a recent version of <code>ant</code> (mine is 1.6.2) and a 1.5 JDK (mine is 1.5.0_02); and, there will be some warnings about missing <code>serialVersionUID</code>s.</small><br /><br />Hopefully, and if all goes out as expected, you'll have 3 files in the <samp>dist</samp> folder:<br /><ul><li><samp>jauvm.jar</samp> (java archive, no dependencies);</li><li><samp>jauvm-all.jar</samp> (java archive, all dependencies included);</li><li>and, <samp>jauvm-src.tgz</samp> (source tarball).</li></ul><br />You'll want the <samp>jauvm-all.jar</samp>. Add that to your classpath, compile and run the following example:<br /><blockquote><p><strong>Test.java</strong></p><pre><code><b style="color:#A020F0">import</b> net.sf.jauvm.Interpreter;<br /><b style="color:#A020F0">import</b> net.sf.jauvm.interpretable;<br /><br /><b style="color:#A020F0">public</b> <b style="color:#A020F0">class</b> Test <b style="color:#A020F0">implements</b> Runnable {<br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">static</b> <b style="color:#A020F0">void</b> main(String[] args) {<br /> <b style="color:#A020F0">new</b> Interpreter(<b style="color:#A020F0">new</b> Test()).run();<br /> }<br /><br /> <b style="color:#A020F0">public</b> @interpretable <b style="color:#A020F0">void</b> run() {<br /> System.out.println(<b style="color:#BC8F8F">"Hello World!"</b>);<br /> System.out.println(System.currentTimeMillis());<br /> iprint(Math.PI);<br /> nprint(Math.E);<br /> itest();<br /> ntest();<br /> }<br /><br /> <b style="color:#A020F0">public</b> @interpretable <b style="color:#A020F0">void</b> itest() {<br /> System.out.println(<b style="color:#A020F0">this</b>);<br /> }<br /><br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> ntest() {<br /> itest();<br /> }<br /><br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">static</b> @interpretable <b style="color:#A020F0">void</b> iprint(<b style="color:#A020F0">double</b> d) {<br /> System.out.println(d);<br /> }<br /><br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">static</b> <b style="color:#A020F0">void</b> nprint(<b style="color:#A020F0">double</b> d) {<br /> iprint(d);<br /> }<br />}</code></pre></blockquote><br />The output should be something like:<br /><blockquote><pre><samp>Hello World!<br />1123726157960<br />3.141592653589793<br />2.718281828459045<br />Test@e0b6f5<br />Test@e0b6f5</samp></pre></blockquote><br />I'll leave it up to you to figure out what's being interpreted and what's not.<br /><br />Next steps will be: getting interface and special invocations working (including constructors and <code>private</code> methods - <code>super</code> invocations may be a problem). In the process I hope to implement tail-calls (which seem pretty easy) and a bunch more opcodes, and soften a few rough edges. That's all before getting into continuations.<br /><br />This will now get exiting, at least for me!Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-14103762.post-1122661724202137942005-07-29T17:38:00.000+01:002005-07-29T19:31:35.906+01:00The second commit?If you'd kept an eye on the repository, you'd know I've been working on the <code>Frame</code> class, and I'm pretty much done with it for now. =)<br /><br />As I said, there were different possibilities regarding the implementation of this class - let me present you with two.<br /><br />Frames must store a stack for the function. This frame's size is well known, so this is not a problem. There are two kinds of things the frame must hold: primitive values (<code>int</code>s, <code>float</code>s, <code>long</code>s and <code>double</code>s - since <code>boolean</code>s, <code>byte</code>s, <code>short</code>s and <code>char</code>s are stored as <code>int</code>s) and references (subclasses of <code>Object</code>). From these: <code>int</code>s, <code>float</code>s and references take 32 bits for 1 word; and, <code>long</code>s and <code>double</code>s take 64 bits for 2 words.<br /><br />First approach: use an <code>Object[]</code> and box primitive values. For <code>long</code>s and <code>double</code>s store the boxed <code>Long</code> or <code>Double</code> in the first word and <code>null</code> in the second word.<br /><br />Second approach: use 3 arrays (an <code>int[]</code>, a <code>double[]</code> and an <code>Object[]</code>) one to hold 32 bit primitives, another for 64 bit ones and one for references; the <code>double[]</code> can have half the size.<br /><br />The first approach is conceptually simpler, and it also makes all operations simpler. The second approach was tested to be at least two times faster than the first (even without taking into account the extra garbage the first produces).<br /><br />The rational for the second approach is that: no primitives are boxed; <code>int</code>s are more common than <code>float</code>s (and <code>double</code>s more common than <code>long</code>s); <code>intBitsToFloat</code> (and <code>longBitsToDouble</code>, etc) are fast; space wast is minimized (vs. having 5 arrays).<br /><br />I took the simpler, though slower, approach for now. I have, however, tried to encapsulate inside the <code>Frame</code> class everything necessary to make the move later. Here goes the class's current interface (you can also check an <a href="http://cvs.sourceforge.net/viewcvs.py/jauvm/jauvm/src/net/sf/jauvm/vm/Frame.java?view=markup">implementation</a>):<br /><blockquote><p><strong>Frame.java</strong></p><pre><code><b style="color:#A020F0">package</b> net.sf.jauvm.vm;<br /><br /><b style="color:#A020F0">import</b> java.io.Serializable;<br /><br /><b style="color:#A020F0">public</b> <b style="color:#A020F0">final</b> <b style="color:#A020F0">class</b> Frame <b style="color:#A020F0">implements</b> Cloneable, Serializable {<br /> <b style="color:#A020F0">public</b> Frame getParent();<br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">int</b> getRet();<br /> <i style="color:#B22222">// public InterpretableMethod getCode();<br /></i><br /> <b style="color:#A020F0">public</b> Integer popInt();<br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> pushInt(Integer val);<br /> <b style="color:#A020F0">public</b> Integer getInt(<b style="color:#A020F0">int</b> var);<br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> putInt(<b style="color:#A020F0">int</b> var, Integer val);<br /> <b style="color:#A020F0">public</b> Long popLong();<br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> pushLong(Long val);<br /> <b style="color:#A020F0">public</b> Long getLong(<b style="color:#A020F0">int</b> var);<br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> putLong(<b style="color:#A020F0">int</b> var, Long val);<br /> <b style="color:#A020F0">public</b> Float popFloat();<br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> pushFloat(Float val);<br /> <b style="color:#A020F0">public</b> Float getFloat(<b style="color:#A020F0">int</b> var);<br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> putFloat(<b style="color:#A020F0">int</b> var, Float val);<br /> <b style="color:#A020F0">public</b> Double popDouble();<br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> pushDouble(Double val);<br /> <b style="color:#A020F0">public</b> Double getDouble(<b style="color:#A020F0">int</b> var);<br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> putDouble(<b style="color:#A020F0">int</b> var, Double val);<br /> <b style="color:#A020F0">public</b> Object popObject();<br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> pushObject(Object val);<br /> <b style="color:#A020F0">public</b> Object getObject(<b style="color:#A020F0">int</b> var);<br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> putObject(<b style="color:#A020F0">int</b> var, Object val);<br /><br /> <b style="color:#A020F0">public</b> Frame popParameters(Class<?>[] parameterTypes, <b style="color:#A020F0">int</b> ret, <i style="color:#B22222">/*InterpretableMethod code,*/</i> <b style="color:#A020F0">int</b> maxStack, <b style="color:#A020F0">int</b> maxLocals);<br /> <b style="color:#A020F0">public</b> Object[] popParameters(Class<?>[] parameterTypes);<br /><br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> pop();<br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> pop2();<br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> dup();<br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> dupBnth1();<br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> dupBnth2();<br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> dup2();<br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> dup2Bnth1();<br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> dup2Bnth2();<br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> swap();<br /><br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">boolean</b> isImmutable();<br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> makeParentsImmutable();<br /> <b style="color:#A020F0">public</b> Frame clone() <b style="color:#A020F0">throws</b> CloneNotSupportedException;<br />}</code></pre></blockquote><br />The first set of methods are getters for: the return address; this frame's parent frame; and, the corresponding method's code (unimplemented) - these properties are constant.<br /><br />The second set are basic stack operations. Popping off and pushing into references and primitives, setting and getting reference or primitive local variables. These functions take and return boxed primitives due to the fact that <code>Frame</code>s are implemented with an <code>Object[]</code>. However, due to Java 5.0's auto-(un)boxing, this interface can be changed to use primitive values, almost without modification to its clients (besides a recompile).<br /><br />The third set are methods that help in handling invocations. The first one creates a new <code>Frame</code> for an interpretable invocation, popping the parameters into it. The second one returns an <code>Object[]</code> suitable for invocation through reflection.<br /><br />The fourth set are the general purpose stack operations of the JVM, that benefit with knowledge of the internal structure of <code>Frame</code> objects.<br /><br />And, the last set manages the immutability of <code>Frame</code> objects -frames captured by continuations must remain immutable. Accordingly: when you do a <code>new Continuation()</code> you call <code>makeParentsImmutable()</code> on the current frame, effectively marking all parent frames as immutable; when you need to modify a <code>Frame</code> you check its immutability with <code>isImmutable()</code> and, if necessary, you <code>clone</code> that <code>Frame</code>.<br /><br />That's all for now. I'll work on that <code>InterpretableMethod</code> class now.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-14103762.post-1122421355688791562005-07-26T23:46:00.000+01:002005-07-29T19:29:41.363+01:00The first commit...OK, so I did my first commit today. You can keep track of the project's code by either browsing it through the <a href="http://cvs.sourceforge.net/viewcvs.py/jauvm/">web-based viewer</a> (which is usually a couple hours off), or by using the anonymous access:<br /><blockquote><pre><kbd>cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/jauvm login<br />cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/jauvm co -P jauvm</kbd></pre></blockquote><br />You may be wondering what took me so long. It's true, I've been available since Friday when I last posted, and yet no news.<br /><br />I've been struggling to solve my first problem: the promised <code>Monitor</code> class. That class involved the creation of methods to implement unbalanced <code>monitorenter</code> and <code>monitorexit</code> operations. Although those can't be expressed directly in Java, they could easily be implemented directly in JVM bytecode.<br /><br />To avoid having an extra compile-time dependency, I'd decided to use ASM, defining the class in XML. It all worked pretty well (including a couple of ANT tasks to automate it), until I actually tried running the code, just to find out that the JVM checks to guarantee at runtime that no method does an unbalanced locking operation.<br /><br />The check was added in 1.4, and is - in my opinion - pretty stupid (sorry clever guys at Sun, but read on). Unbalanced locks <em>are</em> useful, so much so that they are present in rival .NET, and consequently a form of those appeared in 1.5 in the new <code>java.util.concurrent</code> package.<br /><br />This new API though, however “dangerous” for purists, does not suit my needs, because, <cite>au contraire</cite> of what happens in .NET, this it's not “compatible” with the common <code>synchronized</code> block (in the sense that it's not possible to unbalancedly synchronize on an arbitrary object, you can only lock locks). The API's existence however, proves it can be done - most likely through JNI (I know, that sucks, but that's the JVM we've got).<br /><br />So the bad news is, in general, synchronization won't work for the time being. Your options will be: using <code>java.util.concurrent.locks.Lock</code>s where you can; or, waiting for the JNI implementation of <code>Monitor.enter</code> and <code>Monitor.exit</code>, if you can tolerate JNI.<br /><br />Note that this affects all synchronization, meaning all the usages of the <code>synchronized</code> keyword (blocks and methods) in interpreted code (and not just the direct usage of the <code>Monitor</code> class): these will all throw <code>UnsupportedOperationException</code>s until further notice. This is so, because the <code>monitorenter</code> and <code>monitorexit</code> opcodes would have themselves to be implemented through <code>Monitor</code>. Sorry there really seams to be nothing I can do about this.<br /><br />I won't just give up over this - I knew synchronization would be a problem, and it's really not an unsolvable one (it's just nasty when you can't use plain Java to do <em>safe</em>, simple stuff like this).<br /><br />I'll move on, for now, and will look into the design of <code>Frame</code> objects - which are responsible for keeping the interpreter's state. There are a few different possibilities: some faster, others simpler - as usual. I'll go with the simpler version for now, probably, but I'm trying to abstract enough of the inner workings of frames inside the <code>Frame</code> class, to make it easy to latter (as in during or after the summer =) replace it with the faster version.<br /><br />That's all that's been going on, remember to keep an eye on the repository if you're interested.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-14103762.post-1122002829448262832005-07-22T03:02:00.000+01:002005-07-22T04:34:45.966+01:00User Guide - Part FourIn my previous installment I showed you some examples of using continuations. From them you can see continuations are a sort of non-local jumps (a bit like exceptions). Isn't that dangerous? Yes, it is - but fun! Let's have an example:<br /><blockquote><pre><code>@interpretable Continuation aMethod() {<br /> <b style="color:#A020F0">return</b> <b style="color:#A020F0">new</b> Continuation();<br />}<br /><br />@interpretable <b style="color:#A020F0">void</b> anotherMethod() {<br /> Continuation cont = aMethod();<br /><br /> <b style="color:#A020F0">synchronized</b> (<b style="color:#A020F0">this</b>) {<br /> cont.returnTo(cont);<br /> }<br />}</code></pre></blockquote><br />Note the <code>synchronized</code> block. Now that's nasty, right? If you jump somewhere else, just like that, <code>this</code> will remain locked, right? Well, no... Remember continuations are “a bit like exceptions” and the JauVM will handle the unlocking for you, just like the JVM does with exceptions. We have a new problem though:<br /><blockquote><pre><code>@interpretable Continuation aMethod() {<br /> <b style="color:#A020F0">return</b> <b style="color:#A020F0">new</b> Continuation();<br />}<br /><br />@interpretable <b style="color:#A020F0">void</b> anotherMethod() {<br /> Continuation cont = <b style="color:#A020F0">null</b>;<br /><br /> <b style="color:#A020F0">synchronized</b> (<b style="color:#A020F0">this</b>) {<br /> cont = aMethod();<br /> }<br /><br /> cont.returnTo(cont);<br />}</code></pre></blockquote><br />What's happening here? Well, you acquire the lock, then you save the <code>Continuation</code> and release the lock. Afterwards you invoke the <code>Continuation</code>, and you're suddenly inside the <code>synchronized</code> block without the lock.<br /><br />Now wait a minute. Can't the JauVM reacquire the lock for me? Unfortunately no, it's not that simple. And we have the same problem with <code>try</code> ... <code>finally</code> too - <code>finally</code>s are ran, but we have no “<code>initially</code>”.<br /><br />To amend this issue an new <code>Throwable</code> was devised - the <code>continuing</code> class. It can be used to tag a <code>catch</code> clause of a <code>try</code> block as the code to be run when that <code>try</code> is reentered. Confusing? Examples will help.<br /><br />In the presence of continuations code, a <code>synchronized</code> should look like this:<br /><blockquote><pre><code><b style="color:#A020F0">synchronized</b> (<b style="color:#A020F0">this</b>) {<br /> <b style="color:#A020F0">try</b> {<br /> <i style="color:#B22222">// ...<br /></i> } <b style="color:#A020F0">catch</b> (continuing c) {<br /> Monitor.enter(<b style="color:#A020F0">this</b>);<br /> }<br />}</code></pre></blockquote><br />And a <code>try</code> ... <code>finally</code> (safeguarding a JDBC connection, in this case) should be:<br /><blockquote><pre><code>Connection conn = pool.getConnection();<br /><b style="color:#A020F0">try</b> {<br /> <i style="color:#B22222">// ...<br /></i>} <b style="color:#A020F0">catch</b> (continuing c) {<br /> conn = pool.getConnection();<br />} <b style="color:#A020F0">finally</b> {<br /> conn.close();<br />}</code></pre></blockquote><br />As you can see, the <code>catch</code> <code>continuing</code> clause is about reacquiring the resources you've freed when you first left the <code>try</code> block.<br /><br />But what's this <code>continuing</code> class like? Here it is:<br /><blockquote><pre><code><b style="color:#A020F0">public</b> <b style="color:#A020F0">final</b> <b style="color:#A020F0">class</b> continuing <b style="color:#A020F0">extends</b> Error {<br /> <b style="color:#A020F0">private</b> continuing() {<br /> }<br />}</code></pre></blockquote><br />The class is <code>final</code> and the constructor <code>private</code> because there should be no objects of this kind - again this is just a tag! It extends <code>Error</code> for it mustn't be a checked exception, and shouldn't normally be caught either - though it doesn't make a difference if you catch <code>Throwable</code>, only <code>continuing</code> works.<br /><br />Also, you're probably curious about that <code>Monitor</code> class. Well, it will have to be written in assembly, and I haven't made up my mind about an assembler yet (<a href="http://www.judoscript.com/articles/jamaica.html">Jamaica</a>, <a href="http://jasmin.sf.net/">Jasmin</a>...) It'll have at least <code>enter</code> and <code>exit</code> <code>static</code> methods, but you'll see.<br /><br />And that's it, for now! User guide over. Not complete, but I hope I've passed along the general picture. By the way, I'm open to suggestions for names for these all classes and methods (especially the <code>continuing</code> exception, which I particularly dislike).<br /><br />Thanks for “listening”!Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-14103762.post-1121706144648520252005-07-18T16:54:00.000+01:002005-07-22T04:36:19.990+01:00User Guide - Part ThreeI was out for this weekend and will be busy the next few days, but today I'll talk about continuations. I really don't think I'm up to the task of explaining continuations, however <a href="http://www.intertwingly.net/blog/2005/04/13/Continuations-for-Curmudgeons">this</a> is a good introduction on the topic.<br /><br />So, what will continuations be like? In the JauVM a <code>Continuation</code> is Java object, that represents a snapshot of the execution state of an <code>Interpreter</code> object, including the values of local variables. Here is its implementation:<br /><blockquote><p><strong>Continuation.java</strong></p><pre><code><b style="color:#A020F0">package</b> net.sf.jauvm;<br /><br /><b style="color:#A020F0">import</b> java.io.Serializable;<br /><br /><b style="color:#A020F0">public</b> <b style="color:#A020F0">class</b> Continuation <b style="color:#A020F0">implements</b> Serializable {<br /> <b style="color:#A020F0">public</b> Continuation() {<br /> <b style="color:#A020F0">throw</b> <b style="color:#A020F0">new</b> UnsupportedOperationException();<br /> }<br /><br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> returnTo() {<br /> <b style="color:#A020F0">throw</b> <b style="color:#A020F0">new</b> UnsupportedOperationException();<br /> }<br /><br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> returnTo(Object o) {<br /> <b style="color:#A020F0">throw</b> <b style="color:#A020F0">new</b> UnsupportedOperationException();<br /> }<br /><br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> throwTo(Throwable t) {<br /> <b style="color:#A020F0">throw</b> <b style="color:#A020F0">new</b> UnsupportedOperationException();<br /> }<br /><br /> <b style="color:#A020F0">protected</b> <b style="color:#A020F0">void</b> continueFrom() {<br /> <b style="color:#A020F0">throw</b> <b style="color:#A020F0">new</b> UnsupportedOperationException();<br /> }<br />}</code></pre></blockquote><br />The first thing to note are the methods' implementations. All those operations are unsupported because you're not supposed to use them in your regular Java code. A <code>Continuation</code> is a special object, recognized by JauVM's <code>Interpreter</code>, and whose implementation is closely tied to it. A continuation can not be reified or invoked in code ran by the regular JVM.<br /><br />To capture a continuation, you have to create a new <code>Continuation</code> object. For example:<br /><blockquote><pre><code>@interpretable <b style="color:#A020F0">void</b> aMethod() {<br /> Continuation cont = <b style="color:#A020F0">new</b> Continuation();<br />}</code></pre></blockquote><br />In the above code, the variable <code>cont</code> represents the execution state of the current <em>caller</em> of <code>aMethod</code>.<br /><br />Since <code>cont</code> is a regular Java object you can return it, store it in a variable, assign it to a field of another object - whatever you like. You can also call any of it's instance methods, namely the overloaded <code>returnTo</code> method. When you make such a call, the current execution state of the program is discarded and the snapshot of the program represented by the <code>Continuation</code> object is resumed in its place. You may also pass an argument to that method call, which becomes the return value of the method in which the <code>Continuation</code> was captured. For instance:<br /><blockquote><pre><code>@interpretable Object aMethod() {<br /> <b style="color:#A020F0">return</b> <b style="color:#A020F0">new</b> Continuation();<br />}<br /><br />@interpretable <b style="color:#A020F0">void</b> anotherMethod() {<br /> Object obj = aMethod();<br /><br /> <b style="color:#A020F0">if</b> (obj <b style="color:#A020F0">instanceof</b> Continuation) {<br /> System.out.println(<b style="color:#BC8F8F">"obj is a continuation"</b>);<br /> Continuation cont = (Continuation) obj;<br /> cont.returnTo(100);<br /> }<br /> <br /> System.out.println(<b style="color:#BC8F8F">"obj is "</b> + obj.toString());<br />}</code></pre></blockquote><br />Invoking <code>anotherMethod</code> yields the following output:<br /><blockquote><pre><samp>obj is a Continuation<br />obj is 100</samp></pre></blockquote><br />When <code>returnTo</code> is invoked, the program jumps back to the call to <code>aMethod</code>, but this time <code>aMethod</code> returns the <code>Integer</code> <code>100</code> passed into <code>returnTo</code>.<br /><br />What about <code>throwTo</code>? A continuation can be thought as representing the return from a method invocation. In Java, in addition to a normal return, a method may return due to an exception. The <code>throwTo</code> method throws its argument in the context of the <code>Continuation</code> after it's restored. For example:<br /><blockquote><pre><code>@interpretable Object aMethod() {<br /> <b style="color:#A020F0">return</b> <b style="color:#A020F0">new</b> Continuation();<br />}<br /><br />@interpretable <b style="color:#A020F0">void</b> anotherMethod() {<br /> Object obj = <b style="color:#A020F0">null</b>;<br /><br /> <b style="color:#A020F0">try</b> {<br /> obj = aMethod();<br /> } <b style="color:#A020F0">catch</b> (RuntimeException e) {<br /> System.out.println(e);<br /> }<br /><br /> <b style="color:#A020F0">if</b> (obj <b style="color:#A020F0">instanceof</b> Continuation) {<br /> System.out.println(<b style="color:#BC8F8F">"obj is a Continuation"</b>);<br /> Continuation cont = (Continuation) obj;<br /> cont.throwTo(<b style="color:#A020F0">new</b> RuntimeException(<b style="color:#BC8F8F">"thrown from aMethod"</b>));<br /> }<br />}</code></pre></blockquote><br />Invoking <code>anotherMethod</code> yields the following output:<br /><blockquote><pre><samp>obj is a Continuation<br />RuntimeException: thrown from aMethod</samp></pre></blockquote><br />This isn't all there is to know about continuations, but this post is already huge, the rest will have to wait. Keep tuned!Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-14103762.post-1121385333607293062005-07-14T23:54:00.000+01:002005-07-16T06:12:34.360+01:00User Guide - Part TwoYesterday I said I was going to show what tail-calls <em>look</em> like, not how they <em>will look</em> like. That's because nothing will be changed, except perhaps you, the programmer - who may start using them a lot more.<br /><br />But what are tail-calls anyway? Tail-calls are function calls - or method calls, in Javanese - done in tail position. What the hell is tail position? Well, something is in tail position, if it's done just before you do a return.<br /><br />Confusing? Lets see some examples of what this means in Java:<br /><blockquote><pre><code><i style="color:#B22222">// first example<br /></i>methodCall();<br /><b style="color:#A020F0">return</b>;<br /><br /><i style="color:#B22222">// second example<br /></i><b style="color:#A020F0">return</b> methodCall();</code></pre></blockquote><br />As you can see, tail-calls come in two shapes in Java: they're either a method call followed by a <code>void</code> <code>return</code>, or a <code>return</code> of a method call.<br /><br />Is it that simple? Yep, pretty much. Well, no. In fact, tail-calls <em>always</em> look like this, but these aren't <em>always</em> tail-calls.<br /><br />Imagine, in our first example above, <code>methodCall</code> returns an <code>int</code>. This <code>int</code> has to be discarded by the JVM, before control is returned to our parent method, so the method call isn't quite the last thing that's being done before the <code>return</code>.<br /><br />Now take our second example, and consider that <code>methodCall</code> returns a <code>float</code> but the method we are returning from returns a <code>double</code>. The JVM must coerce the <code>float</code> returned by <code>methodCall</code> to a <code>double</code> before returning from this method, so again that function call isn't the last thing done before the <code>return</code>. Depending on your compiler (which is <code>javac</code>, most likely) some coercions do work (<code>byte</code>, <code>short</code> and <code>char</code> to <code>int</code>, and coercions amongst objects without casts).<br /><br />All this details mean that, if you do come to depend on tail-calls, you must beware of these issues. Other, simpler, examples where “tail-calls don't work” are:<br /><blockquote><pre><code><i style="color:#B22222">// first example<br /></i><b style="color:#A020F0">synchronized</b> (obj) {<br /> <b style="color:#A020F0">return</b> methodCall();<br />}<br /><br /><i style="color:#B22222">// second example<br /></i><b style="color:#A020F0">try</b> {<br /> <b style="color:#A020F0">return</b> methodCall();<br />} <b style="color:#A020F0">catch</b> (Exception e) {<br /> <i style="color:#B22222">// ...<br /></i>} <b style="color:#A020F0">finally</b> {<br /> <i style="color:#B22222">// ...<br /></i>}</code></pre></blockquote><br />Clearly, on both examples, there are things to be done after the method call - to release the lock, to handle exceptions and to run finallies - so these aren't really tail-calls.<br /><br />But hey, what's so special about tail-calls? Well, remember all that stuff about them being the very last thing done in a method? If there's nothing more to be done in that method, you can simply jump to the other method and ignore the caller and its frame. This both reduces stack space, allows the earlier collection of some local variables, and promotes a recursion oriented programming style.<br /><br />That's all there is to know about tail-calls. Tomorrow, continuations will follow.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-14103762.post-1121290936597923782005-07-13T21:41:00.000+01:002005-07-23T21:29:23.906+01:00User Guide - Part OneAs I promised yesterday, today, I'll start a series of entries with a very rough first user guide for the JauVM.<br /><br />Lets start with the interpreter itself.<br /><br />In the proposal text there's a brief description on what <code>Interpreter</code> objects should look like. Lets elaborate a bit on that:<br /><blockquote><p><strong>Interpreter.java</strong></p><pre><code><b style="color:#A020F0">package</b> net.sf.jauvm;<br /><br /><b style="color:#A020F0">public</b> <b style="color:#A020F0">class</b> Interpreter <b style="color:#A020F0">implements</b> Runnable {<br /> <b style="color:#A020F0">private</b> <b style="color:#A020F0">final</b> Runnable r;<br /><br /> <b style="color:#A020F0">public</b> Interpreter(<b style="color:#A020F0">final</b> Runnable r) {<br /> <b style="color:#A020F0">this</b>.r = r;<br /> }<br /><br /> <b style="color:#A020F0">public</b> Interpreter(<b style="color:#A020F0">final</b> Continuation c) {<br /> <b style="color:#A020F0">this</b>.r = <b style="color:#A020F0">new</b> Runnable() {<br /> <b style="color:#A020F0">public</b> @interpretable <b style="color:#A020F0">void</b> run() {<br /> c.continueFrom();<br /> }<br /> };<br /> }<br /><br /> <b style="color:#A020F0">public</b> <b style="color:#A020F0">void</b> run() {<br /> <i style="color:#B22222">// interpret r.run()<br /></i> }<br />}</code></pre></blockquote><br />This is pretty much what I had already described, though there are some new things.<br /><br />As you can see, I've “added” a second constructor that takes a <code>Continuation</code> which is then continued when the interpreter is run. This is handy when you wish to call a continuation you've just deserialized on a new <code>Interpreter</code> object.<br /><br />It also serves the purpose of showing you how to write an interpretable method: just tag it with the <code>@interpretable</code> annotation. Here is the code for this annotation:<br /><blockquote><p><strong>interpretable.java</strong></p><pre><code><b style="color:#A020F0">package</b> net.sf.jauvm;<br /><br /><b style="color:#A020F0">import</b> java.lang.annotation.*;<br /><br />@Retention(RetentionPolicy.RUNTIME)<br />@Target(ElementType.METHOD)<br /><b style="color:#A020F0">public</b> @<b style="color:#A020F0">interface</b> interpretable {}</code></pre></blockquote><br />The fact that an <code>Interpreter</code> implements <code>Runnable</code> facilitates the creation of an interpreter on a new thread, look:<br /><blockquote><pre><code><b style="color:#A020F0">new</b> Thread(<b style="color:#A020F0">new</b> Interpreter(<b style="color:#A020F0">new</b> Runnable() {<br /> <b style="color:#A020F0">public</b> @interpretable <b style="color:#A020F0">void</b> run() {<br /> <i style="color:#B22222">// ...<br /></i> }<br />})).start();</code></pre></blockquote><br />Tomorrow, I'll shed some light what tail-calls look like.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-14103762.post-1121215480347235712005-07-13T00:34:00.000+01:002005-07-22T04:37:38.383+01:00No code yet?Well, the exam season at my University ends on July 23, and my last exam is on July 21. So, the Summer of Code will, unfortunately, have to wait a bit longer...<br /><br />That doesn't mean I won't do a thing, of course - just that it won't be full-time dedication.<br /><br /><cite>Bah... no more excuses, back to code!</cite> OK, then - say no more!<br /><br />In fact, I wanted to past some code here the other day; the geek in me wanted it highlighted, though. So, today, I worked out this little script (while studying for an exam) to do just that:<br /><blockquote><p><strong>code2html</strong></p><pre><code><b style="color: #5F9EA0">#!/bin/bash<br /></b><br />enscript --color -E -Whtml -p - ${1-<b style="color: #BC8F8F">'-'</b>} |<br /><br />sed <b style="color: #BC8F8F">'<br /> 1,/<PRE>/d<br /> /<\/PRE>/,$d<br /><br /> s/<B><FONT COLOR="\([^"]*\)">/<b style="color:\1">/g<br /> s/<I><FONT COLOR="\([^"]*\)">/<i style="color:\1">/g<br /> s/<FONT COLOR="\([^"]*\)"><B>/<b style="color:\1">/g<br /> s/<FONT COLOR="\([^"]*\)"><I>/<i style="color:\1">/g<br /> s/<FONT COLOR="\([^"]*\)">/<span style="color:\1">/g<br /><br /> s/<\/FONT><\/B>/<\/b>/g<br /> s/<\/FONT><\/I>/<\/i>/g<br /> s/<\/FONT>/<\/span>/g<br /> '</b> |<br /><br />sed <b style="color: #BC8F8F">'<br /> 1s/.*/<pre><code>&/<br /> $s/.*/&<\/code><\/pre>/<br /> '</b></code></pre></blockquote><br />Nothing to do with the JauVM, right?<br /><br />Well, with this great little tool at hand, tomorrow, I'll start a series of posts showing <em>you</em> - the potential user of this library - what will <em>your</em> code look like.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-14103762.post-1120861255928284332005-07-08T22:50:00.000+01:002005-07-22T04:38:09.110+01:00Yay Sourceforge!I finally got the JauVM accepted at Sourceforge. A link to the project page is - you guessed it - in the links section.<br /><br />Why am I this happy about it? Well, it was quite an adventure... read on.<br /><br />The project was rejected upon first review, but it's done now:<br /><blockquote><p><strong>SourceForge.net Project Approved</strong></p><pre>Your project registration for SourceForge.net has been approved.<br /><br />Project Information:<br /><br />Project Descriptive Name: the Jau Virtual Machine<br />Project Unix Name: jauvm<br />CVS Server: cvs.sourceforge.net<br />Shell Server: shell.sourceforge.net<br />Web Server: jauvm.sourceforge.net<br /><br />[...]<br /><br /> -- the SourceForge.net crew</pre></blockquote><br />It turns out the rejection was due to my description being too vague. I'd linked to the proposal text, but it seems the reviewers just don't follow links.<br /><br />In the end, it all went pretty smoothly: I supplied additional info - more or less copy-pasted the first two paragraphs of the proposal text - and before I knew it, the registration was accepted, in 2 business days instead of the expected 5.<br /><br />Yay Sourceforge!Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-14103762.post-1120267061011084812005-07-02T01:55:00.000+01:002005-07-18T16:41:30.150+01:00But... what's with the funny name?<cite>Where does it come from?</cite><br /><cite>How is it pronounced?</cite><br /><br />If it's ever to get used, this is bound to become one of those projects with these questions on its FAQ...<br /><br />So, I'll just satisfy your curiosity right away!<br /><br />‘Jau’ is Portuguese for ‘Javanese’ - <q cite="http://www.answers.com/javanese">Of or relating to Java or its people, language, or culture</q>. (Portuguese fellows in amazement, check your dictionaries)<br /><br />It's pronouced ‘Jou’ as in <strong>J</strong>ava and <strong>ou</strong>t.<br /><br />Pretty cool, ain't it?<br /><br />I'm actually really proud of it - that is, of knowing the one who thought it up for me... many thanks!Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-14103762.post-1120263211977500222005-07-01T17:05:00.000+01:002005-07-18T18:52:54.853+01:00So... what does it do?Another Virtual Machine!? What for?<br /><br />Well, read the proposal yourself:<br /><blockquote><p>The goal of my project (it doesn't have a name yet, unfortunately) is the implementation of a JVM bytecode interpreter in Java. This interpreter, hereby called the “Secondary JVM”, will be executed by the JVM itself, hereby called the “Primary JVM”.<br /><br />The “Secondary JVM” will not need to implement all the features of a standard JVM, since it can rely on the “Primary JVM” for things like class loading, bytecode verification, garbage collection and heap management. The “Secondary JVM” will however manage its own stack. This will allow the “Secondary JVM” to provide two popular features the Java Platform currently lacks: general tail call elimination and serializable continuations.<br /><br />Tail call elimination (or optimization) is important since it opens up the possibility of a functional/recursion-oriented programming style. Continuations are even more fundamental, since it can be proved that all control structures can be implemented with continuations.<br /><br />Having these two features implemented “at the VM level” (the “Secondary JVM” in this case) greatly simplifies the implementation of compilers for “functional” languages like Scheme or Ruby targeting the JVM, as well as the creation of web-application frameworks like Cocoon or RIFE.<br /><br />The following web page, at IBM developerWorks, supports the idea of using continuations for the development of complex web-applications (<a href="http://www-106.ibm.com/developerworks/library/j-contin.html">Use continuations to develop complex Web applications</a>); and, there's a long-standing RFE at Sun's Bug Database asking for the implementation of tail call elimination at the JVM level (<a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4726340">Bug ID: 4726340 RFE: Tail Call Optimization</a>).<br /><br />The “Secondary JVM” will be just a regular Java object, probably implementing the <code>Runnable</code> interface. It will itself take a <code>Runnable</code> as a parameter on construction. Upon calling its run method, the “Secondary JVM” will interpret the run method of the <code>Runnable</code> it was constructed with. This interpretation will probably rely on some form of JIT compilation, but the “Secondary JVM” will keep its own stack. It will be possible to create multiple “Secondary JVMs”, and run them on separate threads.<br /><br />Tail call elimination will be done by the “Secondary JVM”, and it will be possible to capture the execution state through the creation of <code>Continuation</code> objects - which will be serializable.<br /><br />It will be important, though challenging, to respect the Java class-loading semantics.<br /><br />Only methods tagged as “interpretable” will be run by the “Secondary JVM”, other methods will be delegated to the “Primary JVM” for execution. This tagging will probably be done through the use of annotations, and can be seen as somewhat similar to marking a method as native. There will be some restrictions on what methods can be tagged as “interpretable” - static constructors can't, and neither can native methods, obviously - it is not yet clear, however, the extent of these restrictions, though most methods will certainly qualify.<br /><br />Programs using this library can be seen as a combination of methods specified to run on the “Primary” or “Secondary JVMs”. The execution of a Java program will always start on the “Primary JVM”, which may then create a “Secondary JVM” to run certain methods, benefiting from the provided features. The “Secondary JVM” can then delegate certain methods that do not require those features back to “Primary JVM” for performance.<br /><br />The idea for this library came from the need to support these features (tail calls and continuations) in yet another Scheme-to-JVM compiler I might be creating next year for school. Thinking this might be equally useful to someone creating a Ruby-to-JVM compiler, for instance, I decided to code it as a separate library, and make it freely available. Google's “Summer of Code” may just be the incentive I need to have it finished during this summer. Irrespectively of the approval of this application, I will go forward with the project, which I intend to release under either the BSD or the Apache licenses.<br /><br />Prototyping work on this project has already begun, and more intensive work will follow as soon as the examinations season at my University ends, in mid-July. At that time, I will probably apply for hosting at Sourceforge, or a similar site. By September, there must already exist a stable interface for all features, as well as a usable implementation. Whatever the state of the project in September, work on it will not stop by then. I intend to maintain the project, further improving it both performance- and feature-wise.</p></blockquote><br />So, that's it! Keep tuned!Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-14103762.post-1120236769418895452005-07-01T00:12:00.000+01:002005-07-08T23:21:18.900+01:00Welcome!Not long ago, I got an e-mail that left me in shock:<br /><blockquote><p><strong>Congratulations!</strong><br /><br />Dear Nuno Cruces,<br /><br />We are delighted to tell you that your project (attached) has been<br />selected to receive a grant in Google's Summer of Code program.<br /><br />[...]<br /><br />Best regards,<br />The Summer of Code team</p></blockquote><br />I've learnt a lot about the IRS and tax regulations since. Hopefully I'll learn a lot more - and not just about tax!<br /><br />But all that - the tax and all the paperwork, I mean - hasn't taken the fun of it. Honestly, I couldn't care less about the money. Sure, it can buy me a brand new Intel Powerbook, but that's not why I'm doing it.<br /><br />I'm doing it because it's cool.<br />I'm doing it because it was something I had just thought up before Google's program was announced, and I decided to give it a try.<br />I'm doing it because this way it's even more of a challenge, and that's the best way to get me working.<br /><br />I didn't actually expect to be accepted.<br />I didn't really think I had worded the proposal appropriately, I thought it was too vague.<br />I didn't think anybody would interested enough in my project.<br /><br />It seems I was wrong.<br /><br />You know that feeling you get when you have this crazy ideia, and you're able to share your enthusiasm with someone?<br /><br />I know now - it's great.<br /><br />So, this is what this blog is about: me coding all summer, waiving my vacations, and being mightily enthusiastic about it!<br /><br />Welcome!Unknownnoreply@blogger.com1