From 72b081c97aaff92738349aa8c33d5d82d36d68ad Mon Sep 17 00:00:00 2001 From: Stephen Gutekanst Date: Sat, 20 Aug 2022 11:41:01 -0700 Subject: [PATCH] mach: improve compatibility with self-hosted compiler Signed-off-by: Stephen Gutekanst --- src/platform/common.zig | 27 +++++++++++++++++++++------ src/platform/native.zig | 5 ++++- src/platform/util.zig | 34 ++++++++++++++++++++++------------ 3 files changed, 47 insertions(+), 19 deletions(-) diff --git a/src/platform/common.zig b/src/platform/common.zig index 116b4ff8..4964678b 100644 --- a/src/platform/common.zig +++ b/src/platform/common.zig @@ -8,24 +8,39 @@ pub fn checkApplication(comptime app_pkg: type) void { if (@hasDecl(App, "init")) { const InitFn = @TypeOf(@field(App, "init")); - if (InitFn != fn (app: *App, core: *Core) @typeInfo(@typeInfo(InitFn).Fn.return_type.?).ErrorUnion.error_set!void) - @compileError("expected 'pub fn init(app: *App, core: *mach.Core) !void' found '" ++ @typeName(InitFn) ++ "'"); + if (@import("builtin").zig_backend == .stage1) { + if (InitFn != fn (app: *App, core: *Core) @typeInfo(@typeInfo(InitFn).Fn.return_type.?).ErrorUnion.error_set!void) + @compileError("expected 'pub fn init(app: *App, core: *mach.Core) !void' found '" ++ @typeName(InitFn) ++ "'"); + } else { + if (InitFn != *const fn (app: *App, core: *Core) @typeInfo(@typeInfo(InitFn).Fn.return_type.?).ErrorUnion.error_set!void) + @compileError("expected 'pub fn init(app: *App, core: *mach.Core) !void' found '" ++ @typeName(InitFn) ++ "'"); + } } else { @compileError("App must export 'pub fn init(app: *App, core: *mach.Core) !void'"); } if (@hasDecl(App, "update")) { const UpdateFn = @TypeOf(@field(App, "update")); - if (UpdateFn != fn (app: *App, core: *Core) @typeInfo(@typeInfo(UpdateFn).Fn.return_type.?).ErrorUnion.error_set!void) - @compileError("expected 'pub fn update(app: *App, core: *mach.Core) !void' found '" ++ @typeName(UpdateFn) ++ "'"); + if (@import("builtin").zig_backend == .stage1) { + if (UpdateFn != fn (app: *App, core: *Core) @typeInfo(@typeInfo(UpdateFn).Fn.return_type.?).ErrorUnion.error_set!void) + @compileError("expected 'pub fn update(app: *App, core: *mach.Core) !void' found '" ++ @typeName(UpdateFn) ++ "'"); + } else { + if (UpdateFn != *const fn (app: *App, core: *Core) @typeInfo(@typeInfo(UpdateFn).Fn.return_type.?).ErrorUnion.error_set!void) + @compileError("expected 'pub fn update(app: *App, core: *mach.Core) !void' found '" ++ @typeName(UpdateFn) ++ "'"); + } } else { @compileError("App must export 'pub fn update(app: *App, core: *mach.Core) !void'"); } if (@hasDecl(App, "deinit")) { const DeinitFn = @TypeOf(@field(App, "deinit")); - if (DeinitFn != fn (app: *App, core: *Core) void) - @compileError("expected 'pub fn deinit(app: *App, core: *mach.Core) void' found '" ++ @typeName(DeinitFn) ++ "'"); + if (@import("builtin").zig_backend == .stage1) { + if (DeinitFn != fn (app: *App, core: *Core) void) + @compileError("expected 'pub fn deinit(app: *App, core: *mach.Core) void' found '" ++ @typeName(DeinitFn) ++ "'"); + } else { + if (DeinitFn != *const fn (app: *App, core: *Core) void) + @compileError("expected 'pub fn deinit(app: *App, core: *mach.Core) void' found '" ++ @typeName(DeinitFn) ++ "'"); + } } else { @compileError("App must export 'pub fn deinit(app: *App, core: *mach.Core) void'"); } diff --git a/src/platform/native.zig b/src/platform/native.zig index e1182300..2c3c71ed 100644 --- a/src/platform/native.zig +++ b/src/platform/native.zig @@ -632,7 +632,10 @@ pub fn coreDeinit(core: *Core, allocator: std.mem.Allocator) void { allocator.destroy(core); } -pub const CoreResizeCallback = fn (*Core, u32, u32) callconv(.C) void; +pub const CoreResizeCallback = if (@import("builtin").zig_backend == .stage1) + fn (*Core, u32, u32) callconv(.C) void +else + *const fn (*Core, u32, u32) callconv(.C) void; pub fn coreUpdate(core: *Core, resize: ?CoreResizeCallback) !void { if (core.internal.wait_event_timeout > 0.0) { diff --git a/src/platform/util.zig b/src/platform/util.zig index e769ca2d..8915e7ea 100644 --- a/src/platform/util.zig +++ b/src/platform/util.zig @@ -2,9 +2,7 @@ const std = @import("std"); const glfw = @import("glfw"); const gpu = @import("gpu"); -const objc = @cImport({ - @cInclude("objc/message.h"); -}); +const objc = @import("objc_message.zig"); pub inline fn printUnhandledErrorCallback(_: void, typ: gpu.ErrorType, message: [*:0]const u8) void { switch (typ) { @@ -166,21 +164,33 @@ pub const AutoReleasePool = if (!@import("builtin").target.isDarwin()) opaque { }; // Borrowed from https://github.com/hazeycode/zig-objcrt -fn msgSend(obj: anytype, sel_name: [:0]const u8, args: anytype, comptime ReturnType: type) ReturnType { +pub fn msgSend(obj: anytype, sel_name: [:0]const u8, args: anytype, comptime ReturnType: type) ReturnType { const args_meta = @typeInfo(@TypeOf(args)).Struct.fields; - const FnType = switch (args_meta.len) { - 0 => fn (@TypeOf(obj), objc.SEL) callconv(.C) ReturnType, - 1 => fn (@TypeOf(obj), objc.SEL, args_meta[0].field_type) callconv(.C) ReturnType, - 2 => fn (@TypeOf(obj), objc.SEL, args_meta[0].field_type, args_meta[1].field_type) callconv(.C) ReturnType, - 3 => fn (@TypeOf(obj), objc.SEL, args_meta[0].field_type, args_meta[1].field_type, args_meta[2].field_type) callconv(.C) ReturnType, - 4 => fn (@TypeOf(obj), objc.SEL, args_meta[0].field_type, args_meta[1].field_type, args_meta[2].field_type, args_meta[3].field_type) callconv(.C) ReturnType, + const FnType = if (@import("builtin").zig_backend == .stage1) + switch (args_meta.len) { + 0 => fn (@TypeOf(obj), objc.SEL) callconv(.C) ReturnType, + 1 => fn (@TypeOf(obj), objc.SEL, args_meta[0].field_type) callconv(.C) ReturnType, + 2 => fn (@TypeOf(obj), objc.SEL, args_meta[0].field_type, args_meta[1].field_type) callconv(.C) ReturnType, + 3 => fn (@TypeOf(obj), objc.SEL, args_meta[0].field_type, args_meta[1].field_type, args_meta[2].field_type) callconv(.C) ReturnType, + 4 => fn (@TypeOf(obj), objc.SEL, args_meta[0].field_type, args_meta[1].field_type, args_meta[2].field_type, args_meta[3].field_type) callconv(.C) ReturnType, + else => @compileError("Unsupported number of args"), + } + else switch (args_meta.len) { + 0 => *const fn (@TypeOf(obj), objc.SEL) callconv(.C) ReturnType, + 1 => *const fn (@TypeOf(obj), objc.SEL, args_meta[0].field_type) callconv(.C) ReturnType, + 2 => *const fn (@TypeOf(obj), objc.SEL, args_meta[0].field_type, args_meta[1].field_type) callconv(.C) ReturnType, + 3 => *const fn (@TypeOf(obj), objc.SEL, args_meta[0].field_type, args_meta[1].field_type, args_meta[2].field_type) callconv(.C) ReturnType, + 4 => *const fn (@TypeOf(obj), objc.SEL, args_meta[0].field_type, args_meta[1].field_type, args_meta[2].field_type, args_meta[3].field_type) callconv(.C) ReturnType, else => @compileError("Unsupported number of args"), }; // NOTE: func is a var because making it const causes a compile error which I believe is a compiler bug - var func = @ptrCast(FnType, objc.objc_msgSend); - const sel = objc.sel_getUid(sel_name); + var func = if (@import("builtin").zig_backend == .stage1) + @ptrCast(FnType, objc.objc_msgSend) + else + @ptrCast(FnType, &objc.objc_msgSend); + const sel = objc.sel_getUid(@ptrCast([*c]const u8, sel_name)); return @call(.{}, func, .{ obj, sel } ++ args); }