fix(kernel): update outdated implementation of MemoryBlock::next_ptr (#509)

`MemoryBlock::next_ptr` used to calculate the offset to the data of the
next block, but it should be returning the start of the `MemoryBlock`
structure in memory. Also updates the tests for this case.

This was discovered when trying to update the kernel in the go-sdk:
https://github.com/extism/go-sdk/pull/32

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: zshipko <zshipko@users.noreply.github.com>
This commit is contained in:
zach
2023-10-12 17:57:50 -07:00
committed by GitHub
parent 6f4b43bedc
commit c893faede4
3 changed files with 13 additions and 14 deletions

View File

@@ -283,7 +283,7 @@ impl MemoryRoot {
// Bump the position by the size of the actual data + the size of the MemoryBlock structure
self.position.fetch_add(
length + core::mem::size_of::<MemoryBlock>() as u64 - 1,
length + core::mem::size_of::<MemoryBlock>() as u64,
Ordering::SeqCst,
);
@@ -316,9 +316,7 @@ impl MemoryBlock {
/// is calculated based on metadata provided by the current block
#[inline]
pub unsafe fn next_ptr(&mut self) -> *mut MemoryBlock {
self.data
.as_mut_ptr()
.add(self.size + core::mem::size_of::<MemoryBlock>()) as *mut MemoryBlock
self.data.as_mut_ptr().add(self.size) as *mut MemoryBlock
}
/// Mark a block as free

Binary file not shown.

View File

@@ -182,17 +182,18 @@ fn test_kernel_allocations() {
assert_eq!(extism_length(&mut store, instance, x), 2);
extism_free(&mut store, instance, x);
// 64 bytes
let p = extism_alloc(&mut store, instance, 64);
assert!(p > 0);
assert_eq!(extism_length(&mut store, instance, p), 64);
extism_free(&mut store, instance, p);
for i in 0..64 {
let p = extism_alloc(&mut store, instance, 64 - i);
assert!(p > 0);
assert_eq!(extism_length(&mut store, instance, p), 64 - i);
extism_free(&mut store, instance, p);
// 64 bytes, should re-use the last allocation
let q = extism_alloc(&mut store, instance, 64);
assert_eq!(p, q);
assert_eq!(extism_length(&mut store, instance, q), 64);
extism_free(&mut store, instance, q);
// should re-use the last allocation
let q = extism_alloc(&mut store, instance, 64 - i);
assert_eq!(p, q);
assert_eq!(extism_length(&mut store, instance, q), 64 - i);
extism_free(&mut store, instance, q);
}
// 512 bytes, test block re-use + splitting
let p = extism_alloc(&mut store, instance, 512);