Skip to content

Commit 50ac5ad

Browse files
committed
Add PSequence specializations for array constructor and extend
1 parent 054ab35 commit 50ac5ad

File tree

2 files changed

+87
-7
lines changed

2 files changed

+87
-7
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ArrayModuleBuiltins.java

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
import com.oracle.graal.python.builtins.objects.array.PArray;
4343
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
4444
import com.oracle.graal.python.builtins.objects.bytes.PBytesLike;
45+
import com.oracle.graal.python.builtins.objects.common.SequenceNodes;
46+
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
4547
import com.oracle.graal.python.builtins.objects.function.PKeyword;
4648
import com.oracle.graal.python.builtins.objects.module.PythonModule;
4749
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
@@ -60,6 +62,8 @@
6062
import com.oracle.graal.python.runtime.PythonCore;
6163
import com.oracle.graal.python.runtime.exception.PException;
6264
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
65+
import com.oracle.graal.python.runtime.sequence.PSequence;
66+
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
6367
import com.oracle.graal.python.util.BufferFormat;
6468
import com.oracle.graal.python.util.OverflowException;
6569
import com.oracle.graal.python.util.PythonUtils;
@@ -188,7 +192,43 @@ PArray arrayWithBytesInitializer(VirtualFrame frame, Object cls, String typeCode
188192
return array;
189193
}
190194

191-
// TODO impl for PSequence and PArray or use lenght_hint
195+
@Specialization
196+
PArray arrayArrayInitializer(VirtualFrame frame, Object cls, String typeCode, PArray initializer,
197+
@Cached ArrayNodes.PutValueNode putValueNode,
198+
@Cached ArrayNodes.GetValueNode getValueNode) {
199+
BufferFormat format = getFormatChecked(typeCode);
200+
try {
201+
PArray array = getFactory().createArray(cls, typeCode, format, initializer.getLength());
202+
for (int i = 0; i < initializer.getLength(); i++) {
203+
putValueNode.execute(frame, array, i, getValueNode.execute(initializer, i));
204+
}
205+
return array;
206+
} catch (OverflowException e) {
207+
CompilerDirectives.transferToInterpreterAndInvalidate();
208+
throw raise(MemoryError);
209+
}
210+
}
211+
212+
@Specialization
213+
PArray arraySequenceInitializer(VirtualFrame frame, Object cls, String typeCode, PSequence initializer,
214+
@Cached ArrayNodes.PutValueNode putValueNode,
215+
@Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode,
216+
@Cached SequenceStorageNodes.LenNode lenNode,
217+
@Cached SequenceStorageNodes.GetItemScalarNode getItemNode) {
218+
BufferFormat format = getFormatChecked(typeCode);
219+
SequenceStorage storage = getSequenceStorageNode.execute(initializer);
220+
int lenght = lenNode.execute(storage);
221+
try {
222+
PArray array = getFactory().createArray(cls, typeCode, format, lenght);
223+
for (int i = 0; i < lenght; i++) {
224+
putValueNode.execute(frame, array, i, getItemNode.execute(storage, i));
225+
}
226+
return array;
227+
} catch (OverflowException e) {
228+
CompilerDirectives.transferToInterpreterAndInvalidate();
229+
throw raise(MemoryError);
230+
}
231+
}
192232

193233
@Specialization(guards = "!isBytes(initializer)", limit = "3")
194234
PArray arrayIteratorInitializer(VirtualFrame frame, Object cls, String typeCode, Object initializer,

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/ArrayBuiltins.java

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
import com.oracle.graal.python.nodes.subscript.SliceLiteralNode;
9090
import com.oracle.graal.python.nodes.util.CastToJavaStringNode;
9191
import com.oracle.graal.python.runtime.exception.PException;
92+
import com.oracle.graal.python.runtime.sequence.PSequence;
9293
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
9394
import com.oracle.graal.python.util.BufferFormat;
9495
import com.oracle.graal.python.util.OverflowException;
@@ -697,12 +698,43 @@ Object extend(PArray self, PArray value) {
697698
}
698699
}
699700

700-
@Specialization(guards = "self.getFormat() != value.getFormat()")
701-
@SuppressWarnings("unused")
702-
Object error(PArray self, PArray value) {
703-
// CPython allows extending an array with an arbitrary iterable. Except a differently
704-
// formatted array. Weird
705-
throw raise(TypeError, "can only extend with array of same kind");
701+
@Specialization
702+
Object extend(VirtualFrame frame, PArray self, PSequence value,
703+
@Cached ArrayNodes.PutValueNode putValueNode,
704+
@Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode,
705+
@Cached SequenceStorageNodes.LenNode lenNode,
706+
@Cached SequenceStorageNodes.GetItemScalarNode getItemNode) {
707+
SequenceStorage storage = getSequenceStorageNode.execute(value);
708+
int storageLenght = lenNode.execute(storage);
709+
boolean capacityEnsured = false;
710+
try {
711+
self.ensureCapacity(PythonUtils.addExact(self.getLength(), storageLenght));
712+
capacityEnsured = true;
713+
} catch (OverflowException e) {
714+
CompilerDirectives.transferToInterpreterAndInvalidate();
715+
// Let it fail later, so that it fails in the same state as the generic
716+
// specialization
717+
}
718+
int lenght = self.getLength();
719+
for (int i = 0; i < storageLenght; i++) {
720+
// The whole extend is not atomic, just individual inserts are. That's the same as
721+
// in CPython
722+
if (capacityEnsured) {
723+
lenght++;
724+
} else {
725+
try {
726+
lenght = PythonUtils.addExact(lenght, 1);
727+
self.ensureCapacity(lenght);
728+
} catch (OverflowException e) {
729+
CompilerDirectives.transferToInterpreterAndInvalidate();
730+
throw raise(MemoryError);
731+
}
732+
}
733+
putValueNode.execute(frame, self, lenght - 1, getItemNode.execute(storage, i));
734+
self.setLenght(lenght);
735+
}
736+
737+
return PNone.NONE;
706738
}
707739

708740
@Specialization(guards = "!isArray(value)", limit = "3")
@@ -736,6 +768,14 @@ Object extend(VirtualFrame frame, PArray self, Object value,
736768

737769
return PNone.NONE;
738770
}
771+
772+
@Specialization(guards = "self.getFormat() != value.getFormat()")
773+
@SuppressWarnings("unused")
774+
Object error(PArray self, PArray value) {
775+
// CPython allows extending an array with an arbitrary iterable. Except a differently
776+
// formatted array. Weird
777+
throw raise(TypeError, "can only extend with array of same kind");
778+
}
739779
}
740780

741781
@Builtin(name = "insert", minNumOfPositionalArgs = 3, numOfPositionalOnlyArgs = 3, parameterNames = {"$self", "index", "value"})

0 commit comments

Comments
 (0)