authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-10-17 15:46:36-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-10-17 15:46:36-07:00
log0011def2b24f63233f2ee24909701f92264c2ef5
treee196ebce13d03869524583f41fea46e3d83c0f52
parent245d98d32dd29e80de9732f415a4731748008acf

fix compilation error when building with io_mode evented

The merge of #5613 introduced a regression when building with io_mode evented, fixed in this commit. closes #6715

2 files changed, 40 insertions(+), 10 deletions(-)

lib/std/start.zig+39-9
......@@ -159,7 +159,7 @@ fn WinStartup() callconv(.Stdcall) noreturn {
159159
160160 std.debug.maybeEnableSegfaultHandler();
161161
162 std.os.windows.kernel32.ExitProcess(initEventLoopAndCallMain(u8, callMain));
162 std.os.windows.kernel32.ExitProcess(initEventLoopAndCallMain());
163163}
164164
165165fn wWinMainCRTStartup() callconv(.Stdcall) noreturn {
......@@ -170,8 +170,7 @@ fn wWinMainCRTStartup() callconv(.Stdcall) noreturn {
170170
171171 std.debug.maybeEnableSegfaultHandler();
172172
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());
175174}
176175
177176// TODO https://github.com/ziglang/zig/issues/265
......@@ -225,7 +224,7 @@ fn callMainWithArgs(argc: usize, argv: [*][*:0]u8, envp: [][*:0]u8) u8 {
225224
226225 std.debug.maybeEnableSegfaultHandler();
227226
228 return initEventLoopAndCallMain(u8, callMain);
227 return initEventLoopAndCallMain();
229228}
230229
231230fn 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
240239
241240// This is marked inline because for some reason LLVM in release mode fails to inline it,
242241// and we want fewer call frames in stack traces.
243inline fn initEventLoopAndCallMain(comptime Out: type, comptime mainFunc: fn () Out) Out {
242inline fn initEventLoopAndCallMain() u8 {
244243 if (std.event.Loop.instance) |loop| {
245244 if (!@hasDecl(root, "event_loop")) {
246245 loop.init() catch |err| {
......@@ -254,7 +253,7 @@ inline fn initEventLoopAndCallMain(comptime Out: type, comptime mainFunc: fn ()
254253
255254 var result: u8 = undefined;
256255 var frame: @Frame(callMainAsync) = undefined;
257 _ = @asyncCall(&frame, &result, callMainAsync, .{ u8, mainFunc, loop });
256 _ = @asyncCall(&frame, &result, callMainAsync, .{loop});
258257 loop.run();
259258 return result;
260259 }
......@@ -262,13 +261,44 @@ inline fn initEventLoopAndCallMain(comptime Out: type, comptime mainFunc: fn ()
262261
263262 // This is marked inline because for some reason LLVM in release mode fails to inline it,
264263 // and we want fewer call frames in stack traces.
265 return @call(.{ .modifier = .always_inline }, mainFunc, .{});
264 return @call(.{ .modifier = .always_inline }, callMain, .{});
266265}
267fn 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.
271inline 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
296fn callMainAsync(loop: *std.event.Loop) callconv(.Async) u8 {
268297 // 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.
269299 loop.beginOneEvent();
270300 defer loop.finishOneEvent();
271 return mainProc();
301 return callMain();
272302}
273303
274304// This is not marked inline because it is called with @asyncCall when
test/stack_traces.zig+1-1
......@@ -282,7 +282,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
282282 \\source.zig:10:8: [address] in main (test)
283283 \\ foo();
284284 \\ ^
285 \\start.zig:289:29: [address] in std.start.posixCallMainAndExit (test)
285 \\start.zig:319:29: [address] in std.start.posixCallMainAndExit (test)
286286 \\ return root.main();
287287 \\ ^
288288 \\start.zig:151:5: [address] in std.start._start (test)