Skip to content

Commit 94aa446

Browse files
committed
No need to create ClassicRegexp instances
1 parent 42ae4ed commit 94aa446

File tree

3 files changed

+29
-88
lines changed

3 files changed

+29
-88
lines changed

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

Lines changed: 26 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -36,21 +36,16 @@
3636
***** END LICENSE BLOCK *****/
3737
package org.truffleruby.core.regexp;
3838

39-
import static org.truffleruby.core.string.StringUtils.EMPTY_STRING_ARRAY;
40-
4139
import java.nio.charset.StandardCharsets;
4240
import java.util.Arrays;
43-
import java.util.Iterator;
4441

4542
import com.oracle.truffle.api.strings.AbstractTruffleString;
46-
import com.oracle.truffle.api.strings.TruffleString;
4743
import com.oracle.truffle.api.strings.TruffleStringBuilder;
4844
import org.jcodings.Encoding;
4945
import org.jcodings.specific.EUCJPEncoding;
5046
import org.jcodings.specific.SJISEncoding;
5147
import org.jcodings.specific.USASCIIEncoding;
5248
import org.jcodings.specific.UTF8Encoding;
53-
import org.joni.NameEntry;
5449
import org.joni.Option;
5550
import org.joni.Regex;
5651
import org.joni.Syntax;
@@ -60,7 +55,6 @@
6055
import org.truffleruby.collections.ByteArrayBuilder;
6156
import org.truffleruby.core.encoding.Encodings;
6257
import org.truffleruby.core.encoding.RubyEncoding;
63-
import org.truffleruby.core.encoding.TStringUtils;
6458
import org.truffleruby.core.string.ATStringWithEncoding;
6559
import org.truffleruby.core.string.TStringBuilder;
6660
import org.truffleruby.core.string.TStringWithEncoding;
@@ -69,21 +63,12 @@
6963
import org.truffleruby.language.backtrace.BacktraceFormatter;
7064
import org.truffleruby.language.control.DeferredRaiseException;
7165
import org.truffleruby.language.control.RaiseException;
72-
import org.truffleruby.parser.ReOptions;
7366

7467
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
7568
import com.oracle.truffle.api.nodes.Node;
7669
import org.truffleruby.parser.RubyDeferredWarnings;
7770

78-
public final class ClassicRegexp implements ReOptions {
79-
80-
private final Regex pattern;
81-
private final TStringWithEncoding str;
82-
private final RegexpOptions options;
83-
84-
public Encoding getEncoding() {
85-
return pattern.getEncoding();
86-
}
71+
public final class ClassicRegexp {
8772

8873
public static Regex makeRegexp(RubyDeferredWarnings rubyDeferredWarnings,
8974
TStringBuilder processedSource, RegexpOptions options,
@@ -109,23 +94,6 @@ public static String getRegexErrorMessage(AbstractTruffleString source, Exceptio
10994
return BacktraceFormatter.formatJavaThrowableMessage(e) + ": /" + source + "/" + options.toOptionsString();
11095
}
11196

112-
public ClassicRegexp(TStringWithEncoding strEnc, RegexpOptions originalOptions)
113-
throws DeferredRaiseException {
114-
if (strEnc.encoding.isDummy) {
115-
throw new UnsupportedOperationException("can't make regexp with dummy encoding");
116-
}
117-
118-
RegexpOptions[] optionsArray = new RegexpOptions[]{ originalOptions };
119-
RubyEncoding[] fixedEnc = new RubyEncoding[]{ null };
120-
TStringBuilder unescaped = preprocess(strEnc, strEnc.encoding, fixedEnc, RegexpSupport.ErrorMode.RAISE);
121-
final RubyEncoding computedEnc = computeRegexpEncoding(optionsArray, strEnc.encoding, fixedEnc);
122-
final RegexpOptions options = optionsArray[0];
123-
final TruffleString source = strEnc.forceEncoding(computedEnc).tstring;
124-
this.pattern = makeRegexp(null, unescaped, options, computedEnc, source, null);
125-
this.options = options;
126-
this.str = strEnc;
127-
}
128-
12997
@TruffleBoundary
13098
@SuppressWarnings("fallthrough")
13199
private static boolean unescapeNonAscii(TStringBuilder to, TStringWithEncoding str, RubyEncoding enc,
@@ -835,34 +803,33 @@ public static void appendOptions(TStringBuilder to, RegexpOptions options) {
835803
}
836804

837805
@SuppressWarnings("unused")
838-
public ByteArrayBuilder toByteArrayBuilder() {
806+
public static TStringWithEncoding toS(TStringWithEncoding source, RegexpOptions options) {
839807
RegexpOptions newOptions = (RegexpOptions) options.clone();
840-
var byteArray = str.getInternalByteArray();
808+
var byteArray = source.getInternalByteArray();
841809
int p = 0;
842810
int len = byteArray.getLength();
843811

844812
TStringBuilder result = TStringBuilder.create(len);
845813
result.append((byte) '(');
846814
result.append((byte) '?');
847815

848-
again: do {
816+
do {
849817
if (len >= 4 && byteArray.get(p) == '(' && byteArray.get(p + 1) == '?') {
850-
boolean err = true;
851818
p += 2;
852-
if ((len -= 2) > 0) {
853-
do {
854-
if (byteArray.get(p) == 'm') {
855-
newOptions = newOptions.setMultiline(true);
856-
} else if (byteArray.get(p) == 'i') {
857-
newOptions = newOptions.setIgnorecase(true);
858-
} else if (byteArray.get(p) == 'x') {
859-
newOptions = newOptions.setExtended(true);
860-
} else {
861-
break;
862-
}
863-
p++;
864-
} while (--len > 0);
865-
}
819+
len -= 2;
820+
do {
821+
if (byteArray.get(p) == 'm') {
822+
newOptions = newOptions.setMultiline(true);
823+
} else if (byteArray.get(p) == 'i') {
824+
newOptions = newOptions.setIgnorecase(true);
825+
} else if (byteArray.get(p) == 'x') {
826+
newOptions = newOptions.setExtended(true);
827+
} else {
828+
break;
829+
}
830+
p++;
831+
} while (--len > 0);
832+
866833
if (len > 1 && byteArray.get(p) == '-') {
867834
++p;
868835
--len;
@@ -883,9 +850,10 @@ public ByteArrayBuilder toByteArrayBuilder() {
883850
if (byteArray.get(p) == ')') {
884851
--len;
885852
++p;
886-
continue again;
853+
continue;
887854
}
888855

856+
boolean err = true;
889857
if (byteArray.get(p) == ':' && byteArray.get(p + len - 1) == ')') {
890858
p++;
891859
try {
@@ -894,7 +862,7 @@ public ByteArrayBuilder toByteArrayBuilder() {
894862
p + byteArray.getOffset(),
895863
p + byteArray.getOffset() + (len -= 2),
896864
Option.DEFAULT,
897-
str.encoding.jcoding,
865+
source.encoding.jcoding,
898866
Syntax.DEFAULT,
899867
new RegexWarnCallback());
900868
err = false;
@@ -906,7 +874,7 @@ public ByteArrayBuilder toByteArrayBuilder() {
906874
if (err) {
907875
newOptions = options;
908876
p = 0;
909-
len = str.byteLength();
877+
len = source.byteLength();
910878
}
911879
}
912880

@@ -925,17 +893,16 @@ public ByteArrayBuilder toByteArrayBuilder() {
925893
}
926894
}
927895
result.append((byte) ':');
928-
appendRegexpString(result, str, p, len);
896+
appendRegexpString(result, source, p, len);
929897

930898
result.append((byte) ')');
931-
result.setEncoding(Encodings.getBuiltInEncoding(getEncoding()));
932-
return result;
933-
//return RubyString.newString(getRuntime(), result, getEncoding()).infectBy(this);
899+
result.setEncoding(source.encoding);
900+
return result.toTStringWithEnc();
934901
} while (true);
935902
}
936903

937904
@TruffleBoundary
938-
public void appendRegexpString(TStringBuilder to, TStringWithEncoding fullStr, int start, int len) {
905+
public static void appendRegexpString(TStringBuilder to, TStringWithEncoding fullStr, int start, int len) {
939906
var str = fullStr.substring(start, len);
940907

941908
final var enc = str.encoding.jcoding;
@@ -981,24 +948,6 @@ public void appendRegexpString(TStringBuilder to, TStringWithEncoding fullStr, i
981948
}
982949
}
983950

984-
public String[] getNames() {
985-
int nameLength = pattern.numberOfNames();
986-
if (nameLength == 0) {
987-
return EMPTY_STRING_ARRAY;
988-
}
989-
990-
RubyEncoding encoding = Encodings.getBuiltInEncoding(pattern.getEncoding());
991-
String[] names = new String[nameLength];
992-
int j = 0;
993-
for (Iterator<NameEntry> i = pattern.namedBackrefIterator(); i.hasNext();) {
994-
NameEntry e = i.next();
995-
// intern() to improve footprint
996-
names[j++] = TStringUtils.bytesToJavaStringOrThrow(e.name, e.nameP, e.nameEnd - e.nameP, encoding).intern();
997-
}
998-
999-
return names;
1000-
}
1001-
1002951
// Code that used to be in ParserSupport but copied here as ParserSupport is coupled with the JRuby lexer & parser.
1003952
// Needed until https://github.com/ruby/prism/issues/1997 is fixed.
1004953

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

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -122,17 +122,8 @@ RubyString toS(RubyRegexp regexp) {
122122

123123
@TruffleBoundary
124124
protected TStringWithEncoding createTString(RubyRegexp regexp) {
125-
final ClassicRegexp classicRegexp;
126-
127-
try {
128-
classicRegexp = new ClassicRegexp(
129-
new TStringWithEncoding(regexp.source, regexp.encoding),
130-
RegexpOptions.fromEmbeddedOptions(regexp.regex.getOptions()));
131-
} catch (DeferredRaiseException dre) {
132-
throw dre.getException(getContext());
133-
}
134-
135-
return classicRegexp.toByteArrayBuilder().toTStringWithEnc(regexp.encoding);
125+
var sourceEnc = new TStringWithEncoding(regexp.source, regexp.encoding);
126+
return ClassicRegexp.toS(sourceEnc, regexp.options);
136127
}
137128
}
138129

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ private RubyRegexp(Regex regex, RegexpOptions options) {
8181
final TStringWithEncoding tstringWithEncoding = (TStringWithEncoding) regex.getUserObject();
8282
this.source = tstringWithEncoding.tstring;
8383
this.encoding = tstringWithEncoding.getEncoding();
84+
assert encoding.jcoding == regex.getEncoding();
8485
this.options = options;
8586
this.cachedEncodings = new EncodingCache();
8687
this.tregexCache = new TRegexCache();

0 commit comments

Comments
 (0)