Skip to content

Commit

Permalink
zemscripten: Allocator wrapping emmalloc
Browse files Browse the repository at this point in the history
Co-authored-by: Deins <[email protected]>
  • Loading branch information
hazeycode and Deins committed Feb 8, 2024
1 parent 2f4c18d commit 225f44f
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 1 deletion.
8 changes: 7 additions & 1 deletion libs/zemscripten/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,13 @@ pub const Package = struct {

const emcc = b.addSystemCommand(&.{
b.pathJoin(&.{ pkg.emsdk_path, "upstream/emscripten/emcc" }),
emcc_options,
std.fmt.allocPrint(
b.allocator,
"-sMALLOC=emmalloc {s}",
.{emcc_options},
) catch |err| switch (err) {
error.OutOfMemory => @panic("Out of memory"),
},
});
emcc.step.dependOn(pkg.emsdk_setup_step);

Expand Down
62 changes: 62 additions & 0 deletions libs/zemscripten/src/root.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
const std = @import("std");

extern "C" fn emmalloc_memalign(alignment: usize, size: usize) ?*anyopaque;
extern "C" fn emmalloc_realloc_try(ptr: ?*anyopaque, size: usize) ?*anyopaque;
extern "C" fn emmalloc_free(ptr: ?*anyopaque) void;

/// Zig Allocator that wraps emmalloc
/// use with linker flag -sMALLOC=emmalloc
pub const Allocator = struct {
const Self = @This();
dummy: u32 = undefined,

pub fn allocator(self: *Self) std.mem.Allocator {
return .{
.ptr = self,
.vtable = &.{
.alloc = &alloc,
.resize = &resize,
.free = &free,
},
};
}

fn alloc(
ctx: *anyopaque,
len: usize,
ptr_align_log2: u8,
return_address: usize,
) ?[*]u8 {
_ = ctx;
_ = return_address;
const ptr_align = @as(usize, 1) << @as(u5, @intCast(ptr_align_log2));
if (!std.math.isPowerOfTwo(ptr_align)) unreachable;
const ptr = emmalloc_memalign(ptr_align, len) orelse return null;
return @ptrCast(ptr);
}

fn resize(
ctx: *anyopaque,
buf: []u8,
buf_align_log2: u8,
new_len: usize,
return_address: usize,
) bool {
_ = ctx;
_ = return_address;
_ = buf_align_log2;
return emmalloc_realloc_try(buf.ptr, new_len) != null;
}

fn free(
ctx: *anyopaque,
buf: []u8,
buf_align_log2: u8,
return_address: usize,
) void {
_ = ctx;
_ = buf_align_log2;
_ = return_address;
return emmalloc_free(buf.ptr);
}
};

0 comments on commit 225f44f

Please sign in to comment.