Skip to content

Commit

Permalink
[Truffle] Adding Array#delete_if separately from Array#reject! becaus…
Browse files Browse the repository at this point in the history
…e of different return values when no modifications are made.
  • Loading branch information
bjfish committed Mar 22, 2015
1 parent 819bb9c commit 0bc4a57
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 3 deletions.
1 change: 0 additions & 1 deletion spec/truffle/tags/core/array/delete_if_tags.txt

This file was deleted.

124 changes: 122 additions & 2 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/ArrayNodes.java
Expand Up @@ -3337,7 +3337,127 @@ public Object selectFixnumInteger(VirtualFrame frame, RubyArray array, RubyProc

}

@CoreMethod(names = { "reject!", "delete_if" }, needsBlock = true, returnsEnumeratorIfNoBlock = true, raiseIfFrozenSelf = true)
@CoreMethod(names = "delete_if" , needsBlock = true, returnsEnumeratorIfNoBlock = true, raiseIfFrozenSelf = true)
@ImportGuards(ArrayGuards.class)
public abstract static class DeleteIfNode extends YieldingCoreMethodNode {

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

public DeleteIfNode(DeleteIfNode prev) {
super(prev);
}

@Specialization(guards = "isNullArray")
public Object rejectInPlaceNull(VirtualFrame frame, RubyArray array, RubyProc block) {
return array;
}

@Specialization(guards = "isIntArray")
public Object rejectInPlaceInt(VirtualFrame frame, RubyArray array, RubyProc block) {
final int[] store = (int[]) array.getStore();

int i = 0;
int n = 0;
for (; n < array.getSize(); n++) {
if (yieldIsTruthy(frame, block, store[n])) {
continue;
}

if (i != n) {
store[i] = store[n];
}

i++;
}
if (i != n) {
final int[] filler = new int[n - i];
System.arraycopy(filler, 0, store, i, n - i);
array.setStore(store, i);
}
return array;
}

@Specialization(guards = "isLongArray")
public Object rejectInPlaceLong(VirtualFrame frame, RubyArray array, RubyProc block) {
final long[] store = (long[]) array.getStore();

int i = 0;
int n = 0;
for (; n < array.getSize(); n++) {
if (yieldIsTruthy(frame, block, store[n])) {
continue;
}

if (i != n) {
store[i] = store[n];
}

i++;
}
if (i != n) {
final long[] filler = new long[n - i];
System.arraycopy(filler, 0, store, i, n - i);
array.setStore(store, i);
}
return array;
}

@Specialization(guards = "isDoubleArray")
public Object rejectInPlaceDouble(VirtualFrame frame, RubyArray array, RubyProc block) {
final double[] store = (double[]) array.getStore();

int i = 0;
int n = 0;
for (; n < array.getSize(); n++) {
if (yieldIsTruthy(frame, block, store[n])) {
continue;
}

if (i != n) {
store[i] = store[n];
}

i++;
}
if (i != n) {
final double[] filler = new double[n - i];
System.arraycopy(filler, 0, store, i, n - i);
array.setStore(store, i);
}
return array;
}

@Specialization(guards = "isObjectArray")
public Object rejectInPlaceObject(VirtualFrame frame, RubyArray array, RubyProc block) {
final Object[] store = (Object[]) array.getStore();

int i = 0;
int n = 0;
for (; n < array.getSize(); n++) {
if (yieldIsTruthy(frame, block, store[n])) {
continue;
}

if (i != n) {
store[i] = store[n];
}

i++;
}
if (i != n) {
final Object[] filler = new Object[n - i];
System.arraycopy(filler, 0, store, i, n - i);
array.setStore(store, i);
}
return array;
}

}


@CoreMethod(names = "reject!", needsBlock = true, returnsEnumeratorIfNoBlock = true, raiseIfFrozenSelf = true)
@ImportGuards(ArrayGuards.class)
public abstract static class RejectInPlaceNode extends YieldingCoreMethodNode {

Expand All @@ -3351,7 +3471,7 @@ public RejectInPlaceNode(RejectInPlaceNode prev) {

@Specialization(guards = "isNullArray")
public Object rejectInPlaceNull(VirtualFrame frame, RubyArray array, RubyProc block) {
return array;
return nil();
}

@Specialization(guards = "isIntArray")
Expand Down

0 comments on commit 0bc4a57

Please sign in to comment.