Skip to content

Commit

Permalink
[Truffle] Update splat coercion to use check_convert_type
Browse files Browse the repository at this point in the history
  • Loading branch information
Brandon Fish committed Nov 26, 2016
1 parent 6f2e683 commit b36bb77
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 22 deletions.
1 change: 0 additions & 1 deletion spec/truffle/tags/language/array_tags.txt

This file was deleted.

Expand Up @@ -22,6 +22,7 @@
import org.jruby.truffle.core.array.ArrayDupNodeGen;
import org.jruby.truffle.language.RubyGuards;
import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.SnippetNode;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.language.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.language.dispatch.DispatchHeadNodeFactory;
Expand All @@ -45,17 +46,13 @@ public enum NilBehavior {
private final DynamicObject conversionMethod;

@Child private ArrayDupNode dup;
@Child private CallDispatchHeadNode respondToToA;
@Child private BooleanCastNode respondToCast;
@Child private CallDispatchHeadNode toA;

public SplatCastNode(RubyContext context, SourceSection sourceSection, NilBehavior nilBehavior, boolean useToAry) {
super(context, sourceSection);
this.nilBehavior = nilBehavior;
// Calling private #to_a is allowed for the *splat operator.
dup = ArrayDupNodeGen.create(context, sourceSection, null);
respondToToA = DispatchHeadNodeFactory.createMethodCall(context, true, MissingBehavior.RETURN_MISSING);
respondToCast = BooleanCastNodeGen.create(null);
toA = DispatchHeadNodeFactory.createMethodCall(context, true, MissingBehavior.RETURN_MISSING);
String name = useToAry ? "to_ary" : "to_a";
conversionMethod = context.getSymbolTable().getSymbol(name);
Expand Down Expand Up @@ -91,25 +88,20 @@ public DynamicObject splat(VirtualFrame frame, DynamicObject array) {
return dup.executeDup(frame, array);
}

@Specialization(guards = { "!isNil(object)", "!isRubyArray(object)" })
@Specialization(guards = {"!isNil(object)", "!isRubyArray(object)"})
public DynamicObject splat(VirtualFrame frame, Object object,
@Cached("create()") BranchProfile errorProfile) {
// MRI tries to call dynamic respond_to? here.
Object respondToResult = respondToToA.call(frame, object, "respond_to?", conversionMethod, true);
if (respondToResult != DispatchNode.MISSING && respondToCast.executeBoolean(frame, respondToResult)) {
final Object array = toA.call(frame, object, conversionMethod);

if (RubyGuards.isRubyArray(array)) {
return (DynamicObject) array;
} else if (array == nil() || array == DispatchNode.MISSING) {
return createArray(new Object[] { object }, 1);
} else {
errorProfile.enter();
throw new RaiseException(coreExceptions().typeErrorCantConvertTo(object, "Array", Layouts.SYMBOL.getString(conversionMethod), array, this));
}
@Cached("create()") BranchProfile errorProfile, @Cached("new()") SnippetNode snippetNode) {
final Object array = snippetNode.execute(frame, "Rubinius::Type.rb_check_convert_type(v, Array, method)",
"v", object, "method", conversionMethod);
if (RubyGuards.isRubyArray(array)) {
return (DynamicObject) array;
} else if (array == nil()) {
return createArray(new Object[]{object}, 1);
} else {
errorProfile.enter();
throw new RaiseException(coreExceptions().typeErrorCantConvertTo(object, "Array",
Layouts.SYMBOL.getString(conversionMethod), array, this));
}

return createArray(new Object[] { object }, 1);
}

}

1 comment on commit b36bb77

@bjfish
Copy link
Contributor

@bjfish bjfish commented on b36bb77 Nov 26, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.