tinyrb

It all started 2 weeks ago. I was stocked by Potion and had been studying Lua and other VMs for a little while. So I dove in and hacked a little Ruby VM with bytecode and all.

It’s Tiny Because There’s Not A Lot in There

The primary goal is to keep it small. This way, lots of people can understand it and change it quickly. My objective is to keep the VM (the C part) under 64K. Right now, it’s 43K and 1541 LOC. Not sure it’s possible, but I’ll take this as a challenge.

But, some very basic things are missing: no Float, no Module, no Proc or Bloc, no Array, Hash, IO, basically, almost nothing. But most of the keywords and core objects are there: Class, Object, Fixnum, Symbol, String, def, class, if, unless, while, until, etc.

The lexer is written in Ragel and the parser in Lemon. I wish to support the commonly used stuff in Ruby but give up on the dark corners or things that are too complex. Right now the grammar is just 100 LOC, that’s nice. The rule is:

>Everything in tinyrb should run in the big Ruby.
>(except bugs and things that don’t comply to the principle of least surprise.)
>But not everything in the big Ruby should run in tinyrb.

It’s Kinda Fast, For Now At Least

I implemented a couple optimizations already, Monomorphic method cache is there, means method lookup is cached at the call site. Also, as a test, I inline 3 methods, Fixnum#+, Fixnum#-, Fixnum#<, which makes a pretty big difference. The interpreter loop uses direct threaded dispatch when available and falls back to while-switch for portability.

Of course, I ran a couple micro-benchmarks. Now you know what they say about benchmarks? So take those with a grain of salt. But I think it just shows that a “fast” interpreter doesn’t need to be huge, at least…

UPDATE well of course I did something wrong here, I forgot to run jruby w/ the -server option. So please consider this benchmark completely false and useless.