Closed
Description
Zig Version
0.11.0-dev.3332+76aa1fffb
Steps to Reproduce and Observed Behavior
The bug was found when executing a WASM library in Deno
Try creating an ArrayList
, and then reserve capacity with ensureTotalCapacityPrecise
.
Here is the code, but whith ensureTotalCapacityPrecise
extracted
var alpha = std.ArrayList(u8).init(alloc);
{
const T = u8;
const alignment = null;
var self = alpha;
const new_capacity = 10;
if (self.capacity >= new_capacity) return;
const old_memory = self.allocatedSlice();
if (self.allocator.resize(old_memory, new_capacity)) {
self.capacity = new_capacity;
} else {
const new_memory = try self.allocator.alignedAlloc(T, alignment, new_capacity);
// In this line, the code panics throwing `RuntimeError: memory access out of bounds` in Deno
@memcpy(new_memory[0..self.items.len], self.items);
self.allocator.free(old_memory);
self.items.ptr = new_memory.ptr;
self.capacity = new_memory.len;
}
}
Replace @memcpy
with std.mem.copyForwards
, and the code stops panicking.
var alpha = std.ArrayList(u8).init(alloc);
{
const T = u8;
const alignment = null;
var self = alpha;
const new_capacity = 10;
if (self.capacity >= new_capacity) return;
const old_memory = self.allocatedSlice();
if (self.allocator.resize(old_memory, new_capacity)) {
self.capacity = new_capacity;
} else {
const new_memory = try self.allocator.alignedAlloc(T, alignment, new_capacity);
// Now this line executes as expected
std.mem.copyForwards(u8, new_memory[0..self.items.len], self.items);
self.allocator.free(old_memory);
self.items.ptr = new_memory.ptr;
self.capacity = new_memory.len;
}
}
Expected Behavior
Well, this shoudn't panic!
My theory is that there is something about Wasm shared memory that messes up @memcpy
when doing zero-sized copies (It seems to work fine when actually copying values, so it may have to do with the high value of the original undefined
pointer). Apart from that, I have no idea,