Skip to content

Commit

Permalink
[WIP] Support compiling rustc to WebAssembly
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorn3 committed Apr 11, 2024
1 parent 05ccc49 commit 295aca5
Show file tree
Hide file tree
Showing 22 changed files with 325 additions and 21 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,8 @@ package.json
tests/rustdoc-gui/src/**.lock

# Before adding new lines, see the comment at the top.

/wasi-sdk-*
/wabt-*
/tmp
/rust_out
195 changes: 191 additions & 4 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,12 @@ dependencies = [
"object 0.32.2",
]

[[package]]
name = "arbitrary"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110"

[[package]]
name = "arrayvec"
version = "0.7.4"
Expand Down Expand Up @@ -834,6 +840,121 @@ dependencies = [
"libc",
]

[[package]]
name = "cranelift-bforest"
version = "0.106.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b3775cc6cc00c90d29eebea55feedb2b0168e23f5415bab7859c4004d7323d1"
dependencies = [
"cranelift-entity",
]

[[package]]
name = "cranelift-codegen"
version = "0.106.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "637f3184ba5bfa48d425bad1d2e4faf5fcf619f5e0ca107edc6dc02f589d4d74"
dependencies = [
"bumpalo",
"cranelift-bforest",
"cranelift-codegen-meta",
"cranelift-codegen-shared",
"cranelift-control",
"cranelift-entity",
"cranelift-isle",
"gimli",
"hashbrown 0.14.3",
"log",
"regalloc2",
"smallvec",
"target-lexicon",
]

[[package]]
name = "cranelift-codegen-meta"
version = "0.106.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4b35b8240462341d94d31aab807cad704683988708261aecae3d57db48b7212"
dependencies = [
"cranelift-codegen-shared",
]

[[package]]
name = "cranelift-codegen-shared"
version = "0.106.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f3cd1555aa9df1d6d8375732de41b4cb0d787006948d55b6d004d521e9efeb0"

[[package]]
name = "cranelift-control"
version = "0.106.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14b31a562a10e98ab148fa146801e20665c5f9eda4fce9b2c5a3836575887d74"
dependencies = [
"arbitrary",
]

[[package]]
name = "cranelift-entity"
version = "0.106.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af1e0467700a3f4fccf5feddbaebdf8b0eb82535b06a9600c4bc5df40872e75d"

[[package]]
name = "cranelift-frontend"
version = "0.106.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6cb918ee2c23939262efd1b99d76a21212ac7bd35129582133e21a22a6ff0467"
dependencies = [
"cranelift-codegen",
"log",
"smallvec",
"target-lexicon",
]

[[package]]
name = "cranelift-isle"
version = "0.106.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "966e4cfb23cf6d7f1d285d53a912baaffc5f06bcd9c9b0a2d8c66a184fae534b"

[[package]]
name = "cranelift-module"
version = "0.106.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cec3c5879608f8073782974e2c6dda461eb4038c754e1ab02904eb94a0ee0e9f"
dependencies = [
"anyhow",
"cranelift-codegen",
"cranelift-control",
]

[[package]]
name = "cranelift-native"
version = "0.106.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bea803aadfc4aabdfae7c3870f1b1f6dd4332f4091859e9758ef5fca6bf8cc87"
dependencies = [
"cranelift-codegen",
"libc",
"target-lexicon",
]

[[package]]
name = "cranelift-object"
version = "0.106.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db2734474e6b011263cf0ea0ca36378a29e8a9795f8a71b46b3fbb1f7657173c"
dependencies = [
"anyhow",
"cranelift-codegen",
"cranelift-control",
"cranelift-module",
"log",
"object 0.32.2",
"target-lexicon",
]

[[package]]
name = "crc32fast"
version = "1.4.0"
Expand Down Expand Up @@ -1639,6 +1760,15 @@ dependencies = [
"thiserror",
]

[[package]]
name = "hashbrown"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
dependencies = [
"ahash",
]

[[package]]
name = "hashbrown"
version = "0.14.3"
Expand Down Expand Up @@ -1976,7 +2106,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
dependencies = [
"equivalent",
"hashbrown",
"hashbrown 0.14.3",
"rustc-rayon",
"serde",
]
Expand Down Expand Up @@ -2638,7 +2768,7 @@ dependencies = [
"compiler_builtins",
"crc32fast",
"flate2",
"hashbrown",
"hashbrown 0.14.3",
"indexmap",
"memchr",
"rustc-std-workspace-alloc",
Expand Down Expand Up @@ -3215,6 +3345,19 @@ dependencies = [
"thiserror",
]

[[package]]
name = "regalloc2"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad156d539c879b7a24a363a2016d77961786e71f48f2e2fc8302a92abd2429a6"
dependencies = [
"hashbrown 0.13.2",
"log",
"rustc-hash",
"slice-group-by",
"smallvec",
]

[[package]]
name = "regex"
version = "1.8.4"
Expand Down Expand Up @@ -3646,6 +3789,37 @@ dependencies = [
"tracing",
]

[[package]]
name = "rustc_codegen_cranelift"
version = "0.1.0"
dependencies = [
"cranelift-codegen",
"cranelift-frontend",
"cranelift-module",
"cranelift-native",
"cranelift-object",
"gimli",
"indexmap",
"jobserver",
"object 0.32.2",
"rustc_ast",
"rustc_codegen_ssa",
"rustc_data_structures",
"rustc_errors",
"rustc_fs_util",
"rustc_hir",
"rustc_incremental",
"rustc_index",
"rustc_metadata",
"rustc_middle",
"rustc_monomorphize",
"rustc_session",
"rustc_span",
"rustc_target",
"smallvec",
"target-lexicon",
]

[[package]]
name = "rustc_codegen_llvm"
version = "0.0.0"
Expand Down Expand Up @@ -4108,6 +4282,7 @@ dependencies = [
"rustc_attr",
"rustc_borrowck",
"rustc_builtin_macros",
"rustc_codegen_cranelift",
"rustc_codegen_llvm",
"rustc_codegen_ssa",
"rustc_const_eval",
Expand Down Expand Up @@ -5140,6 +5315,12 @@ dependencies = [
"autocfg",
]

[[package]]
name = "slice-group-by"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7"

[[package]]
name = "smallvec"
version = "1.13.2"
Expand Down Expand Up @@ -5245,7 +5426,7 @@ dependencies = [
"core",
"dlmalloc",
"fortanix-sgx-abi",
"hashbrown",
"hashbrown 0.14.3",
"hermit-abi",
"libc",
"miniz_oxide",
Expand Down Expand Up @@ -5444,6 +5625,12 @@ dependencies = [
"xattr",
]

[[package]]
name = "target-lexicon"
version = "0.12.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f"

[[package]]
name = "tempfile"
version = "3.10.1"
Expand Down Expand Up @@ -5552,7 +5739,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4db52ee8fec06e119b692ef3dd2c4cf621a99204c1b8c47407870ed050305b9b"
dependencies = [
"gimli",
"hashbrown",
"hashbrown 0.14.3",
"object 0.32.2",
"tracing",
]
Expand Down
18 changes: 18 additions & 0 deletions comment.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
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.

* Make sure you are running on Linux.
* Clone https://github.com/bjorn3/rust
* Checkout the `compile_rustc_for_wasm10` branch
* 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.
* Run `./x.py install` to build the compiler and install it into the dist dir.
* Use `wasmtime run --dir tmp::/ --dir dist dist/bin/rustc.wasm --sysroot dist --target x86_64-unknown-linux-gnu` to run rustc.

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:

```
$ mkdir tmp
$ 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
$ 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
$ ./rust_out
Hello World!
```
1 change: 1 addition & 0 deletions compiler/rustc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ features = ['unprefixed_malloc_on_supported_platforms']
[features]
# tidy-alphabetical-start
jemalloc = ['jemalloc-sys']
cranelift = ['rustc_driver_impl/cranelift']
llvm = ['rustc_driver_impl/llvm']
max_level_info = ['rustc_driver_impl/max_level_info']
rustc_use_parallel_compiler = ['rustc_driver_impl/rustc_use_parallel_compiler']
Expand Down
18 changes: 17 additions & 1 deletion compiler/rustc_codegen_cranelift/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["dylib"]
crate-type = ["lib", "dylib"]

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

jobserver = "0.1.22"
rustc_middle = { path = "../rustc_middle" }
rustc_ast = { path = "../rustc_ast" }
rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_fs_util = { path = "../rustc_fs_util" }
rustc_hir = { path = "../rustc_hir" }
rustc_incremental = { path = "../rustc_incremental" }
rustc_index = { path = "../rustc_index" }
rustc_metadata = { path = "../rustc_metadata" }
rustc_monomorphize = { path = "../rustc_monomorphize" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }

[patch.crates-io]
# Uncomment to use local checkout of cranelift
#cranelift-codegen = { path = "../wasmtime/cranelift/codegen" }
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_cranelift/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ extern crate rustc_span;
extern crate rustc_target;

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

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

/// This is the entrypoint for a hot plugged rustc_codegen_cranelift
#[no_mangle]
//#[no_mangle]
pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
Box::new(CraneliftCodegenBackend { config: RefCell::new(None) })
}
15 changes: 11 additions & 4 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,17 @@ pub fn link_binary<'a>(
});

if outputs.outputs.should_link() {
let tmpdir = TempFileBuilder::new()
.prefix("rustc")
.tempdir()
.unwrap_or_else(|error| sess.dcx().emit_fatal(errors::CreateTempDir { error }));
let tmpdir = if cfg!(target_family = "wasm") {
TempFileBuilder::new()
.prefix("rustc")
.tempdir_in(std::env::current_dir().unwrap())
.unwrap_or_else(|error| sess.dcx().emit_fatal(errors::CreateTempDir { error }))
} else {
TempFileBuilder::new()
.prefix("rustc")
.tempdir()
.unwrap_or_else(|error| sess.dcx().emit_fatal(errors::CreateTempDir { error }))
};
let path = MaybeTempDir::new(tmpdir, sess.opts.cg.save_temps);
let output = out_filename(
sess,
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_codegen_ssa/src/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@ pub fn get_linker<'a>(
new_path.extend(env::split_paths(&path));
}
}
cmd.env("PATH", env::join_paths(new_path).unwrap());
if cfg!(not(target_family = "wasm")) {
cmd.env("PATH", env::join_paths(new_path).unwrap());
}

// FIXME: Move `/LIBPATH` addition for uwp targets from the linker construction
// to the linker args construction.
Expand Down
Loading

0 comments on commit 295aca5

Please sign in to comment.