Guest

Untitled

By: a guest on Jan 28th, 2012  |  syntax: None  |  size: 0.97 KB  |  hits: 9  |  expires: Never
download  |  raw  |  embed  |  report abuse
Copied
  1. require 'wilson'
  2. require 'inline'
  3. require 'test/unit'
  4.  
  5. class Object
  6.   @@asm = {}
  7.   def asm(name, *args, &block)
  8.     code = @@asm[name] ||= assemble(&block).to_ptr
  9.  
  10.     return execute(code) # TODO: args
  11.   end
  12.  
  13.   inline(:C) do |b|
  14.     b.prefix "typedef long (*fn_ptr)();"
  15.     b.include '"dl.h"'
  16.     b.c "
  17.       VALUE execute(VALUE code) {
  18.         return ((fn_ptr)(RDLPTR(code)->ptr))();
  19.       }
  20.     "
  21.   end
  22. end
  23.  
  24. class Mockup
  25.   def example
  26.     n = 1000
  27.  
  28.     # the following asm block becomes the machine code:
  29.     #   5589E5B800000000403DE803000075F801C040C9C3
  30.  
  31.     asm :count_to_1000 do # TODO: need a better way to cache machine code
  32.       eax.mov 0
  33.       count = self.label
  34.       eax.inc
  35.       eax.cmp n
  36.       jne count
  37.  
  38.       to_ruby eax
  39.     end
  40.   end
  41. end
  42.  
  43. class TestMockup < Test::Unit::TestCase
  44.   def test_example
  45.     assert_equal 1000, Mockup.new.example
  46.   end
  47.  
  48.   def test_example_twice
  49.     assert_equal 1000, Mockup.new.example
  50.   end
  51. end