| ... | @@ -347,7 +347,7 @@ fn WinStartup() callconv(std.os.windows.WINAPI) noreturn { | ... | @@ -347,7 +347,7 @@ fn WinStartup() callconv(std.os.windows.WINAPI) noreturn { |
| 347 | | 347 | |
| 348 | std.debug.maybeEnableSegfaultHandler(); | 348 | std.debug.maybeEnableSegfaultHandler(); |
| 349 | | 349 | |
| 350 | std.os.windows.ntdll.RtlExitUserProcess(initEventLoopAndCallMain()); | 350 | std.os.windows.ntdll.RtlExitUserProcess(callMain()); |
| 351 | } | 351 | } |
| 352 | | 352 | |
| 353 | fn wWinMainCRTStartup() callconv(std.os.windows.WINAPI) noreturn { | 353 | fn wWinMainCRTStartup() callconv(std.os.windows.WINAPI) noreturn { |
| ... | @@ -358,7 +358,7 @@ fn wWinMainCRTStartup() callconv(std.os.windows.WINAPI) noreturn { | ... | @@ -358,7 +358,7 @@ fn wWinMainCRTStartup() callconv(std.os.windows.WINAPI) noreturn { |
| 358 | | 358 | |
| 359 | std.debug.maybeEnableSegfaultHandler(); | 359 | std.debug.maybeEnableSegfaultHandler(); |
| 360 | | 360 | |
| 361 | const result: std.os.windows.INT = initEventLoopAndCallWinMain(); | 361 | const result: std.os.windows.INT = call_wWinMain(); |
| 362 | std.os.windows.ntdll.RtlExitUserProcess(@as(std.os.windows.UINT, @bitCast(result))); | 362 | std.os.windows.ntdll.RtlExitUserProcess(@as(std.os.windows.UINT, @bitCast(result))); |
| 363 | } | 363 | } |
| 364 | | 364 | |
| ... | @@ -422,7 +422,7 @@ fn posixCallMainAndExit() callconv(.C) noreturn { | ... | @@ -422,7 +422,7 @@ fn posixCallMainAndExit() callconv(.C) noreturn { |
| 422 | expandStackSize(phdrs); | 422 | expandStackSize(phdrs); |
| 423 | } | 423 | } |
| 424 | | 424 | |
| 425 | std.os.exit(@call(.always_inline, callMainWithArgs, .{ argc, argv, envp })); | 425 | std.os.exit(callMainWithArgs(argc, argv, envp)); |
| 426 | } | 426 | } |
| 427 | | 427 | |
| 428 | fn expandStackSize(phdrs: []elf.Phdr) void { | 428 | fn expandStackSize(phdrs: []elf.Phdr) void { |
| ... | @@ -459,14 +459,14 @@ fn expandStackSize(phdrs: []elf.Phdr) void { | ... | @@ -459,14 +459,14 @@ fn expandStackSize(phdrs: []elf.Phdr) void { |
| 459 | } | 459 | } |
| 460 | } | 460 | } |
| 461 | | 461 | |
| 462 | fn callMainWithArgs(argc: usize, argv: [*][*:0]u8, envp: [][*:0]u8) u8 { | 462 | inline fn callMainWithArgs(argc: usize, argv: [*][*:0]u8, envp: [][*:0]u8) u8 { |
| 463 | std.os.argv = argv[0..argc]; | 463 | std.os.argv = argv[0..argc]; |
| 464 | std.os.environ = envp; | 464 | std.os.environ = envp; |
| 465 | | 465 | |
| 466 | std.debug.maybeEnableSegfaultHandler(); | 466 | std.debug.maybeEnableSegfaultHandler(); |
| 467 | std.os.maybeIgnoreSigpipe(); | 467 | std.os.maybeIgnoreSigpipe(); |
| 468 | | 468 | |
| 469 | return initEventLoopAndCallMain(); | 469 | return callMain(); |
| 470 | } | 470 | } |
| 471 | | 471 | |
| 472 | fn main(c_argc: c_int, c_argv: [*][*:0]c_char, c_envp: [*:null]?[*:0]c_char) callconv(.C) c_int { | 472 | fn main(c_argc: c_int, c_argv: [*][*:0]c_char, c_envp: [*:null]?[*:0]c_char) callconv(.C) c_int { |
| ... | @@ -481,92 +481,18 @@ fn main(c_argc: c_int, c_argv: [*][*:0]c_char, c_envp: [*:null]?[*:0]c_char) cal | ... | @@ -481,92 +481,18 @@ fn main(c_argc: c_int, c_argv: [*][*:0]c_char, c_envp: [*:null]?[*:0]c_char) cal |
| 481 | expandStackSize(phdrs); | 481 | expandStackSize(phdrs); |
| 482 | } | 482 | } |
| 483 | | 483 | |
| 484 | return @call(.always_inline, callMainWithArgs, .{ @as(usize, @intCast(c_argc)), @as([*][*:0]u8, @ptrCast(c_argv)), envp }); | 484 | return callMainWithArgs(@as(usize, @intCast(c_argc)), @as([*][*:0]u8, @ptrCast(c_argv)), envp); |
| 485 | } | 485 | } |
| 486 | | 486 | |
| 487 | fn mainWithoutEnv(c_argc: c_int, c_argv: [*][*:0]c_char) callconv(.C) c_int { | 487 | fn mainWithoutEnv(c_argc: c_int, c_argv: [*][*:0]c_char) callconv(.C) c_int { |
| 488 | std.os.argv = @as([*][*:0]u8, @ptrCast(c_argv))[0..@as(usize, @intCast(c_argc))]; | 488 | std.os.argv = @as([*][*:0]u8, @ptrCast(c_argv))[0..@as(usize, @intCast(c_argc))]; |
| 489 | return @call(.always_inline, callMain, .{}); | 489 | return callMain(); |
| 490 | } | 490 | } |
| 491 | | 491 | |
| 492 | // General error message for a malformed return type | 492 | // General error message for a malformed return type |
| 493 | const bad_main_ret = "expected return type of main to be 'void', '!void', 'noreturn', 'u8', or '!u8'"; | 493 | const bad_main_ret = "expected return type of main to be 'void', '!void', 'noreturn', 'u8', or '!u8'"; |
| 494 | | 494 | |
| 495 | // This is marked inline because for some reason LLVM in release mode fails to inline it, | 495 | pub inline fn callMain() u8 { |
| 496 | // and we want fewer call frames in stack traces. | | |
| 497 | inline fn initEventLoopAndCallMain() u8 { | | |
| 498 | if (std.event.Loop.instance) |loop| { | | |
| 499 | if (loop == std.event.Loop.default_instance) { | | |
| 500 | loop.init() catch |err| { | | |
| 501 | std.log.err("{s}", .{@errorName(err)}); | | |
| 502 | if (@errorReturnTrace()) |trace| { | | |
| 503 | std.debug.dumpStackTrace(trace.*); | | |
| 504 | } | | |
| 505 | return 1; | | |
| 506 | }; | | |
| 507 | defer loop.deinit(); | | |
| 508 | | | |
| 509 | var result: u8 = undefined; | | |
| 510 | var frame: @Frame(callMainAsync) = undefined; | | |
| 511 | _ = @asyncCall(&frame, &result, callMainAsync, .{loop}); | | |
| 512 | loop.run(); | | |
| 513 | return result; | | |
| 514 | } | | |
| 515 | } | | |
| 516 | | | |
| 517 | // This is marked inline because for some reason LLVM in release mode fails to inline it, | | |
| 518 | // and we want fewer call frames in stack traces. | | |
| 519 | return @call(.always_inline, callMain, .{}); | | |
| 520 | } | | |
| 521 | | | |
| 522 | // This is marked inline because for some reason LLVM in release mode fails to inline it, | | |
| 523 | // and we want fewer call frames in stack traces. | | |
| 524 | // TODO This function is duplicated from initEventLoopAndCallMain instead of using generics | | |
| 525 | // because it is working around stage1 compiler bugs. | | |
| 526 | inline fn initEventLoopAndCallWinMain() std.os.windows.INT { | | |
| 527 | if (std.event.Loop.instance) |loop| { | | |
| 528 | if (loop == std.event.Loop.default_instance) { | | |
| 529 | loop.init() catch |err| { | | |
| 530 | std.log.err("{s}", .{@errorName(err)}); | | |
| 531 | if (@errorReturnTrace()) |trace| { | | |
| 532 | std.debug.dumpStackTrace(trace.*); | | |
| 533 | } | | |
| 534 | return 1; | | |
| 535 | }; | | |
| 536 | defer loop.deinit(); | | |
| 537 | | | |
| 538 | var result: std.os.windows.INT = undefined; | | |
| 539 | var frame: @Frame(callWinMainAsync) = undefined; | | |
| 540 | _ = @asyncCall(&frame, &result, callWinMainAsync, .{loop}); | | |
| 541 | loop.run(); | | |
| 542 | return result; | | |
| 543 | } | | |
| 544 | } | | |
| 545 | | | |
| 546 | // This is marked inline because for some reason LLVM in release mode fails to inline it, | | |
| 547 | // and we want fewer call frames in stack traces. | | |
| 548 | return @call(.always_inline, call_wWinMain, .{}); | | |
| 549 | } | | |
| 550 | | | |
| 551 | fn callMainAsync(loop: *std.event.Loop) callconv(.Async) u8 { | | |
| 552 | // This prevents the event loop from terminating at least until main() has returned. | | |
| 553 | // TODO This shouldn't be needed here; it should be in the event loop code. | | |
| 554 | loop.beginOneEvent(); | | |
| 555 | defer loop.finishOneEvent(); | | |
| 556 | return callMain(); | | |
| 557 | } | | |
| 558 | | | |
| 559 | fn callWinMainAsync(loop: *std.event.Loop) callconv(.Async) std.os.windows.INT { | | |
| 560 | // This prevents the event loop from terminating at least until main() has returned. | | |
| 561 | // TODO This shouldn't be needed here; it should be in the event loop code. | | |
| 562 | loop.beginOneEvent(); | | |
| 563 | defer loop.finishOneEvent(); | | |
| 564 | return call_wWinMain(); | | |
| 565 | } | | |
| 566 | | | |
| 567 | // This is not marked inline because it is called with @asyncCall when | | |
| 568 | // there is an event loop. | | |
| 569 | pub fn callMain() u8 { | | |
| 570 | switch (@typeInfo(@typeInfo(@TypeOf(root.main)).Fn.return_type.?)) { | 496 | switch (@typeInfo(@typeInfo(@TypeOf(root.main)).Fn.return_type.?)) { |
| 571 | .NoReturn => { | 497 | .NoReturn => { |
| 572 | root.main(); | 498 | root.main(); |