Skip to content

Commit 03fd114

Browse files
committed
Allow native strings in regex matching
1 parent ef563d4 commit 03fd114

File tree

2 files changed

+44
-35
lines changed

2 files changed

+44
-35
lines changed

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

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
6060
import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
6161
import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
62+
import com.oracle.graal.python.nodes.util.CannotCastException;
6263
import com.oracle.graal.python.nodes.util.CastToJavaStringNode;
6364
import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext;
6465
import com.oracle.graal.python.runtime.PythonContext;
@@ -123,30 +124,27 @@ protected Source doString(String pattern, String flags) {
123124

124125
@Specialization(limit = "3")
125126
protected Source doGeneric(VirtualFrame frame, Object pattern, String flags,
126-
@CachedLibrary("pattern") InteropLibrary interopLib,
127+
@Cached CastToJavaStringNode cast,
127128
@CachedLibrary("pattern") PythonBufferAcquireLibrary bufferAcquireLib,
128129
@CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) {
129-
if (interopLib.isString(pattern)) {
130+
try {
131+
return doString(cast.execute(pattern), flags);
132+
} catch (CannotCastException ce) {
133+
Object buffer;
130134
try {
131-
return doString(interopLib.asString(pattern), flags);
132-
} catch (UnsupportedMessageException e) {
133-
throw CompilerDirectives.shouldNotReachHere();
135+
buffer = bufferAcquireLib.acquireReadonly(pattern, frame, this);
136+
} catch (PException e) {
137+
throw raise(TypeError, "expected string or bytes-like object");
138+
}
139+
try {
140+
String options = "Flavor=PythonBytes,Encoding=BYTES";
141+
byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer);
142+
int bytesLen = bufferLib.getBufferLength(buffer);
143+
String patternStr = decodeLatin1(bytes, bytesLen);
144+
return constructRegexSource(options, patternStr, flags);
145+
} finally {
146+
bufferLib.release(buffer, frame, this);
134147
}
135-
}
136-
Object buffer;
137-
try {
138-
buffer = bufferAcquireLib.acquireReadonly(pattern, frame, this);
139-
} catch (PException e) {
140-
throw raise(TypeError, "expected string or bytes-like object");
141-
}
142-
try {
143-
String options = "Flavor=PythonBytes,Encoding=BYTES";
144-
byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer);
145-
int bytesLen = bufferLib.getBufferLength(buffer);
146-
String patternStr = decodeLatin1(bytes, bytesLen);
147-
return constructRegexSource(options, patternStr, flags);
148-
} finally {
149-
bufferLib.release(buffer, frame, this);
150148
}
151149
}
152150
}
@@ -212,13 +210,21 @@ abstract static class TRegexCallExec extends PythonTernaryBuiltinNode {
212210

213211
@Specialization(limit = "1")
214212
Object call(VirtualFrame frame, Object callable, Object inputStringOrBytes, Number fromIndex,
213+
@Cached CastToJavaStringNode cast,
215214
@Cached BranchProfile typeError,
216215
@CachedLibrary("callable") InteropLibrary interop) {
217216
PythonContext context = getContext();
218217
PythonLanguage language = getLanguage();
218+
Object input = inputStringOrBytes;
219+
try {
220+
// This would materialize the string if it was native
221+
input = cast.execute(inputStringOrBytes);
222+
} catch (CannotCastException e) {
223+
// It's bytes or other buffer object
224+
}
219225
Object state = IndirectCallContext.enter(frame, language, context, this);
220226
try {
221-
return interop.execute(callable, inputStringOrBytes, fromIndex);
227+
return interop.execute(callable, input, fromIndex);
222228
} catch (ArityException | UnsupportedTypeException | UnsupportedMessageException e) {
223229
typeError.enter();
224230
throw raise(TypeError, "%m", e);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringBuiltins.java

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,6 @@
152152
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
153153
import com.oracle.truffle.api.dsl.Cached;
154154
import com.oracle.truffle.api.dsl.Cached.Shared;
155-
import com.oracle.truffle.api.dsl.Fallback;
156155
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
157156
import com.oracle.truffle.api.dsl.ImportStatic;
158157
import com.oracle.truffle.api.dsl.Specialization;
@@ -2501,22 +2500,32 @@ private static String getSubString(String origin, int start, int stop) {
25012500
@TypeSystemReference(PythonArithmeticTypes.class)
25022501
public abstract static class StrGetItemNode extends PythonBinaryBuiltinNode {
25032502

2504-
@Specialization(guards = "isString(primary)")
2505-
public String doString(VirtualFrame frame, Object primary, PSlice slice,
2503+
@Specialization
2504+
public String doString(VirtualFrame frame, Object self, PSlice slice,
25062505
@Cached CastToJavaStringNode castToJavaString,
25072506
@Cached CoerceToIntSlice sliceCast,
25082507
@Cached ComputeIndices compute,
25092508
@Cached StrGetItemNodeWithSlice getItemNodeWithSlice) {
2510-
String str = castToJavaString.execute(primary);
2509+
String str;
2510+
try {
2511+
str = castToJavaString.execute(self);
2512+
} catch (CannotCastException e) {
2513+
throw raise(TypeError, ErrorMessages.DESCRIPTOR_REQUIRES_OBJ, __GETITEM__, "str", self);
2514+
}
25112515
SliceInfo info = compute.execute(frame, sliceCast.execute(slice), str.length());
25122516
return getItemNodeWithSlice.execute(str, info);
25132517
}
25142518

2515-
@Specialization(guards = {"!isPSlice(idx)", "isString(primary)"})
2516-
public String doString(VirtualFrame frame, Object primary, Object idx,
2519+
@Specialization(guards = "!isPSlice(idx)")
2520+
public String doString(VirtualFrame frame, Object self, Object idx,
25172521
@Cached CastToJavaStringNode castToJavaString,
25182522
@Cached PyNumberAsSizeNode asSizeNode) {
2519-
String str = castToJavaString.execute(primary);
2523+
String str;
2524+
try {
2525+
str = castToJavaString.execute(self);
2526+
} catch (CannotCastException e) {
2527+
throw raise(TypeError, ErrorMessages.DESCRIPTOR_REQUIRES_OBJ, __GETITEM__, "str", self);
2528+
}
25202529
int index = asSizeNode.executeExact(frame, idx);
25212530
if (index < 0) {
25222531
index += str.length();
@@ -2527,16 +2536,10 @@ public String doString(VirtualFrame frame, Object primary, Object idx,
25272536
return charAtToString(str, index);
25282537
}
25292538

2530-
@SuppressWarnings("unused")
2531-
@Fallback
2532-
Object doGeneric(Object self, Object other) {
2533-
return PNotImplemented.NOT_IMPLEMENTED;
2534-
}
2535-
25362539
@TruffleBoundary
25372540
private static String charAtToString(String primary, int index) {
25382541
char character = primary.charAt(index);
2539-
return new String(new char[]{character});
2542+
return String.valueOf(character);
25402543
}
25412544
}
25422545

0 commit comments

Comments
 (0)