Skip to content

Commit

Permalink
Merge pull request #4146 from jruby/truffle-check-funcall
Browse files Browse the repository at this point in the history
[Truffle] Add check_convert_type and check_funcall methods
  • Loading branch information
eregon committed Sep 16, 2016
2 parents 10ce714 + b030e25 commit 33b1667
Show file tree
Hide file tree
Showing 12 changed files with 181 additions and 29 deletions.
1 change: 0 additions & 1 deletion spec/truffle/tags/core/array/flatten_tags.txt

This file was deleted.

Expand Up @@ -160,8 +160,7 @@ private static void addMethod(RubyContext context, DynamicObject module, SharedM
if (ModuleOperations.isMethodPrivateFromName(name)) {
visibility = Visibility.PRIVATE;
}

final InternalMethod method = new InternalMethod(sharedMethodInfo, name, module, visibility, callTarget);
final InternalMethod method = new InternalMethod(context, sharedMethodInfo, name, module, visibility, callTarget);

Layouts.MODULE.getFields(module).addMethod(context, null, method);
}
Expand Down
50 changes: 50 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/core/VMPrimitiveNodes.java
Expand Up @@ -39,7 +39,10 @@

import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.CreateCast;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
Expand All @@ -55,17 +58,24 @@
import org.jruby.truffle.builtins.Primitive;
import org.jruby.truffle.builtins.PrimitiveArrayArgumentsNode;
import org.jruby.truffle.core.basicobject.BasicObjectNodes.ReferenceEqualNode;
import org.jruby.truffle.core.cast.NameToJavaStringNode;
import org.jruby.truffle.core.cast.NameToSymbolOrStringNodeGen;
import org.jruby.truffle.core.kernel.KernelNodes;
import org.jruby.truffle.core.kernel.KernelNodesFactory;
import org.jruby.truffle.core.module.ModuleOperations;
import org.jruby.truffle.core.proc.ProcSignalHandler;
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.truffle.core.thread.ThreadManager;
import org.jruby.truffle.language.RubyGuards;
import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.control.ExitException;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.language.control.ThrowException;
import org.jruby.truffle.language.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.language.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.language.methods.InternalMethod;
import org.jruby.truffle.language.methods.LookupMethodNode;
import org.jruby.truffle.language.methods.LookupMethodNodeGen;
import org.jruby.truffle.language.objects.IsANode;
import org.jruby.truffle.language.objects.IsANodeGen;
import org.jruby.truffle.language.objects.LogicalClassNode;
Expand Down Expand Up @@ -246,6 +256,45 @@ public boolean vmObjectKindOf(Object object, DynamicObject rubyClass) {

}

@Primitive(name = "vm_method_is_basic", needsSelf = false)
public static abstract class VMMethodIsBasicNode extends PrimitiveArrayArgumentsNode {

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

@Specialization
public boolean vmMethodIsBasic(VirtualFrame frame, DynamicObject method) {
return Layouts.METHOD.getMethod(method).isBuiltIn();
}

}

@Primitive(name = "vm_method_lookup", needsSelf = false)
public static abstract class VMMethodLookupNode extends PrimitiveArrayArgumentsNode {

@Child NameToJavaStringNode nameToJavaStringNode;
@Child LookupMethodNode lookupMethodNode;

public VMMethodLookupNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
nameToJavaStringNode = NameToJavaStringNode.create();
lookupMethodNode = LookupMethodNodeGen.create(context, sourceSection, true, false, null, null);
}

@Specialization
public DynamicObject vmMethodLookup(VirtualFrame frame, Object self, Object name) {
// TODO BJF Sep 14, 2016 Handle private
final String normalizedName = nameToJavaStringNode.executeToJavaString(frame, name);
InternalMethod method = lookupMethodNode.executeLookupMethod(frame, self, normalizedName);
if (method == null) {
return nil();
}
return Layouts.METHOD.createMethod(coreLibrary().getMethodFactory(), self, method);
}

}

@Primitive(name = "vm_object_respond_to", needsSelf = false)
public static abstract class VMObjectRespondToPrimitiveNode extends PrimitiveArrayArgumentsNode {

Expand All @@ -263,6 +312,7 @@ public boolean vmObjectRespondTo(VirtualFrame frame, Object object, Object name,

}


@Primitive(name = "vm_object_singleton_class", needsSelf = false)
public static abstract class VMObjectSingletonClassPrimitiveNode extends PrimitiveArrayArgumentsNode {

Expand Down
Expand Up @@ -586,6 +586,7 @@ public Object evalNoBindingCached(
final Object callerSelf = RubyArguments.getSelf(frame);

final InternalMethod method = new InternalMethod(
getContext(),
cachedRootNode.getRootNode().getSharedMethodInfo(),
cachedRootNode.getRootNode().getSharedMethodInfo().getName(),
RubyArguments.getMethod(parentFrame).getDeclaringModule(),
Expand Down Expand Up @@ -1222,7 +1223,7 @@ private InternalMethod createMissingMethod(Object self, DynamicObject name, Stri
final CallTarget newCallTarget = Truffle.getRuntime().createCallTarget(newRootNode);

final DynamicObject module = coreLibrary().getMetaClass(self);
return new InternalMethod(info, normalizedName, module, Visibility.PUBLIC, newCallTarget);
return new InternalMethod(getContext(), info, normalizedName, module, Visibility.PUBLIC, newCallTarget);
}

private static class CallMethodMissingWithStaticName extends RubyNode {
Expand Down
Expand Up @@ -396,7 +396,7 @@ private void createAccesor(DynamicObject module, String name) {
final RubyNode sequence = Translator.sequence(getContext(), sourceSection.getSource(), rubySourceSection, Arrays.asList(checkArity, accessInstanceVariable));
final RubyRootNode rootNode = new RubyRootNode(getContext(), sourceSection, null, sharedMethodInfo, sequence, false);
final CallTarget callTarget = Truffle.getRuntime().createCallTarget(rootNode);
final InternalMethod method = new InternalMethod(sharedMethodInfo, accessorName, module, visibility, callTarget);
final InternalMethod method = new InternalMethod(getContext(), sharedMethodInfo, accessorName, module, visibility, callTarget);

Layouts.MODULE.getFields(module).addMethod(getContext(), this, method);
}
Expand Down Expand Up @@ -1058,7 +1058,7 @@ private DynamicObject defineMethod(DynamicObject module, String name, DynamicObj
final RubyRootNode newRootNode = new RubyRootNode(getContext(), info.getSourceSection(), rootNode.getFrameDescriptor(), info, newBody, false);
final CallTarget newCallTarget = Truffle.getRuntime().createCallTarget(newRootNode);

final InternalMethod method = InternalMethod.fromProc(info, name, module, Visibility.PUBLIC, proc, newCallTarget);
final InternalMethod method = InternalMethod.fromProc(getContext(), info, name, module, Visibility.PUBLIC, proc, newCallTarget);
return addMethod(module, name, method);
}

Expand Down
Expand Up @@ -75,7 +75,7 @@ public Object execute(VirtualFrame frame) {
callNode.forceInlining();

mainObject = context.getCoreLibrary().getMainObject();
method = new InternalMethod(rootNode.getSharedMethodInfo(), rootNode.getSharedMethodInfo().getName(),
method = new InternalMethod(context, rootNode.getSharedMethodInfo(), rootNode.getSharedMethodInfo().getName(),
context.getCoreLibrary().getObjectClass(), Visibility.PUBLIC, callTarget);
}

Expand Down
Expand Up @@ -77,8 +77,8 @@ public DeferredCall prepareExecute(ParserContext parserContext,
} else {
declaringModule = context.getCoreLibrary().getObjectClass();
}

final InternalMethod method = new InternalMethod(
context,
rootNode.getSharedMethodInfo(),
rootNode.getSharedMethodInfo().getName(),
declaringModule,
Expand Down
Expand Up @@ -13,6 +13,7 @@
import com.oracle.truffle.api.object.DynamicObject;
import org.jruby.runtime.Visibility;
import org.jruby.truffle.Layouts;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.language.RubyGuards;
import org.jruby.truffle.language.objects.ObjectGraphNode;

Expand All @@ -33,20 +34,23 @@ public class InternalMethod implements ObjectGraphNode {
private final DynamicObject declaringModule;
private final Visibility visibility;
private final boolean undefined;
private final boolean builtIn;
private final DynamicObject proc; // only if method is created from a Proc

private final CallTarget callTarget;
private final DynamicObject capturedBlock;
private final DynamicObject capturedDefaultDefinee;

public static InternalMethod fromProc(
RubyContext context,
SharedMethodInfo sharedMethodInfo,
String name,
DynamicObject declaringModule,
Visibility visibility,
DynamicObject proc,
CallTarget callTarget) {
return new InternalMethod(
context,
sharedMethodInfo,
name,
declaringModule,
Expand All @@ -59,23 +63,40 @@ public static InternalMethod fromProc(
}

public InternalMethod(
RubyContext context,
SharedMethodInfo sharedMethodInfo,
String name,
DynamicObject declaringModule,
Visibility visibility,
CallTarget callTarget) {
this(sharedMethodInfo, name, declaringModule, visibility, false, null, callTarget, null, null);
this(context, sharedMethodInfo, name, declaringModule, visibility, false, null, callTarget, null, null);
}

public InternalMethod(
RubyContext context,
SharedMethodInfo sharedMethodInfo,
String name,
DynamicObject declaringModule,
Visibility visibility,
boolean undefined,
DynamicObject proc,
CallTarget callTarget) {
this(sharedMethodInfo, name, declaringModule, visibility, undefined, proc, callTarget, null, null);
this(context, sharedMethodInfo, name, declaringModule, visibility, undefined, proc, callTarget, null, null);
}

public InternalMethod(
RubyContext context,
SharedMethodInfo sharedMethodInfo,
String name,
DynamicObject declaringModule,
Visibility visibility,
boolean undefined,
DynamicObject proc,
CallTarget callTarget,
DynamicObject capturedBlock,
DynamicObject capturedDefaultDefinee) {
this(sharedMethodInfo, name, declaringModule, visibility, undefined, !context.getCoreLibrary().isLoaded(),
proc, callTarget, capturedBlock, capturedDefaultDefinee);
}

public InternalMethod(
Expand All @@ -84,6 +105,7 @@ public InternalMethod(
DynamicObject declaringModule,
Visibility visibility,
boolean undefined,
boolean builtIn,
DynamicObject proc,
CallTarget callTarget,
DynamicObject capturedBlock,
Expand All @@ -94,6 +116,7 @@ public InternalMethod(
this.name = name;
this.visibility = visibility;
this.undefined = undefined;
this.builtIn = builtIn;
this.proc = proc;
this.callTarget = callTarget;
this.capturedBlock = capturedBlock;
Expand All @@ -120,6 +143,10 @@ public boolean isUndefined() {
return undefined;
}

public boolean isBuiltIn() {
return builtIn;
}

public CallTarget getCallTarget() {
return callTarget;
}
Expand All @@ -136,6 +163,7 @@ public InternalMethod withDeclaringModule(DynamicObject newDeclaringModule) {
newDeclaringModule,
visibility,
undefined,
builtIn,
proc,
callTarget,
capturedBlock,
Expand All @@ -153,6 +181,7 @@ public InternalMethod withName(String newName) {
declaringModule,
visibility,
undefined,
builtIn,
proc,
callTarget,
capturedBlock,
Expand All @@ -170,6 +199,7 @@ public InternalMethod withVisibility(Visibility newVisibility) {
declaringModule,
newVisibility,
undefined,
builtIn,
proc,
callTarget,
capturedBlock,
Expand All @@ -184,6 +214,7 @@ public InternalMethod undefined() {
declaringModule,
visibility,
true,
builtIn,
proc,
callTarget,
capturedBlock,
Expand Down
Expand Up @@ -53,8 +53,7 @@ public InternalMethod executeMethod(VirtualFrame frame) {
} else {
capturedDefaultDefinee = null;
}

return new InternalMethod(sharedMethodInfo, name, dummyModule, dummyVisibility, false, null, callTarget, null,
return new InternalMethod(getContext(), sharedMethodInfo, name, dummyModule, dummyVisibility, false, null, callTarget, null,
capturedDefaultDefinee);
}

Expand Down
Expand Up @@ -65,8 +65,7 @@ public InternalMethod executeMethod(VirtualFrame frame) {
} else {
capturedBlock = null;
}

return new InternalMethod(sharedMethodInfo, name, dummyModule, dummyVisibility, false, null, callTarget, capturedBlock, null);
return new InternalMethod(getContext(), sharedMethodInfo, name, dummyModule, dummyVisibility, false, null, callTarget, capturedBlock, null);
}

@Override
Expand Down
20 changes: 5 additions & 15 deletions truffle/src/main/ruby/core/array.rb
Expand Up @@ -1193,22 +1193,12 @@ def recursively_flatten(array, out, max_levels = -1)
while i < size
o = array.at i

if Rubinius::Type.object_kind_of? o, Array
modified = true
recursively_flatten o, out, max_levels
elsif Rubinius::Type.object_respond_to? o, :to_ary
ary = o.__send__ :to_ary
if nil.equal? ary
out << o
else
modified = true
recursively_flatten ary, out, max_levels
end
elsif ary = Rubinius::Type.execute_check_convert_type(o, Array, :to_ary)
modified = true
recursively_flatten ary, out, max_levels
else
tmp = Rubinius::Type.rb_check_convert_type(o, Array, :to_ary)
if tmp.nil?
out << o
else
modified = true
recursively_flatten tmp, out, max_levels
end

i += 1
Expand Down

0 comments on commit 33b1667

Please sign in to comment.