|
47 | 47 | import java.util.List;
|
48 | 48 | import java.util.zip.CRC32;
|
49 | 49 |
|
| 50 | +import com.oracle.graal.python.annotations.ArgumentClinic; |
50 | 51 | import com.oracle.graal.python.builtins.Builtin;
|
51 | 52 | import com.oracle.graal.python.builtins.CoreFunctions;
|
52 | 53 | import com.oracle.graal.python.builtins.PythonBuiltinClassType;
|
53 | 54 | import com.oracle.graal.python.builtins.PythonBuiltins;
|
54 | 55 | import com.oracle.graal.python.builtins.objects.PNone;
|
55 | 56 | import com.oracle.graal.python.builtins.objects.array.PArray;
|
56 |
| -import com.oracle.graal.python.builtins.objects.bytes.BytesNodes; |
57 | 57 | import com.oracle.graal.python.builtins.objects.bytes.BytesUtils;
|
58 | 58 | import com.oracle.graal.python.builtins.objects.bytes.PBytes;
|
59 |
| -import com.oracle.graal.python.builtins.objects.bytes.PBytesLike; |
60 | 59 | import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
|
61 |
| -import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodesFactory.ToByteArrayNodeGen; |
62 |
| -import com.oracle.graal.python.builtins.objects.ints.PInt; |
63 |
| -import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView; |
64 | 60 | import com.oracle.graal.python.builtins.objects.module.PythonModule;
|
65 | 61 | import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
|
66 | 62 | import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass;
|
67 | 63 | import com.oracle.graal.python.nodes.ErrorMessages;
|
68 | 64 | import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
|
69 | 65 | import com.oracle.graal.python.nodes.call.CallNode;
|
70 |
| -import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode; |
71 | 66 | import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
|
72 | 67 | import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
|
| 68 | +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode; |
73 | 69 | import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
|
| 70 | +import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; |
74 | 71 | import com.oracle.graal.python.nodes.statement.RaiseNode;
|
75 | 72 | import com.oracle.graal.python.nodes.statement.RaiseNodeGen;
|
76 |
| -import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; |
77 | 73 | import com.oracle.graal.python.runtime.PythonCore;
|
78 | 74 | import com.oracle.graal.python.runtime.exception.PException;
|
79 | 75 | import com.oracle.truffle.api.CompilerDirectives;
|
|
84 | 80 | import com.oracle.truffle.api.dsl.GenerateNodeFactory;
|
85 | 81 | import com.oracle.truffle.api.dsl.NodeFactory;
|
86 | 82 | import com.oracle.truffle.api.dsl.Specialization;
|
87 |
| -import com.oracle.truffle.api.dsl.TypeSystemReference; |
88 |
| -import com.oracle.truffle.api.frame.VirtualFrame; |
89 | 83 | import com.oracle.truffle.api.interop.UnsupportedMessageException;
|
90 | 84 | import com.oracle.truffle.api.library.CachedLibrary;
|
91 |
| -import com.oracle.truffle.api.profiles.ConditionProfile; |
92 | 85 | import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
|
93 | 86 |
|
94 | 87 | @CoreFunctions(defineModule = "binascii")
|
@@ -119,10 +112,14 @@ PBytes doString(String data) {
|
119 | 112 | return factory().createBytes(b64decode(data));
|
120 | 113 | }
|
121 | 114 |
|
122 |
| - @Specialization |
123 |
| - PBytes doBytesLike(VirtualFrame frame, PBytesLike data, |
124 |
| - @Cached("create()") BytesNodes.ToBytesNode toBytesNode) { |
125 |
| - return factory().createBytes(b64decode(toBytesNode.execute(frame, data))); |
| 115 | + @Specialization(guards = "bufferLib.isBuffer(data)", limit = "3") |
| 116 | + PBytes doBuffer(Object data, |
| 117 | + @CachedLibrary("data") PythonObjectLibrary bufferLib) { |
| 118 | + try { |
| 119 | + return factory().createBytes(b64decode(bufferLib.getBufferBytes(data))); |
| 120 | + } catch (UnsupportedMessageException e) { |
| 121 | + throw raise(SystemError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC); |
| 122 | + } |
126 | 123 | }
|
127 | 124 |
|
128 | 125 | @TruffleBoundary
|
@@ -241,123 +238,37 @@ private void raiseObject(Object exceptionObject, String message) {
|
241 | 238 | }
|
242 | 239 | }
|
243 | 240 |
|
244 |
| - @Builtin(name = "b2a_base64", minNumOfPositionalArgs = 1, parameterNames = {"data", "newline"}) |
245 |
| - @TypeSystemReference(PythonArithmeticTypes.class) |
| 241 | + @Builtin(name = "b2a_base64", minNumOfPositionalArgs = 1, numOfPositionalOnlyArgs = 1, parameterNames = {"data"}, keywordOnlyNames = {"newline"}) |
| 242 | + @ArgumentClinic(name = "newline", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "1", useDefaultForNone = true) |
246 | 243 | @GenerateNodeFactory
|
247 |
| - abstract static class B2aBase64Node extends PythonBinaryBuiltinNode { |
248 |
| - |
249 |
| - @Child private SequenceStorageNodes.ToByteArrayNode toByteArray; |
250 |
| - @Child private B2aBase64Node recursiveNode; |
251 |
| - |
252 |
| - private SequenceStorageNodes.ToByteArrayNode getToByteArrayNode() { |
253 |
| - if (toByteArray == null) { |
254 |
| - CompilerDirectives.transferToInterpreterAndInvalidate(); |
255 |
| - toByteArray = insert(ToByteArrayNodeGen.create()); |
256 |
| - } |
257 |
| - return toByteArray; |
258 |
| - } |
259 |
| - |
260 |
| - private B2aBase64Node getRecursiveNode() { |
261 |
| - if (recursiveNode == null) { |
262 |
| - CompilerDirectives.transferToInterpreterAndInvalidate(); |
263 |
| - recursiveNode = insert(BinasciiModuleBuiltinsFactory.B2aBase64NodeFactory.create()); |
264 |
| - } |
265 |
| - return recursiveNode; |
266 |
| - } |
267 |
| - |
| 244 | + abstract static class B2aBase64Node extends PythonBinaryClinicBuiltinNode { |
268 | 245 | @TruffleBoundary
|
269 |
| - private PBytes b2a(byte[] data, boolean newline) { |
| 246 | + private static byte[] b2a(byte[] data, int newline) { |
270 | 247 | String encode = Base64.encode(data);
|
271 |
| - if (newline) { |
272 |
| - return factory().createBytes((encode + "\n").getBytes()); |
| 248 | + if (newline != 0) { |
| 249 | + return (encode + "\n").getBytes(); |
273 | 250 | }
|
274 |
| - return factory().createBytes((encode).getBytes()); |
275 |
| - } |
276 |
| - |
277 |
| - @Specialization(guards = "isNoValue(newline)") |
278 |
| - PBytes b2aBytesLike(PBytesLike data, @SuppressWarnings("unused") PNone newline) { |
279 |
| - return b2aBytesLike(data, 1); |
280 |
| - } |
281 |
| - |
282 |
| - @Specialization |
283 |
| - PBytes b2aBytesLike(PBytesLike data, long newline) { |
284 |
| - return b2a(getToByteArrayNode().execute(data.getSequenceStorage()), newline != 0); |
285 |
| - } |
286 |
| - |
287 |
| - @Specialization |
288 |
| - PBytes b2aBytesLike(PBytesLike data, PInt newline) { |
289 |
| - return b2a(getToByteArrayNode().execute(data.getSequenceStorage()), !newline.isZero()); |
| 251 | + return encode.getBytes(); |
290 | 252 | }
|
291 | 253 |
|
292 |
| - @Specialization(limit = "1") |
293 |
| - PBytes b2aBytesLike(VirtualFrame frame, PBytesLike data, Object newline, |
294 |
| - @CachedLibrary("newline") PythonObjectLibrary lib) { |
295 |
| - return (PBytes) getRecursiveNode().execute(frame, data, asPInt(newline, lib)); |
296 |
| - } |
297 |
| - |
298 |
| - @Specialization(guards = "isNoValue(newline)") |
299 |
| - PBytes b2aArray(VirtualFrame frame, PArray data, @SuppressWarnings("unused") PNone newline, |
300 |
| - @CachedLibrary(limit = "1") PythonObjectLibrary lib) { |
301 |
| - return b2aArray(frame, data, 1, lib); |
302 |
| - } |
303 |
| - |
304 |
| - @Specialization |
305 |
| - PBytes b2aArray(PArray data, long newline) { |
306 |
| - return b2a(getToByteArrayNode().execute(data.getSequenceStorage()), newline != 0); |
307 |
| - } |
308 |
| - |
309 |
| - @Specialization |
310 |
| - PBytes b2aArray(PArray data, PInt newline) { |
311 |
| - return b2a(getToByteArrayNode().execute(data.getSequenceStorage()), !newline.isZero()); |
312 |
| - } |
313 |
| - |
314 |
| - @Specialization(limit = "1") |
315 |
| - PBytes b2aArray(VirtualFrame frame, PArray data, Object newline, |
316 |
| - @CachedLibrary("newline") PythonObjectLibrary lib) { |
317 |
| - return (PBytes) getRecursiveNode().execute(frame, data, asPInt(newline, lib)); |
318 |
| - } |
319 |
| - |
320 |
| - @Specialization(guards = "isNoValue(newline)") |
321 |
| - PBytes b2aMmeory(VirtualFrame frame, PMemoryView data, @SuppressWarnings("unused") PNone newline, |
322 |
| - @Cached("create(TOBYTES)") LookupAndCallUnaryNode toBytesNode, |
323 |
| - @Cached("createBinaryProfile()") ConditionProfile isBytesProfile) { |
324 |
| - return b2aMemory(frame, data, 1, toBytesNode, isBytesProfile); |
325 |
| - } |
326 |
| - |
327 |
| - @Specialization |
328 |
| - PBytes b2aMemory(VirtualFrame frame, PMemoryView data, long newline, |
329 |
| - @Cached("create(TOBYTES)") LookupAndCallUnaryNode toBytesNode, |
330 |
| - @Cached("createBinaryProfile()") ConditionProfile isBytesProfile) { |
331 |
| - Object bytesObj = toBytesNode.executeObject(frame, data); |
332 |
| - if (isBytesProfile.profile(bytesObj instanceof PBytes)) { |
333 |
| - return b2aBytesLike((PBytes) bytesObj, newline); |
| 254 | + @Specialization(guards = "bufferLib.isBuffer(data)", limit = "3") |
| 255 | + PBytes b2aBuffer(Object data, int newline, |
| 256 | + @CachedLibrary("data") PythonObjectLibrary bufferLib) { |
| 257 | + try { |
| 258 | + return factory().createBytes(b2a(bufferLib.getBufferBytes(data), newline)); |
| 259 | + } catch (UnsupportedMessageException e) { |
| 260 | + throw raise(SystemError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC); |
334 | 261 | }
|
335 |
| - throw raise(SystemError, ErrorMessages.COULD_NOT_GET_BYTES_OF_MEMORYVIEW); |
336 |
| - } |
337 |
| - |
338 |
| - @Specialization |
339 |
| - PBytes b2aMmeory(VirtualFrame frame, PMemoryView data, PInt newline, |
340 |
| - @Cached("create(TOBYTES)") LookupAndCallUnaryNode toBytesNode, |
341 |
| - @Cached("createBinaryProfile()") ConditionProfile isBytesProfile) { |
342 |
| - return b2aMemory(frame, data, newline.isZero() ? 0 : 1, toBytesNode, isBytesProfile); |
343 |
| - } |
344 |
| - |
345 |
| - @Specialization(limit = "1") |
346 |
| - PBytes b2aMmeory(VirtualFrame frame, PMemoryView data, Object newline, |
347 |
| - @CachedLibrary("newline") PythonObjectLibrary lib) { |
348 |
| - return (PBytes) getRecursiveNode().execute(frame, data, asPInt(newline, lib)); |
349 | 262 | }
|
350 | 263 |
|
351 | 264 | @Fallback
|
352 | 265 | PBytes b2sGeneral(Object data, @SuppressWarnings("unused") Object newline) {
|
353 | 266 | throw raise(PythonBuiltinClassType.TypeError, ErrorMessages.BYTESLIKE_OBJ_REQUIRED, data);
|
354 | 267 | }
|
355 | 268 |
|
356 |
| - private Object asPInt(Object obj, PythonObjectLibrary lib) { |
357 |
| - if (lib.canBePInt(obj)) { |
358 |
| - return lib.asPInt(obj); |
359 |
| - } |
360 |
| - throw raise(PythonBuiltinClassType.TypeError, ErrorMessages.INTEGER_REQUIRED_GOT, obj); |
| 269 | + @Override |
| 270 | + protected ArgumentClinicProvider getArgumentClinic() { |
| 271 | + return BinasciiModuleBuiltinsClinicProviders.B2aBase64NodeClinicProviderGen.INSTANCE; |
361 | 272 | }
|
362 | 273 | }
|
363 | 274 |
|
|
0 commit comments