52
52
import com .oracle .graal .python .PythonLanguage ;
53
53
import com .oracle .graal .python .builtins .PythonBuiltinClassType ;
54
54
import com .oracle .graal .python .builtins .objects .bytes .PByteArray ;
55
+ import com .oracle .graal .python .builtins .objects .bytes .PBytes ;
55
56
import com .oracle .graal .python .builtins .objects .cext .CExtNodes ;
56
57
import com .oracle .graal .python .builtins .objects .cext .NativeCAPISymbols ;
57
58
import com .oracle .graal .python .builtins .objects .common .SequenceNodes ;
63
64
import com .oracle .graal .python .nodes .PGuards ;
64
65
import com .oracle .graal .python .nodes .PRaiseNode ;
65
66
import com .oracle .graal .python .nodes .attributes .ReadAttributeFromObjectNode ;
67
+ import com .oracle .graal .python .nodes .util .CastToJavaUnsignedLongNode ;
66
68
import com .oracle .graal .python .runtime .PythonContext ;
67
69
import com .oracle .graal .python .runtime .exception .PException ;
68
70
import com .oracle .graal .python .runtime .object .PythonObjectFactory ;
@@ -241,35 +243,175 @@ private static long unpackInt64(byte[] bytes) {
241
243
}
242
244
}
243
245
244
- @ ImportStatic (PMemoryView .BufferFormat .class )
246
+ @ ImportStatic ({ PMemoryView .BufferFormat .class , PGuards . class } )
245
247
abstract static class PackValueNode extends Node {
246
248
@ Child private PRaiseNode raiseNode ;
247
249
248
250
// Output goes to bytes, lenght not checked
249
- public abstract void execute (PMemoryView .BufferFormat format , Object object , byte [] bytes );
251
+ public abstract void execute (VirtualFrame frame , PMemoryView .BufferFormat format , String formatStr , Object object , byte [] bytes );
250
252
251
- @ Specialization (guards = "format == UNSIGNED_BYTE" , limit = "2" )
252
- void packUnsignedByte (@ SuppressWarnings ("unused" ) PMemoryView .BufferFormat format , Object object , byte [] bytes ,
253
+ @ Specialization (guards = "format == UNSIGNED_BYTE" )
254
+ void packUnsignedByteInt (@ SuppressWarnings ("unused" ) PMemoryView .BufferFormat format , String formatStr , int value , byte [] bytes ) {
255
+ assert bytes .length == 1 ;
256
+ if (value < 0 || value > 0xFF ) {
257
+ throw raise (ValueError , ErrorMessages .MEMORYVIEW_INVALID_VALUE_FOR_FORMAT_S , formatStr );
258
+ }
259
+ bytes [0 ] = (byte ) value ;
260
+ }
261
+
262
+ @ Specialization (guards = "format == UNSIGNED_BYTE" , replaces = "packUnsignedByteInt" , limit = "2" )
263
+ void packUnsignedByteGeneric (VirtualFrame frame , @ SuppressWarnings ("unused" ) PMemoryView .BufferFormat format , String formatStr , Object object , byte [] bytes ,
253
264
@ CachedLibrary ("object" ) PythonObjectLibrary lib ) {
265
+ long value = lib .asJavaLong (object , frame );
254
266
assert bytes .length == 1 ;
255
- long value = lib .asJavaLong (object );
256
267
if (value < 0 || value > 0xFF ) {
257
- throw raise (ValueError , ErrorMessages .MEMORYVIEW_INVALID_VALUE_FOR_FORMAT_S , format );
268
+ throw raise (ValueError , ErrorMessages .MEMORYVIEW_INVALID_VALUE_FOR_FORMAT_S , formatStr );
258
269
}
259
270
bytes [0 ] = (byte ) value ;
260
271
}
261
272
273
+ @ Specialization (guards = "format == SIGNED_BYTE" , replaces = "packUnsignedByteInt" , limit = "2" )
274
+ void packSignedByteGeneric (VirtualFrame frame , @ SuppressWarnings ("unused" ) PMemoryView .BufferFormat format , String formatStr , Object object , byte [] bytes ,
275
+ @ CachedLibrary ("object" ) PythonObjectLibrary lib ) {
276
+ long value = lib .asJavaLong (object , frame );
277
+ assert bytes .length == 1 ;
278
+ if (value < Byte .MIN_VALUE || value > Byte .MAX_VALUE ) {
279
+ throw raise (ValueError , ErrorMessages .MEMORYVIEW_INVALID_VALUE_FOR_FORMAT_S , formatStr );
280
+ }
281
+ bytes [0 ] = (byte ) value ;
282
+ }
283
+
284
+ @ Specialization (guards = "format == SIGNED_SHORT" , limit = "2" )
285
+ void packSignedShortGeneric (VirtualFrame frame , @ SuppressWarnings ("unused" ) PMemoryView .BufferFormat format , String formatStr , Object object , byte [] bytes ,
286
+ @ CachedLibrary ("object" ) PythonObjectLibrary lib ) {
287
+ long value = lib .asJavaLong (object , frame );
288
+ if (value < Short .MIN_VALUE || value > Short .MAX_VALUE ) {
289
+ throw raise (ValueError , ErrorMessages .MEMORYVIEW_INVALID_VALUE_FOR_FORMAT_S , formatStr );
290
+ }
291
+ packInt16 ((int ) value , bytes );
292
+ }
293
+
294
+ @ Specialization (guards = "format == UNSIGNED_SHORT" , limit = "2" )
295
+ void packUnsignedShortGeneric (VirtualFrame frame , @ SuppressWarnings ("unused" ) PMemoryView .BufferFormat format , String formatStr , Object object , byte [] bytes ,
296
+ @ CachedLibrary ("object" ) PythonObjectLibrary lib ) {
297
+ long value = lib .asJavaLong (object , frame );
298
+ if (value < 0 || value > (Short .MAX_VALUE << 1 ) + 1 ) {
299
+ throw raise (ValueError , ErrorMessages .MEMORYVIEW_INVALID_VALUE_FOR_FORMAT_S , formatStr );
300
+ }
301
+ packInt16 ((int ) value , bytes );
302
+ }
303
+
304
+ @ Specialization (guards = "format == SIGNED_INT" )
305
+ static void packSignedIntInt (@ SuppressWarnings ("unused" ) PMemoryView .BufferFormat format , @ SuppressWarnings ("unused" ) String formatStr , int value , byte [] bytes ) {
306
+ packInt32 (value , bytes );
307
+ }
308
+
309
+ @ Specialization (guards = "format == SIGNED_INT" , replaces = "packSignedIntInt" , limit = "2" )
310
+ void packSignedIntGeneric (VirtualFrame frame , @ SuppressWarnings ("unused" ) PMemoryView .BufferFormat format , String formatStr , Object object , byte [] bytes ,
311
+ @ CachedLibrary ("object" ) PythonObjectLibrary lib ) {
312
+ long value = lib .asJavaLong (object , frame );
313
+ if (value < Integer .MIN_VALUE || value > Integer .MAX_VALUE ) {
314
+ throw raise (ValueError , ErrorMessages .MEMORYVIEW_INVALID_VALUE_FOR_FORMAT_S , formatStr );
315
+ }
316
+ packInt32 ((int ) value , bytes );
317
+ }
318
+
319
+ @ Specialization (guards = "format == UNSIGNED_INT" , replaces = "packSignedIntInt" , limit = "2" )
320
+ void packUnsignedIntGeneric (VirtualFrame frame , @ SuppressWarnings ("unused" ) PMemoryView .BufferFormat format , String formatStr , Object object , byte [] bytes ,
321
+ @ CachedLibrary ("object" ) PythonObjectLibrary lib ) {
322
+ long value = lib .asJavaLong (object , frame );
323
+ if (value < 0 || value > ((long ) (Integer .MAX_VALUE ) << 1L ) + 1L ) {
324
+ throw raise (ValueError , ErrorMessages .MEMORYVIEW_INVALID_VALUE_FOR_FORMAT_S , formatStr );
325
+ }
326
+ packInt32 ((int ) value , bytes );
327
+ }
328
+
262
329
@ Specialization (guards = "format == SIGNED_LONG" , limit = "2" )
263
- static void packLong (@ SuppressWarnings ("unused" ) PMemoryView .BufferFormat format , Object object , byte [] bytes ,
330
+ static void packSignedLong (VirtualFrame frame , @ SuppressWarnings ("unused" ) PMemoryView .BufferFormat format , @ SuppressWarnings ("unused" ) String formatStr , Object object , byte [] bytes ,
331
+ @ CachedLibrary ("object" ) PythonObjectLibrary lib ) {
332
+ assert bytes .length == 8 ;
333
+ packInt64 (lib .asJavaLong (object , frame ), bytes );
334
+ }
335
+
336
+ @ Specialization (guards = "format == UNSIGNED_LONG" , limit = "2" )
337
+ static void packUnsignedLong (VirtualFrame frame , @ SuppressWarnings ("unused" ) PMemoryView .BufferFormat format , @ SuppressWarnings ("unused" ) String formatStr , Object object , byte [] bytes ,
338
+ @ Cached CastToJavaUnsignedLongNode cast ,
264
339
@ CachedLibrary ("object" ) PythonObjectLibrary lib ) {
265
340
assert bytes .length == 8 ;
266
- long value = lib .asJavaLong (object );
267
- for (int i = 7 ; i >= 0 ; i --) {
268
- bytes [i ] = (byte ) (value & 0xFFL );
269
- value >>= 8 ;
341
+ packInt64 (cast .execute (lib .asIndexWithFrame (object , frame )), bytes );
342
+ }
343
+
344
+ @ Specialization (guards = "format == FLOAT" , limit = "2" )
345
+ static void packFloat (@ SuppressWarnings ("unused" ) PMemoryView .BufferFormat format , @ SuppressWarnings ("unused" ) String formatStr , Object object , byte [] bytes ,
346
+ @ CachedLibrary ("object" ) PythonObjectLibrary lib ) {
347
+ assert bytes .length == 4 ;
348
+ packInt32 (Float .floatToRawIntBits ((float ) lib .asJavaDouble (object )), bytes );
349
+ }
350
+
351
+ @ Specialization (guards = "format == DOUBLE" , limit = "2" )
352
+ static void packDouble (@ SuppressWarnings ("unused" ) PMemoryView .BufferFormat format , @ SuppressWarnings ("unused" ) String formatStr , Object object , byte [] bytes ,
353
+ @ CachedLibrary ("object" ) PythonObjectLibrary lib ) {
354
+ assert bytes .length == 8 ;
355
+ packInt64 (Double .doubleToRawLongBits (lib .asJavaDouble (object )), bytes );
356
+ }
357
+
358
+ @ Specialization (guards = "format == BOOLEAN" , limit = "2" )
359
+ static void packBoolean (VirtualFrame frame , @ SuppressWarnings ("unused" ) PMemoryView .BufferFormat format , @ SuppressWarnings ("unused" ) String formatStr , Object object , byte [] bytes ,
360
+ @ CachedLibrary ("object" ) PythonObjectLibrary lib ) {
361
+ assert bytes .length == 1 ;
362
+ bytes [0 ] = lib .isTrue (object , frame ) ? (byte ) 1 : (byte ) 0 ;
363
+ }
364
+
365
+ @ Specialization (guards = "format == CHAR" , limit = "2" )
366
+ void packChar (@ SuppressWarnings ("unused" ) PMemoryView .BufferFormat format , String formatStr , PBytes object , byte [] bytes ,
367
+ @ CachedLibrary ("object" ) PythonObjectLibrary lib ) {
368
+ try {
369
+ byte [] value = lib .getBufferBytes (object );
370
+ if (value .length != 1 ) {
371
+ throw raise (ValueError , ErrorMessages .MEMORYVIEW_INVALID_VALUE_FOR_FORMAT_S , formatStr );
372
+ }
373
+ bytes [0 ] = value [0 ];
374
+ } catch (UnsupportedMessageException e ) {
375
+ throw CompilerDirectives .shouldNotReachHere ();
270
376
}
271
377
}
272
378
379
+ @ Specialization (guards = {"format == CHAR" , "!isBytes(object)" })
380
+ void packChar (@ SuppressWarnings ("unused" ) PMemoryView .BufferFormat format , String formatStr , @ SuppressWarnings ("unused" ) Object object , @ SuppressWarnings ("unused" ) byte [] bytes ) {
381
+ throw raise (TypeError , ErrorMessages .MEMORYVIEW_INVALID_TYPE_FOR_FORMAT_S , formatStr );
382
+ }
383
+
384
+ @ Specialization (guards = "format == OTHER" )
385
+ void notImplemented (@ SuppressWarnings ("unused" ) PMemoryView .BufferFormat format , String formatStr , @ SuppressWarnings ("unused" ) Object object , @ SuppressWarnings ("unused" ) byte [] bytes ) {
386
+ throw raise (NotImplementedError , ErrorMessages .MEMORYVIEW_FORMAT_S_NOT_SUPPORTED , formatStr );
387
+ }
388
+
389
+ private static void packInt16 (int value , byte [] bytes ) {
390
+ assert bytes .length == 2 ;
391
+ bytes [0 ] = (byte ) value ;
392
+ bytes [1 ] = (byte ) (value >> 8 );
393
+ }
394
+
395
+ private static void packInt32 (int value , byte [] bytes ) {
396
+ assert bytes .length == 4 ;
397
+ bytes [0 ] = (byte ) value ;
398
+ bytes [1 ] = (byte ) (value >> 8 );
399
+ bytes [2 ] = (byte ) (value >> 16 );
400
+ bytes [3 ] = (byte ) (value >> 24 );
401
+ }
402
+
403
+ private static void packInt64 (long value , byte [] bytes ) {
404
+ assert bytes .length == 8 ;
405
+ bytes [0 ] = (byte ) value ;
406
+ bytes [1 ] = (byte ) (value >> 8 );
407
+ bytes [2 ] = (byte ) (value >> 16 );
408
+ bytes [3 ] = (byte ) (value >> 24 );
409
+ bytes [4 ] = (byte ) (value >> 32 );
410
+ bytes [5 ] = (byte ) (value >> 40 );
411
+ bytes [6 ] = (byte ) (value >> 48 );
412
+ bytes [7 ] = (byte ) (value >> 56 );
413
+ }
414
+
273
415
private PException raise (PythonBuiltinClassType type , String message , Object ... args ) {
274
416
if (raiseNode == null ) {
275
417
CompilerDirectives .transferToInterpreterAndInvalidate ();
@@ -372,12 +514,12 @@ abstract static class WriteItemAtNode extends Node {
372
514
public abstract void execute (VirtualFrame frame , PMemoryView self , Object ptr , int offset , Object object );
373
515
374
516
@ Specialization (guards = "ptr != null" )
375
- static void doNative (PMemoryView self , Object ptr , int offset , Object object ,
517
+ static void doNative (VirtualFrame frame , PMemoryView self , Object ptr , int offset , Object object ,
376
518
@ CachedLibrary (limit = "1" ) InteropLibrary lib ,
377
519
@ Cached PackValueNode packValueNode ) {
378
520
int itemsize = self .getItemSize ();
379
521
byte [] bytes = new byte [itemsize ];
380
- packValueNode .execute (self .getFormat (), object , bytes );
522
+ packValueNode .execute (frame , self .getFormat (), self . getFormatString (), object , bytes );
381
523
try {
382
524
for (int i = 0 ; i < itemsize ; i ++) {
383
525
lib .writeArrayElement (ptr , offset + i , bytes [i ]);
@@ -388,13 +530,13 @@ static void doNative(PMemoryView self, Object ptr, int offset, Object object,
388
530
}
389
531
390
532
@ Specialization (guards = "ptr == null" )
391
- static void doManaged (PMemoryView self , @ SuppressWarnings ("unused" ) Object ptr , int offset , Object object ,
533
+ static void doManaged (VirtualFrame frame , PMemoryView self , @ SuppressWarnings ("unused" ) Object ptr , int offset , Object object ,
392
534
@ Cached PackValueNode packValueNode ,
393
535
@ Cached SequenceNodes .GetSequenceStorageNode getStorageNode ,
394
536
@ Cached SequenceStorageNodes .SetItemScalarNode setItemNode ) {
395
537
// TODO assumes bytes storage
396
538
byte [] bytes = new byte [self .getItemSize ()];
397
- packValueNode .execute (self .getFormat (), object , bytes );
539
+ packValueNode .execute (frame , self .getFormat (), self . getFormatString (), object , bytes );
398
540
for (int i = 0 ; i < self .getItemSize (); i ++) {
399
541
setItemNode .execute (getStorageNode .execute (self .getOwner ()), offset + i , bytes [i ]);
400
542
}
0 commit comments