Skip to content

Commit

Permalink
use self hosted classloader fixes mirah#144
Browse files Browse the repository at this point in the history
add a self hosted class loader to work around JRuby 1.6.4's behavior
use a workaround for Java's String encoding behavior
  • Loading branch information
baroquebobcat committed Sep 13, 2011
1 parent a858a2f commit a5963ef
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 36 deletions.
Binary file modified javalib/mirah-bootstrap.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion lib/mirah/ast/intrinsics.rb
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ def compile_ast(name, ast, transformer)
compiler.generate do |outfile, builder|
bytes = builder.generate
name = builder.class_name.gsub(/\//, '.')
class_map[name] = bytes
class_map[name] = Mirah::Util::ClassLoader.binary_string bytes
if transformer.state.save_extensions
outfile = "#{transformer.destination}#{outfile}"
FileUtils.mkdir_p(File.dirname(outfile))
Expand Down
2 changes: 1 addition & 1 deletion lib/mirah/commands/run.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def execute
generator = Mirah::Generator.new(@state, @state.compiler_class, false, @state.verbose)

generator.generate(args).each do |result|
class_map[result.classname.gsub(/\//, '.')] = result.bytes
class_map[result.classname.gsub(/\//, '.')] = Mirah::Util::ClassLoader.binary_string result.bytes
end

# load all classes
Expand Down
38 changes: 5 additions & 33 deletions lib/mirah/util/class_loader.rb
Original file line number Diff line number Diff line change
@@ -1,37 +1,9 @@
# This is a custom classloader impl to allow loading classes with
# interdependencies by having findClass retrieve classes as needed from the
# collection of all classes generated by the target script.
module Mirah
module Util
class ClassLoader < java::security::SecureClassLoader
def initialize(parent, class_map)
super(parent)
@class_map = class_map
end

def findClass(name)
if @class_map[name]
bytes = @class_map[name].to_java_bytes
defineClass(name, bytes, 0, bytes.length)
else
raise java.lang.ClassNotFoundException.new(name)
end
end

def loadClass(name, resolve)
cls = findLoadedClass(name)
if cls == nil
if @class_map[name]
cls = findClass(name)
else
cls = super(name, false)
end
end

resolveClass(cls) if resolve

cls
end
end

ClassLoader = Java::OrgMirah::MirahClassLoader
def ClassLoader.binary_string string
java.lang.String.new string.to_java_bytes, "ISO-8859-1"
end
end
end
38 changes: 38 additions & 0 deletions src/org/mirah/class_loader.mirah
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# This is a custom classloader impl to allow loading classes with
# interdependencies by having findClass retrieve classes as needed from the
# collection of all classes generated by the target script.
import java.security.SecureClassLoader
import java.lang.ClassLoader
import java.util.Map
import java.nio.charset.Charset

class MirahClassLoader < SecureClassLoader
def initialize(parent:ClassLoader, class_map:Map)
super(parent)
@class_map = class_map
end

def findClass(name)
if @class_map[name]
bytes = String(@class_map[name]).getBytes "ISO-8859-1"
defineClass(name, bytes, 0, bytes.length)
else
raise ClassNotFoundException.new(name)
end
end

def loadClass(name, resolve)
cls = findLoadedClass(name)
if cls.nil?
if @class_map[name]
cls = findClass(name)
else
cls = super(name, false)
end
end

resolveClass(cls) if resolve

cls
end
end
2 changes: 1 addition & 1 deletion test/jvm/bytecode_test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def generate_classes compiler
open("#{filename}", "wb") do |f|
f << bytes
end
classes[filename[0..-7]] = bytes
classes[filename[0..-7]] = Mirah::Util::ClassLoader.binary_string bytes
end

loader = Mirah::Util::ClassLoader.new(JRuby.runtime.jruby_class_loader, classes)
Expand Down

0 comments on commit a5963ef

Please sign in to comment.