From 0046ce4c85d7db52923578a0d907597aa26b61e4 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 11 May 2019 12:23:40 +0200 Subject: [PATCH] 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 --- Cargo.lock | 17 ++- Cargo.toml | 7 +- src/driver.rs | 301 +++++++++++++++++++++++++++----------------------- src/lib.rs | 2 - 4 files changed, 171 insertions(+), 156 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 55a1051eb..d718a6f41 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml index c823278cb..2900dd852 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,13 +7,12 @@ authors = ["bjorn3 "] 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 diff --git a/src/driver.rs b/src/driver.rs index 6ec558705..6c66ee0f8 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -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 { - 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 = - Module::new(SimpleJITBuilder::new(cranelift_module::default_libcall_names())); - assert_eq!(pointer_ty(tcx), jit_module.target_config().pointer_type()); - - 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(); - - codegen_cgus(tcx, &mut jit_module, &mut None, &mut log); - crate::allocator::codegen(tcx.sess, &mut jit_module); - jit_module.finalize_definitions(); - - tcx.sess.abort_if_errors(); - - let finalized_main: *const u8 = jit_module.get_finalized_function(main_func_id); - - 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::>(); - let argv = args.iter().map(|arg| arg.as_ptr()).collect::>(); - // 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); + #[cfg(not(target_arch = "wasm32"))] + let _: ! = run_jit(tcx, &mut log); + + #[cfg(target_arch = "wasm32")] + panic!("jit not supported on wasm"); + } + + run_aot(tcx, metadata, need_metadata_module, &mut log) +} + +#[cfg(not(target_arch = "wasm32"))] +fn run_jit<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, log: &mut Option) -> ! { + use cranelift_simplejit::{SimpleJITBackend, SimpleJITBuilder}; + + let mut jit_module: Module = + Module::new(SimpleJITBuilder::new(cranelift_module::default_libcall_names())); + assert_eq!(pointer_ty(tcx), jit_module.target_config().pointer_type()); + + 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(); + + codegen_cgus(tcx, &mut jit_module, &mut None, log); + crate::allocator::codegen(tcx.sess, &mut jit_module); + jit_module.finalize_definitions(); + + tcx.sess.abort_if_errors(); + + let finalized_main: *const u8 = jit_module.get_finalized_function(main_func_id); + + 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::>(); + let argv = args.iter().map(|arg| arg.as_ptr()).collect::>(); + // 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, +) -> Box { + let new_module = |name: String| { + let module: Module = 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, + debug: Option| { + 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 = 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, - debug: Option| { - 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) + None + }; + + codegen_cgus(tcx, &mut faerie_module, &mut debug, 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 - }; - - 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>( diff --git a/src/lib.rs b/src/lib.rs index bfadb90ae..1389a127c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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};