Skip to content

Commit

Permalink
[Truffle] Implement {Method,UnboundMethod}#super_method.
Browse files Browse the repository at this point in the history
  • Loading branch information
eregon committed Dec 25, 2016
1 parent 596e63e commit 9a39bd4
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 9 deletions.
3 changes: 0 additions & 3 deletions spec/truffle/tags/core/method/super_method_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/core/unboundmethod/super_method_tags.txt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.jruby.truffle.builtins.UnaryCoreMethodNode;
import org.jruby.truffle.core.Hashing;
import org.jruby.truffle.core.basicobject.BasicObjectNodes.ReferenceEqualNode;
import org.jruby.truffle.core.module.ModuleOperations;
import org.jruby.truffle.core.proc.ProcOperations;
import org.jruby.truffle.core.proc.ProcType;
import org.jruby.truffle.core.string.StringOperations;
Expand All @@ -42,6 +43,7 @@
import org.jruby.truffle.language.methods.InternalMethod;
import org.jruby.truffle.language.objects.LogicalClassNode;
import org.jruby.truffle.language.objects.LogicalClassNodeGen;
import org.jruby.truffle.language.objects.MetaClassNode;
import org.jruby.truffle.parser.ArgumentDescriptor;

@CoreClass("Method")
Expand Down Expand Up @@ -168,6 +170,26 @@ public Object sourceLocation(DynamicObject method) {

}

@CoreMethod(names = "super_method")
public abstract static class SuperMethodNode extends CoreMethodArrayArgumentsNode {

@Child MetaClassNode metaClassNode = MetaClassNode.create();

@Specialization
public DynamicObject superMethod(DynamicObject method) {
Object receiver = Layouts.METHOD.getReceiver(method);
InternalMethod internalMethod = Layouts.METHOD.getMethod(method);
DynamicObject selfMetaClass = metaClassNode.executeMetaClass(receiver);
InternalMethod superMethod = ModuleOperations.lookupSuperMethod(internalMethod, selfMetaClass);
if (superMethod == null || superMethod.isUndefined()) {
return nil();
} else {
return Layouts.METHOD.createMethod(coreLibrary().getMethodFactory(), receiver, superMethod);
}
}

}

@CoreMethod(names = "unbind")
public abstract static class UnbindNode extends CoreMethodArrayArgumentsNode {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.jruby.truffle.builtins.CoreMethodArrayArgumentsNode;
import org.jruby.truffle.builtins.UnaryCoreMethodNode;
import org.jruby.truffle.core.Hashing;
import org.jruby.truffle.core.module.ModuleOperations;
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.truffle.language.RubyGuards;
import org.jruby.truffle.language.Visibility;
Expand Down Expand Up @@ -179,6 +180,26 @@ public Object sourceLocation(DynamicObject unboundMethod) {

}

@CoreMethod(names = "super_method")
public abstract static class SuperMethodNode extends CoreMethodArrayArgumentsNode {

@Child MetaClassNode metaClassNode = MetaClassNode.create();

@Specialization
public DynamicObject superMethod(DynamicObject unboundMethod) {
InternalMethod internalMethod = Layouts.UNBOUND_METHOD.getMethod(unboundMethod);
DynamicObject origin = Layouts.UNBOUND_METHOD.getOrigin(unboundMethod);
InternalMethod superMethod = ModuleOperations.lookupSuperMethod(internalMethod, origin);
if (superMethod == null || superMethod.isUndefined()) {
return nil();
} else {
return Layouts.UNBOUND_METHOD.createUnboundMethod(coreLibrary().getUnboundMethodFactory(),
superMethod.getDeclaringModule(), superMethod);
}
}

}

@CoreMethod(names = "allocate", constructor = true)
public abstract static class AllocateNode extends UnaryCoreMethodNode {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,15 +302,15 @@ public static InternalMethod lookupMethod(DynamicObject module, String name, Vis
}

public static InternalMethod lookupSuperMethod(InternalMethod currentMethod, DynamicObject objectMetaClass) {
assert RubyGuards.isRubyClass(objectMetaClass);
assert RubyGuards.isRubyModule(objectMetaClass);
final String name = currentMethod.getSharedMethodInfo().getName(); // use the original name
return lookupSuperMethod(currentMethod.getDeclaringModule(), name, objectMetaClass);
}

@TruffleBoundary
public static InternalMethod lookupSuperMethod(DynamicObject declaringModule, String name, DynamicObject objectMetaClass) {
private static InternalMethod lookupSuperMethod(DynamicObject declaringModule, String name, DynamicObject objectMetaClass) {
assert RubyGuards.isRubyModule(declaringModule);
assert RubyGuards.isRubyClass(objectMetaClass);
assert RubyGuards.isRubyModule(objectMetaClass);

boolean foundDeclaringModule = false;
for (DynamicObject module : Layouts.MODULE.getFields(objectMetaClass).ancestors()) {
Expand Down

0 comments on commit 9a39bd4

Please sign in to comment.