1
1
/*
2
- * Copyright (c) 2019, 2024 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2019, 2025 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* The Universal Permissive License (UPL), Version 1.0
42
42
43
43
import static com .oracle .truffle .api .nodes .ExplodeLoop .LoopExplosionKind .FULL_EXPLODE_UNTIL_RETURN ;
44
44
45
+ import java .lang .invoke .MethodHandles ;
46
+ import java .lang .invoke .VarHandle ;
47
+ import java .nio .ByteOrder ;
48
+ import java .util .Arrays ;
49
+
45
50
import org .graalvm .wasm .constants .GlobalModifier ;
46
51
import org .graalvm .wasm .exception .Failure ;
47
52
import org .graalvm .wasm .exception .WasmException ;
48
53
54
+ import com .oracle .truffle .api .CompilerDirectives ;
49
55
import com .oracle .truffle .api .CompilerDirectives .CompilationFinal ;
56
+ import com .oracle .truffle .api .memory .ByteArraySupport ;
50
57
import com .oracle .truffle .api .nodes .ExplodeLoop ;
51
58
52
- import java .util .Arrays ;
53
-
54
59
public abstract class BinaryStreamParser {
55
60
protected static final int SINGLE_RESULT_VALUE = 0 ;
56
61
protected static final int MULTI_RESULT_VALUE = 1 ;
57
62
63
+ private static final VarHandle I16LE = MethodHandles .byteArrayViewVarHandle (short [].class , ByteOrder .LITTLE_ENDIAN );
64
+ private static final VarHandle I32LE = MethodHandles .byteArrayViewVarHandle (int [].class , ByteOrder .LITTLE_ENDIAN );
65
+ private static final VarHandle I64LE = MethodHandles .byteArrayViewVarHandle (long [].class , ByteOrder .LITTLE_ENDIAN );
66
+
58
67
@ CompilationFinal (dimensions = 1 ) protected byte [] data ;
59
68
protected int offset ;
60
69
@@ -353,7 +362,7 @@ public static byte peekLeb128Length(byte[] data, int initialOffset) {
353
362
354
363
/**
355
364
* Reads the unsigned byte value at the given bytecode offset.
356
- *
365
+ *
357
366
* @param bytecode The bytecode
358
367
* @param offset The offset in the bytecode
359
368
* @return the unsigned byte value at the given bytecode offset.
@@ -364,7 +373,7 @@ public static int rawPeekU8(byte[] bytecode, int offset) {
364
373
365
374
/**
366
375
* Reads the signed byte value at the given bytecode offset.
367
- *
376
+ *
368
377
* @param bytecode The bytecode
369
378
* @param offset The offset in the bytecode
370
379
* @return The signed byte value at the given bytecode offset.
@@ -375,27 +384,38 @@ public static byte rawPeekI8(byte[] bytecode, int offset) {
375
384
376
385
/**
377
386
* Reads the unsigned short value at the given bytecode offset.
378
- *
387
+ *
379
388
* @param bytecode The bytecode
380
389
* @param offset The offset in the bytecode
381
390
* @return The unsigned short value at the given bytecode offset.
382
391
*/
383
392
public static int rawPeekU16 (byte [] bytecode , int offset ) {
384
- return ((bytecode [offset ] & 0xFF ) | ((bytecode [offset + 1 ] & 0xFF ) << 8 ));
393
+ return Short .toUnsignedInt (rawPeekI16 (bytecode , offset ));
394
+ }
395
+
396
+ /**
397
+ * Reads the signed short value at the given bytecode offset.
398
+ *
399
+ * @param bytecode The bytecode
400
+ * @param offset The offset in the bytecode
401
+ * @return The signed short value at the given bytecode offset.
402
+ */
403
+ public static short rawPeekI16 (byte [] bytecode , int offset ) {
404
+ if (CompilerDirectives .inCompiledCode ()) {
405
+ return ByteArraySupport .littleEndian ().getShortUnaligned (bytecode , offset );
406
+ }
407
+ return (short ) I16LE .get (bytecode , offset );
385
408
}
386
409
387
410
/**
388
411
* Writes the unsigned short value to the given bytecode offset.
389
- *
412
+ *
390
413
* @param bytecode The bytecode
391
414
* @param offset The offset in the bytecode
392
415
* @param value The value that should be written
393
416
*/
394
417
public static void writeU16 (byte [] bytecode , int offset , int value ) {
395
- final byte low = (byte ) (value & 0xFF );
396
- final byte high = (byte ) ((value >> 8 ) & 0xFF );
397
- bytecode [offset ] = low ;
398
- bytecode [offset + 1 ] = high ;
418
+ I16LE .set (bytecode , offset , (short ) value );
399
419
}
400
420
401
421
/**
@@ -406,60 +426,46 @@ public static void writeU16(byte[] bytecode, int offset, int value) {
406
426
* @return The unsigned integer value at the given bytecode offset.
407
427
*/
408
428
public static long rawPeekU32 (byte [] bytecode , int offset ) {
409
- return (bytecode [offset ] & 0xFFL ) |
410
- ((bytecode [offset + 1 ] & 0xFFL ) << 8 ) |
411
- ((bytecode [offset + 2 ] & 0xFFL ) << 16 ) |
412
- ((bytecode [offset + 3 ] & 0xFFL ) << 24 );
429
+ return Integer .toUnsignedLong (rawPeekI32 (bytecode , offset ));
413
430
}
414
431
415
432
/**
416
433
* Reads the signed integer value at the given bytecode offset.
417
- *
434
+ *
418
435
* @param bytecode The bytecode
419
436
* @param offset The offset in the bytecode.
420
437
* @return The signed integer value at the given bytecode offset.
421
438
*/
422
439
public static int rawPeekI32 (byte [] bytecode , int offset ) {
423
- return ( bytecode [ offset ] & 0xFF ) |
424
- ( (bytecode [ offset + 1 ] & 0xFF ) << 8 ) |
425
- (( bytecode [ offset + 2 ] & 0xFF ) << 16 ) |
426
- (( bytecode [ offset + 3 ] & 0xFF ) << 24 );
440
+ if ( CompilerDirectives . inCompiledCode ()) {
441
+ return ByteArraySupport . littleEndian (). getIntUnaligned (bytecode , offset );
442
+ }
443
+ return ( int ) I32LE . get ( bytecode , offset );
427
444
}
428
445
429
446
/**
430
447
* Reads the signed long value at the given bytecode offset.
431
- *
448
+ *
432
449
* @param bytecode The bytecode
433
450
* @param offset The offset in the bytecode.
434
451
* @return The signed long value at the given bytecode offset.
435
452
*/
436
453
public static long rawPeekI64 (byte [] bytecode , int offset ) {
437
- return (bytecode [offset ] & 0xFFL ) |
438
- ((bytecode [offset + 1 ] & 0xFFL ) << 8 ) |
439
- ((bytecode [offset + 2 ] & 0xFFL ) << 16 ) |
440
- ((bytecode [offset + 3 ] & 0xFFL ) << 24 ) |
441
- ((bytecode [offset + 4 ] & 0xFFL ) << 32 ) |
442
- ((bytecode [offset + 5 ] & 0xFFL ) << 40 ) |
443
- ((bytecode [offset + 6 ] & 0xFFL ) << 48 ) |
444
- ((bytecode [offset + 7 ] & 0xFFL ) << 56 );
454
+ if (CompilerDirectives .inCompiledCode ()) {
455
+ return ByteArraySupport .littleEndian ().getLongUnaligned (bytecode , offset );
456
+ }
457
+ return (long ) I64LE .get (bytecode , offset );
445
458
}
446
459
447
460
/**
448
461
* Writes the signed long value to the given bytecode offset.
449
- *
462
+ *
450
463
* @param bytecode The bytecode
451
464
* @param offset The offset in the bytecode
452
465
* @param value The value that should be written
453
466
*/
454
467
public static void writeI64 (byte [] bytecode , int offset , long value ) {
455
- bytecode [offset ] = (byte ) (value & 0xFF );
456
- bytecode [offset + 1 ] = (byte ) ((value >> 8 ) & 0xFF );
457
- bytecode [offset + 2 ] = (byte ) ((value >> 16 ) & 0xFF );
458
- bytecode [offset + 3 ] = (byte ) ((value >> 24 ) & 0xFF );
459
- bytecode [offset + 4 ] = (byte ) ((value >> 32 ) & 0xFF );
460
- bytecode [offset + 5 ] = (byte ) ((value >> 40 ) & 0xFF );
461
- bytecode [offset + 6 ] = (byte ) ((value >> 48 ) & 0xFF );
462
- bytecode [offset + 7 ] = (byte ) ((value >> 56 ) & 0xFF );
468
+ I64LE .set (bytecode , offset , value );
463
469
}
464
470
465
471
/**
0 commit comments