diff --git a/examples/buffer_suballocation/main.v b/examples/buffer_suballocation/main.v index c85f67a..35aa58d 100644 --- a/examples/buffer_suballocation/main.v +++ b/examples/buffer_suballocation/main.v @@ -128,10 +128,8 @@ fn run() ! { require_success(allocator.map(mut first_allocation, &first_mapped), 'map first staging buffer')! require_success(allocator.map(mut second_allocation, &second_mapped), 'map second staging buffer')! - unsafe { - *(&u8(first_mapped)) = 21 - *(&u8(second_mapped)) = 42 - } + store_mapped_byte(first_mapped, 21) + store_mapped_byte(second_mapped, 42) require_success(allocator.flush(first_allocation), 'flush first upload buffer')! require_success(allocator.flush(second_allocation), 'flush second upload buffer')! assert usize(second_mapped) - usize(first_mapped) == second_allocation.offset - first_allocation.offset diff --git a/examples/buffer_suballocation/mapped_bytes.v b/examples/buffer_suballocation/mapped_bytes.v new file mode 100644 index 0000000..0925271 --- /dev/null +++ b/examples/buffer_suballocation/mapped_bytes.v @@ -0,0 +1,9 @@ +module main + +// Pass the pointer value into a fresh local scope: vlang/v#31481 otherwise +// casts a heap-promoted voidptr slot's address instead of its stored value. +fn store_mapped_byte(mapped voidptr, value u8) { + unsafe { + *(&u8(mapped)) = value + } +} diff --git a/examples/buffer_suballocation/mapped_bytes_test.v b/examples/buffer_suballocation/mapped_bytes_test.v new file mode 100644 index 0000000..af92fb7 --- /dev/null +++ b/examples/buffer_suballocation/mapped_bytes_test.v @@ -0,0 +1,16 @@ +module main + +fn escaped_mapped_byte_store(bytes []u8, value u8) &voidptr { + mut mapped := voidptr(bytes.data) + store_mapped_byte(mapped, value) + return &mapped +} + +fn test_mapped_byte_store_preserves_an_escaped_pointer() { + for value in [u8(0), 21, 255] { + mut bytes := [u8(7), 8, 9, 10] + pointer_slot := escaped_mapped_byte_store(bytes, value) + assert bytes == [value, u8(8), 9, 10] + assert unsafe { *pointer_slot } == bytes.data + } +}