Skip to content

Commit

Permalink
[Truffle] Implement Class#inherited and call it when a subclass is ad…
Browse files Browse the repository at this point in the history
…ded.
  • Loading branch information
eregon committed Dec 17, 2014
1 parent 8ffabd6 commit 1e8c12f
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 2 deletions.
19 changes: 19 additions & 0 deletions core/src/main/java/org/jruby/truffle/nodes/core/ClassNodes.java
Expand Up @@ -13,6 +13,7 @@
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNode;
import org.jruby.truffle.runtime.ModuleOperations;
Expand Down Expand Up @@ -130,6 +131,24 @@ public RubyClass initialize(VirtualFrame frame, RubyClass rubyClass, RubyClass s

}

@CoreMethod(names = "inherited", required = 1, visibility = Visibility.PRIVATE)
public abstract static class InheritedNode extends CoreMethodNode {

public InheritedNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public InheritedNode(InheritedNode prev) {
super(prev);
}

@Specialization
public RubyNilClass inherited(Object subclass) {
return getContext().getCoreLibrary().getNilObject();
}

}

@CoreMethod(names = "superclass")
public abstract static class SuperClassNode extends CoreMethodNode {

Expand Down
Expand Up @@ -9,9 +9,11 @@
*/
package org.jruby.truffle.nodes.objects;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.source.*;
import com.oracle.truffle.api.frame.*;
import org.jruby.truffle.nodes.*;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNode;
import org.jruby.truffle.runtime.*;
import org.jruby.truffle.runtime.control.*;
import org.jruby.truffle.runtime.core.*;
Expand All @@ -22,12 +24,21 @@
public class DefineOrGetClassNode extends DefineOrGetModuleNode {

@Child protected RubyNode superClass;
@Child protected DispatchHeadNode inheritedNode;

public DefineOrGetClassNode(RubyContext context, SourceSection sourceSection, String name, RubyNode lexicalParent, RubyNode superClass) {
super(context, sourceSection, name, lexicalParent);
this.superClass = superClass;
}

private void callInherited(VirtualFrame frame, RubyClass superClass, RubyClass subClass) {
if (inheritedNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
inheritedNode = insert(new DispatchHeadNode(getContext(), true));
}
inheritedNode.call(frame, superClass, "inherited", null, subClass);
}

@Override
public Object execute(VirtualFrame frame) {
notDesignedForCompilation();
Expand All @@ -50,6 +61,7 @@ public Object execute(VirtualFrame frame) {
} else {
definingClass = new RubyClass(context, lexicalParent, superClassObject, name);
}
callInherited(frame, superClassObject, definingClass);
} else {
if (constant.getValue() instanceof RubyClass) {
definingClass = (RubyClass) constant.getValue();
Expand Down
2 changes: 0 additions & 2 deletions spec/truffle/tags/language/class_tags.txt
@@ -1,5 +1,3 @@
fails(inherited):A class definition extending an object (sclass) allows accessing the block of the original scope
fails:A class definition extending an object (sclass) can use return to cause the enclosing method to return
fails:class provides hooks calls inherited when a class is created
fails:Reopening a class raises a TypeError when superclasses mismatch
fails:A class definition extending an object (sclass) allows accessing the block of the original scope

0 comments on commit 1e8c12f

Please sign in to comment.