// Copyright 2026 International Digital Economy Academy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// #region FixedArray
///|
/// **UNSAFE**: Writes a UInt64 to the FixedArray[Byte] in little-endian byte order.
///
/// ⚠️ **Warning: This function is unsafe and can cause undefined behavior!**
///
/// # Safety
/// - **No bounds checking**: This function does not verify that `index + 7 < bytes.length()`
/// - **Buffer overrun risk**: Writing beyond the array boundary may corrupt memory
/// - **Alignment**: No alignment requirements, but misaligned access may be slower on some architectures
/// - **Responsibility**: Caller must ensure sufficient space is available
///
/// # Parameters
/// - `bytes`: The FixedArray[Byte] to write to
/// - `index`: Starting byte index (0-based)
/// - `value`: The UInt64 value to write
///
/// # Behavior
/// Writes 8 bytes starting at `index` in little-endian order:
/// - `bytes[index]` ← bits 0-7 (least significant)
/// - `bytes[index+1]` ← bits 8-15
/// - ...
/// - `bytes[index+7]` ← bits 56-63 (most significant)
#borrow(bytes)
#intrinsic("%bytes.unsafe_write_uint64_le")
pub fn FixedArray::unsafe_write_uint64_le(
bytes : FixedArray[Byte],
index : Int,
value : UInt64,
) -> Unit {
bytes.unsafe_set(index, value.to_byte())
bytes.unsafe_set(index + 1, (value >> 8).to_byte())
bytes.unsafe_set(index + 2, (value >> 16).to_byte())
bytes.unsafe_set(index + 3, (value >> 24).to_byte())
bytes.unsafe_set(index + 4, (value >> 32).to_byte())
bytes.unsafe_set(index + 5, (value >> 40).to_byte())
bytes.unsafe_set(index + 6, (value >> 48).to_byte())
bytes.unsafe_set(index + 7, (value >> 56).to_byte())
}
///|
/// **UNSAFE**: Writes a UInt64 to the FixedArray[Byte] in big-endian byte order.
///
/// ⚠️ **Warning: This function is unsafe and can cause undefined behavior!**
///
/// # Safety
/// - **No bounds checking**: This function does not verify that `index + 7 < bytes.length()`
/// - **Buffer overrun risk**: Writing beyond the array boundary may corrupt memory
/// - **Alignment**: No alignment requirements, but misaligned access may be slower on some architectures
/// - **Responsibility**: Caller must ensure sufficient space is available
///
/// # Parameters
/// - `bytes`: The FixedArray[Byte] to write to
/// - `index`: Starting byte index (0-based)
/// - `value`: The UInt64 value to write
///
/// # Behavior
/// Writes 8 bytes starting at `index` in big-endian order:
/// - `bytes[index]` ← bits 56-63 (most significant)
/// - `bytes[index+1]` ← bits 48-55
/// - ...
/// - `bytes[index+7]` ← bits 0-7 (least significant)
#borrow(bytes)
#intrinsic("%bytes.unsafe_write_uint64_be")
pub fn FixedArray::unsafe_write_uint64_be(
bytes : FixedArray[Byte],
index : Int,
value : UInt64,
) -> Unit {
bytes.unsafe_set(index, (value >> 56).to_byte())
bytes.unsafe_set(index + 1, (value >> 48).to_byte())
bytes.unsafe_set(index + 2, (value >> 40).to_byte())
bytes.unsafe_set(index + 3, (value >> 32).to_byte())
bytes.unsafe_set(index + 4, (value >> 24).to_byte())
bytes.unsafe_set(index + 5, (value >> 16).to_byte())
bytes.unsafe_set(index + 6, (value >> 8).to_byte())
bytes.unsafe_set(index + 7, value.to_byte())
}
///|
/// **UNSAFE**: Writes a UInt32 to the FixedArray[Byte] in little-endian byte order.
///
/// ⚠️ **Warning: This function is unsafe and can cause undefined behavior!**
///
/// # Safety
/// - **No bounds checking**: This function does not verify that `index + 3 < bytes.length()`
/// - **Buffer overrun risk**: Writing beyond the array boundary may corrupt memory
/// - **Alignment**: No alignment requirements, but misaligned access may be slower on some architectures
/// - **Responsibility**: Caller must ensure sufficient space is available
///
/// # Parameters
/// - `bytes`: The FixedArray[Byte] to write to
/// - `index`: Starting byte index (0-based)
/// - `value`: The UInt32 value to write
///
/// # Behavior
/// Writes 4 bytes starting at `index` in little-endian order:
/// - `bytes[index]` ← bits 0-7 (least significant)
/// - `bytes[index+1]` ← bits 8-15
/// - `bytes[index+2]` ← bits 16-23
/// - `bytes[index+3]` ← bits 24-31 (most significant)
#borrow(bytes)
#intrinsic("%bytes.unsafe_write_uint32_le")
pub fn FixedArray::unsafe_write_uint32_le(
bytes : FixedArray[Byte],
index : Int,
value : UInt,
) -> Unit {
bytes.unsafe_set(index, value.to_byte())
bytes.unsafe_set(index + 1, (value >> 8).to_byte())
bytes.unsafe_set(index + 2, (value >> 16).to_byte())
bytes.unsafe_set(index + 3, (value >> 24).to_byte())
}
///|
/// **UNSAFE**: Writes a UInt32 to the FixedArray[Byte] in big-endian byte order.
///
/// ⚠️ **Warning: This function is unsafe and can cause undefined behavior!**
///
/// # Safety
/// - **No bounds checking**: This function does not verify that `index + 3 < bytes.length()`
/// - **Buffer overrun risk**: Writing beyond the array boundary may corrupt memory
/// - **Alignment**: No alignment requirements, but misaligned access may be slower on some architectures
/// - **Responsibility**: Caller must ensure sufficient space is available
///
/// # Parameters
/// - `bytes`: The FixedArray[Byte] to write to
/// - `index`: Starting byte index (0-based)
/// - `value`: The UInt32 value to write
///
/// # Behavior
/// Writes 4 bytes starting at `index` in big-endian order:
/// - `bytes[index]` ← bits 24-31 (most significant)
/// - `bytes[index+1]` ← bits 16-23
/// - `bytes[index+2]` ← bits 8-15
/// - `bytes[index+3]` ← bits 0-7 (least significant)
#borrow(bytes)
#intrinsic("%bytes.unsafe_write_uint32_be")
pub fn FixedArray::unsafe_write_uint32_be(
bytes : FixedArray[Byte],
index : Int,
value : UInt,
) -> Unit {
bytes.unsafe_set(index, (value >> 24).to_byte())
bytes.unsafe_set(index + 1, (value >> 16).to_byte())
bytes.unsafe_set(index + 2, (value >> 8).to_byte())
bytes.unsafe_set(index + 3, value.to_byte())
}
///|
/// **UNSAFE**: Writes a UInt16 to the FixedArray[Byte] in little-endian byte order.
///
/// ⚠️ **Warning: This function is unsafe and can cause undefined behavior!**
///
/// # Safety
/// - **No bounds checking**: This function does not verify that `index + 1 < bytes.length()`
/// - **Buffer overrun risk**: Writing beyond the array boundary may corrupt memory
/// - **Alignment**: No alignment requirements, but misaligned access may be slower on some architectures
/// - **Responsibility**: Caller must ensure sufficient space is available
///
/// # Parameters
/// - `bytes`: The FixedArray[Byte] to write to
/// - `index`: Starting byte index (0-based)
/// - `value`: The UInt16 value to write
///
/// # Behavior
/// Writes 2 bytes starting at `index` in little-endian order:
/// - `bytes[index]` ← bits 0-7 (least significant)
/// - `bytes[index+1]` ← bits 8-15 (most significant)
#borrow(bytes)
#intrinsic("%bytes.unsafe_write_uint16_le")
pub fn FixedArray::unsafe_write_uint16_le(
bytes : FixedArray[Byte],
index : Int,
value : UInt16,
) -> Unit {
bytes.unsafe_set(index, value.to_byte())
bytes.unsafe_set(index + 1, (value >> 8).to_byte())
}
///|
/// **UNSAFE**: Writes a UInt16 to the FixedArray[Byte] in big-endian byte order.
///
/// ⚠️ **Warning: This function is unsafe and can cause undefined behavior!**
///
/// # Safety
/// - **No bounds checking**: This function does not verify that `index + 1 < bytes.length()`
/// - **Buffer overrun risk**: Writing beyond the array boundary may corrupt memory
/// - **Alignment**: No alignment requirements, but misaligned access may be slower on some architectures
/// - **Responsibility**: Caller must ensure sufficient space is available
///
/// # Parameters
/// - `bytes`: The FixedArray[Byte] to write to
/// - `index`: Starting byte index (0-based)
/// - `value`: The UInt16 value to write
///
/// # Behavior
/// Writes 2 bytes starting at `index` in big-endian order:
/// - `bytes[index]` ← bits 8-15 (most significant)
/// - `bytes[index+1]` ← bits 0-7 (least significant)
#borrow(bytes)
#intrinsic("%bytes.unsafe_write_uint16_be")
pub fn FixedArray::unsafe_write_uint16_be(
bytes : FixedArray[Byte],
index : Int,
value : UInt16,
) -> Unit {
bytes.unsafe_set(index, (value >> 8).to_byte())
bytes.unsafe_set(index + 1, value.to_byte())
}
// #endregion
// #region Bytes
///|
/// **UNSAFE**: Reads a UInt64 from the bytes in little-endian byte order.
///
/// ⚠️ **Warning: This function is unsafe and can cause undefined behavior!**
///
/// # Safety
/// - **No bounds checking**: This function does not verify that `index + 7 < bytes.length()`
/// - **Buffer overrun risk**: Reading beyond the buffer boundary may access invalid memory
/// - **Alignment**: No alignment requirements, but misaligned access may be slower on some architectures
/// - **Responsibility**: Caller must ensure sufficient bytes are available
///
/// # Parameters
/// - `bytes`: The Bytes to read from
/// - `index`: Starting byte index (0-based)
///
/// # Behavior
/// Reads 8 bytes starting at `index` and interprets them as a UInt64 in little-endian order:
/// - `bytes[index]` → bits 0-7 (least significant)
/// - `bytes[index+1]` → bits 8-15
/// - ...
/// - `bytes[index+7]` → bits 56-63 (most significant)
#borrow(bytes)
#intrinsic("%bytes.unsafe_read_uint64_le")
#doc(hidden)
pub fn Bytes::unsafe_read_uint64_le(bytes : Bytes, index : Int) -> UInt64 {
bytes.unsafe_get(index).to_uint64() |
(bytes.unsafe_get(index + 1).to_uint64() << 8) |
(bytes.unsafe_get(index + 2).to_uint64() << 16) |
(bytes.unsafe_get(index + 3).to_uint64() << 24) |
(bytes.unsafe_get(index + 4).to_uint64() << 32) |
(bytes.unsafe_get(index + 5).to_uint64() << 40) |
(bytes.unsafe_get(index + 6).to_uint64() << 48) |
(bytes.unsafe_get(index + 7).to_uint64() << 56)
}
///|
/// **UNSAFE**: Reads a UInt64 from the bytes in big-endian byte order.
///
/// ⚠️ **Warning: This function is unsafe and can cause undefined behavior!**
///
/// # Safety
/// - **No bounds checking**: This function does not verify that `index + 7 < bytes.length()`
/// - **Buffer overrun risk**: Reading beyond the buffer boundary may access invalid memory
/// - **Alignment**: No alignment requirements, but misaligned access may be slower on some architectures
/// - **Responsibility**: Caller must ensure sufficient bytes are available
///
/// # Parameters
/// - `bytes`: The Bytes to read from
/// - `index`: Starting byte index (0-based)
///
/// # Behavior
/// Reads 8 bytes starting at `index` and interprets them as a UInt64 in big-endian order:
/// - `bytes[index]` → bits 56-63 (most significant)
/// - `bytes[index+1]` → bits 48-55
/// - ...
/// - `bytes[index+7]` → bits 0-7 (least significant)
#borrow(bytes)
#intrinsic("%bytes.unsafe_read_uint64_be")
#doc(hidden)
pub fn Bytes::unsafe_read_uint64_be(bytes : Bytes, index : Int) -> UInt64 {
(bytes.unsafe_get(index).to_uint64() << 56) |
(bytes.unsafe_get(index + 1).to_uint64() << 48) |
(bytes.unsafe_get(index + 2).to_uint64() << 40) |
(bytes.unsafe_get(index + 3).to_uint64() << 32) |
(bytes.unsafe_get(index + 4).to_uint64() << 24) |
(bytes.unsafe_get(index + 5).to_uint64() << 16) |
(bytes.unsafe_get(index + 6).to_uint64() << 8) |
bytes.unsafe_get(index + 7).to_uint64()
}
///|
/// **UNSAFE**: Reads a UInt32 from the bytes in little-endian byte order.
///
/// ⚠️ **Warning: This function is unsafe and can cause undefined behavior!**
///
/// # Safety
/// - **No bounds checking**: This function does not verify that `index + 3 < bytes.length()`
/// - **Buffer overrun risk**: Reading beyond the buffer boundary may access invalid memory
/// - **Alignment**: No alignment requirements, but misaligned access may be slower on some architectures
/// - **Responsibility**: Caller must ensure sufficient bytes are available
///
/// # Parameters
/// - `bytes`: The Bytes to read from
/// - `index`: Starting byte index (0-based)
///
/// # Behavior
/// Reads 4 bytes starting at `index` and interprets them as a UInt32 in little-endian order:
/// - `bytes[index]` → bits 0-7 (least significant)
/// - `bytes[index+1]` → bits 8-15
/// - `bytes[index+2]` → bits 16-23
/// - `bytes[index+3]` → bits 24-31 (most significant)
#borrow(bytes)
#intrinsic("%bytes.unsafe_read_uint32_le")
#doc(hidden)
pub fn Bytes::unsafe_read_uint32_le(bytes : Bytes, index : Int) -> UInt {
bytes.unsafe_get(index).to_uint() |
(bytes.unsafe_get(index + 1).to_uint() << 8) |
(bytes.unsafe_get(index + 2).to_uint() << 16) |
(bytes.unsafe_get(index + 3).to_uint() << 24)
}
///|
/// **UNSAFE**: Reads a UInt32 from the bytes in big-endian byte order.
///
/// ⚠️ **Warning: This function is unsafe and can cause undefined behavior!**
///
/// # Safety
/// - **No bounds checking**: This function does not verify that `index + 3 < bytes.length()`
/// - **Buffer overrun risk**: Reading beyond the buffer boundary may access invalid memory
/// - **Alignment**: No alignment requirements, but misaligned access may be slower on some architectures
/// - **Responsibility**: Caller must ensure sufficient bytes are available
///
/// # Parameters
/// - `bytes`: The Bytes to read from
/// - `index`: Starting byte index (0-based)
///
/// # Behavior
/// Reads 4 bytes starting at `index` and interprets them as a UInt32 in big-endian order:
/// - `bytes[index]` → bits 24-31 (most significant)
/// - `bytes[index+1]` → bits 16-23
/// - `bytes[index+2]` → bits 8-15
/// - `bytes[index+3]` → bits 0-7 (least significant)
#borrow(bytes)
#intrinsic("%bytes.unsafe_read_uint32_be")
#doc(hidden)
pub fn Bytes::unsafe_read_uint32_be(bytes : Bytes, index : Int) -> UInt {
(bytes.unsafe_get(index).to_uint() << 24) |
(bytes.unsafe_get(index + 1).to_uint() << 16) |
(bytes.unsafe_get(index + 2).to_uint() << 8) |
bytes.unsafe_get(index + 3).to_uint()
}
///|
/// **UNSAFE**: Reads a UInt16 from the bytes in little-endian byte order.
///
/// ⚠️ **Warning: This function is unsafe and can cause undefined behavior!**
///
/// # Safety
/// - **No bounds checking**: This function does not verify that `index + 1 < bytes.length()`
/// - **Buffer overrun risk**: Reading beyond the buffer boundary may access invalid memory
/// - **Alignment**: No alignment requirements, but misaligned access may be slower on some architectures
/// - **Responsibility**: Caller must ensure sufficient bytes are available
///
/// # Parameters
/// - `bytes`: The Bytes to read from
/// - `index`: Starting byte index (0-based)
///
/// # Behavior
/// Reads 2 bytes starting at `index` and interprets them as a UInt16 in little-endian order:
/// - `bytes[index]` → bits 0-7 (least significant)
/// - `bytes[index+1]` → bits 8-15 (most significant)
#borrow(bytes)
#intrinsic("%bytes.unsafe_read_uint16_le")
#doc(hidden)
pub fn Bytes::unsafe_read_uint16_le(bytes : Bytes, index : Int) -> UInt16 {
bytes.unsafe_get(index).to_uint16() |
(bytes.unsafe_get(index + 1).to_uint16() << 8)
}
///|
/// **UNSAFE**: Reads a UInt16 from the bytes in big-endian byte order.
///
/// ⚠️ **Warning: This function is unsafe and can cause undefined behavior!**
///
/// # Safety
/// - **No bounds checking**: This function does not verify that `index + 1 < bytes.length()`
/// - **Buffer overrun risk**: Reading beyond the buffer boundary may access invalid memory
/// - **Alignment**: No alignment requirements, but misaligned access may be slower on some architectures
/// - **Responsibility**: Caller must ensure sufficient bytes are available
///
/// # Parameters
/// - `bytes`: The Bytes to read from
/// - `index`: Starting byte index (0-based)
///
/// # Behavior
/// Reads 2 bytes starting at `index` and interprets them as a UInt16 in big-endian order:
/// - `bytes[index]` → bits 8-15 (most significant)
/// - `bytes[index+1]` → bits 0-7 (least significant)
#borrow(bytes)
#intrinsic("%bytes.unsafe_read_uint16_be")
#doc(hidden)
pub fn Bytes::unsafe_read_uint16_be(bytes : Bytes, index : Int) -> UInt16 {
(bytes.unsafe_get(index).to_uint16() << 8) |
bytes.unsafe_get(index + 1).to_uint16()
}
///|
/// **UNSAFE**: Reads a UInt64 from the BytesView in little-endian byte order.
///
/// ⚠️ **Warning: This function is unsafe and can cause undefined behavior!**
///
/// # Safety
/// - **No bounds checking**: This function does not verify that `index + 7 < bytes.length()`
/// - **Buffer overrun risk**: Reading beyond the view boundary may access invalid memory
/// - **Responsibility**: Caller must ensure sufficient bytes are available within the view
///
/// # Parameters
/// - `bytes`: The BytesView to read from
/// - `index`: Relative index within the view (0-based)
///
/// # Note
/// This function delegates to `Bytes::unsafe_read_uint64_le` with the proper offset calculation.
#doc(hidden)
pub fn BytesView::unsafe_read_uint64_le(
bytes : BytesView,
index : Int,
) -> UInt64 {
bytes.bytes().unsafe_read_uint64_le(bytes.start() + index)
}
///|
/// **UNSAFE**: Reads a UInt64 from the BytesView in big-endian byte order.
///
/// ⚠️ **Warning: This function is unsafe and can cause undefined behavior!**
///
/// # Safety
/// - **No bounds checking**: This function does not verify that `index + 7 < bytes.length()`
/// - **Buffer overrun risk**: Reading beyond the view boundary may access invalid memory
/// - **Responsibility**: Caller must ensure sufficient bytes are available within the view
///
/// # Parameters
/// - `bytes`: The BytesView to read from
/// - `index`: Relative index within the view (0-based)
///
/// # Note
/// This function delegates to `Bytes::unsafe_read_uint64_be` with the proper offset calculation.
#doc(hidden)
pub fn BytesView::unsafe_read_uint64_be(
bytes : BytesView,
index : Int,
) -> UInt64 {
bytes.bytes().unsafe_read_uint64_be(bytes.start() + index)
}
///|
/// **UNSAFE**: Reads a UInt32 from the BytesView in little-endian byte order.
///
/// ⚠️ **Warning: This function is unsafe and can cause undefined behavior!**
///
/// # Safety
/// - **No bounds checking**: This function does not verify that `index + 3 < bytes.length()`
/// - **Buffer overrun risk**: Reading beyond the view boundary may access invalid memory
/// - **Responsibility**: Caller must ensure sufficient bytes are available within the view
///
/// # Parameters
/// - `bytes`: The BytesView to read from
/// - `index`: Relative index within the view (0-based)
///
/// # Note
/// This function delegates to `Bytes::unsafe_read_uint32_le` with the proper offset calculation.
#doc(hidden)
pub fn BytesView::unsafe_read_uint32_le(bytes : BytesView, index : Int) -> UInt {
bytes.bytes().unsafe_read_uint32_le(bytes.start() + index)
}
///|
/// **UNSAFE**: Reads a UInt32 from the BytesView in big-endian byte order.
///
/// ⚠️ **Warning: This function is unsafe and can cause undefined behavior!**
///
/// # Safety
/// - **No bounds checking**: This function does not verify that `index + 3 < bytes.length()`
/// - **Buffer overrun risk**: Reading beyond the view boundary may access invalid memory
/// - **Responsibility**: Caller must ensure sufficient bytes are available within the view
///
/// # Parameters
/// - `bytes`: The BytesView to read from
/// - `index`: Relative index within the view (0-based)
///
/// # Note
/// This function delegates to `Bytes::unsafe_read_uint32_be` with the proper offset calculation.
#doc(hidden)
pub fn BytesView::unsafe_read_uint32_be(bytes : BytesView, index : Int) -> UInt {
bytes.bytes().unsafe_read_uint32_be(bytes.start() + index)
}
///|
/// **UNSAFE**: Reads a UInt16 from the BytesView in little-endian byte order.
///
/// ⚠️ **Warning: This function is unsafe and can cause undefined behavior!**
///
/// # Safety
/// - **No bounds checking**: This function does not verify that `index + 1 < bytes.length()`
/// - **Buffer overrun risk**: Reading beyond the view boundary may access invalid memory
/// - **Responsibility**: Caller must ensure sufficient bytes are available within the view
///
/// # Parameters
/// - `bytes`: The BytesView to read from
/// - `index`: Relative index within the view (0-based)
///
/// # Note
/// This function delegates to `Bytes::unsafe_read_uint16_le` with the proper offset calculation.
#doc(hidden)
pub fn BytesView::unsafe_read_uint16_le(
bytes : BytesView,
index : Int,
) -> UInt16 {
bytes.bytes().unsafe_read_uint16_le(bytes.start() + index)
}
///|
/// **UNSAFE**: Reads a UInt16 from the BytesView in big-endian byte order.
///
/// ⚠️ **Warning: This function is unsafe and can cause undefined behavior!**
///
/// # Safety
/// - **No bounds checking**: This function does not verify that `index + 1 < bytes.length()`
/// - **Buffer overrun risk**: Reading beyond the view boundary may access invalid memory
/// - **Responsibility**: Caller must ensure sufficient bytes are available within the view
///
/// # Parameters
/// - `bytes`: The BytesView to read from
/// - `index`: Relative index within the view (0-based)
///
/// # Note
/// This function delegates to `Bytes::unsafe_read_uint16_be` with the proper offset calculation.
#doc(hidden)
pub fn BytesView::unsafe_read_uint16_be(
bytes : BytesView,
index : Int,
) -> UInt16 {
bytes.bytes().unsafe_read_uint16_be(bytes.start() + index)
}
///|
/// **UNSAFE**: Compares two byte ranges for equality without bounds checking.
///
/// ⚠️ **Warning: This function is unsafe and can cause undefined behavior!**
///
/// # Safety
/// - **No bounds checking**: caller must ensure both ranges
/// `[self_off, self_off + len)` and `[other_off, other_off + len)` are fully
/// within their respective buffers.
///
/// # Parameters
/// - `self`, `other`: the two byte sequences
/// - `self_off`, `other_off`: starting byte offsets
/// - `len`: number of bytes to compare
///
/// This is the shared intrinsic-backed primitive for view/owned equality
/// comparisons (e.g. `BytesView == BytesView`, `BytesView::equal_to_bytes`).
/// The function body is the fallback implementation for targets without the
/// intrinsic.
///
/// Native lowers the intrinsic to `memcmp`, so the body only runs on wasm,
/// wasm-gc and js. On wasm, ranges of at least sixteen bytes are compared
/// sixteen bytes at a time by `bytes_range_equal_simd`.
///
/// TODO: this wasm body is a library workaround for a compiler gap. The wasm
/// backend does not lower this intrinsic, although it already has vectorized
/// runtime routines for whole-object equality (compiler/ideas#2608). Once it
/// does, delete the `#cfg(target="wasm")` definition, the vector helper, the
/// wasm-only `all_true` helpers in `simd.mbt` and the `#cfg(target="wasm")`
/// tests of the vector helpers in `range_equal_wbtest.mbt`, then drop
/// `#cfg(not(target="wasm"))` from the scalar definition below.
#borrow(self, other)
#cfg(target="wasm")
#intrinsic("%bytes.unsafe_range_equal")
fn Bytes::unsafe_range_equal(
self : Bytes,
self_off~ : Int,
other : Bytes,
other_off~ : Int,
len~ : Int,
) -> Bool {
if len >= 16 {
return bytes_range_equal_simd(self, self_off, other, other_off, len)
}
for i in 0.. Bool {
for i in 0..= 16`. It compares
/// sixteen bytes per step; a remainder of one to fifteen bytes is covered by
/// one more load of the last sixteen bytes of each range, which overlaps the
/// previous block and stays inside both ranges because `len >= 16`.
#borrow(left, right)
#cfg(target="wasm")
fn bytes_range_equal_simd(
left : Bytes,
left_off : Int,
right : Bytes,
right_off : Int,
len : Int,
) -> Bool {
let left_data = unsafe_from_bytes(left)
let right_data = unsafe_from_bytes(right)
for i = 0; i + 16 <= len; i = i + 16 {
let a = v128_load(left_data, left_off + i)
let b = v128_load(right_data, right_off + i)
guard i8x16_all_true(i8x16_eq(a, b)) else { return false }
}
if (len & 15) != 0 {
let a = v128_load(left_data, left_off + len - 16)
let b = v128_load(right_data, right_off + len - 16)
return i8x16_all_true(i8x16_eq(a, b))
}
true
}
// #endregion
// #region FixedArray fastpath helpers
//
// Private intrinsic-backed reads on FixedArray[Byte], used from
// `bitstring.mbt` to power the byte-aligned fastpath methods on
// ArrayView[Byte]. Not exported.
///|
/// Zero-cost reinterpretation of the backing buffer as `FixedArray[Byte]`, so
/// the intrinsic-backed `fixedarray_read_*` helpers below can run against the
/// underlying storage of an `ArrayView[Byte]`.
fn buffer_to_fixedarray(buf : UninitializedArray[Byte]) -> FixedArray[Byte] = "%identity"
///|
#borrow(bytes)
#intrinsic("%bytes.unsafe_read_uint16_le")
fn fixedarray_read_uint16_le(bytes : FixedArray[Byte], index : Int) -> UInt16 {
bytes.unsafe_get(index).to_uint16() |
(bytes.unsafe_get(index + 1).to_uint16() << 8)
}
///|
#borrow(bytes)
#intrinsic("%bytes.unsafe_read_uint16_be")
fn fixedarray_read_uint16_be(bytes : FixedArray[Byte], index : Int) -> UInt16 {
(bytes.unsafe_get(index).to_uint16() << 8) |
bytes.unsafe_get(index + 1).to_uint16()
}
///|
#borrow(bytes)
#intrinsic("%bytes.unsafe_read_uint32_le")
fn fixedarray_read_uint32_le(bytes : FixedArray[Byte], index : Int) -> UInt {
bytes.unsafe_get(index).to_uint() |
(bytes.unsafe_get(index + 1).to_uint() << 8) |
(bytes.unsafe_get(index + 2).to_uint() << 16) |
(bytes.unsafe_get(index + 3).to_uint() << 24)
}
///|
#borrow(bytes)
#intrinsic("%bytes.unsafe_read_uint32_be")
fn fixedarray_read_uint32_be(bytes : FixedArray[Byte], index : Int) -> UInt {
(bytes.unsafe_get(index).to_uint() << 24) |
(bytes.unsafe_get(index + 1).to_uint() << 16) |
(bytes.unsafe_get(index + 2).to_uint() << 8) |
bytes.unsafe_get(index + 3).to_uint()
}
///|
#borrow(bytes)
#intrinsic("%bytes.unsafe_read_uint64_le")
fn fixedarray_read_uint64_le(bytes : FixedArray[Byte], index : Int) -> UInt64 {
bytes.unsafe_get(index).to_uint64() |
(bytes.unsafe_get(index + 1).to_uint64() << 8) |
(bytes.unsafe_get(index + 2).to_uint64() << 16) |
(bytes.unsafe_get(index + 3).to_uint64() << 24) |
(bytes.unsafe_get(index + 4).to_uint64() << 32) |
(bytes.unsafe_get(index + 5).to_uint64() << 40) |
(bytes.unsafe_get(index + 6).to_uint64() << 48) |
(bytes.unsafe_get(index + 7).to_uint64() << 56)
}
///|
#borrow(bytes)
#intrinsic("%bytes.unsafe_read_uint64_be")
fn fixedarray_read_uint64_be(bytes : FixedArray[Byte], index : Int) -> UInt64 {
(bytes.unsafe_get(index).to_uint64() << 56) |
(bytes.unsafe_get(index + 1).to_uint64() << 48) |
(bytes.unsafe_get(index + 2).to_uint64() << 40) |
(bytes.unsafe_get(index + 3).to_uint64() << 32) |
(bytes.unsafe_get(index + 4).to_uint64() << 24) |
(bytes.unsafe_get(index + 5).to_uint64() << 16) |
(bytes.unsafe_get(index + 6).to_uint64() << 8) |
bytes.unsafe_get(index + 7).to_uint64()
}
// #endregion