From e8d788c60730b37c8a8825aa971c6027204485e1 Mon Sep 17 00:00:00 2001 From: Jasper Bekkers Date: Fri, 24 Jul 2020 11:37:14 +0100 Subject: [PATCH] TheBackend in a cargo project to play around with --- .gitignore | 2 + Cargo.toml | 12 +++++ build_codegen.bat | 1 + libempty.rlib | 1 + run.bat | 1 + setup.bat | 1 + src/lib.rs | 117 ++++++++++++++++++++++++++++++++++++++++++++++ tests/empty.rs | 2 + 8 files changed, 137 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 build_codegen.bat create mode 100644 libempty.rlib create mode 100644 run.bat create mode 100644 setup.bat create mode 100644 src/lib.rs create mode 100644 tests/empty.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..96ef6c0b94 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000000..826bb45b4d --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "rustc_codegen_spirv" +version = "0.1.0" +authors = ["Jasper Bekkers "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["dylib"] + +[dependencies] diff --git a/build_codegen.bat b/build_codegen.bat new file mode 100644 index 0000000000..d7a5d49df3 --- /dev/null +++ b/build_codegen.bat @@ -0,0 +1 @@ +cargo +nightly build \ No newline at end of file diff --git a/libempty.rlib b/libempty.rlib new file mode 100644 index 0000000000..81d368bb85 --- /dev/null +++ b/libempty.rlib @@ -0,0 +1 @@ +This has been "compiled" successfully. \ No newline at end of file diff --git a/run.bat b/run.bat new file mode 100644 index 0000000000..982b8d1447 --- /dev/null +++ b/run.bat @@ -0,0 +1 @@ +rustc +nightly -Zcodegen-backend=target\debug\rustc_codegen_spirv.dll --crate-type lib tests\empty.rs \ No newline at end of file diff --git a/setup.bat b/setup.bat new file mode 100644 index 0000000000..8e0e9adbb0 --- /dev/null +++ b/setup.bat @@ -0,0 +1 @@ +rustup +nightly component add rust-src rustc-dev llvm-tools-preview \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000000..d2fcf5fda0 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,117 @@ +#![feature(rustc_private)] + +extern crate rustc_codegen_ssa; +extern crate rustc_errors; +extern crate rustc_middle; +#[macro_use] +extern crate rustc_data_structures; +extern crate rustc_driver; +extern crate rustc_hir; +extern crate rustc_session; +extern crate rustc_span; +extern crate rustc_symbol_mangling; +extern crate rustc_target; + +use rustc_codegen_ssa::traits::CodegenBackend; +use rustc_data_structures::owning_ref::OwningRef; +use rustc_data_structures::sync::MetadataRef; +use rustc_errors::ErrorReported; +use rustc_middle::dep_graph::DepGraph; +use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoader, MetadataLoaderDyn}; +use rustc_middle::ty::query::Providers; +use rustc_middle::ty::TyCtxt; +use rustc_session::config::OutputFilenames; +use rustc_session::Session; +use rustc_span::symbol::Symbol; +use rustc_target::spec::Target; +use std::any::Any; +use std::path::Path; + +pub struct NoLlvmMetadataLoader; + +impl MetadataLoader for NoLlvmMetadataLoader { + fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result { + let buf = + std::fs::read(filename).map_err(|e| format!("metadata file open err: {:?}", e))?; + let buf: OwningRef, [u8]> = OwningRef::new(buf); + Ok(rustc_erase_owner!(buf.map_owner_box())) + } + + fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result { + self.get_rlib_metadata(target, filename) + } +} + +struct TheBackend; + +impl CodegenBackend for TheBackend { + fn metadata_loader(&self) -> Box { + Box::new(NoLlvmMetadataLoader) + } + + fn provide(&self, providers: &mut Providers) { + rustc_symbol_mangling::provide(providers); + + // providers.supported_target_features = |tcx, _cnum| { + // Default::default() // Just a dummy + // }; + providers.is_reachable_non_generic = |_tcx, _defid| true; + providers.exported_symbols = |_tcx, _crate| &[]; + } + + fn provide_extern(&self, providers: &mut Providers) { + providers.is_reachable_non_generic = |_tcx, _defid| true; + } + + fn codegen_crate<'a, 'tcx>( + &self, + tcx: TyCtxt<'tcx>, + _metadata: EncodedMetadata, + _need_metadata_module: bool, + ) -> Box { + use rustc_hir::def_id::LOCAL_CRATE; + + println!("In codegen_crate"); + + Box::new(tcx.crate_name(LOCAL_CRATE) as Symbol) + } + + fn join_codegen( + &self, + ongoing_codegen: Box, + _sess: &Session, + _dep_graph: &DepGraph, + ) -> Result, ErrorReported> { + let crate_name = ongoing_codegen + .downcast::() + .expect("in join_codegen: ongoing_codegen is not a Symbol"); + Ok(crate_name) + } + + fn link( + &self, + sess: &Session, + codegen_results: Box, + outputs: &OutputFilenames, + ) -> Result<(), ErrorReported> { + use rustc_session::{config::CrateType, output::out_filename}; + use std::io::Write; + let crate_name = + codegen_results.downcast::().expect("in link: codegen_results is not a Symbol"); + for &crate_type in sess.opts.crate_types.iter() { + if crate_type != CrateType::Rlib { + sess.fatal(&format!("Crate type is {:?}", crate_type)); + } + let output_name = out_filename(sess, crate_type, &outputs, &*crate_name.as_str()); + let mut out_file = ::std::fs::File::create(output_name).unwrap(); + write!(out_file, "This has been \"compiled\" successfully.").unwrap(); + } + Ok(()) + } +} + +/// This is the entrypoint for a hot plugged rustc_codegen_llvm +#[no_mangle] +pub fn __rustc_codegen_backend() -> Box { + Box::new(TheBackend) +} \ No newline at end of file diff --git a/tests/empty.rs b/tests/empty.rs new file mode 100644 index 0000000000..da27b7f346 --- /dev/null +++ b/tests/empty.rs @@ -0,0 +1,2 @@ +#![feature(no_core)] +#![no_core]