Skip to content

Commit 295aca5

Browse files
committed
[WIP] Support compiling rustc to WebAssembly
1 parent 05ccc49 commit 295aca5

File tree

22 files changed

+325
-21
lines changed

22 files changed

+325
-21
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,8 @@ package.json
7979
tests/rustdoc-gui/src/**.lock
8080

8181
# Before adding new lines, see the comment at the top.
82+
83+
/wasi-sdk-*
84+
/wabt-*
85+
/tmp
86+
/rust_out

Cargo.lock

Lines changed: 191 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,12 @@ dependencies = [
217217
"object 0.32.2",
218218
]
219219

220+
[[package]]
221+
name = "arbitrary"
222+
version = "1.3.2"
223+
source = "registry+https://github.com/rust-lang/crates.io-index"
224+
checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110"
225+
220226
[[package]]
221227
name = "arrayvec"
222228
version = "0.7.4"
@@ -834,6 +840,121 @@ dependencies = [
834840
"libc",
835841
]
836842

843+
[[package]]
844+
name = "cranelift-bforest"
845+
version = "0.106.1"
846+
source = "registry+https://github.com/rust-lang/crates.io-index"
847+
checksum = "5b3775cc6cc00c90d29eebea55feedb2b0168e23f5415bab7859c4004d7323d1"
848+
dependencies = [
849+
"cranelift-entity",
850+
]
851+
852+
[[package]]
853+
name = "cranelift-codegen"
854+
version = "0.106.1"
855+
source = "registry+https://github.com/rust-lang/crates.io-index"
856+
checksum = "637f3184ba5bfa48d425bad1d2e4faf5fcf619f5e0ca107edc6dc02f589d4d74"
857+
dependencies = [
858+
"bumpalo",
859+
"cranelift-bforest",
860+
"cranelift-codegen-meta",
861+
"cranelift-codegen-shared",
862+
"cranelift-control",
863+
"cranelift-entity",
864+
"cranelift-isle",
865+
"gimli",
866+
"hashbrown 0.14.3",
867+
"log",
868+
"regalloc2",
869+
"smallvec",
870+
"target-lexicon",
871+
]
872+
873+
[[package]]
874+
name = "cranelift-codegen-meta"
875+
version = "0.106.1"
876+
source = "registry+https://github.com/rust-lang/crates.io-index"
877+
checksum = "e4b35b8240462341d94d31aab807cad704683988708261aecae3d57db48b7212"
878+
dependencies = [
879+
"cranelift-codegen-shared",
880+
]
881+
882+
[[package]]
883+
name = "cranelift-codegen-shared"
884+
version = "0.106.1"
885+
source = "registry+https://github.com/rust-lang/crates.io-index"
886+
checksum = "8f3cd1555aa9df1d6d8375732de41b4cb0d787006948d55b6d004d521e9efeb0"
887+
888+
[[package]]
889+
name = "cranelift-control"
890+
version = "0.106.1"
891+
source = "registry+https://github.com/rust-lang/crates.io-index"
892+
checksum = "14b31a562a10e98ab148fa146801e20665c5f9eda4fce9b2c5a3836575887d74"
893+
dependencies = [
894+
"arbitrary",
895+
]
896+
897+
[[package]]
898+
name = "cranelift-entity"
899+
version = "0.106.1"
900+
source = "registry+https://github.com/rust-lang/crates.io-index"
901+
checksum = "af1e0467700a3f4fccf5feddbaebdf8b0eb82535b06a9600c4bc5df40872e75d"
902+
903+
[[package]]
904+
name = "cranelift-frontend"
905+
version = "0.106.1"
906+
source = "registry+https://github.com/rust-lang/crates.io-index"
907+
checksum = "6cb918ee2c23939262efd1b99d76a21212ac7bd35129582133e21a22a6ff0467"
908+
dependencies = [
909+
"cranelift-codegen",
910+
"log",
911+
"smallvec",
912+
"target-lexicon",
913+
]
914+
915+
[[package]]
916+
name = "cranelift-isle"
917+
version = "0.106.1"
918+
source = "registry+https://github.com/rust-lang/crates.io-index"
919+
checksum = "966e4cfb23cf6d7f1d285d53a912baaffc5f06bcd9c9b0a2d8c66a184fae534b"
920+
921+
[[package]]
922+
name = "cranelift-module"
923+
version = "0.106.1"
924+
source = "registry+https://github.com/rust-lang/crates.io-index"
925+
checksum = "cec3c5879608f8073782974e2c6dda461eb4038c754e1ab02904eb94a0ee0e9f"
926+
dependencies = [
927+
"anyhow",
928+
"cranelift-codegen",
929+
"cranelift-control",
930+
]
931+
932+
[[package]]
933+
name = "cranelift-native"
934+
version = "0.106.1"
935+
source = "registry+https://github.com/rust-lang/crates.io-index"
936+
checksum = "bea803aadfc4aabdfae7c3870f1b1f6dd4332f4091859e9758ef5fca6bf8cc87"
937+
dependencies = [
938+
"cranelift-codegen",
939+
"libc",
940+
"target-lexicon",
941+
]
942+
943+
[[package]]
944+
name = "cranelift-object"
945+
version = "0.106.1"
946+
source = "registry+https://github.com/rust-lang/crates.io-index"
947+
checksum = "db2734474e6b011263cf0ea0ca36378a29e8a9795f8a71b46b3fbb1f7657173c"
948+
dependencies = [
949+
"anyhow",
950+
"cranelift-codegen",
951+
"cranelift-control",
952+
"cranelift-module",
953+
"log",
954+
"object 0.32.2",
955+
"target-lexicon",
956+
]
957+
837958
[[package]]
838959
name = "crc32fast"
839960
version = "1.4.0"
@@ -1639,6 +1760,15 @@ dependencies = [
16391760
"thiserror",
16401761
]
16411762

1763+
[[package]]
1764+
name = "hashbrown"
1765+
version = "0.13.2"
1766+
source = "registry+https://github.com/rust-lang/crates.io-index"
1767+
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
1768+
dependencies = [
1769+
"ahash",
1770+
]
1771+
16421772
[[package]]
16431773
name = "hashbrown"
16441774
version = "0.14.3"
@@ -1976,7 +2106,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
19762106
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
19772107
dependencies = [
19782108
"equivalent",
1979-
"hashbrown",
2109+
"hashbrown 0.14.3",
19802110
"rustc-rayon",
19812111
"serde",
19822112
]
@@ -2638,7 +2768,7 @@ dependencies = [
26382768
"compiler_builtins",
26392769
"crc32fast",
26402770
"flate2",
2641-
"hashbrown",
2771+
"hashbrown 0.14.3",
26422772
"indexmap",
26432773
"memchr",
26442774
"rustc-std-workspace-alloc",
@@ -3215,6 +3345,19 @@ dependencies = [
32153345
"thiserror",
32163346
]
32173347

3348+
[[package]]
3349+
name = "regalloc2"
3350+
version = "0.9.3"
3351+
source = "registry+https://github.com/rust-lang/crates.io-index"
3352+
checksum = "ad156d539c879b7a24a363a2016d77961786e71f48f2e2fc8302a92abd2429a6"
3353+
dependencies = [
3354+
"hashbrown 0.13.2",
3355+
"log",
3356+
"rustc-hash",
3357+
"slice-group-by",
3358+
"smallvec",
3359+
]
3360+
32183361
[[package]]
32193362
name = "regex"
32203363
version = "1.8.4"
@@ -3646,6 +3789,37 @@ dependencies = [
36463789
"tracing",
36473790
]
36483791

3792+
[[package]]
3793+
name = "rustc_codegen_cranelift"
3794+
version = "0.1.0"
3795+
dependencies = [
3796+
"cranelift-codegen",
3797+
"cranelift-frontend",
3798+
"cranelift-module",
3799+
"cranelift-native",
3800+
"cranelift-object",
3801+
"gimli",
3802+
"indexmap",
3803+
"jobserver",
3804+
"object 0.32.2",
3805+
"rustc_ast",
3806+
"rustc_codegen_ssa",
3807+
"rustc_data_structures",
3808+
"rustc_errors",
3809+
"rustc_fs_util",
3810+
"rustc_hir",
3811+
"rustc_incremental",
3812+
"rustc_index",
3813+
"rustc_metadata",
3814+
"rustc_middle",
3815+
"rustc_monomorphize",
3816+
"rustc_session",
3817+
"rustc_span",
3818+
"rustc_target",
3819+
"smallvec",
3820+
"target-lexicon",
3821+
]
3822+
36493823
[[package]]
36503824
name = "rustc_codegen_llvm"
36513825
version = "0.0.0"
@@ -4108,6 +4282,7 @@ dependencies = [
41084282
"rustc_attr",
41094283
"rustc_borrowck",
41104284
"rustc_builtin_macros",
4285+
"rustc_codegen_cranelift",
41114286
"rustc_codegen_llvm",
41124287
"rustc_codegen_ssa",
41134288
"rustc_const_eval",
@@ -5140,6 +5315,12 @@ dependencies = [
51405315
"autocfg",
51415316
]
51425317

5318+
[[package]]
5319+
name = "slice-group-by"
5320+
version = "0.3.1"
5321+
source = "registry+https://github.com/rust-lang/crates.io-index"
5322+
checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7"
5323+
51435324
[[package]]
51445325
name = "smallvec"
51455326
version = "1.13.2"
@@ -5245,7 +5426,7 @@ dependencies = [
52455426
"core",
52465427
"dlmalloc",
52475428
"fortanix-sgx-abi",
5248-
"hashbrown",
5429+
"hashbrown 0.14.3",
52495430
"hermit-abi",
52505431
"libc",
52515432
"miniz_oxide",
@@ -5444,6 +5625,12 @@ dependencies = [
54445625
"xattr",
54455626
]
54465627

5628+
[[package]]
5629+
name = "target-lexicon"
5630+
version = "0.12.14"
5631+
source = "registry+https://github.com/rust-lang/crates.io-index"
5632+
checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f"
5633+
54475634
[[package]]
54485635
name = "tempfile"
54495636
version = "3.10.1"
@@ -5552,7 +5739,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
55525739
checksum = "4db52ee8fec06e119b692ef3dd2c4cf621a99204c1b8c47407870ed050305b9b"
55535740
dependencies = [
55545741
"gimli",
5555-
"hashbrown",
5742+
"hashbrown 0.14.3",
55565743
"object 0.32.2",
55575744
"tracing",
55585745
]

comment.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Got a new version up. This time all logic to handle using different codegen backends for the different stages, so you don't need to do a multi stage process.
2+
3+
* Make sure you are running on Linux.
4+
* Clone https://github.com/bjorn3/rust
5+
* Checkout the `compile_rustc_for_wasm10` branch
6+
* Download and extract https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-linux.tar.gz into the rust checkout.
7+
* Run `./x.py install` to build the compiler and install it into the dist dir.
8+
* Use `wasmtime run --dir tmp::/ --dir dist dist/bin/rustc.wasm --sysroot dist --target x86_64-unknown-linux-gnu` to run rustc.
9+
10+
Note that linking is not supported as wasi doesn't allow spawning executables. You can use something like the following to compile using the wasm32-wasi rustc and then link using native gcc:
11+
12+
```
13+
$ mkdir tmp
14+
$ echo 'fn main() { println!("Hello World!"); }' | wasmtime run -Sthreads=y -Spreview2=n --dir tmp::/ --dir dist --env RUST_MIN_STACK=16777216 dist/bin/rustc.wasm - --sysroot dist --target x86_64-unknown-linux-gnu -Csave-temps
15+
$ gcc -fuse-ld=lld tmp/rmeta*/lib.rmeta tmp/rust_out.* dist/lib/rustlib/x86_64-unknown-linux-gnu/lib/lib*.rlib -o rust_out
16+
$ ./rust_out
17+
Hello World!
18+
```

compiler/rustc/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ features = ['unprefixed_malloc_on_supported_platforms']
2828
[features]
2929
# tidy-alphabetical-start
3030
jemalloc = ['jemalloc-sys']
31+
cranelift = ['rustc_driver_impl/cranelift']
3132
llvm = ['rustc_driver_impl/llvm']
3233
max_level_info = ['rustc_driver_impl/max_level_info']
3334
rustc_use_parallel_compiler = ['rustc_driver_impl/rustc_use_parallel_compiler']

compiler/rustc_codegen_cranelift/Cargo.toml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ version = "0.1.0"
44
edition = "2021"
55

66
[lib]
7-
crate-type = ["dylib"]
7+
crate-type = ["lib", "dylib"]
88

99
[dependencies]
1010
# These have to be in sync with each other
@@ -22,6 +22,22 @@ indexmap = "2.0.0"
2222
libloading = { version = "0.8.0", optional = true }
2323
smallvec = "1.8.1"
2424

25+
jobserver = "0.1.22"
26+
rustc_middle = { path = "../rustc_middle" }
27+
rustc_ast = { path = "../rustc_ast" }
28+
rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
29+
rustc_data_structures = { path = "../rustc_data_structures" }
30+
rustc_errors = { path = "../rustc_errors" }
31+
rustc_fs_util = { path = "../rustc_fs_util" }
32+
rustc_hir = { path = "../rustc_hir" }
33+
rustc_incremental = { path = "../rustc_incremental" }
34+
rustc_index = { path = "../rustc_index" }
35+
rustc_metadata = { path = "../rustc_metadata" }
36+
rustc_monomorphize = { path = "../rustc_monomorphize" }
37+
rustc_session = { path = "../rustc_session" }
38+
rustc_span = { path = "../rustc_span" }
39+
rustc_target = { path = "../rustc_target" }
40+
2541
[patch.crates-io]
2642
# Uncomment to use local checkout of cranelift
2743
#cranelift-codegen = { path = "../wasmtime/cranelift/codegen" }

compiler/rustc_codegen_cranelift/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ extern crate rustc_span;
2727
extern crate rustc_target;
2828

2929
// This prevents duplicating functions and statics that are already part of the host rustc process.
30-
#[allow(unused_extern_crates)]
31-
extern crate rustc_driver;
30+
//#[allow(unused_extern_crates)]
31+
//extern crate rustc_driver;
3232

3333
use std::any::Any;
3434
use std::cell::{Cell, RefCell};
@@ -350,7 +350,7 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Arc<dyn isa::Tar
350350
}
351351

352352
/// This is the entrypoint for a hot plugged rustc_codegen_cranelift
353-
#[no_mangle]
353+
//#[no_mangle]
354354
pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
355355
Box::new(CraneliftCodegenBackend { config: RefCell::new(None) })
356356
}

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,17 @@ pub fn link_binary<'a>(
104104
});
105105

106106
if outputs.outputs.should_link() {
107-
let tmpdir = TempFileBuilder::new()
108-
.prefix("rustc")
109-
.tempdir()
110-
.unwrap_or_else(|error| sess.dcx().emit_fatal(errors::CreateTempDir { error }));
107+
let tmpdir = if cfg!(target_family = "wasm") {
108+
TempFileBuilder::new()
109+
.prefix("rustc")
110+
.tempdir_in(std::env::current_dir().unwrap())
111+
.unwrap_or_else(|error| sess.dcx().emit_fatal(errors::CreateTempDir { error }))
112+
} else {
113+
TempFileBuilder::new()
114+
.prefix("rustc")
115+
.tempdir()
116+
.unwrap_or_else(|error| sess.dcx().emit_fatal(errors::CreateTempDir { error }))
117+
};
111118
let path = MaybeTempDir::new(tmpdir, sess.opts.cg.save_temps);
112119
let output = out_filename(
113120
sess,

compiler/rustc_codegen_ssa/src/back/linker.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,9 @@ pub fn get_linker<'a>(
126126
new_path.extend(env::split_paths(&path));
127127
}
128128
}
129-
cmd.env("PATH", env::join_paths(new_path).unwrap());
129+
if cfg!(not(target_family = "wasm")) {
130+
cmd.env("PATH", env::join_paths(new_path).unwrap());
131+
}
130132

131133
// FIXME: Move `/LIBPATH` addition for uwp targets from the linker construction
132134
// to the linker args construction.

0 commit comments

Comments
 (0)