Created
January 17, 2011 23:19
-
-
Save headius/783686 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git a/src/org/jruby/RubyClass.java b/src/org/jruby/RubyClass.java | |
| index eeed0b2..1f6e2e6 100644 | |
| --- a/src/org/jruby/RubyClass.java | |
| +++ b/src/org/jruby/RubyClass.java | |
| @@ -385,6 +385,7 @@ public class RubyClass extends RubyModule { | |
| super(runtime, runtime.getClassClass(), objectSpace); | |
| this.runtime = runtime; | |
| setSuperClass(superClass); // this is the only case it might be null here (in MetaClass construction) | |
| + this.reifiable = superClass != null && (superClass == runtime.getObject() || superClass.isReifiable()); | |
| } | |
| /** used by CLASS_ALLOCATOR (any Class' class will be a Class!) | |
| @@ -394,6 +395,7 @@ public class RubyClass extends RubyModule { | |
| super(runtime, runtime.getClassClass()); | |
| this.runtime = runtime; | |
| index = ClassIndex.CLASS; | |
| + this.reifiable = false; | |
| } | |
| /** rb_class_boot (for plain Classes) | |
| @@ -1142,6 +1144,46 @@ public class RubyClass extends RubyModule { | |
| } | |
| }; | |
| + /** | |
| + * Whether this class can be reified into a Java class. Currently only objects | |
| + * that descend from Object (or Ruby-based classes that descend from Object) | |
| + * can be reified. | |
| + * | |
| + * @return true if the class can be reified, false otherwise | |
| + */ | |
| + public boolean isReifiable() { | |
| + return reifiable; | |
| + } | |
| + | |
| + /** | |
| + * Reify this class, first reifying all its ancestors. This causes the | |
| + * reified class and all ancestors' reified classes to come into existence, | |
| + * so any future changes will not be reflected. | |
| + */ | |
| + public void reifyWithAncestors() { | |
| + if (isReifiable()) { | |
| + getSuperClass().getRealClass().reifyWithAncestors(); | |
| + reify(); | |
| + } | |
| + } | |
| + | |
| + /** | |
| + * Reify this class, first reifying all its ancestors. This causes the | |
| + * reified class and all ancestors' reified classes to come into existence, | |
| + * so any future changes will not be reflected. | |
| + * | |
| + * This form also accepts a string argument indicating a path in which to dump | |
| + * the intermediate reified class bytes. | |
| + * | |
| + * @param classDumpDir the path in which to dump reified class bytes | |
| + */ | |
| + public void reifyWithAncestors(String classDumpDir) { | |
| + if (isReifiable()) { | |
| + getSuperClass().getRealClass().reifyWithAncestors(classDumpDir); | |
| + reify(classDumpDir); | |
| + } | |
| + } | |
| + | |
| public synchronized void reify() { | |
| reify(null); | |
| } | |
| @@ -1166,7 +1208,12 @@ public class RubyClass extends RubyModule { | |
| String javaName = "rubyobj." + name.replaceAll("::", "."); | |
| String javaPath = "rubyobj/" + name.replaceAll("::", "/"); | |
| OneShotClassLoader parentCL; | |
| - if (superClass.getRealClass().getReifiedClass().getClassLoader() instanceof OneShotClassLoader) { | |
| + Class parentReified = superClass.getRealClass().getReifiedClass(); | |
| + if (parentReified == null) { | |
| + throw getClassRuntime().newTypeError("class " + getName() + " parent class is not yet reified"); | |
| + } | |
| + | |
| + if (parentReified.getClassLoader() instanceof OneShotClassLoader) { | |
| parentCL = (OneShotClassLoader)superClass.getRealClass().getReifiedClass().getClassLoader(); | |
| } else { | |
| parentCL = new OneShotClassLoader(runtime.getJRubyClassLoader()); | |
| @@ -1768,4 +1815,7 @@ public class RubyClass extends RubyModule { | |
| /** A cached tuple of method and generation for marshal loading */ | |
| private CacheEntry cachedLoad = CacheEntry.NULL_CACHE; | |
| + | |
| + /** Whether this class can be reified into a Java class */ | |
| + private final boolean reifiable; | |
| } | |
| diff --git a/src/org/jruby/RubyJRuby.java b/src/org/jruby/RubyJRuby.java | |
| index 4d9abde..651967a 100644 | |
| --- a/src/org/jruby/RubyJRuby.java | |
| +++ b/src/org/jruby/RubyJRuby.java | |
| @@ -483,9 +483,9 @@ public class RubyJRuby { | |
| } | |
| if (args.length > 0) { | |
| - clazz.reify(args[0].convertToString().asJavaString()); | |
| + clazz.reifyWithAncestors(args[0].convertToString().asJavaString()); | |
| } else { | |
| - clazz.reify(); | |
| + clazz.reifyWithAncestors(); | |
| } | |
| return JavaUtil.convertJavaToUsableRubyObject(context.getRuntime(), clazz.getReifiedClass()); | |
| diff --git a/src/org/jruby/RubyObject.java b/src/org/jruby/RubyObject.java | |
| index 2b74f65..c04212d 100644 | |
| --- a/src/org/jruby/RubyObject.java | |
| +++ b/src/org/jruby/RubyObject.java | |
| @@ -181,16 +181,9 @@ public class RubyObject extends RubyBasicObject { | |
| public static final ObjectAllocator REIFYING_OBJECT_ALLOCATOR = new ObjectAllocator() { | |
| public IRubyObject allocate(Ruby runtime, RubyClass klass) { | |
| - reifyAncestors(klass); | |
| + klass.reifyWithAncestors(); | |
| return klass.allocate(); | |
| } | |
| - | |
| - public void reifyAncestors(RubyClass klass) { | |
| - if (klass.getAllocator() == this) { | |
| - reifyAncestors(klass.getSuperClass().getRealClass()); | |
| - klass.reify(); | |
| - } | |
| - } | |
| }; | |
| /** |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment