Skip to content

Commit

Permalink
Don't add argc and argv arguments to main on WASI.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
sunfishcode committed Oct 17, 2019
1 parent b043380 commit b25e323
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 7 deletions.
25 changes: 18 additions & 7 deletions src/librustc_codegen_ssa/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,11 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &'
rust_main_def_id: DefId,
use_start_lang_item: bool,
) {
let llfty =
cx.type_func(&[cx.type_int(), cx.type_ptr_to(cx.type_i8p())], cx.type_int());
let llfty = if cx.sess().target.target.options.main_needs_argc_argv {
cx.type_func(&[cx.type_int(), cx.type_ptr_to(cx.type_i8p())], cx.type_int())
} else {
cx.type_func(&[], cx.type_int())
};

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

bx.insert_reference_to_gdb_debug_scripts_section_global();

// Params from native main() used as args for rust start function
let param_argc = bx.get_param(0);
let param_argv = bx.get_param(1);
let arg_argc = bx.intcast(param_argc, cx.type_isize(), true);
let arg_argv = param_argv;
let (arg_argc, arg_argv) = if cx.sess().target.target.options.main_needs_argc_argv {
// Params from native main() used as args for rust start function
let param_argc = bx.get_param(0);
let param_argv = bx.get_param(1);
let arg_argc = bx.intcast(param_argc, cx.type_isize(), true);
let arg_argv = param_argv;
(arg_argc, arg_argv)
} else {
// The Rust start function doesn't need argc and argv, so just pass zeros.
let arg_argc = bx.const_int(cx.type_int(), 0);
let arg_argv = bx.const_null(cx.type_ptr_to(cx.type_i8p()));
(arg_argc, arg_argv)
};

let (start_fn, args) = if use_start_lang_item {
let start_def_id = cx.tcx().require_lang_item(StartFnLangItem, None);
Expand Down
6 changes: 6 additions & 0 deletions src/librustc_target/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,9 @@ pub struct TargetOptions {
/// defined in libgcc. If this option is enabled, the target must provide
/// `eh_unwind_resume` lang item.
pub custom_unwind_resume: bool,
/// Whether the runtime startup code requires the `main` function be passed
/// `argc` and `argv` values.
pub main_needs_argc_argv: bool,

/// Flag indicating whether ELF TLS (e.g., #[thread_local]) is available for
/// this target.
Expand Down Expand Up @@ -849,6 +852,7 @@ impl Default for TargetOptions {
link_env_remove: Vec::new(),
archive_format: "gnu".to_string(),
custom_unwind_resume: false,
main_needs_argc_argv: true,
allow_asm: true,
has_elf_tls: false,
obj_is_bitcode: false,
Expand Down Expand Up @@ -1159,6 +1163,7 @@ impl Target {
key!(archive_format);
key!(allow_asm, bool);
key!(custom_unwind_resume, bool);
key!(main_needs_argc_argv, bool);
key!(has_elf_tls, bool);
key!(obj_is_bitcode, bool);
key!(no_integrated_as, bool);
Expand Down Expand Up @@ -1376,6 +1381,7 @@ impl ToJson for Target {
target_option_val!(archive_format);
target_option_val!(allow_asm);
target_option_val!(custom_unwind_resume);
target_option_val!(main_needs_argc_argv);
target_option_val!(has_elf_tls);
target_option_val!(obj_is_bitcode);
target_option_val!(no_integrated_as);
Expand Down
4 changes: 4 additions & 0 deletions src/librustc_target/spec/wasm32_wasi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ pub fn target() -> Result<Target, String> {
// without a main function.
options.crt_static_allows_dylibs = true;

// WASI's `sys::args::init` function ignores its arguments; instead,
// `args::args()` makes the WASI API calls itself.
options.main_needs_argc_argv = false;

Ok(Target {
llvm_target: "wasm32-wasi".to_string(),
target_endian: "little".to_string(),
Expand Down

0 comments on commit b25e323

Please sign in to comment.