| ... | @@ -318,6 +318,51 @@ pub const FixedBufferAllocator = struct { | ... | @@ -318,6 +318,51 @@ pub const FixedBufferAllocator = struct { |
| 318 | } | 318 | } |
| 319 | }; | 319 | }; |
| 320 | | 320 | |
| | 321 | extern fn @"llvm.wasm.memory.grow.i32"(u32, u32) i32; |
| | 322 | |
| | 323 | /// This allocator tries to allocate the specified number of 64 KB pages and uses FixedBufferAllocator internally |
| | 324 | pub const WasmAllocator = blk: { |
| | 325 | if (builtin.arch != builtin.Arch.wasm32) { |
| | 326 | @compileError("only supported in wasm32"); |
| | 327 | } else { |
| | 328 | const mem_grow = @"llvm.wasm.memory.grow.i32"; |
| | 329 | |
| | 330 | const WASM_PAGE_SIZE = 64 * 1024; // 64 kilobytes |
| | 331 | |
| | 332 | break :blk struct { |
| | 333 | allocator: Allocator, |
| | 334 | fb_allocator: FixedBufferAllocator, |
| | 335 | |
| | 336 | pub fn init(num_pages: u32) !WasmAllocator { |
| | 337 | const prev_block = mem_grow(0, num_pages); |
| | 338 | if (prev_block == -1) { |
| | 339 | return error.OutOfMemory; |
| | 340 | } |
| | 341 | |
| | 342 | const buffer_slice = @intToPtr([*]u8, @intCast(usize, prev_block) * WASM_PAGE_SIZE)[0..(WASM_PAGE_SIZE * num_pages)]; |
| | 343 | |
| | 344 | return WasmAllocator{ |
| | 345 | .allocator = Allocator{ |
| | 346 | .reallocFn = realloc, |
| | 347 | .shrinkFn = shrink, |
| | 348 | }, |
| | 349 | .fb_allocator = FixedBufferAllocator.init(buffer_slice), |
| | 350 | }; |
| | 351 | } |
| | 352 | |
| | 353 | fn realloc(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) ![]u8 { |
| | 354 | const self = @fieldParentPtr(WasmAllocator, "allocator", allocator); |
| | 355 | return FixedBufferAllocator.realloc(&self.fb_allocator.allocator, old_mem, old_align, new_size, new_align); |
| | 356 | } |
| | 357 | |
| | 358 | fn shrink(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 { |
| | 359 | const self = @fieldParentPtr(WasmAllocator, "allocator", allocator); |
| | 360 | return FixedBufferAllocator.shrink(&self.fb_allocator.allocator, old_mem, old_align, new_size, new_align); |
| | 361 | } |
| | 362 | }; |
| | 363 | } |
| | 364 | }; |
| | 365 | |
| 321 | pub const ThreadSafeFixedBufferAllocator = blk: { | 366 | pub const ThreadSafeFixedBufferAllocator = blk: { |
| 322 | if (builtin.single_threaded) { | 367 | if (builtin.single_threaded) { |
| 323 | break :blk FixedBufferAllocator; | 368 | break :blk FixedBufferAllocator; |