Skip to content

Commit 2eb2bcc

Browse files
committed
[GR-32617] Warn when TRegex needs to use backtracking for a Regexp
PullRequest: truffleruby/2836
2 parents 787b585 + 73f0a8f commit 2eb2bcc

File tree

3 files changed

+25
-2
lines changed

3 files changed

+25
-2
lines changed

mx.truffleruby/suite.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
{
88
"name": "regex",
99
"subdir": True,
10-
"version": "a1346dffebe541333754360e825b2185d60cb005",
10+
"version": "bc35c63a6db0aa8faf5471b74f9771c7be8f7a9b",
1111
"urls": [
1212
{"url": "https://github.com/oracle/graal.git", "kind": "git"},
1313
{"url": "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind": "binary"},
@@ -16,7 +16,7 @@
1616
{
1717
"name": "sulong",
1818
"subdir": True,
19-
"version": "a1346dffebe541333754360e825b2185d60cb005",
19+
"version": "bc35c63a6db0aa8faf5471b74f9771c7be8f7a9b",
2020
"urls": [
2121
{"url": "https://github.com/oracle/graal.git", "kind": "git"},
2222
{"url": "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind": "binary"},

src/main/java/org/truffleruby/core/regexp/TRegexCache.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import org.truffleruby.core.rope.Rope;
2929
import org.truffleruby.core.rope.RopeBuilder;
3030
import org.truffleruby.core.rope.RopeOperations;
31+
import org.truffleruby.interop.InteropNodes;
32+
import org.truffleruby.interop.TranslateInteropExceptionNode;
3133
import org.truffleruby.language.Nil;
3234
import org.truffleruby.language.control.DeferredRaiseException;
3335

@@ -75,6 +77,15 @@ public Object compile(RubyContext context, RubyRegexp regexp, boolean atStart, R
7577
atStart,
7678
encoding);
7779
}
80+
} else if (isBacktracking(tregex)) {
81+
if (context.getOptions().WARN_TRUFFLE_REGEX_COMPILE_FALLBACK) {
82+
node.getWarnOnFallbackNode().call(
83+
context.getCoreLibrary().truffleRegexpOperationsModule,
84+
"warn_backtracking",
85+
regexp,
86+
atStart,
87+
encoding);
88+
}
7889
}
7990

8091
if (encoding == Encodings.US_ASCII) {
@@ -108,6 +119,14 @@ public Object compile(RubyContext context, RubyRegexp regexp, boolean atStart, R
108119
return tregex;
109120
}
110121

122+
private static boolean isBacktracking(Object tregex) {
123+
return (boolean) InteropNodes.readMember(
124+
InteropLibrary.getUncached(),
125+
tregex,
126+
"isBacktracking",
127+
TranslateInteropExceptionNode.getUncached());
128+
}
129+
111130
public static String toTRegexEncoding(Encoding encoding) {
112131
if (encoding == UTF8Encoding.INSTANCE) {
113132
return "UTF-8";

src/main/ruby/truffleruby/core/truffle/regexp_operations.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ def self.warn_fallback_regex(re, at_start, encoding)
101101
warn "Regexp #{re.inspect} at_start=#{at_start} encoding=#{encoding} cannot be compiled to a Truffle regexp and fell back to Joni", uplevel: 1
102102
end
103103

104+
def self.warn_backtracking(re, at_start, encoding)
105+
warn "Regexp #{re.inspect} at_start=#{at_start} encoding=#{encoding} requires backtracking and will not match in linear time", uplevel: 1
106+
end
107+
104108
def self.match_args_to_string(re, str, from, to, at_start, start, suffix)
105109
"match_in_region(#{re.inspect}, #{str.inspect}@#{str.encoding}, #{from}, #{to}, #{at_start}, #{start}) #{suffix}"
106110
end

0 commit comments

Comments
 (0)