11/*
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.
33 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44 *
55 * The Universal Permissive License (UPL), Version 1.0
4242
4343import static com .oracle .truffle .api .nodes .ExplodeLoop .LoopExplosionKind .FULL_EXPLODE_UNTIL_RETURN ;
4444
45+ import java .lang .invoke .MethodHandles ;
46+ import java .lang .invoke .VarHandle ;
47+ import java .nio .ByteOrder ;
48+ import java .util .Arrays ;
49+
4550import org .graalvm .wasm .constants .GlobalModifier ;
4651import org .graalvm .wasm .exception .Failure ;
4752import org .graalvm .wasm .exception .WasmException ;
4853
54+ import com .oracle .truffle .api .CompilerDirectives ;
4955import com .oracle .truffle .api .CompilerDirectives .CompilationFinal ;
56+ import com .oracle .truffle .api .memory .ByteArraySupport ;
5057import com .oracle .truffle .api .nodes .ExplodeLoop ;
5158
52- import java .util .Arrays ;
53-
5459public abstract class BinaryStreamParser {
5560 protected static final int SINGLE_RESULT_VALUE = 0 ;
5661 protected static final int MULTI_RESULT_VALUE = 1 ;
5762
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+
5867 @ CompilationFinal (dimensions = 1 ) protected byte [] data ;
5968 protected int offset ;
6069
@@ -353,7 +362,7 @@ public static byte peekLeb128Length(byte[] data, int initialOffset) {
353362
354363 /**
355364 * Reads the unsigned byte value at the given bytecode offset.
356- *
365+ *
357366 * @param bytecode The bytecode
358367 * @param offset The offset in the bytecode
359368 * @return the unsigned byte value at the given bytecode offset.
@@ -364,7 +373,7 @@ public static int rawPeekU8(byte[] bytecode, int offset) {
364373
365374 /**
366375 * Reads the signed byte value at the given bytecode offset.
367- *
376+ *
368377 * @param bytecode The bytecode
369378 * @param offset The offset in the bytecode
370379 * @return The signed byte value at the given bytecode offset.
@@ -375,27 +384,38 @@ public static byte rawPeekI8(byte[] bytecode, int offset) {
375384
376385 /**
377386 * Reads the unsigned short value at the given bytecode offset.
378- *
387+ *
379388 * @param bytecode The bytecode
380389 * @param offset The offset in the bytecode
381390 * @return The unsigned short value at the given bytecode offset.
382391 */
383392 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 );
385408 }
386409
387410 /**
388411 * Writes the unsigned short value to the given bytecode offset.
389- *
412+ *
390413 * @param bytecode The bytecode
391414 * @param offset The offset in the bytecode
392415 * @param value The value that should be written
393416 */
394417 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 );
399419 }
400420
401421 /**
@@ -406,60 +426,46 @@ public static void writeU16(byte[] bytecode, int offset, int value) {
406426 * @return The unsigned integer value at the given bytecode offset.
407427 */
408428 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 ));
413430 }
414431
415432 /**
416433 * Reads the signed integer value at the given bytecode offset.
417- *
434+ *
418435 * @param bytecode The bytecode
419436 * @param offset The offset in the bytecode.
420437 * @return The signed integer value at the given bytecode offset.
421438 */
422439 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 );
427444 }
428445
429446 /**
430447 * Reads the signed long value at the given bytecode offset.
431- *
448+ *
432449 * @param bytecode The bytecode
433450 * @param offset The offset in the bytecode.
434451 * @return The signed long value at the given bytecode offset.
435452 */
436453 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 );
445458 }
446459
447460 /**
448461 * Writes the signed long value to the given bytecode offset.
449- *
462+ *
450463 * @param bytecode The bytecode
451464 * @param offset The offset in the bytecode
452465 * @param value The value that should be written
453466 */
454467 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 );
463469 }
464470
465471 /**
0 commit comments