Skip to content

Commit 3e1da91

Browse files
authored
Rollup merge of #65576 - sunfishcode:main-needs-argc-argv, r=alexcrichton
Don't add `argc` and `argv` arguments to `main` on WASI. Add a target setting to allow targets to specify whether the generated `main` function should be passed `argc` and `argv` arguments. Set it to false on wasm32-wasi, since WASI's `args::args()` calls into the WASI APIs itself. This will allow the WASI toolchain to avoid linking and running command-line argument initialization code when the arguments aren't actually needed.
2 parents ed4c2c2 + b25e323 commit 3e1da91

File tree

3 files changed

+28
-7
lines changed

3 files changed

+28
-7
lines changed

src/librustc_codegen_ssa/base.rs

+18-7
Original file line numberDiff line numberDiff line change
@@ -414,8 +414,11 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &'
414414
rust_main_def_id: DefId,
415415
use_start_lang_item: bool,
416416
) {
417-
let llfty =
418-
cx.type_func(&[cx.type_int(), cx.type_ptr_to(cx.type_i8p())], cx.type_int());
417+
let llfty = if cx.sess().target.target.options.main_needs_argc_argv {
418+
cx.type_func(&[cx.type_int(), cx.type_ptr_to(cx.type_i8p())], cx.type_int())
419+
} else {
420+
cx.type_func(&[], cx.type_int())
421+
};
419422

420423
let main_ret_ty = cx.tcx().fn_sig(rust_main_def_id).output();
421424
// Given that `main()` has no arguments,
@@ -445,11 +448,19 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &'
445448

446449
bx.insert_reference_to_gdb_debug_scripts_section_global();
447450

448-
// Params from native main() used as args for rust start function
449-
let param_argc = bx.get_param(0);
450-
let param_argv = bx.get_param(1);
451-
let arg_argc = bx.intcast(param_argc, cx.type_isize(), true);
452-
let arg_argv = param_argv;
451+
let (arg_argc, arg_argv) = if cx.sess().target.target.options.main_needs_argc_argv {
452+
// Params from native main() used as args for rust start function
453+
let param_argc = bx.get_param(0);
454+
let param_argv = bx.get_param(1);
455+
let arg_argc = bx.intcast(param_argc, cx.type_isize(), true);
456+
let arg_argv = param_argv;
457+
(arg_argc, arg_argv)
458+
} else {
459+
// The Rust start function doesn't need argc and argv, so just pass zeros.
460+
let arg_argc = bx.const_int(cx.type_int(), 0);
461+
let arg_argv = bx.const_null(cx.type_ptr_to(cx.type_i8p()));
462+
(arg_argc, arg_argv)
463+
};
453464

454465
let (start_fn, args) = if use_start_lang_item {
455466
let start_def_id = cx.tcx().require_lang_item(StartFnLangItem, None);

src/librustc_target/spec/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,9 @@ pub struct TargetOptions {
691691
/// defined in libgcc. If this option is enabled, the target must provide
692692
/// `eh_unwind_resume` lang item.
693693
pub custom_unwind_resume: bool,
694+
/// Whether the runtime startup code requires the `main` function be passed
695+
/// `argc` and `argv` values.
696+
pub main_needs_argc_argv: bool,
694697

695698
/// Flag indicating whether ELF TLS (e.g., #[thread_local]) is available for
696699
/// this target.
@@ -849,6 +852,7 @@ impl Default for TargetOptions {
849852
link_env_remove: Vec::new(),
850853
archive_format: "gnu".to_string(),
851854
custom_unwind_resume: false,
855+
main_needs_argc_argv: true,
852856
allow_asm: true,
853857
has_elf_tls: false,
854858
obj_is_bitcode: false,
@@ -1159,6 +1163,7 @@ impl Target {
11591163
key!(archive_format);
11601164
key!(allow_asm, bool);
11611165
key!(custom_unwind_resume, bool);
1166+
key!(main_needs_argc_argv, bool);
11621167
key!(has_elf_tls, bool);
11631168
key!(obj_is_bitcode, bool);
11641169
key!(no_integrated_as, bool);
@@ -1376,6 +1381,7 @@ impl ToJson for Target {
13761381
target_option_val!(archive_format);
13771382
target_option_val!(allow_asm);
13781383
target_option_val!(custom_unwind_resume);
1384+
target_option_val!(main_needs_argc_argv);
13791385
target_option_val!(has_elf_tls);
13801386
target_option_val!(obj_is_bitcode);
13811387
target_option_val!(no_integrated_as);

src/librustc_target/spec/wasm32_wasi.rs

+4
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ pub fn target() -> Result<Target, String> {
101101
// without a main function.
102102
options.crt_static_allows_dylibs = true;
103103

104+
// WASI's `sys::args::init` function ignores its arguments; instead,
105+
// `args::args()` makes the WASI API calls itself.
106+
options.main_needs_argc_argv = false;
107+
104108
Ok(Target {
105109
llvm_target: "wasm32-wasi".to_string(),
106110
target_endian: "little".to_string(),

0 commit comments

Comments
 (0)