Skip to content

Commit 7b206aa

Browse files
committed
[Truffle] Randomise empty arrays to any storage type.
1 parent 1993f47 commit 7b206aa

File tree

4 files changed

+145
-1
lines changed

4 files changed

+145
-1
lines changed

truffle/src/main/java/org/jruby/truffle/nodes/RubyCallNode.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public class RubyCallNode extends RubyNode {
4646
@CompilerDirectives.CompilationFinal private boolean seenNullInUnsplat = false;
4747
@CompilerDirectives.CompilationFinal private boolean seenIntegerFixnumInUnsplat = false;
4848
@CompilerDirectives.CompilationFinal private boolean seenLongFixnumInUnsplat = false;
49+
@CompilerDirectives.CompilationFinal private boolean seenFloatInUnsplat = false;
4950
@CompilerDirectives.CompilationFinal private boolean seenObjectInUnsplat = false;
5051

5152
@Child private CallDispatchHeadNode respondToMissing;
@@ -136,6 +137,8 @@ private Object[] splat(Object argument) {
136137
return ArrayUtils.boxUntil((int[]) store, size);
137138
} else if (seenLongFixnumInUnsplat && store instanceof long[]) {
138139
return ArrayUtils.boxUntil((long[]) store, size);
140+
} else if (seenFloatInUnsplat && store instanceof double[]) {
141+
return ArrayUtils.boxUntil((double[]) store, size);
139142
} else if (seenObjectInUnsplat && store instanceof Object[]) {
140143
return ArrayUtils.extractRange((Object[]) store, 0, size);
141144
}
@@ -151,6 +154,9 @@ private Object[] splat(Object argument) {
151154
} else if (store instanceof long[]) {
152155
seenLongFixnumInUnsplat = true;
153156
return ArrayUtils.boxUntil((long[]) store, size);
157+
} else if (store instanceof double[]) {
158+
seenFloatInUnsplat = true;
159+
return ArrayUtils.boxUntil((double[]) store, size);
154160
} else if (store instanceof Object[]) {
155161
seenObjectInUnsplat = true;
156162
return ArrayUtils.extractRange((Object[]) store, 0, size);

truffle/src/main/java/org/jruby/truffle/nodes/core/ArrayBuilderNode.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,36 @@ public Object append(Object store, int index, RubyArray array) {
440440

441441
CompilerDirectives.transferToInterpreterAndInvalidate();
442442

443+
if (otherStore instanceof int[]) {
444+
// TODO CS 5-Feb-15 hack to get things working with empty int[] store
445+
446+
if (((int[]) otherStore).length > 0) {
447+
throw new UnsupportedOperationException();
448+
}
449+
450+
return store;
451+
}
452+
453+
if (otherStore instanceof long[]) {
454+
// TODO CS 5-Feb-15 hack to get things working with empty long[] store
455+
456+
if (((long[]) otherStore).length > 0) {
457+
throw new UnsupportedOperationException();
458+
}
459+
460+
return store;
461+
}
462+
463+
if (otherStore instanceof double[]) {
464+
// TODO CS 5-Feb-15 hack to get things working with empty double[] store
465+
466+
if (((double[]) otherStore).length > 0) {
467+
throw new UnsupportedOperationException();
468+
}
469+
470+
return store;
471+
}
472+
443473
if (otherStore instanceof Object[]) {
444474
hasAppendedObjectArray = true;
445475
System.arraycopy(otherStore, 0, store, index, array.getSize());

truffle/src/main/java/org/jruby/truffle/nodes/core/ArrayNodes.java

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,54 @@ public RubyArray addNullObject(RubyArray a, RubyArray b) {
136136
return new RubyArray(getContext().getCoreLibrary().getArrayClass(), Arrays.copyOf((Object[]) b.getStore(), size), size);
137137
}
138138

139+
@Specialization(guards = "isIntegerFixnum")
140+
public RubyArray addEmptyIntegerFixnum(RubyArray a, RubyArray b) {
141+
// TODO CS 5-Feb-15 hack to get things working with empty int[] store
142+
143+
if (a.getSize() != 0) {
144+
throw new UnsupportedOperationException();
145+
}
146+
147+
final int size = b.getSize();
148+
return new RubyArray(getContext().getCoreLibrary().getArrayClass(), ArrayUtils.box(b.getStore()), size);
149+
}
150+
151+
@Specialization(guards = "isLongFixnum")
152+
public RubyArray addEmptyLongFixnum(RubyArray a, RubyArray b) {
153+
// TODO CS 5-Feb-15 hack to get things working with empty long[] store
154+
155+
if (a.getSize() != 0) {
156+
throw new UnsupportedOperationException();
157+
}
158+
159+
final int size = b.getSize();
160+
return new RubyArray(getContext().getCoreLibrary().getArrayClass(), ArrayUtils.box(b.getStore()), size);
161+
}
162+
163+
@Specialization(guards = "isFloat")
164+
public RubyArray addEmptyDouble(RubyArray a, RubyArray b) {
165+
// TODO CS 5-Feb-15 hack to get things working with empty double[] store
166+
167+
if (a.getSize() != 0) {
168+
throw new UnsupportedOperationException();
169+
}
170+
171+
final int size = b.getSize();
172+
return new RubyArray(getContext().getCoreLibrary().getArrayClass(), ArrayUtils.box(b.getStore()), size);
173+
}
174+
175+
@Specialization(guards = "isObject")
176+
public RubyArray addEmptyObject(RubyArray a, RubyArray b) {
177+
// TODO CS 5-Feb-15 hack to get things working with empty Object[] store
178+
179+
if (a.getSize() != 0) {
180+
throw new UnsupportedOperationException();
181+
}
182+
183+
final int size = b.getSize();
184+
return new RubyArray(getContext().getCoreLibrary().getArrayClass(), ArrayUtils.box(b.getStore()), size);
185+
}
186+
139187
}
140188

141189
@CoreMethod(names = "-", required = 1)
@@ -2084,6 +2132,23 @@ public boolean includeLongFixnum(VirtualFrame frame, RubyArray array, Object val
20842132
return false;
20852133
}
20862134

2135+
@Specialization(guards = "isFloat")
2136+
public boolean includeFloat(VirtualFrame frame, RubyArray array, Object value) {
2137+
final double[] store = (double[]) array.getStore();
2138+
2139+
for (int n = 0; n < array.getSize(); n++) {
2140+
final Object stored = store[n];
2141+
2142+
notDesignedForCompilation();
2143+
2144+
if (equalNode.executeSameOrEqual(frame, stored, value)) {
2145+
return true;
2146+
}
2147+
}
2148+
2149+
return false;
2150+
}
2151+
20872152
@Specialization(guards = "isObject")
20882153
public boolean includeObject(VirtualFrame frame, RubyArray array, Object value) {
20892154
final Object[] store = (Object[]) array.getStore();
@@ -3289,6 +3354,30 @@ public RubyArray pushLongFixnumSingleLongFixnum(RubyArray array, Object... value
32893354
return array;
32903355
}
32913356

3357+
@Specialization(guards = "isLongFixnum")
3358+
public RubyArray pushLongFixnum(RubyArray array, Object... values) {
3359+
// TODO CS 5-Feb-15 hack to get things working with empty long[] store
3360+
3361+
if (array.getSize() != 0) {
3362+
throw new UnsupportedOperationException();
3363+
}
3364+
3365+
array.setStore(values, values.length);
3366+
return array;
3367+
}
3368+
3369+
@Specialization(guards = "isFloat")
3370+
public RubyArray pushFloat(RubyArray array, Object... values) {
3371+
// TODO CS 5-Feb-15 hack to get things working with empty double[] store
3372+
3373+
if (array.getSize() != 0) {
3374+
throw new UnsupportedOperationException();
3375+
}
3376+
3377+
array.setStore(values, values.length);
3378+
return array;
3379+
}
3380+
32923381
@Specialization(guards = "isObject")
32933382
public RubyArray pushObject(RubyArray array, Object... values) {
32943383
final int oldSize = array.getSize();

truffle/src/main/java/org/jruby/truffle/runtime/core/RubyArray.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,25 @@ public void setStore(Object store, int size) {
223223

224224
@CompilerDirectives.TruffleBoundary
225225
private static Object randomizeStorageStrategy(Object store, int size) {
226+
// Use any type for empty arrays
227+
228+
if (size == 0) {
229+
switch (random.nextInt(5)) {
230+
case 0:
231+
return null;
232+
case 1:
233+
return new int[]{};
234+
case 2:
235+
return new long[]{};
236+
case 3:
237+
return new double[]{};
238+
case 4:
239+
return new Object[]{};
240+
default:
241+
throw new IllegalStateException();
242+
}
243+
}
244+
226245
// Convert to the canonical store type first
227246

228247
final Object[] boxedStore = ArrayUtils.box(store);
@@ -272,7 +291,7 @@ private static Object randomizeStorageStrategy(Object store, int size) {
272291

273292
return canonicalStore;
274293
} else {
275-
return canonicalStore;
294+
throw new UnsupportedOperationException();
276295
}
277296
}
278297

0 commit comments

Comments
 (0)