-
-
Notifications
You must be signed in to change notification settings - Fork 925
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Truffle] New primitive array node for writing to an array by simple …
…index.
- 9.4.12.0
- 9.4.11.0
- 9.4.10.0
- 9.4.9.0
- 9.4.8.0
- 9.4.7.0
- 9.4.6.0
- 9.4.5.0
- 9.4.4.0
- 9.4.3.0
- 9.4.2.0
- 9.4.1.0
- 9.4.0.0
- 9.3.15.0
- 9.3.14.0
- 9.3.13.0
- 9.3.12.0
- 9.3.11.0
- 9.3.10.0
- 9.3.9.0
- 9.3.8.0
- 9.3.7.0
- 9.3.6.0
- 9.3.5.0
- 9.3.4.0
- 9.3.3.0
- 9.3.2.0
- 9.3.1.0
- 9.3.0.0
- 9.2.21.0
- 9.2.20.1
- 9.2.20.0
- 9.2.19.0
- 9.2.18.0
- 9.2.17.0
- 9.2.16.0
- 9.2.15.0
- 9.2.14.0
- 9.2.13.0
- 9.2.12.0
- 9.2.11.1
- 9.2.11.0
- 9.2.10.0
- 9.2.9.0
- 9.2.8.0
- 9.2.7.0
- 9.2.6.0
- 9.2.5.0
- 9.2.4.1
- 9.2.4.0
- 9.2.3.0
- 9.2.2.0
- 9.2.1.0
- 9.2.0.0
- 9.1.17.0
- 9.1.16.0
- 9.1.15.0
- 9.1.14.0
- 9.1.13.0
- 9.1.12.0
- 9.1.11.0
- 9.1.10.0
- 9.1.9.0
- 9.1.8.0
- 9.1.7.0
- 9.1.6.0
- 9.1.5.0
- 9.1.4.0
- 9.1.3.0
- 9.1.2.0
- 9.1.1.0
- 9.1.0.0
- 9.0.5.0
- 9.0.4.0
- 9.0.3.0
- 9.0.1.0
- 9.0.0.0
- 9.0.0.0.rc2
- 9.0.0.0.rc1
- 9.0.0.0.pre2
1 parent
4a5a146
commit a294f73
Showing
7 changed files
with
583 additions
and
299 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
truffle/src/main/java/org/jruby/truffle/nodes/array/ArrayWriteDenormalizedNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.nodes.array; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.source.SourceSection; | ||
import org.jruby.truffle.nodes.RubyNode; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
import org.jruby.truffle.runtime.core.RubyArray; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value="array", type=RubyNode.class), | ||
@NodeChild(value="index", type=RubyNode.class), | ||
@NodeChild(value="value", type=RubyNode.class) | ||
}) | ||
public abstract class ArrayWriteDenormalizedNode extends RubyNode { | ||
|
||
@Child private ArrayWriteNormalizedNode readNode; | ||
|
||
public ArrayWriteDenormalizedNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public ArrayWriteDenormalizedNode(ArrayWriteDenormalizedNode prev) { | ||
super(prev); | ||
readNode = prev.readNode; | ||
} | ||
|
||
public abstract Object executeWrite(VirtualFrame frame, RubyArray array, int index, Object value); | ||
|
||
@Specialization | ||
public Object read(VirtualFrame frame, RubyArray array, int index, Object value) { | ||
if (readNode == null) { | ||
CompilerDirectives.transferToInterpreter(); | ||
readNode = insert(ArrayWriteNormalizedNodeFactory.create(getContext(), getSourceSection(), null, null, null)); | ||
} | ||
|
||
final int normalizedIndex = array.normalizeIndex(index); | ||
|
||
return readNode.executeWrite(frame, array, normalizedIndex, value); | ||
This comment has been minimized.
Sorry, something went wrong. |
||
} | ||
|
||
} |
325 changes: 325 additions & 0 deletions
325
truffle/src/main/java/org/jruby/truffle/nodes/array/ArrayWriteNormalizedNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,325 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.nodes.array; | ||
|
||
import com.oracle.truffle.api.dsl.ImportGuards; | ||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.source.SourceSection; | ||
import org.jruby.truffle.nodes.RubyNode; | ||
import org.jruby.truffle.nodes.core.ArrayGuards; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
import org.jruby.truffle.runtime.core.RubyArray; | ||
import org.jruby.truffle.runtime.core.RubyBasicObject; | ||
import org.jruby.truffle.runtime.core.RubyNilClass; | ||
import org.jruby.truffle.runtime.util.ArrayUtils; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value="array", type=RubyNode.class), | ||
@NodeChild(value="index", type=RubyNode.class), | ||
@NodeChild(value="value", type=RubyNode.class) | ||
}) | ||
@ImportGuards(ArrayGuards.class) | ||
public abstract class ArrayWriteNormalizedNode extends RubyNode { | ||
|
||
@Child private EnsureCapacityArrayNode ensureCapacityNode; | ||
@Child private GeneralizeArrayNode generalizeNode; | ||
|
||
public ArrayWriteNormalizedNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
|
||
// TODO CS 9-Feb-15 make this lazy later on | ||
ensureCapacityNode = EnsureCapacityArrayNodeFactory.create(context, sourceSection, null, null); | ||
generalizeNode = GeneralizeArrayNodeFactory.create(context, sourceSection, null, null); | ||
} | ||
|
||
public ArrayWriteNormalizedNode(ArrayWriteNormalizedNode prev) { | ||
super(prev); | ||
ensureCapacityNode = prev.ensureCapacityNode; | ||
generalizeNode = prev.generalizeNode; | ||
} | ||
|
||
public abstract Object executeWrite(VirtualFrame frame, RubyArray array, int index, Object value); | ||
|
||
// Writing at index 0 into a null array creates a new array of the most specific type | ||
|
||
@Specialization( | ||
guards={"isNullArray", "isIndex0"} | ||
) | ||
public boolean writeNull0(RubyArray array, int index, boolean value) { | ||
array.setStore(new Object[]{value}, 1); | ||
return value; | ||
} | ||
|
||
@Specialization( | ||
guards={"isNullArray", "isIndex0"} | ||
) | ||
public int writeNull0(RubyArray array, int index, int value) { | ||
array.setStore(new int[]{value}, 1); | ||
return value; | ||
} | ||
|
||
@Specialization( | ||
guards={"isNullArray", "isIndex0"} | ||
) | ||
public long writeNull0(RubyArray array, int index, long value) { | ||
array.setStore(new long[]{value}, 1); | ||
return value; | ||
} | ||
|
||
@Specialization( | ||
guards={"isNullArray", "isIndex0"} | ||
) | ||
public double writeNull0(RubyArray array, int index, double value) { | ||
array.setStore(new double[]{value}, 1); | ||
return value; | ||
} | ||
|
||
@Specialization( | ||
guards={"isNullArray", "isIndex0"} | ||
) | ||
public RubyBasicObject writeNull0(RubyArray array, int index, RubyBasicObject value) { | ||
array.setStore(new Object[]{value}, 1); | ||
return value; | ||
} | ||
|
||
// Writing beyond index 0 in a null array creates an Object[] as we need to fill the rest with nil | ||
|
||
@Specialization( | ||
guards={"isNullArray", "!isIndex0"} | ||
) | ||
public Object writeNullBeyond(RubyArray array, int index, Object value) { | ||
final Object[] store = new Object[index + 1]; | ||
|
||
for (int n = 0; n < index; n++) { | ||
store[n] = getContext().getCoreLibrary().getNilObject(); | ||
} | ||
|
||
store[index] = value; | ||
array.setStore(store, store.length); | ||
return value; | ||
} | ||
|
||
// Writing within an existing array with a compatible type | ||
|
||
@Specialization( | ||
guards={"isObjectArray", "isInBounds"} | ||
) | ||
public boolean writeWithin(RubyArray array, int index, boolean value) { | ||
final Object[] store = (Object[]) array.getStore(); | ||
store[index] = value; | ||
return value; | ||
} | ||
|
||
@Specialization( | ||
guards={"isIntArray", "isInBounds"} | ||
) | ||
public int writeWithin(RubyArray array, int index, int value) { | ||
final int[] store = (int[]) array.getStore(); | ||
store[index] = value; | ||
return value; | ||
} | ||
|
||
@Specialization( | ||
guards={"isLongArray", "isInBounds"} | ||
) | ||
public int writeWithinIntIntoLong(RubyArray array, int index, int value) { | ||
writeWithin(array, index, (long) value); | ||
return value; | ||
} | ||
|
||
@Specialization( | ||
guards={"isLongArray", "isInBounds"} | ||
) | ||
public long writeWithin(RubyArray array, int index, long value) { | ||
final long[] store = (long[]) array.getStore(); | ||
store[index] = value; | ||
return value; | ||
} | ||
|
||
@Specialization( | ||
guards={"isDoubleArray", "isInBounds"} | ||
) | ||
public double writeWithin(RubyArray array, int index, double value) { | ||
final double[] store = (double[]) array.getStore(); | ||
store[index] = value; | ||
return value; | ||
} | ||
|
||
@Specialization( | ||
guards={"isObjectArray", "isInBounds"} | ||
) | ||
public Object writeWithin(RubyArray array, int index, Object value) { | ||
final Object[] store = (Object[]) array.getStore(); | ||
store[index] = value; | ||
return value; | ||
} | ||
|
||
// Writing within an existing array with an incompatible type - need to generalise | ||
|
||
@Specialization( | ||
guards={"isIntArray", "isInBounds"} | ||
) | ||
public long writeWithinInt(RubyArray array, int index, long value) { | ||
final int[] intStore = (int[]) array.getStore(); | ||
final long[] longStore = new long[array.getSize()]; | ||
|
||
for (int n = 0; n < array.getSize(); n++) { | ||
longStore[n] = intStore[n]; | ||
} | ||
|
||
longStore[index] = value; | ||
array.setStore(longStore, array.getSize()); | ||
return value; | ||
} | ||
|
||
@Specialization( | ||
guards={"isIntArray", "isInBounds", "!isInteger(value)", "!isLong(value)"} | ||
) | ||
public Object writeWithinInt(RubyArray array, int index, Object value) { | ||
final Object[] objectStore = ArrayUtils.box((int[]) array.getStore()); | ||
objectStore[index] = value; | ||
array.setStore(objectStore, array.getSize()); | ||
return value; | ||
} | ||
|
||
@Specialization( | ||
guards={"isLongArray", "isInBounds", "!isInteger(value)", "!isLong(value)"} | ||
) | ||
public Object writeWithinLong(RubyArray array, int index, Object value) { | ||
final Object[] objectStore = ArrayUtils.box((long[]) array.getStore()); | ||
objectStore[index] = value; | ||
array.setStore(objectStore, array.getSize()); | ||
return value; | ||
} | ||
|
||
@Specialization( | ||
guards={"isDoubleArray", "isInBounds", "!isDouble(value)"} | ||
) | ||
public Object writeWithinDouble(RubyArray array, int index, Object value) { | ||
final Object[] objectStore = ArrayUtils.box((double[]) array.getStore()); | ||
objectStore[index] = value; | ||
array.setStore(objectStore, array.getSize()); | ||
return value; | ||
} | ||
|
||
// Extending an array of compatible type by just one | ||
|
||
@Specialization( | ||
guards={"isObjectArray", "isExtendingByOne"} | ||
) | ||
public boolean writeExtendByOne(VirtualFrame frame, RubyArray array, int index, boolean value) { | ||
ensureCapacityNode.executeEnsureCapacity(frame, array, index + 1); | ||
((Object[]) array.getStore())[index] = value; | ||
array.setStore(array.getStore(), index + 1); | ||
return value; | ||
} | ||
|
||
@Specialization( | ||
guards={"isIntArray", "isExtendingByOne"} | ||
) | ||
public int writeExtendByOne(VirtualFrame frame, RubyArray array, int index, int value) { | ||
ensureCapacityNode.executeEnsureCapacity(frame, array, index + 1); | ||
((int[]) array.getStore())[index] = value; | ||
array.setStore(array.getStore(), index + 1); | ||
return value; | ||
} | ||
|
||
@Specialization( | ||
guards={"isLongArray", "isExtendingByOne"} | ||
) | ||
public int writeExtendByOneIntIntoLong(VirtualFrame frame, RubyArray array, int index, int value) { | ||
ensureCapacityNode.executeEnsureCapacity(frame, array, index + 1); | ||
((long[]) array.getStore())[index] = value; | ||
array.setStore(array.getStore(), index + 1); | ||
return value; | ||
} | ||
|
||
@Specialization( | ||
guards={"isLongArray", "isExtendingByOne"} | ||
) | ||
public long writeExtendByOne(VirtualFrame frame, RubyArray array, int index, long value) { | ||
ensureCapacityNode.executeEnsureCapacity(frame, array, index + 1); | ||
((long[]) array.getStore())[index] = value; | ||
array.setStore(array.getStore(), index + 1); | ||
return value; | ||
} | ||
|
||
@Specialization( | ||
guards={"isDoubleArray", "isExtendingByOne"} | ||
) | ||
public double writeExtendByOne(VirtualFrame frame, RubyArray array, int index, double value) { | ||
ensureCapacityNode.executeEnsureCapacity(frame, array, index + 1); | ||
((double[]) array.getStore())[index] = value; | ||
array.setStore(array.getStore(), index + 1); | ||
return value; | ||
} | ||
|
||
@Specialization( | ||
guards={"isObjectArray", "isExtendingByOne"} | ||
) | ||
public RubyBasicObject writeExtendByOne(VirtualFrame frame, RubyArray array, int index, RubyBasicObject value) { | ||
ensureCapacityNode.executeEnsureCapacity(frame, array, index + 1); | ||
((Object[]) array.getStore())[index] = value; | ||
array.setStore(array.getStore(), index + 1); | ||
return value; | ||
} | ||
|
||
// Writing beyond the end of an array - may need to generalise to Object[] or otherwise extend | ||
|
||
@Specialization( | ||
guards={"!isObjectArray", "!isInBounds", "!isExtendingByOne"} | ||
) | ||
public Object writeBeyondPrimitive(VirtualFrame frame, RubyArray array, int index, Object value) { | ||
generalizeNode.executeGeneralize(frame, array, index + 1); | ||
final Object[] objectStore = ((Object[]) array.getStore()); | ||
|
||
for (int n = array.getSize(); n < index; n++) { | ||
objectStore[n] = getContext().getCoreLibrary().getNilObject(); | ||
} | ||
|
||
objectStore[index] = value; | ||
array.setStore(array.getStore(), index + 1); | ||
return value; | ||
} | ||
|
||
@Specialization( | ||
guards={"isObjectArray", "!isInBounds", "!isExtendingByOne"} | ||
) | ||
public Object writeBeyondObject(VirtualFrame frame, RubyArray array, int index, Object value) { | ||
ensureCapacityNode.executeEnsureCapacity(frame, array, index + 1); | ||
final Object[] objectStore = ((Object[]) array.getStore()); | ||
|
||
for (int n = array.getSize(); n < index; n++) { | ||
objectStore[n] = getContext().getCoreLibrary().getNilObject(); | ||
} | ||
|
||
objectStore[index] = value; | ||
array.setStore(array.getStore(), index + 1); | ||
return value; | ||
} | ||
|
||
// Guards | ||
|
||
protected static boolean isInBounds(RubyArray array, int index) { | ||
return index >= 0 && index < array.getSize(); | ||
} | ||
|
||
protected static boolean isExtendingByOne(RubyArray array, int index) { | ||
return index == array.getSize(); | ||
} | ||
|
||
protected static boolean isIndex0(RubyArray array, int index) { | ||
return index == 0; | ||
} | ||
|
||
} |
102 changes: 102 additions & 0 deletions
102
truffle/src/main/java/org/jruby/truffle/nodes/array/EnsureCapacityArrayNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.nodes.array; | ||
|
||
import com.oracle.truffle.api.dsl.ImportGuards; | ||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.source.SourceSection; | ||
import com.oracle.truffle.api.utilities.ConditionProfile; | ||
import org.jruby.truffle.nodes.RubyNode; | ||
import org.jruby.truffle.nodes.core.ArrayGuards; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
import org.jruby.truffle.runtime.core.RubyArray; | ||
import org.jruby.truffle.runtime.util.ArrayUtils; | ||
|
||
import java.util.Arrays; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value="array", type=RubyNode.class), | ||
@NodeChild(value="requiredCapacity", type=RubyNode.class) | ||
}) | ||
@ImportGuards(ArrayGuards.class) | ||
public abstract class EnsureCapacityArrayNode extends RubyNode { | ||
|
||
private final ConditionProfile allocateProfile = ConditionProfile.createCountingProfile(); | ||
|
||
public EnsureCapacityArrayNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public EnsureCapacityArrayNode(EnsureCapacityArrayNode prev) { | ||
super(prev); | ||
} | ||
|
||
public abstract Object executeEnsureCapacity(VirtualFrame frame, RubyArray array, int requiredCapacity); | ||
|
||
@Specialization( | ||
guards={"isIntArray"} | ||
) | ||
public boolean ensureCapacityInt(RubyArray array, int requiredCapacity) { | ||
final int[] store = (int[]) array.getStore(); | ||
|
||
if (allocateProfile.profile(store.length < requiredCapacity)) { | ||
array.setStore(Arrays.copyOf(store, ArrayUtils.capacity(store.length, requiredCapacity)), array.getSize()); | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
} | ||
|
||
@Specialization( | ||
guards={"isLongArray"} | ||
) | ||
public boolean ensureCapacityLong(RubyArray array, int requiredCapacity) { | ||
final long[] store = (long[]) array.getStore(); | ||
|
||
if (allocateProfile.profile(store.length < requiredCapacity)) { | ||
array.setStore(Arrays.copyOf(store, ArrayUtils.capacity(store.length, requiredCapacity)), array.getSize()); | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
} | ||
|
||
@Specialization( | ||
guards={"isDoubleArray"} | ||
) | ||
public boolean ensureCapacityDouble(RubyArray array, int requiredCapacity) { | ||
final double[] store = (double[]) array.getStore(); | ||
|
||
if (allocateProfile.profile(store.length < requiredCapacity)) { | ||
array.setStore(Arrays.copyOf(store, ArrayUtils.capacity(store.length, requiredCapacity)), array.getSize()); | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
} | ||
|
||
@Specialization( | ||
guards={"isObjectArray"} | ||
) | ||
public boolean ensureCapacityObject(RubyArray array, int requiredCapacity) { | ||
final Object[] store = (Object[]) array.getStore(); | ||
|
||
if (allocateProfile.profile(store.length < requiredCapacity)) { | ||
array.setStore(Arrays.copyOf(store, ArrayUtils.capacity(store.length, requiredCapacity)), array.getSize()); | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
} | ||
|
||
} |
81 changes: 81 additions & 0 deletions
81
truffle/src/main/java/org/jruby/truffle/nodes/array/GeneralizeArrayNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.nodes.array; | ||
|
||
import com.oracle.truffle.api.dsl.ImportGuards; | ||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.source.SourceSection; | ||
import com.oracle.truffle.api.utilities.ConditionProfile; | ||
import org.jruby.truffle.nodes.RubyNode; | ||
import org.jruby.truffle.nodes.core.ArrayGuards; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
import org.jruby.truffle.runtime.core.RubyArray; | ||
import org.jruby.truffle.runtime.util.ArrayUtils; | ||
|
||
import java.util.Arrays; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value="array", type=RubyNode.class), | ||
@NodeChild(value="requiredCapacity", type=RubyNode.class) | ||
}) | ||
@ImportGuards(ArrayGuards.class) | ||
public abstract class GeneralizeArrayNode extends RubyNode { | ||
|
||
public GeneralizeArrayNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public GeneralizeArrayNode(GeneralizeArrayNode prev) { | ||
super(prev); | ||
} | ||
|
||
public abstract Object executeGeneralize(VirtualFrame frame, RubyArray array, int requiredCapacity); | ||
|
||
// TODO CS 9-Feb-15 should use ArrayUtils.capacity? | ||
|
||
@Specialization( | ||
guards={"isNullArray"} | ||
) | ||
public RubyArray generalizeNull(RubyArray array, int requiredCapacity) { | ||
array.setStore(new Object[requiredCapacity], array.getSize()); | ||
return array; | ||
} | ||
|
||
@Specialization( | ||
guards={"isIntArray"} | ||
) | ||
public RubyArray generalizeInt(RubyArray array, int requiredCapacity) { | ||
final int[] intStore = (int[]) array.getStore(); | ||
array.setStore(ArrayUtils.box(intStore, requiredCapacity - intStore.length), array.getSize()); | ||
return array; | ||
} | ||
|
||
@Specialization( | ||
guards={"isLongArray"} | ||
) | ||
public RubyArray generalizeLong(RubyArray array, int requiredCapacity) { | ||
final long[] intStore = (long[]) array.getStore(); | ||
array.setStore(ArrayUtils.box(intStore, requiredCapacity - intStore.length), array.getSize()); | ||
return array; | ||
} | ||
|
||
@Specialization( | ||
guards={"isDoubleArray"} | ||
) | ||
public RubyArray generalizeDouble(RubyArray array, int requiredCapacity) { | ||
final double[] intStore = (double[]) array.getStore(); | ||
array.setStore(ArrayUtils.box(intStore, requiredCapacity - intStore.length), array.getSize()); | ||
return array; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This reads in a interesting way 😉