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: 4dbe96e7a1cc
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 819bb9cba037
Choose a head ref
  • 2 commits
  • 2 files changed
  • 2 contributors

Commits on Mar 22, 2015

  1. Copy the full SHA
    495bff7 View commit details
  2. Merge pull request #2740 from bjfish/truffle_array_shift

    [Truffle] Adding more Array#shift.
    chrisseaton committed Mar 22, 2015
    Copy the full SHA
    819bb9c View commit details
Showing with 445 additions and 16 deletions.
  1. +0 −10 spec/truffle/tags/core/array/shift_tags.txt
  2. +445 −6 truffle/src/main/java/org/jruby/truffle/nodes/core/ArrayNodes.java
10 changes: 0 additions & 10 deletions spec/truffle/tags/core/array/shift_tags.txt

This file was deleted.

451 changes: 445 additions & 6 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/ArrayNodes.java
Original file line number Diff line number Diff line change
@@ -3616,8 +3616,10 @@ public Object selectFixnumInteger(VirtualFrame frame, RubyArray array, RubyProc

}

@CoreMethod(names = "shift", raiseIfFrozenSelf = true)
public abstract static class ShiftNode extends CoreMethodNode {
@CoreMethod(names = "shift", raiseIfFrozenSelf = true, optional = 1)
public abstract static class ShiftNode extends ArrayCoreMethodNode {

@Child private ToIntNode toIntNode;

public ShiftNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
@@ -3627,13 +3629,450 @@ public ShiftNode(ShiftNode prev) {
super(prev);
}

@Specialization
public Object shift(RubyArray array) {
notDesignedForCompilation();
public abstract Object executeShift(VirtualFrame frame, RubyArray array, Object n);

@Specialization(guards = "isNullOrEmpty")
public Object shiftNil(VirtualFrame frame, RubyArray array, UndefinedPlaceholder undefinedPlaceholder) {
return nil();
}

@Specialization(guards = "isIntegerFixnum", rewriteOn = UnexpectedResultException.class)
public int shiftIntegerFixnumInBounds(VirtualFrame frame, RubyArray array, UndefinedPlaceholder undefinedPlaceholder) throws UnexpectedResultException {
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.UNLIKELY_PROBABILITY, array.getSize() == 0)) {
throw new UnexpectedResultException(nil());
} else {
final int[] store = ((int[]) array.getStore());
final int value = store[0];
System.arraycopy(store, 1, store, 0, array.getSize() - 1);
final int[] filler = new int[1];
System.arraycopy(filler, 0, store, array.getSize() - 1, 1);
array.setStore(store, array.getSize() - 1);
return value;
}
}

@Specialization(contains = "shiftIntegerFixnumInBounds", guards = "isIntegerFixnum")
public Object shiftIntegerFixnum(VirtualFrame frame, RubyArray array, UndefinedPlaceholder undefinedPlaceholder) {
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.UNLIKELY_PROBABILITY, array.getSize() == 0)) {
return nil();
} else {
final int[] store = ((int[]) array.getStore());
final int value = store[0];
System.arraycopy(store, 1, store, 0, array.getSize() - 1);
final int[] filler = new int[1];
System.arraycopy(filler, 0, store, array.getSize() - 1, 1);
array.setStore(store, array.getSize() - 1);
return value;
}
}

@Specialization(guards = "isLongFixnum", rewriteOn = UnexpectedResultException.class)
public long shiftLongFixnumInBounds(VirtualFrame frame, RubyArray array, UndefinedPlaceholder undefinedPlaceholder) throws UnexpectedResultException {
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.UNLIKELY_PROBABILITY, array.getSize() == 0)) {
throw new UnexpectedResultException(nil());
} else {
final long[] store = ((long[]) array.getStore());
final long value = store[0];
System.arraycopy(store, 1, store, 0, array.getSize() - 1);
final long[] filler = new long[1];
System.arraycopy(filler, 0, store, array.getSize() - 1, 1);
array.setStore(store, array.getSize() - 1);
return value;
}
}

@Specialization(contains = "shiftLongFixnumInBounds", guards = "isLongFixnum")
public Object shiftLongFixnum(VirtualFrame frame, RubyArray array, UndefinedPlaceholder undefinedPlaceholder) {
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.UNLIKELY_PROBABILITY, array.getSize() == 0)) {
return nil();
} else {
final long[] store = ((long[]) array.getStore());
final long value = store[0];
System.arraycopy(store, 1, store, 0, array.getSize() - 1);
final long[] filler = new long[1];
System.arraycopy(filler, 0, store, array.getSize() - 1, 1);
array.setStore(store, array.getSize() - 1);
return value;
}
}

@Specialization(guards = "isFloat", rewriteOn = UnexpectedResultException.class)
public double shiftFloatInBounds(VirtualFrame frame, RubyArray array, UndefinedPlaceholder undefinedPlaceholder) throws UnexpectedResultException {
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.UNLIKELY_PROBABILITY, array.getSize() == 0)) {
throw new UnexpectedResultException(nil());
} else {
final double[] store = ((double[]) array.getStore());
final double value = store[0];
System.arraycopy(store, 1, store, 0, array.getSize() - 1);
final double[] filler = new double[1];
System.arraycopy(filler, 0, store, array.getSize() - 1, 1);
array.setStore(store, array.getSize() - 1);
return value;
}
}

@Specialization(contains = "shiftFloatInBounds", guards = "isFloat")
public Object shiftFloat(VirtualFrame frame, RubyArray array, UndefinedPlaceholder undefinedPlaceholder) {
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.UNLIKELY_PROBABILITY, array.getSize() == 0)) {
return nil();
} else {
final double[] store = ((double[]) array.getStore());
final double value = store[0];
System.arraycopy(store, 1, store, 0, array.getSize() - 1);
final double[] filler = new double[1];
System.arraycopy(filler, 0, store, array.getSize() - 1, 1);
array.setStore(store, array.getSize() - 1);
return value;
}
}

@Specialization(guards = "isObject")
public Object shiftObject(VirtualFrame frame, RubyArray array, UndefinedPlaceholder undefinedPlaceholder) {
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.UNLIKELY_PROBABILITY, array.getSize() == 0)) {
return nil();
} else {
final Object[] store = ((Object[]) array.getStore());
final Object value = store[0];
System.arraycopy(store, 1, store, 0, array.getSize() - 1);
final Object[] filler = new Object[1];
System.arraycopy(filler, 0, store, array.getSize() - 1, 1);
array.setStore(store, array.getSize() - 1);
return value;
}
}

@Specialization(guards = {"isNullOrEmpty","!isUndefinedPlaceholder(arguments[1])"})
public Object shiftNilWithNum(VirtualFrame frame, RubyArray array, Object object) {
if (object instanceof Integer && ((Integer) object) < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
} else {
if (toIntNode == null) {
CompilerDirectives.transferToInterpreter();
toIntNode = insert(ToIntNodeFactory.create(getContext(), getSourceSection(), null));
}
final int n = toIntNode.executeIntegerFixnum(frame, object);
if (n < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}
}
return new RubyArray(getContext().getCoreLibrary().getArrayClass(), null, 0);
}

@Specialization(guards = "isIntegerFixnum", rewriteOn = UnexpectedResultException.class)
public RubyArray popIntegerFixnumInBoundsWithNum(VirtualFrame frame, RubyArray array, int num) throws UnexpectedResultException {
if (num < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.UNLIKELY_PROBABILITY, array.getSize() == 0)) {
throw new UnexpectedResultException(nil());
} else {
final int numShift = array.getSize() < num ? array.getSize() : num;
final int[] store = ((int[]) array.getStore());
final RubyArray result = new RubyArray(getContext().getCoreLibrary().getArrayClass(), Arrays.copyOfRange(store, 0 , numShift), numShift);
final int[] filler = new int[numShift];
System.arraycopy(store, numShift, store, 0 , array.getSize() - numShift);
System.arraycopy(filler, 0, store, array.getSize() - numShift, numShift);
array.setStore(store, array.getSize() - numShift);
return result;
}
}

@Specialization(contains = "popIntegerFixnumInBoundsWithNum", guards = "isIntegerFixnum")
public Object popIntegerFixnumWithNum(VirtualFrame frame, RubyArray array, int num) {
if (num < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.UNLIKELY_PROBABILITY, array.getSize() == 0)) {
return nil();
} else {
final int numShift = array.getSize() < num ? array.getSize() : num;
final int[] store = ((int[]) array.getStore());
final RubyArray result = new RubyArray(getContext().getCoreLibrary().getArrayClass(), Arrays.copyOfRange(store, 0 , numShift), numShift);
final int[] filler = new int[numShift];
System.arraycopy(store, numShift, store, 0 , array.getSize() - numShift);
System.arraycopy(filler, 0, store, array.getSize() - numShift, numShift);
array.setStore(store, array.getSize() - numShift);
return result;
}
}

@Specialization(guards = "isLongFixnum", rewriteOn = UnexpectedResultException.class)
public RubyArray shiftLongFixnumInBoundsWithNum(VirtualFrame frame, RubyArray array, int num) throws UnexpectedResultException {
if (num < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.UNLIKELY_PROBABILITY, array.getSize() == 0)) {
throw new UnexpectedResultException(nil());
} else {
final int numShift = array.getSize() < num ? array.getSize() : num;
final long[] store = ((long[]) array.getStore());
final RubyArray result = new RubyArray(getContext().getCoreLibrary().getArrayClass(), Arrays.copyOfRange(store, 0 , numShift), numShift);
final long[] filler = new long[numShift];
System.arraycopy(store, numShift, store, 0 , array.getSize() - numShift);
System.arraycopy(filler, 0, store, array.getSize() - numShift, numShift);
array.setStore(store, array.getSize() - numShift);
return result;
}
}

@Specialization(contains = "shiftLongFixnumInBoundsWithNum", guards = "isLongFixnum")
public Object shiftLongFixnumWithNum(VirtualFrame frame, RubyArray array, int num) {
if (num < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.UNLIKELY_PROBABILITY, array.getSize() == 0)) {
return nil();
} else {
final int numShift = array.getSize() < num ? array.getSize() : num;
final long[] store = ((long[]) array.getStore());
final RubyArray result = new RubyArray(getContext().getCoreLibrary().getArrayClass(), Arrays.copyOfRange(store, 0 , numShift), numShift);
final long[] filler = new long[numShift];
System.arraycopy(store, numShift, store, 0 , array.getSize() - numShift);
System.arraycopy(filler, 0, store, array.getSize() - numShift, numShift);
array.setStore(store, array.getSize() - numShift);
return result;
}
}

@Specialization(guards = "isFloat", rewriteOn = UnexpectedResultException.class)
public RubyArray shiftFloatInBoundsWithNum(VirtualFrame frame, RubyArray array, int num) throws UnexpectedResultException {
if (num < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.UNLIKELY_PROBABILITY, array.getSize() == 0)) {
throw new UnexpectedResultException(nil());
} else {
final int numShift = array.getSize() < num ? array.getSize() : num;
final double[] store = ((double[]) array.getStore());
final RubyArray result = new RubyArray(getContext().getCoreLibrary().getArrayClass(), Arrays.copyOfRange(store, 0, numShift), numShift);
final double[] filler = new double[numShift];
System.arraycopy(store, numShift, store, 0, array.getSize() - numShift);
System.arraycopy(filler, 0, store, array.getSize() - numShift, numShift);
array.setStore(store, array.getSize() - numShift);
return result;
}
}

@Specialization(contains = "shiftFloatInBoundsWithNum", guards = "isFloat")
public Object shiftFloatWithNum(VirtualFrame frame, RubyArray array, int num) {
if (num < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.UNLIKELY_PROBABILITY, array.getSize() == 0)) {
return nil();
} else {
final int numShift = array.getSize() < num ? array.getSize() : num;
final double[] store = ((double[]) array.getStore());
final RubyArray result = new RubyArray(getContext().getCoreLibrary().getArrayClass(), Arrays.copyOfRange(store, 0, numShift), numShift);
final double[] filler = new double[numShift];
System.arraycopy(store, numShift, store, 0, array.getSize() - numShift);
System.arraycopy(filler, 0, store, array.getSize() - numShift, numShift);
array.setStore(store, array.getSize() - numShift);
return result;
}
}

@Specialization(guards = "isObject")
public Object shiftObjectWithNum(VirtualFrame frame, RubyArray array, int num) {
if (num < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.UNLIKELY_PROBABILITY, array.getSize() == 0)) {
return nil();
} else {
final int numShift = array.getSize() < num ? array.getSize() : num;
final Object[] store = ((Object[]) array.getStore());
final RubyArray result = new RubyArray(getContext().getCoreLibrary().getArrayClass(), Arrays.copyOfRange(store, 0, numShift), numShift);
final Object[] filler = new Object[numShift];
System.arraycopy(store, numShift, store, 0, array.getSize() - numShift);
System.arraycopy(filler, 0, store, array.getSize() - numShift, numShift);
array.setStore(store, array.getSize() - numShift);
return result;
}
}

@Specialization(guards = {"isIntegerFixnum","!isInteger(arguments[1])","!isUndefinedPlaceholder(arguments[1])"}, rewriteOn = UnexpectedResultException.class)
public RubyArray shiftIntegerFixnumInBoundsWithNumObj(VirtualFrame frame, RubyArray array, Object object) throws UnexpectedResultException {
if (toIntNode == null) {
CompilerDirectives.transferToInterpreter();
toIntNode = insert(ToIntNodeFactory.create(getContext(), getSourceSection(), null));
}
final int num = toIntNode.executeIntegerFixnum(frame, object);
if (num < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.UNLIKELY_PROBABILITY, array.getSize() == 0)) {
throw new UnexpectedResultException(nil());
} else {
final int numShift = array.getSize() < num ? array.getSize() : num;
final int[] store = ((int[]) array.getStore());
final RubyArray result = new RubyArray(getContext().getCoreLibrary().getArrayClass(), Arrays.copyOfRange(store, 0 , numShift), numShift);
final int[] filler = new int[numShift];
System.arraycopy(store, numShift, store, 0 , array.getSize() - numShift);
System.arraycopy(filler, 0, store, array.getSize() - numShift, numShift);
array.setStore(store, array.getSize() - numShift);
return result;
}
}

return array.slowShift();
@Specialization(contains = "shiftIntegerFixnumInBoundsWithNumObj", guards = {"isIntegerFixnum","!isInteger(arguments[1])","!isUndefinedPlaceholder(arguments[1])"} )
public Object shiftIntegerFixnumWithNumObj(VirtualFrame frame, RubyArray array, Object object) {
if (toIntNode == null) {
CompilerDirectives.transferToInterpreter();
toIntNode = insert(ToIntNodeFactory.create(getContext(), getSourceSection(), null));
}
final int num = toIntNode.executeIntegerFixnum(frame, object);
if (num < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.UNLIKELY_PROBABILITY, array.getSize() == 0)) {
return nil();
} else {
final int numShift = array.getSize() < num ? array.getSize() : num;
final int[] store = ((int[]) array.getStore());
final RubyArray result = new RubyArray(getContext().getCoreLibrary().getArrayClass(), Arrays.copyOfRange(store, 0 , numShift), numShift);
final int[] filler = new int[numShift];
System.arraycopy(store, numShift, store, 0 , array.getSize() - numShift);
System.arraycopy(filler, 0, store, array.getSize() - numShift, numShift);
array.setStore(store, array.getSize() - numShift);
return result;
}
}

@Specialization(guards = {"isLongFixnum","!isInteger(arguments[1])","!isUndefinedPlaceholder(arguments[1])"} , rewriteOn = UnexpectedResultException.class)
public RubyArray shiftLongFixnumInBoundsWithNumObj(VirtualFrame frame, RubyArray array, Object object) throws UnexpectedResultException {
if (toIntNode == null) {
CompilerDirectives.transferToInterpreter();
toIntNode = insert(ToIntNodeFactory.create(getContext(), getSourceSection(), null));
}
final int num = toIntNode.executeIntegerFixnum(frame, object);
if (num < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.UNLIKELY_PROBABILITY, array.getSize() == 0)) {
throw new UnexpectedResultException(nil());
} else {
final int numShift = array.getSize() < num ? array.getSize() : num;
final long[] store = ((long[]) array.getStore());
final RubyArray result = new RubyArray(getContext().getCoreLibrary().getArrayClass(), Arrays.copyOfRange(store, 0 , numShift), numShift);
final long[] filler = new long[numShift];
System.arraycopy(store, numShift, store, 0 , array.getSize() - numShift);
System.arraycopy(filler, 0, store, array.getSize() - numShift, numShift);
array.setStore(store, array.getSize() - numShift);
return result;
}
}

@Specialization(contains = "shiftLongFixnumInBoundsWithNumObj", guards = {"isLongFixnum","!isInteger(arguments[1])","!isUndefinedPlaceholder(arguments[1])"})
public Object shiftLongFixnumWithNumObj(VirtualFrame frame, RubyArray array, Object object) {
if (toIntNode == null) {
CompilerDirectives.transferToInterpreter();
toIntNode = insert(ToIntNodeFactory.create(getContext(), getSourceSection(), null));
}
final int num = toIntNode.executeIntegerFixnum(frame, object);
if (num < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.UNLIKELY_PROBABILITY, array.getSize() == 0)) {
return nil();
} else {
final int numShift = array.getSize() < num ? array.getSize() : num;
final long[] store = ((long[]) array.getStore());
final RubyArray result = new RubyArray(getContext().getCoreLibrary().getArrayClass(), Arrays.copyOfRange(store, 0 , numShift), numShift);
final long[] filler = new long[numShift];
System.arraycopy(store, numShift, store, 0 , array.getSize() - numShift);
System.arraycopy(filler, 0, store, array.getSize() - numShift, numShift);
array.setStore(store, array.getSize() - numShift);
return result; }
}

@Specialization(guards = {"isFloat","!isInteger(arguments[1])","!isUndefinedPlaceholder(arguments[1])"}, rewriteOn = UnexpectedResultException.class)
public RubyArray shiftFloatInBoundsWithNumObj(VirtualFrame frame, RubyArray array, Object object) throws UnexpectedResultException {
if (toIntNode == null) {
CompilerDirectives.transferToInterpreter();
toIntNode = insert(ToIntNodeFactory.create(getContext(), getSourceSection(), null));
}
final int num = toIntNode.executeIntegerFixnum(frame, object);
if (num < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.UNLIKELY_PROBABILITY, array.getSize() == 0)) {
throw new UnexpectedResultException(nil());
} else {
final int numShift = array.getSize() < num ? array.getSize() : num;
final double[] store = ((double[]) array.getStore());
final RubyArray result = new RubyArray(getContext().getCoreLibrary().getArrayClass(), Arrays.copyOfRange(store, 0, array.getSize() - numShift), numShift);
final double[] filler = new double[numShift];
System.arraycopy(store, numShift, store, 0, array.getSize() - numShift);
System.arraycopy(filler, 0, store, array.getSize() - numShift, numShift);
array.setStore(store, array.getSize() - numShift);
return result;
}
}

@Specialization(contains = "shiftFloatInBoundsWithNumObj", guards = {"isFloat","!isInteger(arguments[1])","!isUndefinedPlaceholder(arguments[1])"})
public Object shiftFloatWithNumObj(VirtualFrame frame, RubyArray array, Object object) {
if (toIntNode == null) {
CompilerDirectives.transferToInterpreter();
toIntNode = insert(ToIntNodeFactory.create(getContext(), getSourceSection(), null));
}
final int num = toIntNode.executeIntegerFixnum(frame, object);
if (num < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.UNLIKELY_PROBABILITY, array.getSize() == 0)) {
return nil();
} else {
final int numShift = array.getSize() < num ? array.getSize() : num;
final double[] store = ((double[]) array.getStore());
final RubyArray result = new RubyArray(getContext().getCoreLibrary().getArrayClass(), Arrays.copyOfRange(store, 0, array.getSize() - numShift), numShift);
final double[] filler = new double[numShift];
System.arraycopy(store, numShift, store, 0, array.getSize() - numShift);
System.arraycopy(filler, 0, store, array.getSize() - numShift, numShift);
array.setStore(store, array.getSize() - numShift);
return result;
}
}

@Specialization(guards = {"isObject","!isInteger(arguments[1])","!isUndefinedPlaceholder(arguments[1])"})
public Object shiftObjectWithNumObj(VirtualFrame frame, RubyArray array, Object object) {
if (toIntNode == null) {
CompilerDirectives.transferToInterpreter();
toIntNode = insert(ToIntNodeFactory.create(getContext(), getSourceSection(), null));
}
final int num = toIntNode.executeIntegerFixnum(frame, object);
if (num < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative array size", this));
}
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.UNLIKELY_PROBABILITY, array.getSize() == 0)) {
return nil();
} else {
final int numShift = array.getSize() < num ? array.getSize() : num;
final Object[] store = ((Object[]) array.getStore());
final RubyArray result = new RubyArray(getContext().getCoreLibrary().getArrayClass(), Arrays.copyOfRange(store, 0, array.getSize() - numShift), numShift);
final Object[] filler = new Object[numShift];
System.arraycopy(store, numShift, store, 0, array.getSize() - numShift);
System.arraycopy(filler, 0, store, array.getSize() - numShift, numShift);
array.setStore(store, array.getSize() - numShift);
return result;
}
}
}

@CoreMethod(names = {"size", "length"})