April 8th, 2008
Welcome Waxy.org and Slashdot readers. I blog about JavaScript, like it's my job, feel free to subscribe for a ton more posts like this.
Related Posts:
Note: I'm not the creator of HotRuby, as mentioned elsewhere - it is the work of a highly-skilled Japanese developer.
HotRuby is a project which aims to port the Ruby Virtual Machine over to ECMAScript (allowing it to run, directly, in a browser using JavaScript or indirectly using ActionScript in Flash).
Currently the code works by using Ruby 1.9's YARV (Yet Another Ruby VM) to compile down a Ruby script into opcodes, which are then serialized and passed to the browser for execution. It's a little bit indirect but it still capable of creating a compelling result.
If you were to run one of the examples in your browser the actual chain of execution would be something like this:
- Script finds <script type="text/ruby"></script> tags and extracts the inline Ruby code from them.
- The Ruby code is sent to the server via an XMLHttpRequest.
- The server-side CGI script (in Ruby, using Ruby 1.9) compiles the incoming Ruby into its associated opcodes and serializes it into a JSON data structure.
- The browser consumes the opcodes, translating it into JavaScript, and executes it.
To observe this full process we can take a look at the code in the provided benchmark and watch its full path through the server and final execution:
startTime = Time.new.to_f
sum = ""
50000.times{|e| sum += e.to_s}
endTime = Time.new.to_f
puts (endTime - startTime).to_s + ' sec'
For example, observe this portion of the CGI script:
#!
/usr/local/bin/ruby
# Requires Ruby
1.
9.
0
# The license of
this source
is "Ruby License"
require 'json'
require 'cgi'
cgi = CGI.new
puts "Content-type: text/plain\n\n"
puts VM::InstructionSequence.compile(cgi['src'], "src", 1, {}).to_a.to_json
and a sample of the opcode data returned by the server:
["YARVInstructionSequence\/SimpleDataFormat",1,1,1,{"arg_size":0,"local_size":4,"stack_max":3},"","src","top",["startTime","sum","endTime"],0,[["break",null,"label_21","label_29","label_29",0]],[2,["putnil"],["getconstant","Time"],["send","new",0,null,0,null],["send","to_f",0,null,0,null],["setlocal",4],4,["putstring",""],["setlocal",3],"label_21",5,["putobject",50000],["send","times",0,["YARVInstructionSequence\/SimpleDataFormat",1,1,1,{"arg_size":1,"local_size":1,"stack_max":2},"block in ","src","block",["e"],[1,[],0,0,-1,-1,3],[["redo",null,"label_0","label_22","label_0",0],["next",null,"label_0","label_22","label_22",0]],["label_0",5,["getdynamic",3,1],["getdynamic",1,0],["send","to_s",0,null,0,null],["send","+",1,null,0,null],["dup"],["setdynamic",3,1],"label_22",["leave"]]],0,null],"label_29",["pop"],7,["putnil"],["getconstant","Time"],["send","new",0,null,0,null],["send","to_f",0,null,0,null],["setlocal",2],9,["putnil"],8,["getlocal",2],["getlocal",4],["send","-",1,null,0,null],["send","to_s",0,null,0,null],["putstring"," sec"],9,["send","+",1,null,0,null],["send","puts",1,null,8,null],8,["leave"]]]
and you can find the full client-side virtual machine here: HotRuby.js.
Perhaps most fascinating about this, though, is the speeds that are able to be achieved with this script. Granted, the above benchmark is rather contrived, but the end performance results are quite fascinating:
| Firefox 3.0b5 |
2.47s |
| Firefox 2 |
6.71s |
| Ruby 1.8.2 |
12.25s |
We can see a 2.71x speed improvement from Firefox 2 to Firefox 3 and a 5x performance improvement over regular Ruby 1.8.2, running on the command-line.
It's a fascinating time to be working with JavaScript. The performance improvements that are being provided to us by the browser afford us a realm of possibility that wasn't, previously, viable. The fact that we're even discussing running a virtual machine, implemented in JavaScript, is quite impressive. I'm curious to see what applications end up being built with this implementation - and within what context they end up using it.
Tags: javascript, ecmascript, ruby, vm
39 Comments on 'Ruby VM in JavaScript'
August 8th, 2007
After yesterday's post on the browser scripting revolution, detailing the new projects being built on top of Tamarin, a number of questions came up concerning the choice of Tamarin instead of other virtual machines. Two engines came up, in particular: The Java Virtual Machine (JVM) - which is already able to run Jython and JRuby, and Mono - which is able to run IronPython and IronRuby.
I'll defer to the words of Mike Shaver and Brendan Eich to explain the reasons as to why, though in a nutshell: The non-technical reasons for choosing Tamarin are over intellectual property and licensing issues and the technical issues are related to compilation speed, file size, and memory footprint.
Mike Shaver:
Here are a few, at least as I see them:
* Optimized to run JavaScript and sibling languages, which is our most important language target by a vast margin.
* Licensed appropriately.
* About 1/25 the size, I think (200KB for Tamarin, 5MB for Mono as described by Miguel elsewhere)
* In my coarse measurements, significantly smaller memory footprint.
I was once quite a supporter of getting Mono into our world, including writing a prototype XPCOM binding for it, but I didn't see a path to getting the important factors (performance, licensing, footprint in code and memory) resolved, and I don't think it's much closer today. Nobody in Mono-land was interested enough to contribute to that, which is another counterpoint with Tamarin I suppose, where we have very active contributions from Adobe and others to help us get it in the state we need for it to be a suitable basis for building our whole app on.
It's not like we didn't look hard at Mono, and in the case of many of us lobby hard for licensing and patent concerns to be swept aside. Tamarin is a very good fit for us in a large number of ways, unfortunately including a number of ways in which Mono is not.
Brendan Eich:
Moreover, for Mozilla at least, we absolutely cannot depend on closed source, and we require a non-copyleft BSD license, or at most MPL/GPL/LGPL. Java was not even open source until recently (I don’t remember the date; it was preannounced one too many times :-/), well after we had to make our own plans and commitments.
Finally, in spite of the prospects with JRuby, the JVM really is about Java first and last. Tamarin is about an ECMAScript variant, so it’s a better target now, and more likely to evolve to support JS1 and JS2 in a first class way, than the JVM.
Compilation heroics can help, but the browser will remain an environment where compilation must be very fast. Wherefore our forthcoming work on a trace-based JIT.
Tags: vm, tamarin, mozilla, javascript, mono, ecmascript, java
11 Comments on 'Why Tamarin instead of...'