Skip to content

Commit 92d3537

Browse files
committed
Add wasi-exec-model cg option for emitting wasi reactors
1 parent 7efc097 commit 92d3537

File tree

9 files changed

+69
-20
lines changed

9 files changed

+69
-20
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1193,6 +1193,7 @@ fn exec_linker(
11931193

11941194
fn link_output_kind(sess: &Session, crate_type: CrateType) -> LinkOutputKind {
11951195
let kind = match (crate_type, sess.crt_static(Some(crate_type)), sess.relocation_model()) {
1196+
(CrateType::Executable, _, _) if sess.is_wasi_reactor() => LinkOutputKind::WasiReactorExe,
11961197
(CrateType::Executable, false, RelocModel::Pic) => LinkOutputKind::DynamicPicExe,
11971198
(CrateType::Executable, false, _) => LinkOutputKind::DynamicNoPicExe,
11981199
(CrateType::Executable, true, RelocModel::Pic) => LinkOutputKind::StaticPicExe,

compiler/rustc_codegen_ssa/src/back/linker.rs

+11
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,10 @@ impl<'a> Linker for GccLinker<'a> {
314314
self.cmd.arg("-static");
315315
self.build_dylib(out_filename);
316316
}
317+
LinkOutputKind::WasiReactorExe => {
318+
self.linker_arg("--entry");
319+
self.linker_arg("_initialize");
320+
}
317321
}
318322
// VxWorks compiler driver introduced `--static-crt` flag specifically for rustc,
319323
// it switches linking for libc and similar system libraries to static without using
@@ -662,6 +666,9 @@ impl<'a> Linker for MsvcLinker<'a> {
662666
arg.push(out_filename.with_extension("dll.lib"));
663667
self.cmd.arg(arg);
664668
}
669+
LinkOutputKind::WasiReactorExe => {
670+
panic!("can't link as reactor on non-wasi target");
671+
}
665672
}
666673
}
667674

@@ -1085,6 +1092,10 @@ impl<'a> Linker for WasmLd<'a> {
10851092
LinkOutputKind::DynamicDylib | LinkOutputKind::StaticDylib => {
10861093
self.cmd.arg("--no-entry");
10871094
}
1095+
LinkOutputKind::WasiReactorExe => {
1096+
self.cmd.arg("--entry");
1097+
self.cmd.arg("_initialize");
1098+
}
10881099
}
10891100
}
10901101

compiler/rustc_interface/src/tests.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_session::config::{build_configuration, build_session_options, to_crate
77
use rustc_session::config::{rustc_optgroups, ErrorOutputType, ExternLocation, Options, Passes};
88
use rustc_session::config::{CFGuard, ExternEntry, LinkerPluginLto, LtoCli, SwitchWithOptPath};
99
use rustc_session::config::{
10-
Externs, OutputType, OutputTypes, SanitizerSet, SymbolManglingVersion,
10+
Externs, OutputType, OutputTypes, SanitizerSet, SymbolManglingVersion, WasiExecModel,
1111
};
1212
use rustc_session::lint::Level;
1313
use rustc_session::search_paths::SearchPath;
@@ -597,6 +597,7 @@ fn test_debugging_options_tracking_hash() {
597597
tracked!(unleash_the_miri_inside_of_you, true);
598598
tracked!(use_ctors_section, Some(true));
599599
tracked!(verify_llvm_ir, true);
600+
tracked!(wasi_exec_model, Some(WasiExecModel::Reactor));
600601
}
601602

602603
#[test]

compiler/rustc_session/src/config.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2086,6 +2086,7 @@ crate mod dep_tracking {
20862086
SymbolManglingVersion, TrimmedDefPaths,
20872087
};
20882088
use crate::lint;
2089+
use crate::options::WasiExecModel;
20892090
use crate::utils::NativeLibKind;
20902091
use rustc_feature::UnstableFeatures;
20912092
use rustc_span::edition::Edition;
@@ -2141,6 +2142,7 @@ crate mod dep_tracking {
21412142
impl_dep_tracking_hash_via_hash!(Option<RelocModel>);
21422143
impl_dep_tracking_hash_via_hash!(Option<CodeModel>);
21432144
impl_dep_tracking_hash_via_hash!(Option<TlsModel>);
2145+
impl_dep_tracking_hash_via_hash!(Option<WasiExecModel>);
21442146
impl_dep_tracking_hash_via_hash!(Option<PanicStrategy>);
21452147
impl_dep_tracking_hash_via_hash!(Option<RelroLevel>);
21462148
impl_dep_tracking_hash_via_hash!(Option<lint::Level>);

compiler/rustc_session/src/options.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ macro_rules! options {
278278
pub const parse_tls_model: &str =
279279
"one of supported TLS models (`rustc --print tls-models`)";
280280
pub const parse_target_feature: &str = parse_string;
281+
pub const parse_wasi_exec_model: &str = "either `command` or `reactor`";
281282
}
282283

283284
#[allow(dead_code)]
@@ -708,6 +709,15 @@ macro_rules! options {
708709
None => false,
709710
}
710711
}
712+
713+
fn parse_wasi_exec_model(slot: &mut Option<WasiExecModel>, v: Option<&str>) -> bool {
714+
match v {
715+
Some("command") => *slot = Some(WasiExecModel::Command),
716+
Some("reactor") => *slot = Some(WasiExecModel::Reactor),
717+
_ => return false,
718+
}
719+
true
720+
}
711721
}
712722
) }
713723

@@ -1147,9 +1157,17 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
11471157
"in general, enable more debug printouts (default: no)"),
11481158
verify_llvm_ir: bool = (false, parse_bool, [TRACKED],
11491159
"verify LLVM IR (default: no)"),
1160+
wasi_exec_model: Option<WasiExecModel> = (None, parse_wasi_exec_model, [TRACKED],
1161+
"whether to build a wasi command or reactor"),
11501162

11511163
// This list is in alphabetical order.
11521164
//
11531165
// If you add a new option, please update:
1154-
// - src/librustc_interface/tests.rs
1166+
// - compiler/rustc_interface/src/tests.rs
1167+
}
1168+
1169+
#[derive(Clone, Hash)]
1170+
pub enum WasiExecModel {
1171+
Command,
1172+
Reactor,
11551173
}

compiler/rustc_session/src/session.rs

+8
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,14 @@ impl Session {
796796
self.opts.debugging_opts.tls_model.unwrap_or(self.target.tls_model)
797797
}
798798

799+
pub fn is_wasi_reactor(&self) -> bool {
800+
self.target.options.os == "wasi"
801+
&& matches!(
802+
self.opts.debugging_opts.wasi_exec_model,
803+
Some(config::WasiExecModel::Reactor)
804+
)
805+
}
806+
799807
pub fn must_not_eliminate_frame_pointers(&self) -> bool {
800808
// "mcount" function relies on stack pointer.
801809
// See <https://sourceware.org/binutils/docs/gprof/Implementation.html>.

compiler/rustc_target/src/spec/crt_objects.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@
55
//! The `crtx` ones are generally distributed with libc and the `begin/end` ones with gcc.
66
//! See <https://dev.gentoo.org/~vapier/crt.txt> for some more details.
77
//!
8-
//! | Pre-link CRT objects | glibc | musl | bionic | mingw | wasi |
9-
//! |----------------------|------------------------|------------------------|------------------|-------------------|------|
10-
//! | dynamic-nopic-exe | crt1, crti, crtbegin | crt1, crti, crtbegin | crtbegin_dynamic | crt2, crtbegin | crt1 |
11-
//! | dynamic-pic-exe | Scrt1, crti, crtbeginS | Scrt1, crti, crtbeginS | crtbegin_dynamic | crt2, crtbegin | crt1 |
12-
//! | static-nopic-exe | crt1, crti, crtbeginT | crt1, crti, crtbegin | crtbegin_static | crt2, crtbegin | crt1 |
13-
//! | static-pic-exe | rcrt1, crti, crtbeginS | rcrt1, crti, crtbeginS | crtbegin_dynamic | crt2, crtbegin | crt1 |
14-
//! | dynamic-dylib | crti, crtbeginS | crti, crtbeginS | crtbegin_so | dllcrt2, crtbegin | - |
15-
//! | static-dylib (gcc) | crti, crtbeginT | crti, crtbeginS | crtbegin_so | dllcrt2, crtbegin | - |
16-
//! | static-dylib (clang) | crti, crtbeginT | N/A | crtbegin_static | dllcrt2, crtbegin | - |
8+
//! | Pre-link CRT objects | glibc | musl | bionic | mingw | wasi |
9+
//! |----------------------|------------------------|------------------------|------------------|-------------------|--------------|
10+
//! | dynamic-nopic-exe | crt1, crti, crtbegin | crt1, crti, crtbegin | crtbegin_dynamic | crt2, crtbegin | crt1 |
11+
//! | dynamic-pic-exe | Scrt1, crti, crtbeginS | Scrt1, crti, crtbeginS | crtbegin_dynamic | crt2, crtbegin | crt1 |
12+
//! | static-nopic-exe | crt1, crti, crtbeginT | crt1, crti, crtbegin | crtbegin_static | crt2, crtbegin | crt1 |
13+
//! | static-pic-exe | rcrt1, crti, crtbeginS | rcrt1, crti, crtbeginS | crtbegin_dynamic | crt2, crtbegin | crt1 |
14+
//! | dynamic-dylib | crti, crtbeginS | crti, crtbeginS | crtbegin_so | dllcrt2, crtbegin | - |
15+
//! | static-dylib (gcc) | crti, crtbeginT | crti, crtbeginS | crtbegin_so | dllcrt2, crtbegin | - |
16+
//! | static-dylib (clang) | crti, crtbeginT | N/A | crtbegin_static | dllcrt2, crtbegin | - |
17+
//! | wasi-reactor-exe | N/A | N/A | N/A | N/A | crt1-reactor |
1718
//!
1819
//! | Post-link CRT objects | glibc | musl | bionic | mingw | wasi |
1920
//! |-----------------------|---------------|---------------|----------------|--------|------|
@@ -105,6 +106,7 @@ pub(super) fn pre_wasi_fallback() -> CrtObjects {
105106
(LinkOutputKind::DynamicPicExe, &["crt1.o"]),
106107
(LinkOutputKind::StaticNoPicExe, &["crt1.o"]),
107108
(LinkOutputKind::StaticPicExe, &["crt1.o"]),
109+
(LinkOutputKind::WasiReactorExe, &["crt1-reactor.o"]),
108110
])
109111
}
110112

compiler/rustc_target/src/spec/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,8 @@ pub enum LinkOutputKind {
407407
DynamicDylib,
408408
/// Dynamic library with bundled libc ("statically linked").
409409
StaticDylib,
410+
/// WASI module with a lifetime past the _initialize entry point
411+
WasiReactorExe,
410412
}
411413

412414
impl LinkOutputKind {
@@ -418,6 +420,7 @@ impl LinkOutputKind {
418420
LinkOutputKind::StaticPicExe => "static-pic-exe",
419421
LinkOutputKind::DynamicDylib => "dynamic-dylib",
420422
LinkOutputKind::StaticDylib => "static-dylib",
423+
LinkOutputKind::WasiReactorExe => "wasi-reactor-exe",
421424
}
422425
}
423426

@@ -429,6 +432,7 @@ impl LinkOutputKind {
429432
"static-pic-exe" => LinkOutputKind::StaticPicExe,
430433
"dynamic-dylib" => LinkOutputKind::DynamicDylib,
431434
"static-dylib" => LinkOutputKind::StaticDylib,
435+
"wasi-reactor-exe" => LinkOutputKind::WasiReactorExe,
432436
_ => return None,
433437
})
434438
}
@@ -1377,7 +1381,7 @@ impl Target {
13771381
let kind = LinkOutputKind::from_str(&k).ok_or_else(|| {
13781382
format!("{}: '{}' is not a valid value for CRT object kind. \
13791383
Use '(dynamic,static)-(nopic,pic)-exe' or \
1380-
'(dynamic,static)-dylib'", name, k)
1384+
'(dynamic,static)-dylib' or 'wasi-reactor-exe'", name, k)
13811385
})?;
13821386

13831387
let v = v.as_array().ok_or_else(||

src/bootstrap/compile.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -187,14 +187,16 @@ fn copy_self_contained_objects(
187187
}
188188
} else if target.ends_with("-wasi") {
189189
let srcdir = builder.wasi_root(target).unwrap().join("lib/wasm32-wasi");
190-
copy_and_stamp(
191-
builder,
192-
&libdir_self_contained,
193-
&srcdir,
194-
"crt1.o",
195-
&mut target_deps,
196-
DependencyType::TargetSelfContained,
197-
);
190+
for &obj in &["crt1.o", "crt1-reactor.o"] {
191+
copy_and_stamp(
192+
builder,
193+
&libdir_self_contained,
194+
&srcdir,
195+
obj,
196+
&mut target_deps,
197+
DependencyType::TargetSelfContained,
198+
);
199+
}
198200
} else if target.contains("windows-gnu") {
199201
for obj in ["crt2.o", "dllcrt2.o"].iter() {
200202
let src = compiler_file(builder, builder.cc(target), target, obj);

0 commit comments

Comments
 (0)