44
44
import static com .oracle .graal .python .nodes .SpecialMethodNames .__RMUL__ ;
45
45
import static com .oracle .graal .python .nodes .SpecialMethodNames .__STR__ ;
46
46
import static com .oracle .graal .python .runtime .exception .PythonErrorType .IndexError ;
47
- import static com .oracle .graal .python .runtime .exception .PythonErrorType .LookupError ;
48
47
import static com .oracle .graal .python .runtime .exception .PythonErrorType .MemoryError ;
49
48
import static com .oracle .graal .python .runtime .exception .PythonErrorType .TypeError ;
50
- import static com .oracle .graal .python .runtime .exception .PythonErrorType .UnicodeEncodeError ;
51
49
import static com .oracle .graal .python .runtime .exception .PythonErrorType .ValueError ;
52
50
53
- import java .nio .ByteBuffer ;
54
- import java .nio .CharBuffer ;
55
- import java .nio .charset .CharacterCodingException ;
56
- import java .nio .charset .Charset ;
57
51
import java .nio .charset .CharsetEncoder ;
58
- import java .nio .charset .CodingErrorAction ;
59
- import java .nio .charset .IllegalCharsetNameException ;
60
52
import java .nio .charset .StandardCharsets ;
61
- import java .nio .charset .UnsupportedCharsetException ;
62
53
import java .util .Arrays ;
63
54
import java .util .List ;
64
55
import java .util .Locale ;
75
66
import com .oracle .graal .python .builtins .CoreFunctions ;
76
67
import com .oracle .graal .python .builtins .PythonBuiltinClassType ;
77
68
import com .oracle .graal .python .builtins .PythonBuiltins ;
69
+ import com .oracle .graal .python .builtins .modules .BuiltinFunctions ;
70
+ import com .oracle .graal .python .builtins .modules .CodecsModuleBuiltins ;
71
+ import com .oracle .graal .python .builtins .modules .OperatorModuleBuiltins ;
78
72
import com .oracle .graal .python .builtins .objects .PNone ;
79
73
import com .oracle .graal .python .builtins .objects .PNotImplemented ;
80
74
import com .oracle .graal .python .builtins .objects .bytes .BytesUtils ;
75
+ import com .oracle .graal .python .builtins .objects .bytes .PByteArray ;
76
+ import com .oracle .graal .python .builtins .objects .bytes .PBytes ;
81
77
import com .oracle .graal .python .builtins .objects .cext .PythonAbstractNativeObject ;
82
78
import com .oracle .graal .python .builtins .objects .common .FormatNodeBase ;
83
79
import com .oracle .graal .python .builtins .objects .common .HashingCollectionNodes ;
84
80
import com .oracle .graal .python .builtins .objects .common .HashingStorage ;
85
81
import com .oracle .graal .python .builtins .objects .common .HashingStorageLibrary ;
86
82
import com .oracle .graal .python .builtins .objects .common .SequenceNodes .GetObjectArrayNode ;
87
83
import com .oracle .graal .python .builtins .objects .common .SequenceNodesFactory .GetObjectArrayNodeGen ;
84
+ import com .oracle .graal .python .builtins .objects .common .SequenceStorageNodes ;
88
85
import com .oracle .graal .python .builtins .objects .dict .PDict ;
89
86
import com .oracle .graal .python .builtins .objects .iterator .PStringIterator ;
90
87
import com .oracle .graal .python .builtins .objects .list .ListBuiltins .ListReverseNode ;
103
100
import com .oracle .graal .python .builtins .objects .tuple .PTuple ;
104
101
import com .oracle .graal .python .builtins .objects .tuple .TupleBuiltins ;
105
102
import com .oracle .graal .python .builtins .objects .type .TypeNodes .IsSameTypeNode ;
103
+ import com .oracle .graal .python .builtins .objects .function .PKeyword ;
104
+ import com .oracle .graal .python .builtins .objects .object .PythonObjectLibrary ;
106
105
import com .oracle .graal .python .lib .PyNumberAsSizeNode ;
107
106
import com .oracle .graal .python .lib .PyObjectHashNode ;
107
+ import static com .oracle .graal .python .nodes .BuiltinNames .ENCODE ;
108
+ import static com .oracle .graal .python .nodes .BuiltinNames .FORMAT ;
109
+ import static com .oracle .graal .python .nodes .BuiltinNames .FORMAT_MAP ;
108
110
import com .oracle .graal .python .nodes .ErrorMessages ;
111
+ import static com .oracle .graal .python .nodes .ErrorMessages .ENCODER_RETURNED_P_INSTEAD_OF_BYTES ;
112
+ import static com .oracle .graal .python .nodes .ErrorMessages .OBJ_NOT_SUBSCRIPTABLE ;
113
+ import static com .oracle .graal .python .nodes .ErrorMessages .TAKES_EXACTLY_S_ARGUMENTS_D_GIVEN ;
109
114
import com .oracle .graal .python .nodes .PGuards ;
110
115
import com .oracle .graal .python .nodes .PRaiseNode ;
111
116
import com .oracle .graal .python .nodes .SpecialMethodNames ;
@@ -227,6 +232,76 @@ private Spec getAndValidateSpec(String formatString) {
227
232
}
228
233
}
229
234
235
+ @ Builtin (name = FORMAT , minNumOfPositionalArgs = 1 , takesVarArgs = true , takesVarKeywordArgs = true , declaresExplicitSelf = true )
236
+ @ GenerateNodeFactory
237
+ abstract static class StrFormatNode extends PythonBuiltinNode {
238
+ @ Specialization
239
+ String format (VirtualFrame frame , PString self , Object [] args , PKeyword [] kwargs ,
240
+ @ Cached BuiltinFunctions .FormatNode format ,
241
+ @ Cached OperatorModuleBuiltins .GetItemNode getItem ) {
242
+ return format (frame , self .getValue (), args , kwargs , format , getItem );
243
+ }
244
+
245
+ @ Specialization
246
+ String format (VirtualFrame frame , String self , Object [] args , PKeyword [] kwargs ,
247
+ @ Cached BuiltinFunctions .FormatNode format ,
248
+ @ Cached OperatorModuleBuiltins .GetItemNode getItem ) {
249
+
250
+ TemplateFormatter template = new TemplateFormatter (self );
251
+
252
+ PythonLanguage language = PythonLanguage .get (this );
253
+ PythonContext context = PythonContext .get (this );
254
+ Object state = IndirectCallContext .enter (frame , language , context , this );
255
+ try {
256
+ return template .build (this , args , kwargs , format , getItem );
257
+ } finally {
258
+ IndirectCallContext .exit (frame , language , context , state );
259
+ }
260
+ }
261
+ }
262
+
263
+ @ Builtin (name = FORMAT_MAP , minNumOfPositionalArgs = 1 , declaresExplicitSelf = true , parameterNames = {"self" , "mapping" })
264
+ @ ArgumentClinic (name = "self" , conversion = ArgumentClinic .ClinicConversion .String )
265
+ @ GenerateNodeFactory
266
+ @ ImportStatic (SpecialMethodNames .class )
267
+ abstract static class FormatMapNode extends PythonBinaryClinicBuiltinNode {
268
+ @ Override
269
+ protected ArgumentClinicProvider getArgumentClinic () {
270
+ return StringBuiltinsClinicProviders .FormatMapNodeClinicProviderGen .INSTANCE ;
271
+ }
272
+
273
+ @ Specialization (guards = "lib.isMapping(mapping)" , limit = "1" )
274
+ String format (VirtualFrame frame , String self , Object mapping ,
275
+ @ Cached BuiltinFunctions .FormatNode format ,
276
+ @ Cached OperatorModuleBuiltins .GetItemNode getItem ,
277
+ @ SuppressWarnings ("unused" ) @ CachedLibrary ("mapping" ) PythonObjectLibrary lib ) {
278
+
279
+ TemplateFormatter template = new TemplateFormatter (self );
280
+
281
+ PythonLanguage language = PythonLanguage .get (this );
282
+ PythonContext context = PythonContext .get (this );
283
+ Object state = IndirectCallContext .enter (frame , language , context , this );
284
+ try {
285
+ return template .build (this , null , mapping , format , getItem );
286
+ } finally {
287
+ IndirectCallContext .exit (frame , language , context , state );
288
+ }
289
+ }
290
+
291
+ @ SuppressWarnings ("unused" )
292
+ @ Specialization (guards = {"!lib.isMapping(obj)" , "!isNone(obj)" }, limit = "1" )
293
+ String format (String self , Object obj ,
294
+ @ SuppressWarnings ("unused" ) @ CachedLibrary ("obj" ) PythonObjectLibrary lib ) {
295
+ throw raise (TypeError , OBJ_NOT_SUBSCRIPTABLE , obj );
296
+ }
297
+
298
+ @ SuppressWarnings ("unused" )
299
+ @ Specialization (guards = "isNone(obj)" )
300
+ String format (String self , PNone obj ) {
301
+ throw raise (TypeError , TAKES_EXACTLY_S_ARGUMENTS_D_GIVEN , "format_map" , "one" , 0 );
302
+ }
303
+ }
304
+
230
305
@ Builtin (name = __REPR__ , minNumOfPositionalArgs = 1 )
231
306
@ GenerateNodeFactory
232
307
abstract static class ReprNode extends PythonUnaryBuiltinNode {
@@ -1743,8 +1818,15 @@ public int rindex(Object self, Object sub, int start, int end,
1743
1818
}
1744
1819
}
1745
1820
1746
- // This is only used during bootstrap and then replaced with Python code
1747
- @ Builtin (name = "encode" , minNumOfPositionalArgs = 1 , parameterNames = {"self" , "encoding" , "errors" })
1821
+ @ Builtin (name = ENCODE , minNumOfPositionalArgs = 1 , parameterNames = {"self" , "encoding" , "errors" }, doc = "Decode the bytes using the codec registered for encoding.\n \n " +
1822
+ " encoding\n " +
1823
+ " The encoding with which to decode the bytes.\n " +
1824
+ " errors\n " +
1825
+ " The error handling scheme to use for the handling of decoding errors.\n " +
1826
+ " The default is 'strict' meaning that decoding errors raise a\n " +
1827
+ " UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n " +
1828
+ " as well as any other name registered with codecs.register_error that\n " +
1829
+ " can handle UnicodeDecodeErrors." )
1748
1830
@ ArgumentClinic (name = "encoding" , conversion = ClinicConversion .String , defaultValue = "\" utf-8\" " , useDefaultForNone = true )
1749
1831
@ ArgumentClinic (name = "errors" , conversion = ClinicConversion .String , defaultValue = "\" strict\" " , useDefaultForNone = true )
1750
1832
@ GenerateNodeFactory
@@ -1757,48 +1839,26 @@ protected ArgumentClinicProvider getArgumentClinic() {
1757
1839
}
1758
1840
1759
1841
@ Specialization
1760
- Object doStringEncodingErrors (String self , String encoding , String errors ) {
1761
- return encodeString (self , encoding , errors );
1842
+ Object doStringEncoding (VirtualFrame frame , String self , String encoding , String errors ,
1843
+ @ Cached CodecsModuleBuiltins .EncodeNode encodeNode ,
1844
+ @ Cached SequenceStorageNodes .CopyNode copyNode ) {
1845
+ Object result = encodeNode .call (frame , self , encoding , errors );
1846
+ if (!(result instanceof PBytes )) {
1847
+ if (result instanceof PByteArray ) {
1848
+ return factory ().createBytes (copyNode .execute (((PByteArray ) result ).getSequenceStorage ()));
1849
+ }
1850
+ throw raise (TypeError , ENCODER_RETURNED_P_INSTEAD_OF_BYTES , encoding , result );
1851
+ }
1852
+ return result ;
1762
1853
}
1763
1854
1764
1855
@ Specialization
1765
- Object doGeneric (Object self , String encoding , String errors ,
1766
- @ Cached CastToJavaStringCheckedNode castSelfNode ) {
1856
+ Object doGeneric (VirtualFrame frame , Object self , String encoding , String errors ,
1857
+ @ Cached CastToJavaStringCheckedNode castSelfNode ,
1858
+ @ Cached CodecsModuleBuiltins .EncodeNode encodeNode ,
1859
+ @ Cached SequenceStorageNodes .CopyNode copyNode ) {
1767
1860
String selfStr = castSelfNode .cast (self , ErrorMessages .REQUIRES_STR_OBJECT_BUT_RECEIVED_P , "index" , self );
1768
- return encodeString (selfStr , encoding , errors );
1769
- }
1770
-
1771
- @ TruffleBoundary
1772
- private Object encodeString (String self , String encoding , String errors ) {
1773
- // Note: to support custom actions, we can use CharsetEncoderICU from icu4j-charset
1774
- CodingErrorAction errorAction ;
1775
- switch (errors ) {
1776
- case "ignore" :
1777
- errorAction = CodingErrorAction .IGNORE ;
1778
- break ;
1779
- case "replace" :
1780
- errorAction = CodingErrorAction .REPLACE ;
1781
- break ;
1782
- default :
1783
- errorAction = CodingErrorAction .REPORT ;
1784
- break ;
1785
- }
1786
-
1787
- Charset cs ;
1788
- try {
1789
- cs = Charset .forName (encoding );
1790
- } catch (UnsupportedCharsetException | IllegalCharsetNameException e ) {
1791
- throw raise (LookupError , ErrorMessages .UNKNOWN_ENCODING , encoding );
1792
- }
1793
- try {
1794
- ByteBuffer encoded = cs .newEncoder ().onMalformedInput (errorAction ).onUnmappableCharacter (errorAction ).encode (CharBuffer .wrap (self ));
1795
- int n = encoded .remaining ();
1796
- byte [] data = new byte [n ];
1797
- encoded .get (data );
1798
- return factory ().createBytes (data );
1799
- } catch (CharacterCodingException e ) {
1800
- throw raise (UnicodeEncodeError , e );
1801
- }
1861
+ return doStringEncoding (frame , selfStr , encoding , errors , encodeNode , copyNode );
1802
1862
}
1803
1863
}
1804
1864
0 commit comments