Title: [927] trunk: Add java_inline library to jruby_extras.
Revision
927
Author
headius
Date
2008-03-07 12:13:45 -0500 (Fri, 07 Mar 2008)

Log Message

Add java_inline library to jruby_extras.

Added Paths


Diff

Added: trunk/java_inline/lib/java_inline.rb (0 => 927)


--- trunk/java_inline/lib/java_inline.rb	                        (rev 0)
+++ trunk/java_inline/lib/java_inline.rb	2008-03-07 17:13:45 UTC (rev 927)
@@ -0,0 +1,101 @@
+require 'inline'
+require 'java'
+
+# Add the inline cache dir to CLASSPATH
+$CLASSPATH << Inline.directory
+
+module Inline
+  
+  # A Java builder for RubyInline. Provides the basic methods needed to
+  # allow assembling a set of Java methods that compile into a class and
+  # get bound to the same names in the containing module.
+  class Java
+    JFile = java.io.File
+    import javax.tools.ToolProvider
+    import javax.tools.SimpleJavaFileObject
+    import javax.tools.StandardLocation
+
+    def initialize(mod)
+      @context = mod
+      @src = ""
+      @imports = []
+      @sigs = []
+    end
+    
+    def load_cache
+      false
+    end
+    
+    # Set the package to use for the Java class being generated, as in
+    # builder.package "org.foo.bar"
+    def package(pkg)
+      @pkg = pkg
+    end
+
+    # Add an "import" line with the given class, as in
+    # builder.import "java.util.ArrayList". The imports will be composed
+    # into an appropriate block of code and added to the top of the source.
+    def import(cls)
+      @imports << cls
+    end
+
+    # Add a Java method to the built Java source. This expects the method to
+    # be public and static, so it can be called as a function.
+    def java(src)
+      @src << src << "\n"
+      signature = src.match(/public static\W+(\w+)\W+([a-zA-Z0-9_]+)\((.*)\)/)
+      raise "Could not parse method signature" unless signature
+      @sigs << [signature[1], signature[2], signature[3]]
+    end
+
+    def build
+      compiler = ToolProvider.system_java_compiler
+      file_mgr = compiler.get_standard_file_manager(nil, nil, nil)
+      file_mgr.set_location(StandardLocation::CLASS_OUTPUT, [JFile.new(Inline.directory)])
+      
+      if @pkg
+        directory = "#{Inline.directory}/[EMAIL PROTECTED]('.', '/')}"
+        unless File.directory? directory then
+          $stderr.puts "NOTE: creating #{directory} for RubyInline" if $DEBUG
+          FileUtils.mkdir_p directory
+        end
+        
+        @name = "[EMAIL PROTECTED]"
+        @load_name = "[EMAIL PROTECTED]@name}"
+        filename = "#{directory}/[EMAIL PROTECTED]"
+      
+        imports = "import " + @imports.join(";\nimport ") + ";" if @imports.size > 0
+        full_src = "
+          package [EMAIL PROTECTED];
+          #{imports}
+          public class [EMAIL PROTECTED] {
+          [EMAIL PROTECTED]
+          }
+        "
+      else
+        @load_name = @name = "[EMAIL PROTECTED]"
+        filename = "#{Inline.directory}/[EMAIL PROTECTED]"
+      
+        imports = "import " + @imports.join(";\nimport ") + ";" if @imports.size > 0
+        full_src = "
+          #{imports}
+          public class [EMAIL PROTECTED] {
+          [EMAIL PROTECTED]
+          }
+        "
+      end
+      
+      File.open(filename, "w") {|file| file.write(full_src)}
+      file_objs = file_mgr.get_java_file_objects_from_strings([filename])
+      
+      compiler.get_task(nil, file_mgr, nil, nil, nil, file_objs).call
+      file_mgr.close
+    end
+
+    def load
+      @sigs.each do |sig|
+        @context.module_eval "const_set :[EMAIL PROTECTED], ::Java::[EMAIL PROTECTED]; p '[EMAIL PROTECTED]'; def #{sig[1]}(*args); [EMAIL PROTECTED](*args); end"
+      end
+    end
+  end
+end

Added: trunk/java_inline/samples/fastmath.rb (0 => 927)


--- trunk/java_inline/samples/fastmath.rb	                        (rev 0)
+++ trunk/java_inline/samples/fastmath.rb	2008-03-07 17:13:45 UTC (rev 927)
@@ -0,0 +1,56 @@
+require 'rubygems'
+require 'inline'
+require 'java_inline'
+require 'benchmark'
+
+class FastMath
+  def factorial_ruby(n)
+    f = 1
+    n.downto(2) { |x| f *= x }
+    return f
+  end
+
+  def fib_ruby(n)
+    if n < 2
+      n
+    else
+      fib_ruby(n - 2) + fib_ruby(n - 1)
+    end
+  end
+  
+  inline :Java do |builder|
+    builder.package "org.jruby.test"
+    builder.java "
+      public static long factorial_java(int max) {
+        int i=max, result=1;
+        while (i >= 2) { result *= i--; }
+        return result;
+      }
+      "
+
+    builder.java "
+      public static int fib_java(int n) {
+        if (n < 2) return n;
+
+        return fib_java(n - 2) + fib_java(n - 1); 
+      }
+      "
+  end
+
+  def bench
+    require 'benchmark'
+
+    Benchmark.bm(30) do |bm|
+    end
+  end
+end
+
+math = FastMath.new
+
+Benchmark.bmbm(30) {|bm|
+  5.times { bm.report("factorial_ruby") { 30000.times { math.factorial_ruby(30) } } }
+  5.times { bm.report("factorial_java") { 30000.times { math.factorial_java(30) } } }
+  5.times { bm.report("fib_ruby(35)") { math.fib_ruby(30) } }
+  5.times { bm.report("fib_java(35)") { math.fib_java(30) } }
+}
+
_______________________________________________
Jruby-extras-devel mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/jruby-extras-devel

Reply via email to