Skip to content

Commit

Permalink
Showing 2 changed files with 27 additions and 6 deletions.
4 changes: 0 additions & 4 deletions spec/truffle/tags/core/array/element_set_tags.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
fails:Array#[]= sets elements in the range arguments when passed ranges
fails:Array#[]= does nothing if the section defined by range has negative width and the rhs is an empty array
fails:Array#[]= tries to convert Range elements to Integers using #to_int with [m..n] and [m...n]
fails:Array#[]= calls to_ary on its rhs argument for multi-element sets
fails:Array#[]= with [m..n] inserts the other section at m if m > n
fails:Array#[]= with [m..n] accepts Range subclasses
29 changes: 27 additions & 2 deletions truffle/src/main/java/org/jruby/truffle/core/array/ArrayNodes.java
Original file line number Diff line number Diff line change
@@ -378,7 +378,7 @@ public Object set(DynamicObject array, int index, Object value, NotProvided unus

// array[index] = object with non-int index

@Specialization(guards = { "!isInteger(indexObject)", "!isIntegerFixnumRange(indexObject)" })
@Specialization(guards = { "!isInteger(indexObject)", "!isIntegerFixnumRange(indexObject)", "!isObjectRange(indexObject)" })
public Object set(VirtualFrame frame, DynamicObject array, Object indexObject, Object value, NotProvided unused) {
final int index = toInt(frame, indexObject);
return executeSet(frame, array, index, value, unused);
@@ -504,9 +504,34 @@ public Object setRange(VirtualFrame frame, DynamicObject array, DynamicObject ra
inclusiveEnd = -1;
}
final int length = inclusiveEnd - start + 1;
return executeSet(frame, array, start, length, value);
final int normalizeLength = length > -1 ? length : 0;
return executeSet(frame, array, start, normalizeLength, value);
}

@Specialization(guards = "isObjectRange(range)")
public Object setObjectRange(VirtualFrame frame, DynamicObject array, DynamicObject range, Object value, NotProvided unused,
@Cached("createBinaryProfile()") ConditionProfile negativeBeginProfile,
@Cached("createBinaryProfile()") ConditionProfile negativeEndProfile,
@Cached("create()") BranchProfile errorProfile) {
final int size = getSize(array);
final int begin = toInt(frame, Layouts.OBJECT_RANGE.getBegin(range));

final int start = ArrayOperations.normalizeIndex(size, begin, negativeBeginProfile);
if (start < 0) {
errorProfile.enter();
throw new RaiseException(coreExceptions().rangeError(range, this));
}
final int end = ArrayOperations.normalizeIndex(size, toInt(frame, Layouts.OBJECT_RANGE.getEnd(range)), negativeEndProfile);
int inclusiveEnd = Layouts.OBJECT_RANGE.getExcludedEnd(range) ? end - 1 : end;
if (inclusiveEnd < 0) {
inclusiveEnd = -1;
}
final int length = inclusiveEnd - start + 1;
final int normalizeLength = length > -1 ? length : 0;
return executeSet(frame, array, start, normalizeLength, value);
}


// Helpers

private void checkIndex(DynamicObject array, int index, int normalizedIndex) {

0 comments on commit 310353f

Please sign in to comment.