Partial support for wasm32-unknown-wasi as host triple

This needs a rustc compiled for wasi (see rust-lang/miri#722)
It also needs CraneStation/target-lexicon#14
This commit is contained in:
bjorn3 2019-05-11 12:23:40 +02:00
parent e998997f98
commit 0046ce4c85
4 changed files with 157 additions and 142 deletions

17
Cargo.lock generated
View File

@ -139,7 +139,7 @@ dependencies = [
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.4.0",
]
[[package]]
@ -165,7 +165,7 @@ dependencies = [
"faerie 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"goblin 0.0.21 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.4.0",
]
[[package]]
@ -175,7 +175,7 @@ source = "git+https://github.com/CraneStation/cranelift.git#a1d8fbc8dda7984edcf3
dependencies = [
"cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/cranelift.git)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.4.0",
]
[[package]]
@ -196,7 +196,7 @@ source = "git+https://github.com/CraneStation/cranelift.git#a1d8fbc8dda7984edcf3
dependencies = [
"cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/cranelift.git)",
"raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.4.0",
]
[[package]]
@ -210,7 +210,7 @@ dependencies = [
"errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"region 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.4.0",
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -259,7 +259,7 @@ dependencies = [
"string-interner 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt-derive 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.4.0",
]
[[package]]
@ -594,12 +594,11 @@ dependencies = [
"cranelift-faerie 0.30.0 (git+https://github.com/CraneStation/cranelift.git)",
"cranelift-module 0.30.0 (git+https://github.com/CraneStation/cranelift.git)",
"cranelift-simplejit 0.30.0 (git+https://github.com/CraneStation/cranelift.git)",
"env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"faerie 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gimli 0.18.0 (git+https://github.com/gimli-rs/gimli.git)",
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.4.0",
"tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -725,7 +724,6 @@ dependencies = [
[[package]]
name = "target-lexicon"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -931,7 +929,6 @@ dependencies = [
"checksum structopt-derive 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "528aeb7351d042e6ffbc2a6fb76a86f9b622fdf7c25932798e7a82cb03bc94c6"
"checksum syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)" = "a1393e4a97a19c01e900df2aec855a29f71cf02c402e2f443b8d2747c25c5dbe"
"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
"checksum target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1b0ab4982b8945c35cc1c46a83a9094c414f6828a099ce5dcaa8ee2b04642dcb"
"checksum tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b86c784c88d98c801132806dadd3819ed29d8600836c4088e855cdf3e178ed8a"
"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f"
"checksum termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dde0593aeb8d47accea5392b39350015b5eccb12c0d98044d856983d89548dea"

View File

@ -7,13 +7,12 @@ authors = ["bjorn3 <bjorn3@users.noreply.github.com>"]
edition = "2018"
[lib]
crate-type = ["dylib"]
crate-type = ["rlib", "dylib"]
[dependencies]
# These have to be in sync with each other
cranelift = { git = "https://github.com/CraneStation/cranelift.git" }
cranelift-module = { git = "https://github.com/CraneStation/cranelift.git" }
cranelift-simplejit = { git = "https://github.com/CraneStation/cranelift.git" }
cranelift-faerie = { git = "https://github.com/CraneStation/cranelift.git" }
target-lexicon = "0.4.0"
faerie = "0.10.0"
@ -24,7 +23,6 @@ bitflags = "1.0.3"
byteorder = "1.2.7"
libc = "0.2.53"
tempfile = "3.0.7"
env_logger = "0.6"
gimli = { git = "https://github.com/gimli-rs/gimli.git" }
indexmap = "1.0.2"
@ -38,5 +36,8 @@ indexmap = "1.0.2"
#[patch."https://github.com/gimli-rs/gimli.git"]
#gimli = { path = "../" }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
cranelift-simplejit = { git = "https://github.com/CraneStation/cranelift.git" }
[profile.dev.overrides."*"]
opt-level = 3

View File

@ -17,9 +17,8 @@ use crate::prelude::*;
pub fn codegen_crate<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
metadata: EncodedMetadata,
_need_metadata_module: bool,
need_metadata_module: bool,
) -> Box<dyn Any> {
env_logger::init();
if !tcx.sess.crate_types.get().contains(&CrateType::Executable)
&& std::env::var("SHOULD_RUN").is_ok()
{
@ -36,148 +35,168 @@ pub fn codegen_crate<'a, 'tcx>(
};
if std::env::var("SHOULD_RUN").is_ok() {
let mut jit_module: Module<SimpleJITBackend> =
Module::new(SimpleJITBuilder::new(cranelift_module::default_libcall_names()));
assert_eq!(pointer_ty(tcx), jit_module.target_config().pointer_type());
#[cfg(not(target_arch = "wasm32"))]
let _: ! = run_jit(tcx, &mut log);
let sig = Signature {
params: vec![
AbiParam::new(jit_module.target_config().pointer_type()),
AbiParam::new(jit_module.target_config().pointer_type()),
],
returns: vec![AbiParam::new(
jit_module.target_config().pointer_type(), /*isize*/
)],
call_conv: CallConv::SystemV,
};
let main_func_id = jit_module
.declare_function("main", Linkage::Import, &sig)
.unwrap();
#[cfg(target_arch = "wasm32")]
panic!("jit not supported on wasm");
}
codegen_cgus(tcx, &mut jit_module, &mut None, &mut log);
crate::allocator::codegen(tcx.sess, &mut jit_module);
jit_module.finalize_definitions();
run_aot(tcx, metadata, need_metadata_module, &mut log)
}
tcx.sess.abort_if_errors();
#[cfg(not(target_arch = "wasm32"))]
fn run_jit<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, log: &mut Option<File>) -> ! {
use cranelift_simplejit::{SimpleJITBackend, SimpleJITBuilder};
let finalized_main: *const u8 = jit_module.get_finalized_function(main_func_id);
let mut jit_module: Module<SimpleJITBackend> =
Module::new(SimpleJITBuilder::new(cranelift_module::default_libcall_names()));
assert_eq!(pointer_ty(tcx), jit_module.target_config().pointer_type());
println!("Rustc codegen cranelift will JIT run the executable, because the SHOULD_RUN env var is set");
let sig = Signature {
params: vec![
AbiParam::new(jit_module.target_config().pointer_type()),
AbiParam::new(jit_module.target_config().pointer_type()),
],
returns: vec![AbiParam::new(
jit_module.target_config().pointer_type(), /*isize*/
)],
call_conv: CallConv::SystemV,
};
let main_func_id = jit_module
.declare_function("main", Linkage::Import, &sig)
.unwrap();
let f: extern "C" fn(c_int, *const *const c_char) -> c_int =
unsafe { ::std::mem::transmute(finalized_main) };
codegen_cgus(tcx, &mut jit_module, &mut None, log);
crate::allocator::codegen(tcx.sess, &mut jit_module);
jit_module.finalize_definitions();
let args = ::std::env::var("JIT_ARGS").unwrap_or_else(|_| String::new());
let args = args
.split(" ")
.chain(Some(&*tcx.crate_name(LOCAL_CRATE).as_str().to_string()))
.map(|arg| CString::new(arg).unwrap())
.collect::<Vec<_>>();
let argv = args.iter().map(|arg| arg.as_ptr()).collect::<Vec<_>>();
// TODO: Rust doesn't care, but POSIX argv has a NULL sentinel at the end
tcx.sess.abort_if_errors();
let ret = f(args.len() as c_int, argv.as_ptr());
let finalized_main: *const u8 = jit_module.get_finalized_function(main_func_id);
jit_module.finish();
std::process::exit(ret);
println!("Rustc codegen cranelift will JIT run the executable, because the SHOULD_RUN env var is set");
let f: extern "C" fn(c_int, *const *const c_char) -> c_int =
unsafe { ::std::mem::transmute(finalized_main) };
let args = ::std::env::var("JIT_ARGS").unwrap_or_else(|_| String::new());
let args = args
.split(" ")
.chain(Some(&*tcx.crate_name(LOCAL_CRATE).as_str().to_string()))
.map(|arg| CString::new(arg).unwrap())
.collect::<Vec<_>>();
let argv = args.iter().map(|arg| arg.as_ptr()).collect::<Vec<_>>();
// TODO: Rust doesn't care, but POSIX argv has a NULL sentinel at the end
let ret = f(args.len() as c_int, argv.as_ptr());
jit_module.finish();
std::process::exit(ret);
}
fn run_aot<'a, 'tcx: 'a>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
metadata: EncodedMetadata,
_need_metadata_module: bool,
log: &mut Option<File>,
) -> Box<CodegenResults> {
let new_module = |name: String| {
let module: Module<FaerieBackend> = Module::new(
FaerieBuilder::new(
crate::build_isa(tcx.sess),
name + ".o",
FaerieTrapCollection::Disabled,
cranelift_module::default_libcall_names(),
)
.unwrap(),
);
assert_eq!(pointer_ty(tcx), module.target_config().pointer_type());
module
};
let emit_module = |name: &str,
kind: ModuleKind,
mut module: Module<FaerieBackend>,
debug: Option<DebugContext>| {
module.finalize_definitions();
let mut artifact = module.finish().artifact;
if let Some(mut debug) = debug {
debug.emit(&mut artifact);
}
let tmp_file = tcx
.output_filenames(LOCAL_CRATE)
.temp_path(OutputType::Object, Some(name));
let obj = artifact.emit().unwrap();
std::fs::write(&tmp_file, obj).unwrap();
CompiledModule {
name: name.to_string(),
kind,
object: Some(tmp_file),
bytecode: None,
bytecode_compressed: None,
}
};
let mut faerie_module = new_module("some_file".to_string());
let mut debug = if tcx.sess.opts.debuginfo != DebugInfo::None
// macOS debuginfo doesn't work yet (see #303)
&& !tcx.sess.target.target.options.is_like_osx
{
let debug = DebugContext::new(
tcx,
faerie_module.target_config().pointer_type().bytes() as u8,
);
Some(debug)
} else {
let new_module = |name: String| {
let module: Module<FaerieBackend> = Module::new(
FaerieBuilder::new(
crate::build_isa(tcx.sess),
name + ".o",
FaerieTrapCollection::Disabled,
cranelift_module::default_libcall_names(),
)
.unwrap(),
);
assert_eq!(pointer_ty(tcx), module.target_config().pointer_type());
module
};
None
};
let emit_module = |name: &str,
kind: ModuleKind,
mut module: Module<FaerieBackend>,
debug: Option<DebugContext>| {
module.finalize_definitions();
let mut artifact = module.finish().artifact;
codegen_cgus(tcx, &mut faerie_module, &mut debug, log);
if let Some(mut debug) = debug {
debug.emit(&mut artifact);
}
tcx.sess.abort_if_errors();
let tmp_file = tcx
.output_filenames(LOCAL_CRATE)
.temp_path(OutputType::Object, Some(name));
let obj = artifact.emit().unwrap();
std::fs::write(&tmp_file, obj).unwrap();
CompiledModule {
name: name.to_string(),
kind,
object: Some(tmp_file),
bytecode: None,
bytecode_compressed: None,
}
};
let mut allocator_module = new_module("allocator_shim.o".to_string());
let created_alloc_shim = crate::allocator::codegen(tcx.sess, &mut allocator_module);
let mut faerie_module = new_module("some_file".to_string());
rustc_incremental::assert_dep_graph(tcx);
rustc_incremental::save_dep_graph(tcx);
rustc_incremental::finalize_session_directory(tcx.sess, tcx.crate_hash(LOCAL_CRATE));
let mut debug = if tcx.sess.opts.debuginfo != DebugInfo::None
// macOS debuginfo doesn't work yet (see #303)
&& !tcx.sess.target.target.options.is_like_osx
{
let debug = DebugContext::new(
tcx,
faerie_module.target_config().pointer_type().bytes() as u8,
);
Some(debug)
Box::new(CodegenResults {
crate_name: tcx.crate_name(LOCAL_CRATE),
modules: vec![emit_module(
"dummy_name",
ModuleKind::Regular,
faerie_module,
debug,
)],
allocator_module: if created_alloc_shim {
Some(emit_module(
"allocator_shim",
ModuleKind::Allocator,
allocator_module,
None,
))
} else {
None
};
codegen_cgus(tcx, &mut faerie_module, &mut debug, &mut log);
tcx.sess.abort_if_errors();
let mut allocator_module = new_module("allocator_shim.o".to_string());
let created_alloc_shim = crate::allocator::codegen(tcx.sess, &mut allocator_module);
rustc_incremental::assert_dep_graph(tcx);
rustc_incremental::save_dep_graph(tcx);
rustc_incremental::finalize_session_directory(tcx.sess, tcx.crate_hash(LOCAL_CRATE));
Box::new(CodegenResults {
crate_name: tcx.crate_name(LOCAL_CRATE),
modules: vec![emit_module(
"dummy_name",
ModuleKind::Regular,
faerie_module,
debug,
)],
allocator_module: if created_alloc_shim {
Some(emit_module(
"allocator_shim",
ModuleKind::Allocator,
allocator_module,
None,
))
} else {
None
},
metadata_module: Some(CompiledModule {
name: "dummy_metadata".to_string(),
kind: ModuleKind::Metadata,
object: None,
bytecode: None,
bytecode_compressed: None,
}),
crate_hash: tcx.crate_hash(LOCAL_CRATE),
metadata,
windows_subsystem: None, // Windows is not yet supported
linker_info: LinkerInfo::new(tcx),
crate_info: CrateInfo::new(tcx),
})
}
},
metadata_module: Some(CompiledModule {
name: "dummy_metadata".to_string(),
kind: ModuleKind::Metadata,
object: None,
bytecode: None,
bytecode_compressed: None,
}),
crate_hash: tcx.crate_hash(LOCAL_CRATE),
metadata,
windows_subsystem: None, // Windows is not yet supported
linker_info: LinkerInfo::new(tcx),
crate_info: CrateInfo::new(tcx),
})
}
fn codegen_cgus<'a, 'tcx: 'a>(

View File

@ -1,7 +1,6 @@
#![feature(rustc_private, never_type, decl_macro)]
#![allow(intra_doc_link_resolution_failure)]
extern crate log;
extern crate rustc;
extern crate rustc_allocator;
extern crate rustc_codegen_ssa;
@ -87,7 +86,6 @@ mod prelude {
pub use cranelift_module::{
self, Backend, DataContext, DataId, FuncId, FuncOrDataId, Linkage, Module,
};
pub use cranelift_simplejit::{SimpleJITBackend, SimpleJITBuilder};
pub use crate::abi::*;
pub use crate::base::{trans_operand, trans_place};