Skip to content

Commit db5c968

Browse files
committed
Use PythonObjectLibrary in bytes starts/endswith
1 parent 229b97d commit db5c968

File tree

1 file changed

+68
-67
lines changed
  • graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes

1 file changed

+68
-67
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesBuiltins.java

Lines changed: 68 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@
107107
import com.oracle.truffle.api.dsl.Specialization;
108108
import com.oracle.truffle.api.dsl.TypeSystemReference;
109109
import com.oracle.truffle.api.frame.VirtualFrame;
110+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
110111
import com.oracle.truffle.api.library.CachedLibrary;
111112
import com.oracle.truffle.api.nodes.Node;
112113
import com.oracle.truffle.api.profiles.BranchProfile;
@@ -570,90 +571,96 @@ abstract static class PrefixSuffixBaseNode extends PythonQuaternaryBuiltinNode {
570571
@Child private CastToSliceComponentNode castSliceComponentNode;
571572
@Child private GetObjectArrayNode getObjectArrayNode;
572573

574+
private static final String INVALID_RECEIVER = "Method requires a 'bytes' object, got '%p'";
575+
private static final String INVALID_FIRST_ARG = "first arg must be bytes or a tuple of bytes, not %p";
576+
private static final String INVALID_ELEMENT_TYPE = "a bytes-like object is required, not '%p'";
577+
573578
// common and specialized cases --------------------
574579

575-
@Specialization
576-
boolean doPrefixStartEnd(PIBytesLike self, PIBytesLike substr, int start, int end,
577-
@Shared("toByteArrayNode") @Cached SequenceStorageNodes.ToByteArrayNode toByteArrayNode) {
578-
byte[] bytes = toByteArrayNode.execute(self.getSequenceStorage());
579-
byte[] substrBytes = toByteArrayNode.execute(substr.getSequenceStorage());
580+
@Specialization(guards = "!isPTuple(substr)", limit = "2")
581+
boolean doPrefixStartEnd(PIBytesLike self, Object substr, int start, int end,
582+
@CachedLibrary("self") PythonObjectLibrary lib,
583+
@CachedLibrary("substr") PythonObjectLibrary substrLib) {
584+
byte[] bytes = getBytes(lib, self);
585+
byte[] substrBytes = getBytes(substrLib, substr, INVALID_FIRST_ARG);
580586
int len = bytes.length;
581587
return doIt(bytes, substrBytes, adjustStart(start, len), adjustStart(end, len));
582588
}
583589

584-
@Specialization
585-
boolean doPrefixStart(PIBytesLike self, PIBytesLike substr, int start, @SuppressWarnings("unused") PNone end,
586-
@Shared("toByteArrayNode") @Cached SequenceStorageNodes.ToByteArrayNode toByteArrayNode) {
587-
byte[] bytes = toByteArrayNode.execute(self.getSequenceStorage());
588-
byte[] substrBytes = toByteArrayNode.execute(substr.getSequenceStorage());
590+
@Specialization(guards = "!isPTuple(substr)", limit = "2")
591+
boolean doPrefixStart(PIBytesLike self, Object substr, int start, @SuppressWarnings("unused") PNone end,
592+
@CachedLibrary("self") PythonObjectLibrary lib,
593+
@CachedLibrary("substr") PythonObjectLibrary substrLib) {
594+
byte[] bytes = getBytes(lib, self);
595+
byte[] substrBytes = getBytes(substrLib, substr, INVALID_FIRST_ARG);
589596
int len = bytes.length;
590597
return doIt(bytes, substrBytes, adjustStart(start, len), len);
591598
}
592599

593-
@Specialization
594-
boolean doPrefix(PIBytesLike self, PIBytesLike substr, @SuppressWarnings("unused") PNone start, @SuppressWarnings("unused") PNone end,
595-
@Shared("toByteArrayNode") @Cached SequenceStorageNodes.ToByteArrayNode toByteArrayNode) {
596-
byte[] bytes = toByteArrayNode.execute(self.getSequenceStorage());
597-
byte[] substrBytes = toByteArrayNode.execute(substr.getSequenceStorage());
600+
@Specialization(guards = "!isPTuple(substr)", limit = "2")
601+
boolean doPrefix(PIBytesLike self, Object substr, @SuppressWarnings("unused") PNone start, @SuppressWarnings("unused") PNone end,
602+
@CachedLibrary("self") PythonObjectLibrary lib,
603+
@CachedLibrary("substr") PythonObjectLibrary substrLib) {
604+
byte[] bytes = getBytes(lib, self);
605+
byte[] substrBytes = getBytes(substrLib, substr, INVALID_FIRST_ARG);
598606
return doIt(bytes, substrBytes, 0, bytes.length);
599607
}
600608

601-
@Specialization
609+
@Specialization(limit = "2")
602610
boolean doTuplePrefixStartEnd(PIBytesLike self, PTuple substrs, int start, int end,
603-
@Shared("toByteArrayNode") @Cached SequenceStorageNodes.ToByteArrayNode toByteArrayNode) {
604-
byte[] bytes = toByteArrayNode.execute(self.getSequenceStorage());
611+
@CachedLibrary("self") PythonObjectLibrary lib,
612+
@CachedLibrary(limit = "16") PythonObjectLibrary substrLib) {
613+
byte[] bytes = getBytes(lib, self);
605614
int len = bytes.length;
606-
return doIt(bytes, substrs, adjustStart(start, len), adjustStart(end, len), toByteArrayNode);
615+
return doIt(bytes, substrs, adjustStart(start, len), adjustStart(end, len), substrLib);
607616
}
608617

609-
@Specialization
618+
@Specialization(limit = "2")
610619
boolean doTuplePrefixStart(PIBytesLike self, PTuple substrs, int start, @SuppressWarnings("unused") PNone end,
611-
@Shared("toByteArrayNode") @Cached SequenceStorageNodes.ToByteArrayNode toByteArrayNode) {
612-
byte[] bytes = toByteArrayNode.execute(self.getSequenceStorage());
620+
@CachedLibrary("self") PythonObjectLibrary lib,
621+
@CachedLibrary(limit = "16") PythonObjectLibrary substrLib) {
622+
byte[] bytes = getBytes(lib, self);
613623
int len = bytes.length;
614-
return doIt(bytes, substrs, adjustStart(start, len), len, toByteArrayNode);
624+
return doIt(bytes, substrs, adjustStart(start, len), len, substrLib);
615625
}
616626

617-
@Specialization
627+
@Specialization(limit = "2")
618628
boolean doTuplePrefix(PIBytesLike self, PTuple substrs, @SuppressWarnings("unused") PNone start, @SuppressWarnings("unused") PNone end,
619-
@Shared("toByteArrayNode") @Cached SequenceStorageNodes.ToByteArrayNode toByteArrayNode) {
620-
byte[] bytes = toByteArrayNode.execute(self.getSequenceStorage());
621-
return doIt(bytes, substrs, 0, bytes.length, toByteArrayNode);
629+
@CachedLibrary("self") PythonObjectLibrary lib,
630+
@CachedLibrary(limit = "16") PythonObjectLibrary substrLib) {
631+
byte[] bytes = getBytes(lib, self);
632+
return doIt(bytes, substrs, 0, bytes.length, substrLib);
622633
}
623634

624635
// generic cases --------------------
625636

626-
@Specialization(replaces = {"doPrefixStartEnd", "doPrefixStart", "doPrefix"})
627-
boolean doPrefixGeneric(VirtualFrame frame, PIBytesLike self, PIBytesLike substr, Object start, Object end,
628-
@Shared("toByteArrayNode") @Cached SequenceStorageNodes.ToByteArrayNode toByteArrayNode) {
629-
byte[] bytes = toByteArrayNode.execute(self.getSequenceStorage());
630-
byte[] substrBytes = toByteArrayNode.execute(substr.getSequenceStorage());
637+
@Specialization(guards = "!isPTuple(substr)", replaces = {"doPrefixStartEnd", "doPrefixStart", "doPrefix"}, limit = "200")
638+
boolean doPrefixGeneric(VirtualFrame frame, PIBytesLike self, Object substr, Object start, Object end,
639+
@CachedLibrary("self") PythonObjectLibrary lib,
640+
@CachedLibrary("substr") PythonObjectLibrary substrLib) {
641+
byte[] bytes = getBytes(lib, self);
642+
byte[] substrBytes = getBytes(substrLib, substr, INVALID_FIRST_ARG);
631643
int len = bytes.length;
632644
int istart = PGuards.isPNone(start) ? 0 : castSlicePart(frame, start);
633645
int iend = PGuards.isPNone(end) ? len : adjustEnd(castSlicePart(frame, end), len);
634646
return doIt(bytes, substrBytes, adjustStart(istart, len), adjustStart(iend, len));
635647
}
636648

637-
@Specialization(replaces = {"doTuplePrefixStartEnd", "doTuplePrefixStart", "doTuplePrefix"})
649+
@Specialization(replaces = {"doTuplePrefixStartEnd", "doTuplePrefixStart", "doTuplePrefix"}, limit = "2")
638650
boolean doTuplePrefixGeneric(VirtualFrame frame, PIBytesLike self, PTuple substrs, Object start, Object end,
639-
@Shared("toByteArrayNode") @Cached SequenceStorageNodes.ToByteArrayNode toByteArrayNode) {
640-
byte[] bytes = toByteArrayNode.execute(self.getSequenceStorage());
651+
@CachedLibrary("self") PythonObjectLibrary lib,
652+
@CachedLibrary(limit = "16") PythonObjectLibrary substrLib) {
653+
byte[] bytes = getBytes(lib, self);
641654
int len = bytes.length;
642655
int istart = PGuards.isPNone(start) ? 0 : castSlicePart(frame, start);
643656
int iend = PGuards.isPNone(end) ? len : adjustEnd(castSlicePart(frame, end), len);
644-
return doIt(bytes, substrs, adjustStart(istart, len), adjustStart(iend, len), toByteArrayNode);
645-
}
646-
647-
@Specialization(guards = {"!isBytes(substr)", "!isPTuple(substr)"})
648-
boolean doGeneric(@SuppressWarnings("unused") PIBytesLike self, Object substr, @SuppressWarnings("unused") Object start,
649-
@SuppressWarnings("unused") Object end) {
650-
throw raise(TypeError, "first arg must be bytes or a tuple of bytes, not %p", substr);
657+
return doIt(bytes, substrs, adjustStart(istart, len), adjustStart(iend, len), substrLib);
651658
}
652659

653660
@Specialization(guards = "!isBytes(self)")
654661
boolean doGeneric(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object substr,
655662
@SuppressWarnings("unused") Object start, @SuppressWarnings("unused") Object end) {
656-
throw raise(TypeError, "Method requires a 'bytes' object, got '%p'", self);
663+
throw raise(TypeError, INVALID_RECEIVER, self);
657664
}
658665

659666
// the actual operation; will be overridden by subclasses
@@ -662,22 +669,30 @@ protected boolean doIt(byte[] bytes, byte[] prefix, int start, int end) {
662669
throw new IllegalStateException("should not reach");
663670
}
664671

665-
private boolean doIt(byte[] self, PTuple substrs, int start, int stop, SequenceStorageNodes.ToByteArrayNode toByteArrayNode) {
672+
private boolean doIt(byte[] self, PTuple substrs, int start, int stop, PythonObjectLibrary lib) {
666673
for (Object element : ensureGetObjectArrayNode().execute(substrs)) {
667-
if (element instanceof PIBytesLike) {
668-
if (doIt(self, toByteArrayNode.execute(((PIBytesLike) element).getSequenceStorage()), start, stop)) {
669-
return true;
670-
}
671-
} else {
672-
throw raise(TypeError, getErrorMessage(), element);
674+
byte[] bytes = getBytes(lib, element, INVALID_ELEMENT_TYPE);
675+
if (doIt(self, bytes, start, stop)) {
676+
return true;
673677
}
674678
}
675679
return false;
676680
}
677681

678-
protected String getErrorMessage() {
679-
CompilerDirectives.transferToInterpreter();
680-
throw new IllegalStateException("should not reach");
682+
private byte[] getBytes(PythonObjectLibrary lib, Object object) {
683+
try {
684+
return lib.getBufferBytes(object);
685+
} catch (UnsupportedMessageException e) {
686+
CompilerDirectives.transferToInterpreter();
687+
throw new IllegalStateException(e);
688+
}
689+
}
690+
691+
private byte[] getBytes(PythonObjectLibrary lib, Object object, String errorMessage) {
692+
if (!lib.isBuffer(object)) {
693+
throw raise(TypeError, errorMessage, object);
694+
}
695+
return getBytes(lib, object);
681696
}
682697

683698
// helper methods --------------------
@@ -723,8 +738,6 @@ private GetObjectArrayNode ensureGetObjectArrayNode() {
723738
@GenerateNodeFactory
724739
public abstract static class StartsWithNode extends PrefixSuffixBaseNode {
725740

726-
private static final String INVALID_ELEMENT_TYPE = "a bytes-like object is required, not '%p'";
727-
728741
@Override
729742
protected boolean doIt(byte[] bytes, byte[] prefix, int start, int end) {
730743
// start and end must be normalized indices for 'bytes'
@@ -741,11 +754,6 @@ protected boolean doIt(byte[] bytes, byte[] prefix, int start, int end) {
741754
}
742755
return true;
743756
}
744-
745-
@Override
746-
protected String getErrorMessage() {
747-
return INVALID_ELEMENT_TYPE;
748-
}
749757
}
750758

751759
// bytes.endswith(suffix[, start[, end]])
@@ -754,8 +762,6 @@ protected String getErrorMessage() {
754762
@GenerateNodeFactory
755763
public abstract static class EndsWithNode extends PrefixSuffixBaseNode {
756764

757-
private static final String INVALID_ELEMENT_TYPE = "a bytes-like object is required, not '%p'";
758-
759765
@Override
760766
protected boolean doIt(byte[] bytes, byte[] suffix, int start, int end) {
761767
// start and end must be normalized indices for 'bytes'
@@ -773,11 +779,6 @@ protected boolean doIt(byte[] bytes, byte[] suffix, int start, int end) {
773779
}
774780
return true;
775781
}
776-
777-
@Override
778-
protected String getErrorMessage() {
779-
return INVALID_ELEMENT_TYPE;
780-
}
781782
}
782783

783784
// bytes.index(x)

0 commit comments

Comments
 (0)