Skip to content

Commit a38fa19

Browse files
committed
Use hasIndices flag support in TRegex
1 parent 1670995 commit a38fa19

File tree

9 files changed

+39
-69
lines changed

9 files changed

+39
-69
lines changed

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/builtins/ConstructorBuiltins.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,17 +1028,15 @@ protected DynamicObject constructRegExpImpl(Object patternObj, Object flags, boo
10281028
regexpObject.enter();
10291029
Object compiledRegex = JSRegExp.getCompiledRegex((DynamicObject) patternObj);
10301030
if (flags == Undefined.instance) {
1031-
return getCreateRegExpNode().createRegExp(compiledRegex, true, false);
1031+
return getCreateRegExpNode().createRegExp(compiledRegex);
10321032
} else {
10331033
if (getContext().getEcmaScriptVersion() < 6) {
10341034
throw Errors.createTypeError("Cannot supply flags when constructing one RegExp from another");
10351035
}
10361036
String flagsStr = flagsToString(flags);
10371037
regexpObjectNewFlagsBranch.enter();
1038-
String pattern = getInteropReadPatternNode().execute(compiledRegex, TRegexUtil.Props.CompiledRegex.PATTERN);
1039-
Object newCompiledRegex = getCompileRegexNode().compile(pattern, flagsStr);
1040-
boolean hasIndices = flagsStr.indexOf('d') >= 0;
1041-
return getCreateRegExpNode().createRegExp(newCompiledRegex, true, hasIndices);
1038+
Object newCompiledRegex = getCompileRegexNode().compile(getInteropReadPatternNode().execute(compiledRegex, TRegexUtil.Props.CompiledRegex.PATTERN), flagsStr);
1039+
return getCreateRegExpNode().createRegExp(newCompiledRegex);
10421040
}
10431041
} else if (hasMatchSymbol) {
10441042
regexpMatcherObject.enter();
@@ -1058,8 +1056,7 @@ protected DynamicObject constructRegExpImpl(Object patternObj, Object flags, boo
10581056
String patternStr = getPatternToStringNode().executeString(p);
10591057
String flagsStr = flagsToString(f);
10601058
Object compiledRegex = getCompileRegexNode().compile(patternStr, flagsStr);
1061-
boolean hasIndices = flagsStr.indexOf('d') >= 0;
1062-
DynamicObject regExp = getCreateRegExpNode().createRegExp(compiledRegex, legacyFeaturesEnabled, hasIndices);
1059+
DynamicObject regExp = getCreateRegExpNode().createRegExp(compiledRegex, legacyFeaturesEnabled);
10631060
if (getContext().getContextOptions().isTestV8Mode()) {
10641061
// workaround for the reference equality check at the end of mjsunit/regexp.js
10651062
// TODO: remove this as soon as option maps are available for TRegex Sources

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/builtins/RegExpPrototypeBuiltins.java

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@
5656
import com.oracle.truffle.api.profiles.ConditionProfile;
5757
import com.oracle.truffle.api.profiles.ValueProfile;
5858
import com.oracle.truffle.js.builtins.ArrayPrototypeBuiltins.ArraySpeciesConstructorNode;
59-
import com.oracle.truffle.js.builtins.RegExpPrototypeBuiltinsFactory.HasIndicesGetterNodeGen;
6059
import com.oracle.truffle.js.builtins.RegExpPrototypeBuiltinsFactory.JSRegExpCompileNodeGen;
6160
import com.oracle.truffle.js.builtins.RegExpPrototypeBuiltinsFactory.JSRegExpExecES5NodeGen;
6261
import com.oracle.truffle.js.builtins.RegExpPrototypeBuiltinsFactory.JSRegExpExecNodeGen;
@@ -1617,8 +1616,6 @@ protected Object createNode(JSContext context, JSBuiltin builtin, boolean constr
16171616
return CompiledRegexPatternAccessor.create(context, builtin, args().withThis().fixedArgs(0).createArgumentNodes(context));
16181617
case flags:
16191618
return RegExpFlagsGetterNodeGen.create(context, builtin, args().withThis().fixedArgs(0).createArgumentNodes(context));
1620-
case hasIndices:
1621-
return HasIndicesGetterNodeGen.create(context, builtin, args().withThis().createArgumentNodes(context));
16221619
default:
16231620
return CompiledRegexFlagPropertyAccessor.create(context, builtin, builtinEnum.name(), args().withThis().fixedArgs(0).createArgumentNodes(context));
16241621
}
@@ -1778,30 +1775,4 @@ static CompiledRegexPatternAccessor create(JSContext context, JSBuiltin builtin,
17781775
return RegExpPrototypeBuiltinsFactory.CompiledRegexPatternAccessorNodeGen.create(context, builtin, args);
17791776
}
17801777
}
1781-
1782-
abstract static class HasIndicesGetterNode extends JSBuiltinNode {
1783-
1784-
HasIndicesGetterNode(JSContext context, JSBuiltin builtin) {
1785-
super(context, builtin);
1786-
}
1787-
1788-
@Specialization
1789-
Object doRegExp(JSRegExpObject regExp) {
1790-
return regExp.hasIndices();
1791-
}
1792-
1793-
@Specialization(guards = "isRegExpPrototype(obj)")
1794-
Object doPrototype(@SuppressWarnings("unused") DynamicObject obj) {
1795-
return Undefined.instance;
1796-
}
1797-
1798-
@Fallback
1799-
Object doObject(Object obj) {
1800-
throw Errors.createTypeErrorIncompatibleReceiver(obj);
1801-
}
1802-
1803-
boolean isRegExpPrototype(DynamicObject obj) {
1804-
return obj == getContext().getRealm().getRegExpPrototype();
1805-
}
1806-
}
18071778
}

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/builtins/helper/JSRegExpExecIntlNode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ private Object doExec(JSRegExpObject regExp, Object compiledRegex, String input)
321321
Object flags = compiledRegexAccessor.flags(compiledRegex);
322322
boolean global = flagsAccessor.global(flags);
323323
boolean sticky = ecmaScriptVersion >= 6 && flagsAccessor.sticky(flags);
324-
boolean hasIndices = regExp.hasIndices();
324+
boolean hasIndices = flagsAccessor.hasIndices(flags);
325325
long lastIndex = getLastIndex(regExp);
326326
if (global || sticky) {
327327
if (invalidLastIndex.profile(lastIndex < 0 || lastIndex > input.length())) {

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/access/RegExpLiteralNode.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ public class RegExpLiteralNode extends JavaScriptNode {
5858
private final JSContext context;
5959
private final String pattern;
6060
private final String flags;
61-
private final boolean hasIndices;
6261

6362
@CompilationFinal private Object compiledRegex;
6463

@@ -83,7 +82,6 @@ public Object getNodeObject() {
8382
this.context = context;
8483
this.pattern = pattern;
8584
this.flags = flags;
86-
this.hasIndices = flags.indexOf('d') >= 0;
8785
}
8886

8987
public static RegExpLiteralNode create(JSContext context, String pattern, String flags) {
@@ -96,7 +94,7 @@ public Object execute(VirtualFrame frame) {
9694
CompilerDirectives.transferToInterpreterAndInvalidate();
9795
compiledRegex = RegexCompilerInterface.compile(pattern, flags, context, getIsCompiledRegexNullNode());
9896
}
99-
return getCreateRegExpNode().createRegExp(compiledRegex, true, hasIndices);
97+
return getCreateRegExpNode().createRegExp(compiledRegex);
10098
}
10199

102100
private CreateRegExpNode getCreateRegExpNode() {

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/intl/CreateRegExpNode.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,26 +66,26 @@ public static CreateRegExpNode create(JSContext context) {
6666
}
6767

6868
public JSRegExpObject createRegExp(Object compiledRegex) {
69-
return createRegExp(compiledRegex, true, false);
69+
return createRegExp(compiledRegex, true);
7070
}
7171

72-
public JSRegExpObject createRegExp(Object compiledRegex, boolean legacyFeaturesEnabled, boolean hasIndices) {
73-
return execute(compiledRegex, legacyFeaturesEnabled, hasIndices);
72+
public JSRegExpObject createRegExp(Object compiledRegex, boolean legacyFeaturesEnabled) {
73+
return execute(compiledRegex, legacyFeaturesEnabled);
7474
}
7575

76-
protected abstract JSRegExpObject execute(Object compiledRegex, boolean legacyFeaturesEnabled, boolean hasIndices);
76+
protected abstract JSRegExpObject execute(Object compiledRegex, boolean legacyFeaturesEnabled);
7777

7878
@Specialization(guards = {"!hasNamedCG(compiledRegex)"})
79-
protected JSRegExpObject createWithoutNamedCG(Object compiledRegex, boolean legacyFeaturesEnabled, boolean hasIndices) {
80-
JSRegExpObject reObj = JSRegExp.create(context, compiledRegex, null, legacyFeaturesEnabled, hasIndices);
79+
protected JSRegExpObject createWithoutNamedCG(Object compiledRegex, boolean legacyFeaturesEnabled) {
80+
JSRegExpObject reObj = JSRegExp.create(context, compiledRegex, null, legacyFeaturesEnabled);
8181
setLastIndex.setValueInt(reObj, 0);
8282
return reObj;
8383
}
8484

8585
@Specialization(guards = {"hasNamedCG(compiledRegex)"})
86-
protected JSRegExpObject createWithNamedCG(Object compiledRegex, boolean legacyFeaturesEnabled, boolean hasIndices) {
86+
protected JSRegExpObject createWithNamedCG(Object compiledRegex, boolean legacyFeaturesEnabled) {
8787
Object namedCaptureGroups = readNamedCG.execute(compiledRegex, TRegexUtil.Props.CompiledRegex.GROUPS);
88-
JSRegExpObject reObj = JSRegExp.create(context, compiledRegex, JSRegExp.buildGroupsFactory(context, namedCaptureGroups), legacyFeaturesEnabled, hasIndices);
88+
JSRegExpObject reObj = JSRegExp.create(context, compiledRegex, JSRegExp.buildGroupsFactory(context, namedCaptureGroups), legacyFeaturesEnabled);
8989
setLastIndex.setValueInt(reObj, 0);
9090
return reObj;
9191
}

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/runtime/RegexCompilerInterface.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public static Object compile(String pattern, String flags, JSContext context, TR
7878

7979
@TruffleBoundary
8080
private static Source createRegexSource(String pattern, String flags, String options) {
81-
String regexStr = options + '/' + pattern + '/' + stripDFlag(flags);
81+
String regexStr = options + '/' + pattern + '/' + flags;
8282
return Source.newBuilder("regex", regexStr, regexStr).mimeType("application/tregex").internal(true).build();
8383
}
8484

@@ -94,10 +94,6 @@ public static void validate(JSContext context, String pattern, String flags, int
9494
}
9595
}
9696

97-
private static String stripDFlag(String flags) {
98-
return flags.replace("d", "");
99-
}
100-
10197
@TruffleBoundary
10298
public static void validateFlags(String flags, int ecmaScriptVersion, boolean nashornCompat, boolean allowHasIndices) {
10399
boolean ignoreCase = false;

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/runtime/builtins/JSRegExp.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -199,15 +199,15 @@ public static DynamicObject create(JSContext ctx, Object compiledRegex) {
199199
* Creates a new JavaScript RegExp object <em>without</em> a {@code lastIndex} property.
200200
*/
201201
public static DynamicObject create(JSContext context, Object compiledRegex, JSObjectFactory groupsFactory) {
202-
return create(context, compiledRegex, groupsFactory, true, false);
202+
return create(context, compiledRegex, groupsFactory, true);
203203
}
204204

205205
/**
206206
* Creates a new JavaScript RegExp object <em>without</em> a {@code lastIndex} property.
207207
*/
208-
public static JSRegExpObject create(JSContext context, Object compiledRegex, JSObjectFactory groupsFactory, boolean legacyFeaturesEnabled, boolean hasIndices) {
208+
public static JSRegExpObject create(JSContext context, Object compiledRegex, JSObjectFactory groupsFactory, boolean legacyFeaturesEnabled) {
209209
JSRealm realm = context.getRealm();
210-
JSRegExpObject regExp = JSRegExpObject.create(realm, context.getRegExpFactory(), compiledRegex, groupsFactory, legacyFeaturesEnabled, hasIndices);
210+
JSRegExpObject regExp = JSRegExpObject.create(realm, context.getRegExpFactory(), compiledRegex, groupsFactory, legacyFeaturesEnabled);
211211
assert isJSRegExp(regExp);
212212
return context.trackAllocation(regExp);
213213
}
@@ -285,10 +285,10 @@ public static String prototypeToString(DynamicObject thisObj) {
285285
sb.append(pattern);
286286
sb.append('/');
287287

288-
if (((JSRegExpObject) thisObj).hasIndices()) {
288+
Object flagsObj = TRegexUtil.InteropReadMemberNode.getUncached().execute(regex, TRegexUtil.Props.CompiledRegex.FLAGS);
289+
if (TRegexUtil.InteropReadBooleanMemberNode.getUncached().execute(flagsObj, TRegexUtil.Props.Flags.HAS_INDICES)) {
289290
sb.append('d');
290291
}
291-
Object flagsObj = TRegexUtil.InteropReadMemberNode.getUncached().execute(regex, TRegexUtil.Props.CompiledRegex.FLAGS);
292292
if (TRegexUtil.InteropReadBooleanMemberNode.getUncached().execute(flagsObj, TRegexUtil.Props.Flags.GLOBAL)) {
293293
sb.append('g');
294294
}

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/runtime/builtins/JSRegExpObject.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,13 @@ public final class JSRegExpObject extends JSNonProxyObject implements JSCopyable
5151
private JSObjectFactory groupsFactory;
5252
private final JSRealm realm;
5353
private final boolean legacyFeaturesEnabled;
54-
boolean hasIndices;
5554

56-
protected JSRegExpObject(Shape shape, Object compiledRegex, JSObjectFactory groupsFactory, JSRealm realm, boolean legacyFeaturesEnabled, boolean hasIndices) {
55+
protected JSRegExpObject(Shape shape, Object compiledRegex, JSObjectFactory groupsFactory, JSRealm realm, boolean legacyFeaturesEnabled) {
5756
super(shape);
5857
this.compiledRegex = compiledRegex;
5958
this.groupsFactory = groupsFactory;
6059
this.realm = realm;
6160
this.legacyFeaturesEnabled = legacyFeaturesEnabled;
62-
this.hasIndices = hasIndices;
6361
}
6462

6563
public Object getCompiledRegex() {
@@ -86,25 +84,21 @@ public boolean getLegacyFeaturesEnabled() {
8684
return legacyFeaturesEnabled;
8785
}
8886

89-
public boolean hasIndices() {
90-
return hasIndices;
91-
}
92-
9387
@Override
9488
public String getClassName() {
9589
return JSRegExp.CLASS_NAME;
9690
}
9791

98-
public static JSRegExpObject create(JSRealm realm, JSObjectFactory factory, Object compiledRegex, JSObjectFactory groupsFactory, boolean legacyFeaturesEnabled, boolean hasIndices) {
99-
return factory.initProto(new JSRegExpObject(factory.getShape(realm), compiledRegex, groupsFactory, realm, legacyFeaturesEnabled, hasIndices), realm);
92+
public static JSRegExpObject create(JSRealm realm, JSObjectFactory factory, Object compiledRegex, JSObjectFactory groupsFactory, boolean legacyFeaturesEnabled) {
93+
return factory.initProto(new JSRegExpObject(factory.getShape(realm), compiledRegex, groupsFactory, realm, legacyFeaturesEnabled), realm);
10094
}
10195

10296
public static JSRegExpObject create(Shape shape, Object compiledRegex, JSRealm realm) {
103-
return new JSRegExpObject(shape, compiledRegex, null, realm, false, false);
97+
return new JSRegExpObject(shape, compiledRegex, null, realm, false);
10498
}
10599

106100
@Override
107101
protected JSObject copyWithoutProperties(Shape shape) {
108-
return new JSRegExpObject(shape, compiledRegex, groupsFactory, realm, legacyFeaturesEnabled, hasIndices);
102+
return new JSRegExpObject(shape, compiledRegex, groupsFactory, realm, legacyFeaturesEnabled);
109103
}
110104
}

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/runtime/util/TRegexUtil.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ private Flags() {
9898
public static final String STICKY = "sticky";
9999
public static final String UNICODE = "unicode";
100100
public static final String DOT_ALL = "dotAll";
101+
public static final String HAS_INDICES = "hasIndices";
101102
}
102103

103104
public static final class RegexResult {
@@ -492,6 +493,7 @@ public static final class TRegexFlagsAccessor extends Node {
492493
@Child private InteropReadBooleanMemberNode readStickyNode;
493494
@Child private InteropReadBooleanMemberNode readUnicodeNode;
494495
@Child private InteropReadBooleanMemberNode readDotAllNode;
496+
@Child private InteropReadBooleanMemberNode readHasIndicesNode;
495497

496498
private TRegexFlagsAccessor() {
497499
}
@@ -528,6 +530,10 @@ public boolean dotAll(Object regexFlagsObject) {
528530
return getReadDotAllNode().execute(regexFlagsObject, Props.Flags.DOT_ALL);
529531
}
530532

533+
public boolean hasIndices(Object regexFlagsObject) {
534+
return getReadHasIndicesNode().execute(regexFlagsObject, Props.Flags.HAS_INDICES);
535+
}
536+
531537
private InteropReadStringMemberNode getReadSourceNode() {
532538
if (readSourceNode == null) {
533539
CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -583,6 +589,14 @@ private InteropReadBooleanMemberNode getReadDotAllNode() {
583589
}
584590
return readDotAllNode;
585591
}
592+
593+
private InteropReadBooleanMemberNode getReadHasIndicesNode() {
594+
if (readHasIndicesNode == null) {
595+
CompilerDirectives.transferToInterpreterAndInvalidate();
596+
readHasIndicesNode = insert(InteropReadBooleanMemberNode.create());
597+
}
598+
return readHasIndicesNode;
599+
}
586600
}
587601

588602
public static final class TRegexCompiledRegexSingleFlagAccessor extends Node {

0 commit comments

Comments
 (0)