diff --git a/README.md b/README.md index 2e0ce30..bf40fa8 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ This package is clearly inspired by Go's solution to this problem: https://pkg.g ## Usage -As of May 2024, zjb requires Zig 0.12.0 or greater. +As of March 2025, zjb is only known to work with Zig 0.14.0. The simple folder provides a good template to start from. You'll need to update to reference to zjb in `build.zig.zon`. There's currently no release schedule for point releases, so you should use the latest available code. Eg, copy the entire `simple` folder into your empty project, then run `zig fetch --save=zjb https://github.com/scottredig/zig-javascript-bridge/archive/.zip` diff --git a/build.zig b/build.zig index 10b5343..e4d336a 100644 --- a/build.zig +++ b/build.zig @@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void { const generate_js = b.addExecutable(.{ .name = "generate_js", .root_source_file = b.path("src/generate_js.zig"), - .target = b.host, + .target = b.graph.host, // Reusing this will occur more often than compiling this, as // it usually can be cached. So faster execution is worth slower // initial build. diff --git a/build.zig.zon b/build.zig.zon index d8f857a..4721ef7 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -1,6 +1,7 @@ .{ - .name = "javascript-bridge", + .name = .javascript_bridge, .version = "0.0.0", + .fingerprint = 0x2cab041a0159e113, .paths = .{ "build.zig", "build.zig.zon", diff --git a/example/build.zig b/example/build.zig index 82cc3d0..9fa5cf3 100644 --- a/example/build.zig +++ b/example/build.zig @@ -4,7 +4,7 @@ pub fn build(b: *std.Build) void { const optimize = b.standardOptimizeOption(.{}); const dir = std.Build.InstallDir.bin; - const zjb = b.dependency("zjb", .{}); + const zjb = b.dependency("javascript_bridge", .{}); const example = b.addExecutable(.{ .name = "example", diff --git a/example/build.zig.zon b/example/build.zig.zon index 6c1b4e8..131a62a 100644 --- a/example/build.zig.zon +++ b/example/build.zig.zon @@ -1,8 +1,9 @@ .{ - .name = "example", + .name = .example, .version = "0.0.0", + .fingerprint = 0x6eec9b9fe64850bb, .dependencies = .{ - .zjb = .{ + .javascript_bridge = .{ .path = "../", }, }, diff --git a/example/src/main.zig b/example/src/main.zig index e3db5f0..5112566 100644 --- a/example/src/main.zig +++ b/example/src/main.zig @@ -140,7 +140,7 @@ export fn main() void { } logStr("\n============================= Exporting functions (press a key for a callback) ============================="); - zjb.global("document").call("addEventListener", .{ zjb.constString("keydown"), zjb.fnHandle("keydownCallback", keydownCallback) }, void); + zjb.global("document").call("addEventListener", .{ zjb.constString("keydown"), zjb.fnHandle("keydownCallback", &keydownCallback) }, void); logStr("\n============================= Handle vs ConstHandle ============================="); { @@ -180,9 +180,9 @@ fn setTestVar() callconv(.C) f32 { } comptime { - zjb.exportFn("incrementAndGet", incrementAndGet); + zjb.exportFn("incrementAndGet", &incrementAndGet); zjb.exportGlobal("test_var", &test_var); - zjb.exportFn("checkTestVar", checkTestVar); - zjb.exportFn("setTestVar", setTestVar); + zjb.exportFn("checkTestVar", &checkTestVar); + zjb.exportFn("setTestVar", &setTestVar); } diff --git a/simple/build.zig b/simple/build.zig index d7635cc..5167a1a 100644 --- a/simple/build.zig +++ b/simple/build.zig @@ -4,7 +4,7 @@ pub fn build(b: *std.Build) void { const optimize = b.standardOptimizeOption(.{}); const dir = std.Build.InstallDir.bin; - const zjb = b.dependency("zjb", .{}); + const zjb = b.dependency("javascript_bridge", .{}); const simple = b.addExecutable(.{ .name = "simple", diff --git a/simple/build.zig.zon b/simple/build.zig.zon index 107ad26..e00ccec 100644 --- a/simple/build.zig.zon +++ b/simple/build.zig.zon @@ -1,8 +1,9 @@ .{ - .name = "simple-example", + .name = .simple_example, .version = "0.0.0", + .fingerprint = 0x24a585647bbf2e4e, .dependencies = .{ - .zjb = .{ + .javascript_bridge = .{ .path = "../", }, }, diff --git a/src/generate_js.zig b/src/generate_js.zig index 53d12ff..432f368 100644 --- a/src/generate_js.zig +++ b/src/generate_js.zig @@ -398,9 +398,9 @@ pub fn main() !void { const name = np.slice; try writer.writeAll(" {\n"); - try writer.writeAll(" const ptr = initialView.getUint32(instance.exports."); + try writer.writeAll(" const ptr = instance.exports."); try writer.writeAll(global); - try writer.writeAll(".value, true);\n"); + try writer.writeAll(".value;\n"); try writer.writeAll(" Object.defineProperty(this.exports, \""); try writer.writeAll(name); @@ -603,7 +603,19 @@ const NameParser = struct { } fn mustArgType(self: *NameParser) !ArgType { - if (self.maybe("n")) { + // if (self.maybe("n")) { + // return .number; + // } + if (self.maybe("i32")) { + return .number; + } + if (self.maybe("i64")) { + return .number; + } + if (self.maybe("f32")) { + return .number; + } + if (self.maybe("f64")) { return .number; } if (self.maybe("b")) { diff --git a/src/zjb.zig b/src/zjb.zig index 2dbe67f..2035ec6 100644 --- a/src/zjb.zig +++ b/src/zjb.zig @@ -60,7 +60,7 @@ pub fn exportGlobal(comptime name: []const u8, comptime value: anytype) void { pub fn exportFn(comptime name: []const u8, comptime f: anytype) void { comptime var export_name: []const u8 = "zjb_fn_"; - const type_info = @typeInfo(@TypeOf(f)).Fn; + const type_info = @typeInfo(@typeInfo(@TypeOf(f)).pointer.child).@"fn"; validateToJavascriptReturnType(type_info.return_type orelse void); inline for (type_info.params) |param| { validateFromJavascriptArgumentType(param.type orelse void); @@ -104,10 +104,10 @@ pub fn u8ClampedArrayView(data: []const u8) Handle { pub fn dataView(data: anytype) Handle { switch (@typeInfo(@TypeOf(data))) { - .Pointer => |ptr| { - if (ptr.size == .One) { + .pointer => |ptr| { + if (ptr.size == .one) { return zjb.dataview(data, @sizeOf(ptr.child)); - } else if (ptr.size == .Slice) { + } else if (ptr.size == .slice) { return zjb.dataview(data.ptr, data.len * @sizeOf(ptr.child)); } else { @compileError("dataview pointers must be single objects or slices, got: " ++ @typeName(@TypeOf(data))); @@ -227,7 +227,7 @@ pub const Handle = enum(i32) { fn invoke(handle: Handle, args: anytype, comptime RetType: type, comptime prefix: []const u8, comptime suffix: []const u8) RetType { validateFromJavascriptReturnType(RetType); - const fields = comptime @typeInfo(@TypeOf(args)).Struct.fields; + const fields = comptime @typeInfo(@TypeOf(args)).@"struct".fields; comptime var call_params: [fields.len + 1]std.builtin.Type.Fn.Param = undefined; comptime var extern_name: []const u8 = prefix; @@ -247,7 +247,7 @@ pub const Handle = enum(i32) { extern_name = extern_name ++ comptime shortTypeName(field.type); } - const F = @Type(.{ .Fn = .{ + const F = @Type(.{ .@"fn" = .{ .calling_convention = .C, .is_generic = false, .is_var_args = false, @@ -301,17 +301,24 @@ fn shortTypeName(comptime T: type) []const u8 { Handle, ConstHandle => "o", void => "v", bool => "b", - // The number types map to the same name, even though - // the function signatures are different. Zig and Wasm - // handle this just fine, and produces fewer unique methods - // in javascript so there's no reason not to do it. - i32, i64, f32, f64, comptime_int, comptime_float => "n", + // // The number types map to the same name, even though + // // the function signatures are different. Zig and Wasm + // // handle this just fine, and produces fewer unique methods + // // in javascript so there's no reason not to do it. + // i32, i64, f32, f64, comptime_int, comptime_float => "n", + + // The above should be true, but 0.14.0 broke it. See https://github.com/scottredig/zig-javascript-bridge/issues/14 + i32 => "i32", + i64 => "i64", + f32 => "f32", + f64, comptime_float, comptime_int => "f64", + else => unreachable, }; } fn mapType(comptime T: type) type { - if (T == comptime_int or T == comptime_float) { + if (T == comptime_float or T == comptime_int) { return f64; } return T;