Skip to content

Instantly share code, notes, and snippets.

@headius
Created January 17, 2011 23:19
Show Gist options
  • Select an option

  • Save headius/783686 to your computer and use it in GitHub Desktop.

Select an option

Save headius/783686 to your computer and use it in GitHub Desktop.
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