57
57
import com .oracle .graal .python .nodes .PNodeWithRaiseAndIndirectCall ;
58
58
import com .oracle .graal .python .nodes .call .CallNode ;
59
59
import com .oracle .graal .python .nodes .function .PythonBuiltinBaseNode ;
60
+ import com .oracle .graal .python .nodes .function .builtins .PythonQuaternaryBuiltinNode ;
60
61
import com .oracle .graal .python .nodes .function .builtins .PythonTernaryBuiltinNode ;
61
62
import com .oracle .graal .python .nodes .truffle .PythonArithmeticTypes ;
62
63
import com .oracle .graal .python .nodes .util .CannotCastException ;
65
66
import com .oracle .graal .python .runtime .PythonContext ;
66
67
import com .oracle .graal .python .runtime .PythonOptions ;
67
68
import com .oracle .graal .python .runtime .exception .PException ;
69
+ import com .oracle .graal .python .util .PythonUtils ;
68
70
import com .oracle .truffle .api .CompilerDirectives ;
69
71
import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
70
72
import com .oracle .truffle .api .dsl .Cached ;
80
82
import com .oracle .truffle .api .interop .UnsupportedTypeException ;
81
83
import com .oracle .truffle .api .library .CachedLibrary ;
82
84
import com .oracle .truffle .api .profiles .BranchProfile ;
85
+ import com .oracle .truffle .api .profiles .ConditionProfile ;
83
86
import com .oracle .truffle .api .source .Source ;
84
87
import com .oracle .truffle .api .source .SourceSection ;
85
88
@@ -98,7 +101,7 @@ public void initialize(Python3Core core) {
98
101
99
102
abstract static class ToRegexSourceNode extends PNodeWithRaiseAndIndirectCall {
100
103
101
- public abstract Source execute (VirtualFrame frame , Object pattern , String flags );
104
+ public abstract Source execute (VirtualFrame frame , Object pattern , String flags , String options );
102
105
103
106
@ TruffleBoundary
104
107
private static String decodeLatin1 (byte [] bytes , int length ) {
@@ -117,18 +120,24 @@ private static Source constructRegexSource(String options, String pattern, Strin
117
120
}
118
121
119
122
@ 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 );
123
131
}
124
132
125
133
@ 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 ,
127
136
@ Cached CastToJavaStringNode cast ,
128
137
@ CachedLibrary ("pattern" ) PythonBufferAcquireLibrary bufferAcquireLib ,
129
138
@ CachedLibrary (limit = "1" ) PythonBufferAccessLibrary bufferLib ) {
130
139
try {
131
- return doString (cast .execute (pattern ), flags );
140
+ return doString (cast .execute (pattern ), flags , options , nonEmptyOptionsProfile );
132
141
} catch (CannotCastException ce ) {
133
142
Object buffer ;
134
143
try {
@@ -137,36 +146,42 @@ protected Source doGeneric(VirtualFrame frame, Object pattern, String flags,
137
146
throw raise (TypeError , "expected string or bytes-like object" );
138
147
}
139
148
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
+ }
141
154
byte [] bytes = bufferLib .getInternalOrCopiedByteArray (buffer );
142
155
int bytesLen = bufferLib .getBufferLength (buffer );
143
156
String patternStr = decodeLatin1 (bytes , bytesLen );
144
- return constructRegexSource (options , patternStr , flags );
157
+ return constructRegexSource (PythonUtils . sbToString ( allOptions ) , patternStr , flags );
145
158
} finally {
146
159
bufferLib .release (buffer , frame , this );
147
160
}
148
161
}
149
162
}
150
163
}
151
164
152
- @ Builtin (name = "tregex_compile_internal" , minNumOfPositionalArgs = 3 )
165
+ @ Builtin (name = "tregex_compile_internal" , minNumOfPositionalArgs = 4 )
153
166
@ TypeSystemReference (PythonArithmeticTypes .class )
154
167
@ GenerateNodeFactory
155
- abstract static class TRegexCallCompile extends PythonTernaryBuiltinNode {
168
+ abstract static class TRegexCallCompile extends PythonQuaternaryBuiltinNode {
156
169
157
170
@ 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 ,
159
172
@ Cached BranchProfile potentialSyntaxError ,
160
173
@ Cached BranchProfile syntaxError ,
161
174
@ Cached BranchProfile unsupportedRegexError ,
162
- @ Cached CastToJavaStringNode toStringNode ,
175
+ @ Cached CastToJavaStringNode flagsToStringNode ,
176
+ @ Cached CastToJavaStringNode optionsToStringNode ,
163
177
@ Cached ToRegexSourceNode toRegexSourceNode ,
164
178
@ Cached CallNode callFallbackCompilerNode ,
165
179
@ CachedLibrary (limit = "2" ) InteropLibrary exceptionLib ,
166
180
@ CachedLibrary (limit = "2" ) InteropLibrary compiledRegexLib ) {
167
181
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 );
170
185
Object compiledRegex = getContext ().getEnv ().parseInternal (regexSource ).call ();
171
186
if (compiledRegexLib .isNull (compiledRegex )) {
172
187
unsupportedRegexError .enter ();
0 commit comments