5757import com .oracle .graal .python .nodes .PNodeWithRaiseAndIndirectCall ;
5858import com .oracle .graal .python .nodes .call .CallNode ;
5959import com .oracle .graal .python .nodes .function .PythonBuiltinBaseNode ;
60+ import com .oracle .graal .python .nodes .function .builtins .PythonQuaternaryBuiltinNode ;
6061import com .oracle .graal .python .nodes .function .builtins .PythonTernaryBuiltinNode ;
6162import com .oracle .graal .python .nodes .truffle .PythonArithmeticTypes ;
6263import com .oracle .graal .python .nodes .util .CannotCastException ;
6566import com .oracle .graal .python .runtime .PythonContext ;
6667import com .oracle .graal .python .runtime .PythonOptions ;
6768import com .oracle .graal .python .runtime .exception .PException ;
69+ import com .oracle .graal .python .util .PythonUtils ;
6870import com .oracle .truffle .api .CompilerDirectives ;
6971import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
7072import com .oracle .truffle .api .dsl .Cached ;
8082import com .oracle .truffle .api .interop .UnsupportedTypeException ;
8183import com .oracle .truffle .api .library .CachedLibrary ;
8284import com .oracle .truffle .api .profiles .BranchProfile ;
85+ import com .oracle .truffle .api .profiles .ConditionProfile ;
8386import com .oracle .truffle .api .source .Source ;
8487import com .oracle .truffle .api .source .SourceSection ;
8588
@@ -98,7 +101,7 @@ public void initialize(Python3Core core) {
98101
99102 abstract static class ToRegexSourceNode extends PNodeWithRaiseAndIndirectCall {
100103
101- public abstract Source execute (VirtualFrame frame , Object pattern , String flags );
104+ public abstract Source execute (VirtualFrame frame , Object pattern , String flags , String options );
102105
103106 @ TruffleBoundary
104107 private static String decodeLatin1 (byte [] bytes , int length ) {
@@ -117,18 +120,24 @@ private static Source constructRegexSource(String options, String pattern, Strin
117120 }
118121
119122 @ Specialization
120- protected Source doString (String pattern , String flags ) {
121- String options = "Flavor=PythonStr,Encoding=UTF-16" ;
122- return constructRegexSource (options , pattern , flags );
123+ protected Source doString (String pattern , String flags , String options ,
124+ @ Cached ConditionProfile nonEmptyOptionsProfile ) {
125+ StringBuilder allOptions = PythonUtils .newStringBuilder ("Flavor=PythonStr,Encoding=UTF-16" );
126+ if (nonEmptyOptionsProfile .profile (!options .isEmpty ())) {
127+ PythonUtils .append (allOptions , ',' );
128+ PythonUtils .append (allOptions , options );
129+ }
130+ return constructRegexSource (PythonUtils .sbToString (allOptions ), pattern , flags );
123131 }
124132
125133 @ Specialization (limit = "3" )
126- protected Source doGeneric (VirtualFrame frame , Object pattern , String flags ,
134+ protected Source doGeneric (VirtualFrame frame , Object pattern , String flags , String options ,
135+ @ Cached ConditionProfile nonEmptyOptionsProfile ,
127136 @ Cached CastToJavaStringNode cast ,
128137 @ CachedLibrary ("pattern" ) PythonBufferAcquireLibrary bufferAcquireLib ,
129138 @ CachedLibrary (limit = "1" ) PythonBufferAccessLibrary bufferLib ) {
130139 try {
131- return doString (cast .execute (pattern ), flags );
140+ return doString (cast .execute (pattern ), flags , options , nonEmptyOptionsProfile );
132141 } catch (CannotCastException ce ) {
133142 Object buffer ;
134143 try {
@@ -137,36 +146,42 @@ protected Source doGeneric(VirtualFrame frame, Object pattern, String flags,
137146 throw raise (TypeError , "expected string or bytes-like object" );
138147 }
139148 try {
140- String options = "Flavor=PythonBytes,Encoding=BYTES" ;
149+ StringBuilder allOptions = PythonUtils .newStringBuilder ("Flavor=PythonBytes,Encoding=BYTES" );
150+ if (nonEmptyOptionsProfile .profile (!options .isEmpty ())) {
151+ PythonUtils .append (allOptions , ',' );
152+ PythonUtils .append (allOptions , options );
153+ }
141154 byte [] bytes = bufferLib .getInternalOrCopiedByteArray (buffer );
142155 int bytesLen = bufferLib .getBufferLength (buffer );
143156 String patternStr = decodeLatin1 (bytes , bytesLen );
144- return constructRegexSource (options , patternStr , flags );
157+ return constructRegexSource (PythonUtils . sbToString ( allOptions ) , patternStr , flags );
145158 } finally {
146159 bufferLib .release (buffer , frame , this );
147160 }
148161 }
149162 }
150163 }
151164
152- @ Builtin (name = "tregex_compile_internal" , minNumOfPositionalArgs = 3 )
165+ @ Builtin (name = "tregex_compile_internal" , minNumOfPositionalArgs = 4 )
153166 @ TypeSystemReference (PythonArithmeticTypes .class )
154167 @ GenerateNodeFactory
155- abstract static class TRegexCallCompile extends PythonTernaryBuiltinNode {
168+ abstract static class TRegexCallCompile extends PythonQuaternaryBuiltinNode {
156169
157170 @ Specialization
158- Object call (VirtualFrame frame , Object pattern , Object flags , PFunction fallbackCompiler ,
171+ Object call (VirtualFrame frame , Object pattern , Object flags , Object options , PFunction fallbackCompiler ,
159172 @ Cached BranchProfile potentialSyntaxError ,
160173 @ Cached BranchProfile syntaxError ,
161174 @ Cached BranchProfile unsupportedRegexError ,
162- @ Cached CastToJavaStringNode toStringNode ,
175+ @ Cached CastToJavaStringNode flagsToStringNode ,
176+ @ Cached CastToJavaStringNode optionsToStringNode ,
163177 @ Cached ToRegexSourceNode toRegexSourceNode ,
164178 @ Cached CallNode callFallbackCompilerNode ,
165179 @ CachedLibrary (limit = "2" ) InteropLibrary exceptionLib ,
166180 @ CachedLibrary (limit = "2" ) InteropLibrary compiledRegexLib ) {
167181 try {
168- String flagsStr = toStringNode .execute (flags );
169- Source regexSource = toRegexSourceNode .execute (frame , pattern , flagsStr );
182+ String flagsStr = flagsToStringNode .execute (flags );
183+ String optionsStr = optionsToStringNode .execute (options );
184+ Source regexSource = toRegexSourceNode .execute (frame , pattern , flagsStr , optionsStr );
170185 Object compiledRegex = getContext ().getEnv ().parseInternal (regexSource ).call ();
171186 if (compiledRegexLib .isNull (compiledRegex )) {
172187 unsupportedRegexError .enter ();
0 commit comments