<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>llvmruby.org</title>
	<atom:link href="http://llvmruby.org/wordpress-llvmruby/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://llvmruby.org/wordpress-llvmruby</link>
	<description></description>
	<pubDate>Thu, 25 Dec 2008 00:10:14 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
	<language>en</language>
			<item>
		<title>many updates, new gem version</title>
		<link>http://llvmruby.org/wordpress-llvmruby/?p=31</link>
		<comments>http://llvmruby.org/wordpress-llvmruby/?p=31#comments</comments>
		<pubDate>Thu, 25 Dec 2008 00:10:14 +0000</pubDate>
		<dc:creator>tom</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llvmruby.org/wordpress-llvmruby/?p=31</guid>
		<description><![CDATA[I&#8217;ve merged many good patches into the main llvmruby branch.  We are now officially using LLVM 2.4, compatible with Ruby 1.9 and more complete access to the LLVM API.
I recently became aware of a project by Marc-André Cournoyer using llvmruby to make a compiler for a little Ruby-ish language called Orange.
Miura Hideki has been making [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve merged many good patches into the main llvmruby branch.  We are now officially using LLVM 2.4, compatible with Ruby 1.9 and more complete access to the LLVM API.</p>
<p>I recently became aware of a project by <a href="http://macournoyer.com">Marc-André Cournoyer</a> using llvmruby to make a compiler for a little Ruby-ish language called <a href="http://macournoyer.com/blog/2008/12/09/orange/">Orange</a>.</p>
<p><a href="http://d.hatena.ne.jp/miura1729/">Miura Hideki</a> has been making some great progress with his <a href="http://github.com/miura1729/yarv2llvm/tree/master">yarv2llvm project</a>.  He&#8217;s been compiling much more complex stuff and doing some really nice profiling work.  I finally got to try it out for myself and it has a few issues running on 64-bit, so I plan on sending some fixes back his way.</p>
]]></content:encoded>
			<wfw:commentRss>http://llvmruby.org/wordpress-llvmruby/?feed=rss2&amp;p=31</wfw:commentRss>
		</item>
		<item>
		<title>llvmruby now available in gem format</title>
		<link>http://llvmruby.org/wordpress-llvmruby/?p=29</link>
		<comments>http://llvmruby.org/wordpress-llvmruby/?p=29#comments</comments>
		<pubDate>Sun, 19 Oct 2008 00:34:16 +0000</pubDate>
		<dc:creator>tom</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llvmruby.org/wordpress-llvmruby/?p=29</guid>
		<description><![CDATA[Thanks to Christian Plessl getting gemification started, llvmruby is now available as a gem install from github.  LLVM itself is still a separate install and build.  This will probably remain true as LLVM is huge and takes forever to compile.  Including it with every version of a gem seems ridiculous.  The [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks to Christian Plessl getting gemification started, llvmruby is now available as a gem install from github.  LLVM itself is still a separate install and build.  This will probably remain true as LLVM is huge and takes forever to compile.  Including it with every version of a gem seems ridiculous.  The other good news is that LLVM 2.4 is due out at the end of the month at which point we will be targeting a real non-development version!</p>
<p>To install as a gem, you need to be able to <a href="http://gems.github.com">install gems from github</a>.</p>
<ol>
<li>Upgrade to at least 1.2 of rubygems</li>
<li>Add github as a gem source: gem source -a http://gems.github.com</li>
<li>Make sure that you have built LLVM, that you built it with &#8211;enable-pic, and that llvm-config is in your path</li>
<li>gem install tombagby-llvmruby</li>
</ol>
<p>Now just:</p>
<pre><span class="ident">require</span> <span class="punct">'</span><span class="string">rubygems</span><span class="punct">'</span>
<span class="ident">require</span> <span class="punct">'</span><span class="string">llvm</span><span class="punct">'</span></pre>
<p>And you are good to go!</p>
]]></content:encoded>
			<wfw:commentRss>http://llvmruby.org/wordpress-llvmruby/?feed=rss2&amp;p=29</wfw:commentRss>
		</item>
		<item>
		<title>recent developments</title>
		<link>http://llvmruby.org/wordpress-llvmruby/?p=27</link>
		<comments>http://llvmruby.org/wordpress-llvmruby/?p=27#comments</comments>
		<pubDate>Tue, 14 Oct 2008 02:22:29 +0000</pubDate>
		<dc:creator>tom</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llvmruby.org/wordpress-llvmruby/?p=27</guid>
		<description><![CDATA[I&#8217;ve been busy with my day job and not so busy on llvmruby.  I got more interested in writing a static compiler for a type-inferred subset of Ruby ala RPython than in the YARV/JIT work I was doing so got a little distracted.  Fortunately, open-source software lets others move in and pick up [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been busy with my day job and not so busy on llvmruby.  I got more interested in writing a static compiler for a type-inferred subset of Ruby ala RPython than in the YARV/JIT work I was doing so got a little distracted.  Fortunately, open-source software lets others move in and pick up the slack and today I noticed <a href="http://github.com/miura1729/yarv2llvm/tree/master">a new yarv2llvm project on github</a> which looks like it&#8217;s already yielded <a href="http://d.hatena.ne.jp/miura1729/20081012/1223785541">some interesting results</a>. </p>
<p>As far as development on llvmruby itself, I added more complete floating point and casting support in response to some requests from Christoffer Lernö who was also kind enough to write some <a href="http://github.com/tombagby/llvmruby/wikis/api-documentation">preliminary documentation</a>.  I also received some nice patches from Christian Plessl and Marc-Andre Cournoyer.  It&#8217;s very satisfying to see that kind of support from the community.</p>
<p>I wish it was easier to communicate with the Japanese side of the Ruby community as I&#8217;ve noticed some interesting things <a href="http://d.hatena.ne.jp/miura1729/20080922/1222080204">like this (seemingly successful) effort to get llvmruby to work on Windows under Cygwin</a>.  Time to try contacting and crossing the language barrier I guess.</p>
]]></content:encoded>
			<wfw:commentRss>http://llvmruby.org/wordpress-llvmruby/?feed=rss2&amp;p=27</wfw:commentRss>
		</item>
		<item>
		<title>compiling a standalone binary</title>
		<link>http://llvmruby.org/wordpress-llvmruby/?p=23</link>
		<comments>http://llvmruby.org/wordpress-llvmruby/?p=23#comments</comments>
		<pubDate>Sat, 06 Sep 2008 23:36:46 +0000</pubDate>
		<dc:creator>tom</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llvmruby.org/wordpress-llvmruby/?p=23</guid>
		<description><![CDATA[I added support for function types with variable arguments thus allowing us to call printf as an external function.  This is very important as it allows us to tell the world how much we like grapes.  Here is how you would compile a standalone executable that states your feelings about grapes:
require 'llvm'
include LLVM

m [...]]]></description>
			<content:encoded><![CDATA[<p>I added support for function types with variable arguments thus allowing us to call printf as an external function.  This is very important as it allows us to tell the world how much we like grapes.  Here is how you would compile a standalone executable that states your feelings about grapes:</p>
<pre><span class="ident">require</span> <span class="punct">'</span><span class="string">llvm</span><span class="punct">'</span>
<span class="ident">include</span> <span class="constant">LLVM</span>

<span class="ident">m</span> <span class="punct">=</span> <span class="constant">LLVM</span><span class="punct">::</span><span class="constant">Module</span><span class="punct">.</span><span class="ident">new</span><span class="punct">('</span><span class="string">grapes</span><span class="punct">')</span>
<span class="constant">ExecutionEngine</span><span class="punct">.</span><span class="ident">get</span><span class="punct">(</span><span class="ident">m</span><span class="punct">)</span>

<span class="ident">char_star</span> <span class="punct">=</span> <span class="constant">Type</span><span class="punct">.</span><span class="ident">pointer</span><span class="punct">(</span><span class="constant">Type</span><span class="punct">::</span><span class="constant">Int8Ty</span><span class="punct">)</span>
<span class="ident">main_type</span> <span class="punct">=</span> <span class="constant">Type</span><span class="punct">.</span><span class="ident">function</span><span class="punct">(</span><span class="constant">Type</span><span class="punct">::</span><span class="constant">Int32Ty</span><span class="punct">,</span> <span class="punct">[</span>
  <span class="constant">Type</span><span class="punct">::</span><span class="constant">Int32Ty</span><span class="punct">,</span>
  <span class="constant">Type</span><span class="punct">.</span><span class="ident">pointer</span><span class="punct">(</span><span class="ident">char_star</span><span class="punct">)</span>
<span class="punct">])</span>

<span class="ident">ftype</span> <span class="punct">=</span> <span class="constant">Type</span><span class="punct">.</span><span class="ident">function</span><span class="punct">(</span><span class="constant">Type</span><span class="punct">::</span><span class="constant">Int32Ty</span><span class="punct">,</span> <span class="punct">[</span><span class="ident">char_star</span><span class="punct">],</span> <span class="constant">true</span><span class="punct">)</span>
<span class="ident">printf</span> <span class="punct">=</span> <span class="ident">m</span><span class="punct">.</span><span class="ident">external_function</span><span class="punct">('</span><span class="string">printf</span><span class="punct">',</span> <span class="ident">ftype</span><span class="punct">)</span>

<span class="ident">main</span> <span class="punct">=</span> <span class="ident">m</span><span class="punct">.</span><span class="ident">get_or_insert_function</span><span class="punct">('</span><span class="string">main</span><span class="punct">',</span> <span class="ident">main_type</span><span class="punct">)</span>
<span class="ident">b</span> <span class="punct">=</span> <span class="ident">main</span><span class="punct">.</span><span class="ident">create_block</span><span class="punct">.</span><span class="ident">builder</span>
<span class="ident">grapes_str</span> <span class="punct">=</span> <span class="ident">b</span><span class="punct">.</span><span class="ident">create_global_string_ptr</span><span class="punct">(&quot;</span><span class="string">I LIKE GRAPES!<span class="escape">\n</span></span><span class="punct">&quot;)</span>
<span class="ident">b</span><span class="punct">.</span><span class="ident">call</span><span class="punct">(</span><span class="ident">printf</span><span class="punct">,</span> <span class="ident">grapes_str</span><span class="punct">)</span>
<span class="ident">b</span><span class="punct">.</span><span class="ident">return</span><span class="punct">(</span><span class="number">0</span><span class="punct">.</span><span class="ident">llvm</span><span class="punct">(</span><span class="constant">Type</span><span class="punct">::</span><span class="constant">Int32Ty</span><span class="punct">))</span>

<span class="ident">puts</span> <span class="ident">m</span><span class="punct">.</span><span class="ident">inspect</span>
<span class="ident">m</span><span class="punct">.</span><span class="ident">write_bitcode</span><span class="punct">(&quot;</span><span class="string">main.o</span><span class="punct">&quot;)</span>
</pre>
<p>What happens when you run this program?  First, you will see the resulting llvm code on the console:</p>
<pre><span class="punct">;</span> <span class="constant">ModuleID</span> <span class="punct">=</span> <span class="punct">'</span><span class="string">grapes</span><span class="punct">'</span>
<span class="ident">internal</span> <span class="ident">constant</span> <span class="punct">[</span><span class="number">16</span> <span class="ident">x</span> <span class="ident">i8</span><span class="punct">]</span> <span class="ident">c</span><span class="punct">&quot;</span><span class="string">I LIKE GRAPES!<span class="escape">\0</span>A<span class="escape">\00</span></span><span class="punct">&quot;</span>             <span class="punct">;</span> <span class="punct">&lt;[</span><span class="number">16</span> <span class="ident">x</span> <span class="ident">i8</span><span class="punct">]*&gt;:</span><span class="number">0</span> <span class="punct">[</span><span class="comment">#uses=1]</span>

<span class="ident">declare</span> <span class="ident">void</span> <span class="attribute">@abort</span><span class="punct">()</span>

<span class="ident">declare</span> <span class="ident">i32</span> <span class="attribute">@printf</span><span class="punct">(</span><span class="ident">i8</span><span class="punct">*,</span> <span class="punct">...)</span>

<span class="ident">define</span> <span class="ident">i32</span> <span class="attribute">@main</span><span class="punct">(</span><span class="ident">i32</span><span class="punct">,</span> <span class="ident">i8</span><span class="punct">**)</span> <span class="punct">{</span>
<span class="ident">bb</span><span class="punct">:</span>
        <span class="ident">call</span> <span class="ident">i32</span> <span class="punct">(</span><span class="ident">i8</span><span class="punct">*,</span> <span class="punct">...)*</span> <span class="attribute">@printf</span><span class="punct">(</span> <span class="ident">i8</span><span class="punct">*</span> <span class="ident">getelementptr</span> <span class="punct">([</span><span class="number">16</span> <span class="ident">x</span> <span class="ident">i8</span><span class="punct">]*</span> <span class="attribute">@0</span><span class="punct">,</span> <span class="ident">i32</span> <span class="number">0</span><span class="punct">,</span> <span class="ident">i32</span> <span class="number">0</span><span class="punct">)</span> <span class="punct">)</span>         <span class="punct">;</span> <span class="punct">&lt;</span><span class="ident">i32</span><span class="punct">&gt;:</span><span class="number">2</span> <span class="punct">[</span><span class="comment">#uses=0]</span>
        <span class="ident">ret</span> <span class="ident">i32</span> <span class="number">0</span>
<span class="punct">}</span>
</pre>
<p>This all got turned into bitcode and saved in the file &#8220;main.o&#8221;.  Now all you have to do is link it with the command:
<pre>llvm-ld --native main.o</pre>
<p>Now you have a lovely a.out file which is a little native binary bursting with grape love:</p>
<pre>$ ./a.out
I LIKE GRAPES!</pre>
]]></content:encoded>
			<wfw:commentRss>http://llvmruby.org/wordpress-llvmruby/?feed=rss2&amp;p=23</wfw:commentRss>
		</item>
		<item>
		<title>writing a YARVish bytecode compiler in ruby</title>
		<link>http://llvmruby.org/wordpress-llvmruby/?p=21</link>
		<comments>http://llvmruby.org/wordpress-llvmruby/?p=21#comments</comments>
		<pubDate>Sun, 31 Aug 2008 22:50:17 +0000</pubDate>
		<dc:creator>tom</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llvmruby.org/wordpress-llvmruby/?p=21</guid>
		<description><![CDATA[Since llvmruby let&#8217;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 [...]]]></description>
			<content:encoded><![CDATA[<p>Since llvmruby let&#8217;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 <a href="http://pluskid.lifegoo.com/upload/doc/yarv/yarv_iset.html">the YARV instruction set</a> 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:</p>
<pre><span class="keyword">if</span> <span class="punct">(</span><span class="constant">FIXNUM_2_P</span><span class="punct">(</span><span class="ident">recv</span><span class="punct">,</span> <span class="ident">obj</span><span class="punct">)</span> <span class="punct">&amp;&amp;</span>
	<span class="constant">BASIC_OP_UNREDEFINED_P</span><span class="punct">(</span><span class="constant">BOP_LT</span><span class="punct">))</span> <span class="punct">{</span>
	<span class="ident">long</span> <span class="ident">a</span> <span class="punct">=</span> <span class="constant">FIX2LONG</span><span class="punct">(</span><span class="ident">recv</span><span class="punct">),</span> <span class="ident">b</span> <span class="punct">=</span> <span class="constant">FIX2LONG</span><span class="punct">(</span><span class="ident">obj</span><span class="punct">);</span>

	<span class="keyword">if</span> <span class="punct">(</span><span class="ident">a</span> <span class="punct">&lt;</span> <span class="ident">b</span><span class="punct">)</span> <span class="punct">{</span>
	    <span class="ident">val</span> <span class="punct">=</span> <span class="constant">Qtrue</span><span class="punct">;</span>
	<span class="punct">}</span>
	<span class="keyword">else</span> <span class="punct">{</span>
	    <span class="ident">val</span> <span class="punct">=</span> <span class="constant">Qfalse</span><span class="punct">;</span>
	<span class="punct">}</span>
    <span class="punct">}</span>
    <span class="keyword">else</span> <span class="punct">{</span>
	<span class="constant">PUSH</span><span class="punct">(</span><span class="ident">recv</span><span class="punct">);</span>
	<span class="constant">PUSH</span><span class="punct">(</span><span class="ident">obj</span><span class="punct">);</span>
	<span class="constant">CALL_SIMPLE_METHOD</span><span class="punct">(</span><span class="number">1</span><span class="punct">,</span> <span class="ident">idLT</span><span class="punct">,</span> <span class="ident">recv</span><span class="punct">);</span>
    <span class="punct">}</span>
</pre>
<p>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:</p>
<pre><span class="keyword">when</span> <span class="symbol">:opt_lt</span>
        <span class="ident">obj</span> <span class="punct">=</span> <span class="ident">b</span><span class="punct">.</span><span class="ident">pop</span>
        <span class="ident">recv</span> <span class="punct">=</span> <span class="ident">b</span><span class="punct">.</span><span class="ident">pop</span>
        <span class="ident">x</span> <span class="punct">=</span> <span class="ident">b</span><span class="punct">.</span><span class="ident">fix2int</span><span class="punct">(</span><span class="ident">recv</span><span class="punct">)</span>
        <span class="ident">y</span> <span class="punct">=</span> <span class="ident">b</span><span class="punct">.</span><span class="ident">fix2int</span><span class="punct">(</span><span class="ident">obj</span><span class="punct">)</span>
        <span class="ident">val</span> <span class="punct">=</span> <span class="ident">b</span><span class="punct">.</span><span class="ident">icmp_sle</span><span class="punct">(</span><span class="ident">x</span><span class="punct">,</span> <span class="ident">y</span><span class="punct">)</span>
        <span class="ident">val</span> <span class="punct">=</span> <span class="ident">b</span><span class="punct">.</span><span class="ident">int_cast</span><span class="punct">(</span><span class="ident">val</span><span class="punct">,</span> <span class="constant">LONG</span><span class="punct">,</span> <span class="constant">false</span><span class="punct">)</span>
        <span class="ident">val</span> <span class="punct">=</span> <span class="ident">b</span><span class="punct">.</span><span class="ident">mul</span><span class="punct">(</span><span class="ident">val</span><span class="punct">,</span> <span class="number">2</span><span class="punct">.</span><span class="ident">llvm</span><span class="punct">)</span>
        <span class="ident">b</span><span class="punct">.</span><span class="ident">push</span><span class="punct">(</span><span class="ident">val</span><span class="punct">)</span></pre>
<p>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.</p>
<p>I&#8217;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:</p>
<pre><span class="ident">bytecode</span> <span class="punct">=</span> <span class="punct">[</span>
      <span class="punct">[</span><span class="symbol">:newarray</span><span class="punct">],</span>
      <span class="punct">[</span><span class="symbol">:dup</span><span class="punct">],</span>
      <span class="punct">[</span><span class="symbol">:putobject</span><span class="punct">,</span> <span class="constant">LLVM</span><span class="punct">::</span><span class="constant">Value</span><span class="punct">.</span><span class="ident">get_immediate_constant</span><span class="punct">(</span><span class="number">0</span><span class="punct">)],</span>
      <span class="punct">[</span><span class="symbol">:putobject</span><span class="punct">,</span> <span class="constant">LLVM</span><span class="punct">::</span><span class="constant">Value</span><span class="punct">.</span><span class="ident">get_immediate_constant</span><span class="punct">('</span><span class="string">shaka</span><span class="punct">')],</span>
      <span class="punct">[</span><span class="symbol">:opt_aset</span><span class="punct">],</span>
      <span class="punct">[</span><span class="symbol">:pop</span><span class="punct">]</span>
    <span class="punct">]</span></pre>
<p>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.</p>
]]></content:encoded>
			<wfw:commentRss>http://llvmruby.org/wordpress-llvmruby/?feed=rss2&amp;p=21</wfw:commentRss>
		</item>
		<item>
		<title>support for 32-bit and 64-bit ruby interpreters</title>
		<link>http://llvmruby.org/wordpress-llvmruby/?p=17</link>
		<comments>http://llvmruby.org/wordpress-llvmruby/?p=17#comments</comments>
		<pubDate>Wed, 27 Aug 2008 05:30:51 +0000</pubDate>
		<dc:creator>tom</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llvmruby.org/wordpress-llvmruby/?p=17</guid>
		<description><![CDATA[Tonight, I implemented and tested support for 32-bit Ruby.  How does this work? 
  // Figure out details of the target machine
  const IntegerType *machine_word_type;
  if(sizeof(void*) == 4) {
    machine_word_type = Type::Int32Ty;
  } else {
    machine_word_type = Type::Int64Ty;
  }
  rb_define_const(cLLVMRuby, &#34;MACHINE_WORD&#34;, Data_Wrap_Struct(cLLVMType, [...]]]></description>
			<content:encoded><![CDATA[<p>Tonight, I implemented and tested support for 32-bit Ruby.  How does this work? </p>
<pre>  <span class="punct">/</span><span class="regex"></span><span class="punct">/</span> <span class="ident">Figure</span> <span class="ident">out</span> <span class="ident">details</span> <span class="ident">of</span> <span class="ident">the</span> <span class="ident">target</span> <span class="ident">machine</span>
  <span class="ident">const</span> <span class="constant">IntegerType</span> <span class="punct">*</span><span class="ident">machine_word_type</span><span class="punct">;</span>
  <span class="keyword">if</span><span class="punct">(</span><span class="ident">sizeof</span><span class="punct">(</span><span class="ident">void</span><span class="punct">*)</span> <span class="punct">==</span> <span class="number">4</span><span class="punct">)</span> <span class="punct">{</span>
    <span class="ident">machine_word_type</span> <span class="punct">=</span> <span class="constant">Type</span><span class="punct">::</span><span class="constant">Int32Ty</span><span class="punct">;</span>
  <span class="punct">}</span> <span class="keyword">else</span> <span class="punct">{</span>
    <span class="ident">machine_word_type</span> <span class="punct">=</span> <span class="constant">Type</span><span class="punct">::</span><span class="constant">Int64Ty</span><span class="punct">;</span>
  <span class="punct">}</span>
  <span class="ident">rb_define_const</span><span class="punct">(</span><span class="ident">cLLVMRuby</span><span class="punct">,</span> <span class="punct">&quot;</span><span class="string">MACHINE_WORD</span><span class="punct">&quot;,</span> <span class="constant">Data_Wrap_Struct</span><span class="punct">(</span><span class="ident">cLLVMType</span><span class="punct">,</span> <span class="constant">NULL</span><span class="punct">,</span> <span class="constant">NULL</span><span class="punct">,</span> <span class="ident">const_cast</span><span class="punct">&lt;</span><span class="constant">IntegerType</span><span class="punct">*&gt;(</span><span class="ident">machine_word_type</span><span class="punct">)));</span></pre>
<p>First the extension creates a MACHINE_WORD type based on the pointer size of the machine.</p>
<pre>  <span class="comment"># describe structures used by the ruby 1.8/1.9 interpreters</span>
  <span class="keyword">module </span><span class="module">RubyInternals</span>
    <span class="constant">FIXNUM_FLAG</span> <span class="punct">=</span> <span class="number">0x1</span><span class="punct">.</span><span class="ident">llvm</span>
    <span class="constant">CHAR</span> <span class="punct">=</span> <span class="constant">Type</span><span class="punct">::</span><span class="constant">Int8Ty</span>
    <span class="constant">P_CHAR</span> <span class="punct">=</span> <span class="constant">Type</span><span class="punct">::</span><span class="ident">pointer</span><span class="punct">(</span><span class="constant">CHAR</span><span class="punct">)</span>
    <span class="constant">LONG</span> <span class="punct">=</span> <span class="constant">MACHINE_WORD</span>
    <span class="constant">VALUE</span> <span class="punct">=</span> <span class="constant">MACHINE_WORD</span>
    <span class="constant">P_VALUE</span> <span class="punct">=</span> <span class="constant">Type</span><span class="punct">::</span><span class="ident">pointer</span><span class="punct">(</span><span class="constant">VALUE</span><span class="punct">)</span>
    <span class="constant">ID</span> <span class="punct">=</span> <span class="constant">MACHINE_WORD</span>
    <span class="constant">RBASIC</span> <span class="punct">=</span> <span class="constant">Type</span><span class="punct">::</span><span class="ident">struct</span><span class="punct">([</span><span class="constant">VALUE</span><span class="punct">,</span> <span class="constant">VALUE</span><span class="punct">])</span>
    <span class="constant">RARRAY</span> <span class="punct">=</span> <span class="constant">Type</span><span class="punct">::</span><span class="ident">struct</span><span class="punct">([</span><span class="constant">RBASIC</span><span class="punct">,</span> <span class="constant">LONG</span><span class="punct">,</span> <span class="constant">LONG</span><span class="punct">,</span> <span class="constant">P_VALUE</span><span class="punct">])</span>
    <span class="constant">P_RARRAY</span> <span class="punct">=</span> <span class="constant">Type</span><span class="punct">::</span><span class="ident">pointer</span><span class="punct">(</span><span class="constant">RARRAY</span><span class="punct">)</span>
    <span class="constant">RSTRING</span> <span class="punct">=</span> <span class="constant">Type</span><span class="punct">::</span><span class="ident">struct</span><span class="punct">([</span><span class="constant">RBASIC</span><span class="punct">,</span> <span class="constant">LONG</span><span class="punct">,</span> <span class="constant">P_CHAR</span><span class="punct">,</span> <span class="constant">VALUE</span><span class="punct">])</span>
    <span class="constant">P_RSTRING</span> <span class="punct">=</span> <span class="constant">Type</span><span class="punct">::</span><span class="ident">pointer</span><span class="punct">(</span><span class="constant">RSTRING</span><span class="punct">)</span>
  <span class="keyword">end</span>
</pre>
<p>All the Ruby data types are defined in the RubyInternals module.</p>
<p>If you are familiar with Ruby internals from having worked on C extensions, you will know that everything is a VALUE, which is one machine word that is either nil, true, false, a FixInt, or a pointer to a struct somewhere on the heap.  This makes our definitions pretty simple, all that changes between machines is the size of this pointer.</p>
<p>You&#8217;ll also notice in this code, that the native Ruby data types themselves are defined in Ruby code here.  For example, an Array in Ruby is represented internally using this struct:</p>
<pre><span class="ident">struct</span> <span class="constant">RArray</span> <span class="punct">{</span>
    <span class="ident">struct</span> <span class="constant">RBasic</span> <span class="ident">basic</span><span class="punct">;</span>
    <span class="ident">long</span> <span class="ident">len</span><span class="punct">;</span>
    <span class="ident">union</span> <span class="punct">{</span>
        <span class="ident">long</span> <span class="ident">capa</span><span class="punct">;</span>
        <span class="constant">VALUE</span> <span class="ident">shared</span><span class="punct">;</span>
    <span class="punct">}</span> <span class="ident">aux</span><span class="punct">;</span>
    <span class="constant">VALUE</span> <span class="punct">*</span><span class="ident">ptr</span><span class="punct">;</span>
<span class="punct">};</span>
</pre>
<p>And in our Ruby mappings that allows us to work on this structure, it&#8217;s defined basically the same way using LLVM data types:</p>
<pre><span class="constant">RARRAY</span> <span class="punct">=</span> <span class="constant">Type</span><span class="punct">::</span><span class="ident">struct</span><span class="punct">([</span><span class="constant">RBASIC</span><span class="punct">,</span> <span class="constant">LONG</span><span class="punct">,</span> <span class="constant">LONG</span><span class="punct">,</span> <span class="constant">P_VALUE</span><span class="punct">])</span></pre>
<p>Easy!</p>
]]></content:encoded>
			<wfw:commentRss>http://llvmruby.org/wordpress-llvmruby/?feed=rss2&amp;p=17</wfw:commentRss>
		</item>
		<item>
		<title>what does llvmruby look like?</title>
		<link>http://llvmruby.org/wordpress-llvmruby/?p=9</link>
		<comments>http://llvmruby.org/wordpress-llvmruby/?p=9#comments</comments>
		<pubDate>Tue, 26 Aug 2008 02:24:51 +0000</pubDate>
		<dc:creator>tom</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llvmruby.org/wordpress-llvmruby/?p=9</guid>
		<description><![CDATA[LLVMRuby is a pretty straighforward wrapper around the C++ API for generating LLVM bytecode and JIT compilation.  The LLVM API is both very well designed and very object oriented and so maps pretty straightforwardly into Ruby.  Here is a simple example of using LLVMRuby to construct and JIT compile a function which manipulates [...]]]></description>
			<content:encoded><![CDATA[<p>LLVMRuby is a pretty straighforward wrapper around the C++ API for generating LLVM bytecode and JIT compilation.  The LLVM API is both very well designed and very object oriented and so maps pretty straightforwardly into Ruby.  Here is a simple example of using LLVMRuby to construct and JIT compile a function which manipulates native Ruby objects.</p>
<pre><span class="ident">require</span> <span class="punct">'</span><span class="string">llvm</span><span class="punct">'</span>
<span class="ident">include</span> <span class="constant">LLVM</span>
<span class="ident">include</span> <span class="constant">RubyInternals</span>

<span class="keyword">class </span><span class="class">Builder</span>
  <span class="ident">include</span> <span class="constant">RubyHelpers</span>
<span class="keyword">end</span>

<span class="ident">m</span> <span class="punct">=</span> <span class="constant">LLVM</span><span class="punct">::</span><span class="constant">Module</span><span class="punct">.</span><span class="ident">new</span><span class="punct">('</span><span class="string">ruby_bindings_examples</span><span class="punct">')</span>
<span class="constant">ExecutionEngine</span><span class="punct">.</span><span class="ident">get</span><span class="punct">(</span><span class="ident">m</span><span class="punct">)</span>

<span class="keyword">def </span><span class="method">ftype</span><span class="punct">(</span><span class="ident">ret_type</span><span class="punct">,</span> <span class="ident">arg_types</span><span class="punct">)</span>
  <span class="constant">Type</span><span class="punct">.</span><span class="ident">function</span><span class="punct">(</span><span class="ident">ret_type</span><span class="punct">,</span> <span class="ident">arg_types</span><span class="punct">)</span>
<span class="keyword">end</span>

<span class="ident">rb_ary_new</span> <span class="punct">=</span> <span class="ident">m</span><span class="punct">.</span><span class="ident">external_function</span><span class="punct">('</span><span class="string">rb_ary_new</span><span class="punct">',</span> <span class="ident">ftype</span><span class="punct">(</span><span class="constant">VALUE</span><span class="punct">,</span> <span class="punct">[]))</span>
<span class="ident">rb_to_id</span> <span class="punct">=</span> <span class="ident">m</span><span class="punct">.</span><span class="ident">external_function</span><span class="punct">('</span><span class="string">rb_to_id</span><span class="punct">',</span> <span class="ident">ftype</span><span class="punct">(</span><span class="constant">VALUE</span><span class="punct">,</span> <span class="punct">[</span><span class="constant">VALUE</span><span class="punct">]))</span>
<span class="ident">rb_ivar_get</span> <span class="punct">=</span> <span class="ident">m</span><span class="punct">.</span><span class="ident">external_function</span><span class="punct">('</span><span class="string">rb_ivar_get</span><span class="punct">',</span> <span class="ident">ftype</span><span class="punct">(</span><span class="constant">VALUE</span><span class="punct">,</span> <span class="punct">[</span><span class="constant">VALUE</span><span class="punct">,</span> <span class="constant">ID</span><span class="punct">]))</span>
<span class="ident">rb_ivar_set</span> <span class="punct">=</span> <span class="ident">m</span><span class="punct">.</span><span class="ident">external_function</span><span class="punct">('</span><span class="string">rb_ivar_set</span><span class="punct">',</span> <span class="ident">ftype</span><span class="punct">(</span><span class="constant">VALUE</span><span class="punct">,</span> <span class="punct">[</span><span class="constant">VALUE</span><span class="punct">,</span> <span class="constant">ID</span><span class="punct">,</span> <span class="constant">VALUE</span><span class="punct">]))</span>

<span class="keyword">class </span><span class="class">TestClass</span>
  <span class="keyword">def </span><span class="method">initialize</span>
    <span class="attribute">@shaka</span> <span class="punct">=</span> <span class="punct">'</span><span class="string">khan</span><span class="punct">'</span>
  <span class="keyword">end</span>
<span class="keyword">end</span>

<span class="ident">test_instance</span> <span class="punct">=</span> <span class="constant">TestClass</span><span class="punct">.</span><span class="ident">new</span>

<span class="comment"># take an object and an instance variable symbol, return value of instance variable</span>
<span class="ident">type</span> <span class="punct">=</span> <span class="constant">Type</span><span class="punct">.</span><span class="ident">function</span><span class="punct">(</span><span class="constant">VALUE</span><span class="punct">,</span> <span class="punct">[</span><span class="constant">VALUE</span><span class="punct">,</span> <span class="constant">VALUE</span><span class="punct">])</span>
<span class="ident">f</span> <span class="punct">=</span> <span class="ident">m</span><span class="punct">.</span><span class="ident">get_or_insert_function</span><span class="punct">('</span><span class="string">shakula</span><span class="punct">',</span> <span class="ident">type</span><span class="punct">)</span>
<span class="ident">obj</span><span class="punct">,</span> <span class="ident">ivar_sym</span> <span class="punct">=</span> <span class="ident">f</span><span class="punct">.</span><span class="ident">arguments</span>
<span class="ident">b</span> <span class="punct">=</span> <span class="ident">f</span><span class="punct">.</span><span class="ident">create_block</span><span class="punct">.</span><span class="ident">builder</span>
<span class="ident">new_ary</span> <span class="punct">=</span> <span class="ident">b</span><span class="punct">.</span><span class="ident">call</span><span class="punct">(</span><span class="ident">rb_ary_new</span><span class="punct">)</span>
<span class="ident">ivar_id</span> <span class="punct">=</span> <span class="ident">b</span><span class="punct">.</span><span class="ident">call</span><span class="punct">(</span><span class="ident">rb_to_id</span><span class="punct">,</span> <span class="ident">ivar_sym</span><span class="punct">)</span>
<span class="ident">ret_val</span> <span class="punct">=</span> <span class="ident">b</span><span class="punct">.</span><span class="ident">call</span><span class="punct">(</span><span class="ident">rb_ivar_get</span><span class="punct">,</span> <span class="ident">obj</span><span class="punct">,</span> <span class="ident">ivar_id</span><span class="punct">)</span>
<span class="ident">b</span><span class="punct">.</span><span class="ident">return</span><span class="punct">(</span><span class="ident">ret_val</span><span class="punct">)</span>
<span class="ident">ret</span> <span class="punct">=</span> <span class="constant">ExecutionEngine</span><span class="punct">.</span><span class="ident">run_function</span><span class="punct">(</span><span class="ident">f</span><span class="punct">,</span> <span class="ident">test_instance</span><span class="punct">,</span> <span class="symbol">:@shaka</span><span class="punct">)</span>
<span class="ident">puts</span> <span class="punct">&quot;</span><span class="string">get instance variable @shaka: <span class="expr">#{ret.inspect}</span></span><span class="punct">&quot;</span>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://llvmruby.org/wordpress-llvmruby/?feed=rss2&amp;p=9</wfw:commentRss>
		</item>
		<item>
		<title>llvmruby is fun</title>
		<link>http://llvmruby.org/wordpress-llvmruby/?p=1</link>
		<comments>http://llvmruby.org/wordpress-llvmruby/?p=1#comments</comments>
		<pubDate>Mon, 25 Aug 2008 05:40:49 +0000</pubDate>
		<dc:creator>tom</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://worldofbryan.com/wordpress-llvmruby/?p=1</guid>
		<description><![CDATA[I recently wrote an extension for Ruby which allows to use the LLVM compiler infrastructure from inside the Ruby interpreter.  While still in development, it already supports enough of the LLVM API to write interesting programs.  I have gotten the library to the point that it is able to interact in interesting ways [...]]]></description>
			<content:encoded><![CDATA[<p>I recently wrote an extension for Ruby which allows to use the <a href="http://llvm.org">LLVM compiler infrastructure</a> from inside the Ruby interpreter.  While still in development, it already supports enough of the LLVM API to write interesting programs.  I have gotten the library to the point that it is able to interact in interesting ways with the native internals of the interpreter, meaning that it is possible to create the equivalent of C Ruby extensions from within Ruby itself and just-in-time (JIT) compile them.</p>
<p>I think you will agree that generating abstract assembler with Ruby is much more fun than generating it from C++.</p>
<p>The project now lives on git hub: <a href="http://github.com/tombagby/llvmruby/tree/master">http://github.com/tombagby/llvmruby</a></p>
<p>I have developed/used it only on my home computer, which is 64bit Linux machine.  I imagine that it errors hilariously on 32bit machines.  It does, however, have nice extconf and should build in a nice/standard way.  I am very interested to hear of your build problems with it on different platforms such that I can fix it!</p>
<p>Share and enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://llvmruby.org/wordpress-llvmruby/?feed=rss2&amp;p=1</wfw:commentRss>
		</item>
	</channel>
</rss>
