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: 06ff2ad77ca3
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 1679da8fc5d8
Choose a head ref
  • 2 commits
  • 1 file changed
  • 1 contributor

Commits on Apr 13, 2016

  1. Copy the full SHA
    aef496c View commit details
  2. Copy the full SHA
    1679da8 View commit details
Showing with 30 additions and 73 deletions.
  1. +30 −73 truffle/src/main/java/org/jruby/truffle/core/array/ArrayReadSliceNormalizedNode.java
Original file line number Diff line number Diff line change
@@ -9,6 +9,8 @@
*/
package org.jruby.truffle.core.array;

import static org.jruby.truffle.core.array.ArrayHelpers.getSize;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.NodeChildren;
@@ -21,12 +23,10 @@
import org.jruby.truffle.language.objects.AllocateObjectNode;
import org.jruby.truffle.language.objects.AllocateObjectNodeGen;

import java.util.Arrays;

@NodeChildren({
@NodeChild(value="array", type=RubyNode.class),
@NodeChild(value="index", type=RubyNode.class),
@NodeChild(value="length", type=RubyNode.class)
@NodeChild(value = "array", type = RubyNode.class),
@NodeChild(value = "index", type = RubyNode.class),
@NodeChild(value = "length", type = RubyNode.class)
})
@ImportStatic(ArrayGuards.class)
public abstract class ArrayReadSliceNormalizedNode extends RubyNode {
@@ -42,16 +42,12 @@ public ArrayReadSliceNormalizedNode(RubyContext context, SourceSection sourceSec

// Index out of bounds or negative length always gives you nil

@Specialization(
guards = "!indexInBounds(array, index)"
)
@Specialization(guards = "!indexInBounds(array, index)")
public DynamicObject readIndexOutOfBounds(DynamicObject array, int index, int length) {
return nil();
}

@Specialization(
guards = "!lengthPositive(length)"
)
@Specialization(guards = "!lengthPositive(length)")
public DynamicObject readNegativeLength(DynamicObject array, int index, int length) {
return nil();
}
@@ -62,89 +58,50 @@ public DynamicObject readNegativeLength(DynamicObject array, int index, int leng
guards = { "indexInBounds(array, index)", "lengthPositive(length)", "isNullArray(array)" }
)
public DynamicObject readNull(DynamicObject array, int index, int length) {
return allocateObjectNode.allocate(Layouts.BASIC_OBJECT.getLogicalClass(array), null, 0);
return createArrayOfSameClass(array, null, 0);
}

// Reading within bounds on an array with actual storage

@Specialization(
guards = { "indexInBounds(array, index)", "lengthPositive(length)", "endInBounds(array, index, length)", "isIntArray(array)" }
)
public DynamicObject readIntInBounds(DynamicObject array, int index, int length) {
return allocateObjectNode.allocate(Layouts.BASIC_OBJECT.getLogicalClass(array), Arrays.copyOfRange((int[]) Layouts.ARRAY.getStore(array), index, index + length), length);
}

@Specialization(
guards = { "indexInBounds(array, index)", "lengthPositive(length)", "endInBounds(array, index, length)", "isLongArray(array)" }
)
public DynamicObject readLongInBounds(DynamicObject array, int index, int length) {
return allocateObjectNode.allocate(Layouts.BASIC_OBJECT.getLogicalClass(array), Arrays.copyOfRange((long[]) Layouts.ARRAY.getStore(array), index, index + length), length);
}

@Specialization(
guards = { "indexInBounds(array, index)", "lengthPositive(length)", "endInBounds(array, index, length)", "isDoubleArray(array)" }
)
public DynamicObject readDoubleInBounds(DynamicObject array, int index, int length) {
return allocateObjectNode.allocate(Layouts.BASIC_OBJECT.getLogicalClass(array), Arrays.copyOfRange((double[]) Layouts.ARRAY.getStore(array), index, index + length), length);
}

@Specialization(
guards = { "indexInBounds(array, index)", "lengthPositive(length)", "endInBounds(array, index, length)", "isObjectArray(array)" }
)
public DynamicObject readObjectInBounds(DynamicObject array, int index, int length) {
return allocateObjectNode.allocate(Layouts.BASIC_OBJECT.getLogicalClass(array), Arrays.copyOfRange((Object[]) Layouts.ARRAY.getStore(array), index, index + length), length);
@Specialization(guards = {
"indexInBounds(array, index)", "lengthPositive(length)", "endInBounds(array, index, length)",
"strategy.matches(array)"
}, limit = "ARRAY_STRATEGIES")
public DynamicObject readInBounds(DynamicObject array, int index, int length,
@Cached("of(array)") ArrayStrategy strategy) {
final Object store = strategy.newMirror(array).extractRange(index, index + length).getArray();
return createArrayOfSameClass(array, store, length);
}

// Reading beyond upper bounds on an array with actual storage needs clamping

@Specialization(
guards = { "indexInBounds(array, index)", "lengthPositive(length)", "!endInBounds(array, index, length)", "isIntArray(array)" }
)
public DynamicObject readIntOutOfBounds(DynamicObject array, int index, int length) {
final int clampedLength = Math.min(Layouts.ARRAY.getSize(array), index + length) - index;

return allocateObjectNode.allocate(Layouts.BASIC_OBJECT.getLogicalClass(array), Arrays.copyOfRange((int[]) Layouts.ARRAY.getStore(array), index, index + clampedLength), clampedLength);
}

@Specialization(
guards = { "indexInBounds(array, index)", "lengthPositive(length)", "!endInBounds(array, index, length)", "isLongArray(array)" }
)
public DynamicObject readLongOutOfBounds(DynamicObject array, int index, int length) {
final int clampedLength = Math.min(Layouts.ARRAY.getSize(array), index + length) - index;

return allocateObjectNode.allocate(Layouts.BASIC_OBJECT.getLogicalClass(array), Arrays.copyOfRange((long[]) Layouts.ARRAY.getStore(array), index, index + clampedLength), clampedLength);
}

@Specialization(
guards = { "indexInBounds(array, index)", "lengthPositive(length)", "!endInBounds(array, index, length)", "isDoubleArray(array)" }
)
public DynamicObject readDoubleOutOfBounds(DynamicObject array, int index, int length) {
final int clampedLength = Math.min(Layouts.ARRAY.getSize(array), index + length) - index;

return allocateObjectNode.allocate(Layouts.BASIC_OBJECT.getLogicalClass(array), Arrays.copyOfRange((double[]) Layouts.ARRAY.getStore(array), index, index + clampedLength), clampedLength);
@Specialization(guards = {
"indexInBounds(array, index)", "lengthPositive(length)", "!endInBounds(array, index, length)",
"strategy.matches(array)"
}, limit = "ARRAY_STRATEGIES")
public DynamicObject readOutOfBounds(DynamicObject array, int index, int length,
@Cached("of(array)") ArrayStrategy strategy) {
final int end = getSize(array);
final Object store = strategy.newMirror(array).extractRange(index, end).getArray();
return createArrayOfSameClass(array, store, end - index);
}

@Specialization(
guards = { "indexInBounds(array, index)", "lengthPositive(length)", "!endInBounds(array, index, length)", "isObjectArray(array)" }
)
public DynamicObject readObjectOutOfBounds(DynamicObject array, int index, int length) {
final int clampedLength = Math.min(Layouts.ARRAY.getSize(array), index + length) - index;
// Guards

return allocateObjectNode.allocate(Layouts.BASIC_OBJECT.getLogicalClass(array), Arrays.copyOfRange((Object[]) Layouts.ARRAY.getStore(array), index, index + clampedLength), clampedLength);
protected DynamicObject createArrayOfSameClass(DynamicObject array, Object store, int size) {
return allocateObjectNode.allocate(Layouts.BASIC_OBJECT.getLogicalClass(array), store, size);
}

// Guards

protected static boolean indexInBounds(DynamicObject array, int index) {
return index >= 0 && index <= Layouts.ARRAY.getSize(array);
return index >= 0 && index <= getSize(array);
}

protected static boolean lengthPositive(int length) {
return length >= 0;
}

protected static boolean endInBounds(DynamicObject array, int index, int length) {
return index + length < Layouts.ARRAY.getSize(array);
return index + length <= getSize(array);
}

}