Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: ea4dce834dc7
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 5ac9059a9526
Choose a head ref
  • 3 commits
  • 4 files changed
  • 2 contributors

Commits on Mar 26, 2015

  1. Copy the full SHA
    c165dd9 View commit details

Commits on Mar 27, 2015

  1. Copy the full SHA
    94af6d3 View commit details

Commits on Mar 28, 2015

  1. Merge pull request #2763 from bjfish/truffle_array_initialize

    [Truffle] Adding more implementation of Array#initialize.
    chrisseaton committed Mar 28, 2015
    Copy the full SHA
    5ac9059 View commit details
9 changes: 0 additions & 9 deletions spec/truffle/tags/core/array/initialize_tags.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1 @@
fails:Array#initialize calls #to_ary to convert the value to an array, even if it's private
fails:Array#initialize with no arguments does not use the given block
fails:Array#initialize with (array) does not use the given block
fails:Array#initialize with (array) calls #to_ary to convert the value to an array
fails:Array#initialize with (size, object=nil) raises an ArgumentError if size is negative
fails:Array#initialize with (size, object=nil) raises an ArgumentError if size is too large
fails:Array#initialize with (size, object=nil) calls #to_int to convert the size argument to an Integer when object is given
fails:Array#initialize with (size, object=nil) calls #to_int to convert the size argument to an Integer when object is not given
fails:Array#initialize with (size, object=nil) uses the block value instead of using the default value
fails:Array#initialize with (size, object=nil) returns the value passed to break
9 changes: 1 addition & 8 deletions spec/truffle/tags/core/array/new_tags.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1 @@
fails:Array.new with no arguments does not use the given block
fails:Array.new with (array) does not use the given block
fails:Array.new with (array) calls #to_ary to convert the value to an array
fails:Array.new with (size, object=nil) raises an ArgumentError if size is negative
fails:Array.new with (size, object=nil) raises an ArgumentError if size is too large
fails:Array.new with (size, object=nil) calls #to_int to convert the size argument to an Integer when object is given
fails:Array.new with (size, object=nil) calls #to_int to convert the size argument to an Integer when object is not given
fails:Array.new with (size, object=nil) uses the block value instead of using the default value
fails:Array.new with (size, object=nil) returns the value passed to break
Original file line number Diff line number Diff line change
@@ -128,5 +128,13 @@ public static boolean isIntIndexAndOtherSingleObjectArg(RubyArray array, Object[
return others.length == 2 && others[0] instanceof Integer && others[1] instanceof Object;
}

public static boolean isNegative(RubyArray array, int size) {
return size < 0;
}

public static boolean isNegative(RubyArray array, long size) {
return size < 0;
}


}
154 changes: 144 additions & 10 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/ArrayNodes.java
Original file line number Diff line number Diff line change
@@ -1600,8 +1600,13 @@ public boolean includeObject(VirtualFrame frame, RubyArray array, Object value)
@ImportGuards(ArrayGuards.class)
public abstract static class InitializeNode extends YieldingCoreMethodNode {

@Child private ToIntNode toIntNode;
@Child private CallDispatchHeadNode toAryNode;
@Child private KernelNodes.RespondToNode respondToToAryNode;
@Child private ArrayBuilderNode arrayBuilder;

private final BranchProfile breakProfile = BranchProfile.create();

public InitializeNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
arrayBuilder = new ArrayBuilderNode.UninitializedArrayBuilderNode(context);
@@ -1610,61 +1615,169 @@ public InitializeNode(RubyContext context, SourceSection sourceSection) {
public InitializeNode(InitializeNode prev) {
super(prev);
arrayBuilder = prev.arrayBuilder;
toIntNode = prev.toIntNode;
respondToToAryNode = prev.respondToToAryNode;
}

@Specialization(guards = {"!isInteger(arguments[1])", "!isLong(arguments[1])", "!isUndefinedPlaceholder(arguments[1])", "!isRubyArray(arguments[1])"})
public RubyArray initialize(VirtualFrame frame, RubyArray array, Object object, UndefinedPlaceholder defaultValue, UndefinedPlaceholder block) {

RubyArray copy = null;
if (respondToToAryNode == null) {
CompilerDirectives.transferToInterpreter();
respondToToAryNode = insert(KernelNodesFactory.RespondToNodeFactory.create(getContext(), getSourceSection(), new RubyNode[]{null, null, null}));
}
if (respondToToAryNode.doesRespondTo(frame, object, getContext().makeString("to_ary"), false)) {
if (toAryNode == null) {
CompilerDirectives.transferToInterpreter();
toAryNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext(), false));
}
Object toAryResult = toAryNode.call(frame, object, "to_ary", null);
if (toAryResult instanceof RubyArray) {
copy = (RubyArray) toAryResult;
}

}

if (copy != null) {
return initialize(array, copy, UndefinedPlaceholder.INSTANCE, UndefinedPlaceholder.INSTANCE);
} else {
if (toIntNode == null) {
CompilerDirectives.transferToInterpreter();
toIntNode = insert(ToIntNodeFactory.create(getContext(), getSourceSection(), null));
}
int size = toIntNode.executeIntegerFixnum(frame, object);
if (size < 0) {
return initializeNegative(array, size, UndefinedPlaceholder.INSTANCE, UndefinedPlaceholder.INSTANCE);
} else {
return initialize(array, size, UndefinedPlaceholder.INSTANCE, UndefinedPlaceholder.INSTANCE);
}

}

}


@Specialization
public RubyArray initialize(RubyArray array, UndefinedPlaceholder size, UndefinedPlaceholder defaultValue, UndefinedPlaceholder block) {
return initialize(array, 0, nil(), block);
}

@Specialization
public RubyArray initialize(RubyArray array, UndefinedPlaceholder size, UndefinedPlaceholder defaultValue, RubyProc block) {
return initialize(array, 0, nil(), UndefinedPlaceholder.INSTANCE);
}

@Specialization(guards = "!isNegative")
public RubyArray initialize(RubyArray array, int size, UndefinedPlaceholder defaultValue, UndefinedPlaceholder block) {
return initialize(array, size, nil(), block);
}

@Specialization
@Specialization(guards = "isNegative")
public RubyArray initializeNegative(RubyArray array, int size, UndefinedPlaceholder defaultValue, UndefinedPlaceholder block) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}

@Specialization(guards = "!isNegative")
public RubyArray initialize(RubyArray array, long size, UndefinedPlaceholder defaultValue, UndefinedPlaceholder block) {
if (size > Integer.MAX_VALUE) {
throw new IllegalStateException();
throw new RaiseException(getContext().getCoreLibrary().argumentError("array size too big", this));
}
return initialize(array, (int) size, nil(), block);
}

@Specialization
@Specialization(guards = "isNegative")
public RubyArray initializeNegative(RubyArray array, long size, UndefinedPlaceholder defaultValue, UndefinedPlaceholder block) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}

@Specialization(guards = "!isNegative")
public RubyArray initialize(RubyArray array, int size, int defaultValue, UndefinedPlaceholder block) {
final int[] store = new int[size];
Arrays.fill(store, defaultValue);
array.setStore(store, size);
return array;
}

@Specialization
@Specialization(guards = "isNegative")
public RubyArray initializeNegative(RubyArray array, int size, int defaultValue, UndefinedPlaceholder block) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}

@Specialization(guards = "!isNegative")
public RubyArray initialize(RubyArray array, int size, long defaultValue, UndefinedPlaceholder block) {
final long[] store = new long[size];
Arrays.fill(store, defaultValue);
array.setStore(store, size);
return array;
}

@Specialization
@Specialization(guards = "isNegative")
public RubyArray initializeNegative(RubyArray array, int size, long defaultValue, UndefinedPlaceholder block) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}

@Specialization(guards = "!isNegative")
public RubyArray initialize(RubyArray array, int size, double defaultValue, UndefinedPlaceholder block) {
final double[] store = new double[size];
Arrays.fill(store, defaultValue);
array.setStore(store, size);
return array;
}

@Specialization(guards = "!isUndefinedPlaceholder(arguments[2])")
@Specialization(guards = "isNegative")
public RubyArray initializeNegative(RubyArray array, int size, double defaultValue, UndefinedPlaceholder block) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}

@Specialization(guards = {"!isUndefinedPlaceholder(arguments[2])", "!isNegative"})
public RubyArray initialize(RubyArray array, int size, Object defaultValue, UndefinedPlaceholder block) {
final Object[] store = new Object[size];
Arrays.fill(store, defaultValue);
array.setStore(store, size);
return array;
}

@Specialization
public RubyArray initialize(VirtualFrame frame, RubyArray array, int size, UndefinedPlaceholder defaultValue, RubyProc block) {
Object store = arrayBuilder.start(size);
@Specialization(guards = {"!isUndefinedPlaceholder(arguments[2])", "isNegative"})
public RubyArray initializeNegative(RubyArray array, int size, Object defaultValue, UndefinedPlaceholder block) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}

@Specialization(guards = {"!isInteger(arguments[1])", "!isUndefinedPlaceholder(arguments[2])"})
public RubyArray initialize(VirtualFrame frame, RubyArray array, Object sizeObject, Object defaultValue, UndefinedPlaceholder block) {
if (toIntNode == null) {
CompilerDirectives.transferToInterpreter();
toIntNode = insert(ToIntNodeFactory.create(getContext(), getSourceSection(), null));
}
int size = toIntNode.executeIntegerFixnum(frame, sizeObject);
if (size < 0) {
return initializeNegative(array, size, defaultValue, UndefinedPlaceholder.INSTANCE);
} else {
return initialize(array, size, defaultValue, UndefinedPlaceholder.INSTANCE);
}

}

@Specialization(guards = {"!isUndefinedPlaceholder(arguments[2])", "!isNegative"})
public Object initialize(VirtualFrame frame, RubyArray array, int size, Object defaultValue, RubyProc block) {
return initialize(frame, array, size, UndefinedPlaceholder.INSTANCE, block);
}

@Specialization(guards = {"!isUndefinedPlaceholder(arguments[2])", "isNegative"})
public Object initializeNegative(VirtualFrame frame, RubyArray array, int size, Object defaultValue, RubyProc block) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}

@Specialization(guards = "!isNegative")
public Object initialize(VirtualFrame frame, RubyArray array, int size, UndefinedPlaceholder defaultValue, RubyProc block) {
Object store = arrayBuilder.start();

int count = 0;
try {
@@ -1673,7 +1786,14 @@ public RubyArray initialize(VirtualFrame frame, RubyArray array, int size, Undef
count++;
}

store = arrayBuilder.append(store, n, yield(frame, block, n));
try {
store = arrayBuilder.append(store, n, yield(frame, block, n));
} catch (BreakException e) {
breakProfile.enter();
array.setStore(arrayBuilder.finish(store, n), n);
return e.getResult();
}

}
} finally {
if (CompilerDirectives.inInterpreter()) {
@@ -1685,13 +1805,27 @@ public RubyArray initialize(VirtualFrame frame, RubyArray array, int size, Undef
return array;
}

@Specialization(guards = "isNegative")
public Object initializeNegative(VirtualFrame frame, RubyArray array, int size, UndefinedPlaceholder defaultValue, RubyProc block) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}

@Specialization
public RubyArray initialize(RubyArray array, RubyArray copy, UndefinedPlaceholder defaultValue, UndefinedPlaceholder block) {
notDesignedForCompilation();
array.setStore(copy.slowToArray(), copy.getSize());
return array;
}

@Specialization
public RubyArray initialize(RubyArray array, RubyArray copy, UndefinedPlaceholder defaultValue, RubyProc block) {
notDesignedForCompilation();
array.setStore(copy.slowToArray(), copy.getSize());
return array;
}


}

@CoreMethod(names = "initialize_copy", visibility = Visibility.PRIVATE, required = 1, raiseIfFrozenSelf = true)