Last active
July 26, 2025 03:31
-
-
Save DanB91/490f85ec0e5b7828a01fd13569240fd0 to your computer and use it in GitHub Desktop.
EM_ASM and EM_ASM_INT in Zig
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//A Zig version of emscipten's EM_ASM and EM_ASM_INT | |
//WARNING: I've only tested 32-bit and 64-bit ints and floats for arguments. Haven't tested other types e.g. bool | |
//Example: | |
//em_asm(.{"World!"}, | |
// \\const world = UTF8ToString($0); | |
// \\console.log(`Hello ${world}`); | |
// ); | |
pub inline fn em_asm(args: anytype, comptime script: anytype) void { | |
_ = em_js_int(args, script); | |
} | |
pub fn em_asm_int(args: anytype, comptime script: anytype) c_int { | |
const scoped_script = "{" ++ script ++ "}"; | |
const GlobalVars = struct { | |
extern fn emscripten_asm_const_int(code: ?[*:0]const u8, arg_sigs: ?[*:0]const u8, ...) c_int; | |
var x: [scoped_script.len:0]u8 linksection("em_asm") = scoped_script.*; | |
}; | |
comptime var arg_sigs_buffer: [args.len + 1:0]u8 = [_:0]u8{0} ** (args.len + 1); | |
inline for (args, 0..) |arg, i| { | |
arg_sigs_buffer[i] = switch (@TypeOf(arg)) { | |
u8, i8, u16, i16, u32, i32, usize, isize, bool => 'i', | |
u64, i64 => 'j', | |
f32 => 'f', | |
f64 => 'd', | |
else => if (@typeInfo(@TypeOf(arg)) == .pointer) | |
'p' | |
else | |
@compileError(std.fmt.comptimePrint( | |
"Emscripten argument {} must be an integral type or a pointer. It can't be a comptime_int nor comptime_float", | |
.{i}, | |
)), | |
}; | |
} | |
const arg_sigs = arg_sigs_buffer; | |
const result = @call( | |
.auto, | |
GlobalVars.emscripten_asm_const_int, | |
.{ &GlobalVars.x, &arg_sigs } ++ args, | |
); | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment