Deprecated: Assigning the return value of new by reference is deprecated in /home/worldofb/public_html/llvmruby/wordpress-llvmruby/wp-settings.php on line 468

Deprecated: Assigning the return value of new by reference is deprecated in /home/worldofb/public_html/llvmruby/wordpress-llvmruby/wp-settings.php on line 483

Deprecated: Assigning the return value of new by reference is deprecated in /home/worldofb/public_html/llvmruby/wordpress-llvmruby/wp-settings.php on line 490

Deprecated: Assigning the return value of new by reference is deprecated in /home/worldofb/public_html/llvmruby/wordpress-llvmruby/wp-settings.php on line 526

Deprecated: Assigning the return value of new by reference is deprecated in /home/worldofb/public_html/llvmruby/wordpress-llvmruby/wp-includes/cache.php on line 103

Deprecated: Assigning the return value of new by reference is deprecated in /home/worldofb/public_html/llvmruby/wordpress-llvmruby/wp-includes/query.php on line 21

Deprecated: Assigning the return value of new by reference is deprecated in /home/worldofb/public_html/llvmruby/wordpress-llvmruby/wp-includes/theme.php on line 618
writing a YARVish bytecode compiler in ruby at llvmruby.org

llvmruby.org

writing a YARVish bytecode compiler in ruby

2 comments

Since llvmruby let’s us write native compiled things that interact with Ruby interpreter values, and obvious thing to do with it is to write a compiler for the bytecode used in Ruby 1.9, ie YARV. This is the YARV instruction set and if you click through to an opcode definition, you will see the C code used to execute that opcode. For example, the opt_lt instruction is implemented with this C code:

if (FIXNUM_2_P(recv, obj) &&
	BASIC_OP_UNREDEFINED_P(BOP_LT)) {
	long a = FIX2LONG(recv), b = FIX2LONG(obj);

	if (a < b) {
	    val = Qtrue;
	}
	else {
	    val = Qfalse;
	}
    }
    else {
	PUSH(recv);
	PUSH(obj);
	CALL_SIMPLE_METHOD(1, idLT, recv);
    }

In my llvm based compiler, which is woefully incomplete and for now just assumes that the incoming arguments are fixints, the op code is implemented this way:

when :opt_lt
        obj = b.pop
        recv = b.pop
        x = b.fix2int(recv)
        y = b.fix2int(obj)
        val = b.icmp_sle(x, y)
        val = b.int_cast(val, LONG, false)
        val = b.mul(val, 2.llvm)
        b.push(val)

This bit of assembly avoids jumps by knowing that Ruby represents Qtrue and Qfalse as 2 and 0 respectively, so the single bit 0 or 1 result of the cmp instruction is simply expanded and multiplied by 2.

I’ve implemented a small and growing subset of the YARV instruction set in ruby_vm.rb, and has some tests in test_ruby_vm.rb showing some small example functions put together with this YARVish assembly. For example the sequence:

bytecode = [
      [:newarray],
      [:dup],
      [:putobject, LLVM::Value.get_immediate_constant(0)],
      [:putobject, LLVM::Value.get_immediate_constant('shaka')],
      [:opt_aset],
      [:pop]
    ]

creates a new array and sets the first element of the array to a string. Since the guts of using LLVM from Ruby has been basically finished, I am now mostly working on translating the YARV instruction set into Ruby.

Written by tom

August 31st, 2008 at 3:50 pm

Posted in Uncategorized

2 Responses to 'writing a YARVish bytecode compiler in ruby'

Subscribe to comments with RSS or TrackBack to 'writing a YARVish bytecode compiler in ruby'.

  1. ?????????? ??? ???????? ????, ?? ??????? ???? ????? ?????????? ?? ????? ???????….

    ????????? ???????????/ ???.?????? 9, ie YARV. This is the YARV instruction set and if you click through to an opcode definition, you will see the […….

    Kylie Batt

    15 Apr 10 at 4:27 pm

  2. ?????????? ????????????????? ?? ??????, ????? ????????????? ? ?????????? ????? ???????….

    ?????? ???????? 9, ie YARV. This is the YARV instruction set and if you click through to an opcode definition, you will see the […….

    Kylie Batt

    4 May 10 at 12:26 pm

Leave a Reply