| ... | ... | @@ -159,7 +159,7 @@ fn WinStartup() callconv(.Stdcall) noreturn { |
| 159 | 159 | |
| 160 | 160 | std.debug.maybeEnableSegfaultHandler(); |
| 161 | 161 | |
| 162 | | std.os.windows.kernel32.ExitProcess(initEventLoopAndCallMain(u8, callMain)); |
| 162 | std.os.windows.kernel32.ExitProcess(initEventLoopAndCallMain()); |
| 163 | 163 | } |
| 164 | 164 | |
| 165 | 165 | fn wWinMainCRTStartup() callconv(.Stdcall) noreturn { |
| ... | ... | @@ -170,8 +170,7 @@ fn wWinMainCRTStartup() callconv(.Stdcall) noreturn { |
| 170 | 170 | |
| 171 | 171 | std.debug.maybeEnableSegfaultHandler(); |
| 172 | 172 | |
| 173 | | const result = initEventLoopAndCallMain(std.os.windows.INT, call_wWinMain); |
| 174 | | std.os.windows.kernel32.ExitProcess(@bitCast(std.os.windows.UINT, result)); |
| 173 | std.os.windows.kernel32.ExitProcess(initEventLoopAndCallWinMain()); |
| 175 | 174 | } |
| 176 | 175 | |
| 177 | 176 | // TODO https://github.com/ziglang/zig/issues/265 |
| ... | ... | @@ -225,7 +224,7 @@ fn callMainWithArgs(argc: usize, argv: [*][*:0]u8, envp: [][*:0]u8) u8 { |
| 225 | 224 | |
| 226 | 225 | std.debug.maybeEnableSegfaultHandler(); |
| 227 | 226 | |
| 228 | | return initEventLoopAndCallMain(u8, callMain); |
| 227 | return initEventLoopAndCallMain(); |
| 229 | 228 | } |
| 230 | 229 | |
| 231 | 230 | fn main(c_argc: i32, c_argv: [*][*:0]u8, c_envp: [*:null]?[*:0]u8) callconv(.C) i32 { |
| ... | ... | @@ -240,7 +239,7 @@ const bad_main_ret = "expected return type of main to be 'void', '!void', 'noret |
| 240 | 239 | |
| 241 | 240 | // This is marked inline because for some reason LLVM in release mode fails to inline it, |
| 242 | 241 | // and we want fewer call frames in stack traces. |
| 243 | | inline fn initEventLoopAndCallMain(comptime Out: type, comptime mainFunc: fn () Out) Out { |
| 242 | inline fn initEventLoopAndCallMain() u8 { |
| 244 | 243 | if (std.event.Loop.instance) |loop| { |
| 245 | 244 | if (!@hasDecl(root, "event_loop")) { |
| 246 | 245 | loop.init() catch |err| { |
| ... | ... | @@ -254,7 +253,7 @@ inline fn initEventLoopAndCallMain(comptime Out: type, comptime mainFunc: fn () |
| 254 | 253 | |
| 255 | 254 | var result: u8 = undefined; |
| 256 | 255 | var frame: @Frame(callMainAsync) = undefined; |
| 257 | | _ = @asyncCall(&frame, &result, callMainAsync, .{ u8, mainFunc, loop }); |
| 256 | _ = @asyncCall(&frame, &result, callMainAsync, .{loop}); |
| 258 | 257 | loop.run(); |
| 259 | 258 | return result; |
| 260 | 259 | } |
| ... | ... | @@ -262,13 +261,44 @@ inline fn initEventLoopAndCallMain(comptime Out: type, comptime mainFunc: fn () |
| 262 | 261 | |
| 263 | 262 | // This is marked inline because for some reason LLVM in release mode fails to inline it, |
| 264 | 263 | // and we want fewer call frames in stack traces. |
| 265 | | return @call(.{ .modifier = .always_inline }, mainFunc, .{}); |
| 264 | return @call(.{ .modifier = .always_inline }, callMain, .{}); |
| 266 | 265 | } |
| 267 | | fn callMainAsync(comptime Out: type, comptime mainProc: fn () Out, loop: *std.event.Loop) callconv(.Async) Out { |
| 266 | |
| 267 | // This is marked inline because for some reason LLVM in release mode fails to inline it, |
| 268 | // and we want fewer call frames in stack traces. |
| 269 | // TODO This function is duplicated from initEventLoopAndCallMain instead of using generics |
| 270 | // because it is working around stage1 compiler bugs. |
| 271 | inline fn initEventLoopAndCallWinMain() std.os.windows.INT { |
| 272 | if (std.event.Loop.instance) |loop| { |
| 273 | if (!@hasDecl(root, "event_loop")) { |
| 274 | loop.init() catch |err| { |
| 275 | std.log.err("{}", .{@errorName(err)}); |
| 276 | if (@errorReturnTrace()) |trace| { |
| 277 | std.debug.dumpStackTrace(trace.*); |
| 278 | } |
| 279 | return 1; |
| 280 | }; |
| 281 | defer loop.deinit(); |
| 282 | |
| 283 | var result: u8 = undefined; |
| 284 | var frame: @Frame(callMainAsync) = undefined; |
| 285 | _ = @asyncCall(&frame, &result, callMainAsync, .{loop}); |
| 286 | loop.run(); |
| 287 | return result; |
| 288 | } |
| 289 | } |
| 290 | |
| 291 | // This is marked inline because for some reason LLVM in release mode fails to inline it, |
| 292 | // and we want fewer call frames in stack traces. |
| 293 | return @call(.{ .modifier = .always_inline }, call_wWinMain, .{}); |
| 294 | } |
| 295 | |
| 296 | fn callMainAsync(loop: *std.event.Loop) callconv(.Async) u8 { |
| 268 | 297 | // This prevents the event loop from terminating at least until main() has returned. |
| 298 | // TODO This shouldn't be needed here; it should be in the event loop code. |
| 269 | 299 | loop.beginOneEvent(); |
| 270 | 300 | defer loop.finishOneEvent(); |
| 271 | | return mainProc(); |
| 301 | return callMain(); |
| 272 | 302 | } |
| 273 | 303 | |
| 274 | 304 | // This is not marked inline because it is called with @asyncCall when |