Skip to content

Commit ea468fd

Browse files
committed
Add support for object::write
1 parent 478da67 commit ea468fd

File tree

4 files changed

+107
-35
lines changed

4 files changed

+107
-35
lines changed

Cargo.toml

+4-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ edition = "2018"
99
[lib]
1010
crate-type = ["dylib"]
1111

12+
[features]
13+
backend_object = ["object/write"]
14+
1215
[dependencies]
1316
# These have to be in sync with each other
1417
cranelift = { git = "https://github.com/CraneStation/cranelift.git" }
@@ -29,7 +32,7 @@ libloading = "0.5.1"
2932
[dependencies.object]
3033
version = "0.14.0"
3134
default-features = false
32-
features = ["compression", "read", "std", "write"] # We don't need WASM support
35+
features = ["compression", "read", "std"] # We don't need WASM support
3336

3437
# Uncomment to use local checkout of cranelift
3538
#[patch."https://github.com/CraneStation/cranelift.git"]

src/backend.rs

+73-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
use std::collections::HashMap;
22

3-
use cranelift_module::FuncId;
3+
use rustc::session::Session;
4+
5+
use cranelift_module::{FuncId, Module};
46

57
use faerie::*;
68
use object::{SectionKind, RelocationKind, RelocationEncoding};
79
use object::write::*;
10+
use cranelift_faerie::{FaerieBackend, FaerieBuilder, FaerieProduct, FaerieTrapCollection};
811
use cranelift_object::*;
912

1013
use gimli::SectionId;
@@ -73,11 +76,11 @@ pub trait WriteDebugInfo {
7376
);
7477
}
7578

76-
impl WriteDebugInfo for Artifact {
79+
impl WriteDebugInfo for FaerieProduct {
7780
type SectionId = SectionId;
7881

7982
fn add_debug_section(&mut self, id: SectionId, data: Vec<u8>) -> SectionId {
80-
self.declare_with(id.name(), Decl::section(faerie::SectionKind::Debug), data).unwrap();
83+
self.artifact.declare_with(id.name(), Decl::section(faerie::SectionKind::Debug), data).unwrap();
8184
id
8285
}
8386

@@ -89,6 +92,7 @@ impl WriteDebugInfo for Artifact {
8992
reloc: &DebugReloc,
9093
) {
9194
self
95+
.artifact
9296
.link_with(
9397
faerie::Link {
9498
from: from.name(),
@@ -147,3 +151,69 @@ impl WriteDebugInfo for ObjectProduct {
147151
}).unwrap();
148152
}
149153
}
154+
155+
pub trait Emit {
156+
fn emit(self) -> Vec<u8>;
157+
}
158+
159+
impl Emit for FaerieProduct {
160+
fn emit(self) -> Vec<u8> {
161+
self.artifact.emit().unwrap()
162+
}
163+
}
164+
165+
impl Emit for ObjectProduct {
166+
fn emit(self) -> Vec<u8> {
167+
self.object.write().unwrap()
168+
}
169+
}
170+
171+
#[cfg(not(feature = "backend_object"))]
172+
pub fn with_object(sess: &Session, name: &str, f: impl FnOnce(&mut Artifact)) -> Vec<u8> {
173+
let mut metadata_artifact = faerie::Artifact::new(
174+
crate::build_isa(sess, true).triple().clone(),
175+
name.to_string(),
176+
);
177+
f(&mut metadata_artifact);
178+
metadata_artifact.emit().unwrap()
179+
}
180+
181+
#[cfg(feature = "backend_object")]
182+
pub fn with_object(sess: &Session, name: &str, f: impl FnOnce(&mut Object)) -> Vec<u8> {
183+
let triple = crate::build_isa(sess, true).triple().clone();
184+
let mut metadata_object =
185+
object::write::Object::new(triple.binary_format, triple.architecture);
186+
metadata_object.add_file_symbol(name.as_bytes().to_vec());
187+
f(&mut metadata_object);
188+
metadata_object.write().unwrap()
189+
}
190+
191+
pub type Backend = impl cranelift_module::Backend<Product: Emit + WriteDebugInfo>;
192+
193+
#[cfg(not(feature = "backend_object"))]
194+
pub fn make_module(sess: &Session, name: String) -> Module<Backend> {
195+
let module: Module<FaerieBackend> = Module::new(
196+
FaerieBuilder::new(
197+
crate::build_isa(sess, true),
198+
name + ".o",
199+
FaerieTrapCollection::Disabled,
200+
cranelift_module::default_libcall_names(),
201+
)
202+
.unwrap(),
203+
);
204+
module
205+
}
206+
207+
#[cfg(feature = "backend_object")]
208+
pub fn make_module(sess: &Session, name: String) -> Module<Backend> {
209+
let module: Module<ObjectBackend> = Module::new(
210+
ObjectBuilder::new(
211+
crate::build_isa(sess, true),
212+
name + ".o",
213+
ObjectTrapCollection::Disabled,
214+
cranelift_module::default_libcall_names(),
215+
)
216+
.unwrap(),
217+
);
218+
module
219+
}

src/driver.rs

+29-30
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ use rustc::session::config::{DebugInfo, OutputType};
88
use rustc_codegen_ssa::back::linker::LinkerInfo;
99
use rustc_codegen_ssa::CrateInfo;
1010

11-
use cranelift_faerie::*;
12-
1311
use crate::prelude::*;
1412

13+
use crate::backend::{Emit, WriteDebugInfo};
14+
1515
pub fn codegen_crate(
1616
tcx: TyCtxt<'_>,
1717
metadata: EncodedMetadata,
@@ -147,59 +147,57 @@ fn run_aot(
147147
need_metadata_module: bool,
148148
) -> Box<CodegenResults> {
149149
let new_module = |name: String| {
150-
let module: Module<FaerieBackend> = Module::new(
151-
FaerieBuilder::new(
152-
crate::build_isa(tcx.sess, true),
153-
name + ".o",
154-
FaerieTrapCollection::Disabled,
155-
cranelift_module::default_libcall_names(),
156-
)
157-
.unwrap(),
158-
);
150+
let module = crate::backend::make_module(tcx.sess, name);
159151
assert_eq!(pointer_ty(tcx), module.target_config().pointer_type());
160152
module
161153
};
162154

163-
let emit_module = |kind: ModuleKind,
164-
mut module: Module<FaerieBackend>,
165-
debug: Option<DebugContext>| {
155+
fn emit_module<B: Backend>(
156+
tcx: TyCtxt<'_>,
157+
name: String,
158+
kind: ModuleKind,
159+
mut module: Module<B>,
160+
debug: Option<DebugContext>,
161+
) -> CompiledModule
162+
where B::Product: Emit + WriteDebugInfo,
163+
{
166164
module.finalize_definitions();
167-
let mut artifact = module.finish().artifact;
165+
let mut product = module.finish();
168166

169167
if let Some(mut debug) = debug {
170-
debug.emit(&mut artifact);
168+
debug.emit(&mut product);
171169
}
172170

173171
let tmp_file = tcx
174172
.output_filenames(LOCAL_CRATE)
175-
.temp_path(OutputType::Object, Some(&artifact.name));
176-
let obj = artifact.emit().unwrap();
173+
.temp_path(OutputType::Object, Some(&name));
174+
let obj = product.emit();
177175
std::fs::write(&tmp_file, obj).unwrap();
178176
CompiledModule {
179-
name: artifact.name,
177+
name: name,
180178
kind,
181179
object: Some(tmp_file),
182180
bytecode: None,
183181
bytecode_compressed: None,
184182
}
185183
};
186184

187-
let mut faerie_module = new_module("some_file".to_string());
185+
let mut module = new_module("some_file".to_string());
188186

189187
let mut debug = if tcx.sess.opts.debuginfo != DebugInfo::None
190188
// macOS debuginfo doesn't work yet (see #303)
191189
&& !tcx.sess.target.target.options.is_like_osx
192190
{
193191
let debug = DebugContext::new(
194192
tcx,
195-
faerie_module.target_config().pointer_type().bytes() as u8,
193+
module.target_config().pointer_type().bytes() as u8,
196194
);
197195
Some(debug)
198196
} else {
199197
None
200198
};
201199

202-
codegen_cgus(tcx, &mut faerie_module, &mut debug);
200+
codegen_cgus(tcx, &mut module, &mut debug);
203201

204202
tcx.sess.abort_if_errors();
205203

@@ -221,17 +219,14 @@ fn run_aot(
221219
.as_str()
222220
.to_string();
223221

224-
let mut metadata_artifact = faerie::Artifact::new(
225-
crate::build_isa(tcx.sess, true).triple().clone(),
226-
metadata_cgu_name.clone(),
227-
);
228-
crate::metadata::write_metadata(tcx, &mut metadata_artifact);
229-
230222
let tmp_file = tcx
231223
.output_filenames(LOCAL_CRATE)
232224
.temp_path(OutputType::Metadata, Some(&metadata_cgu_name));
233225

234-
let obj = metadata_artifact.emit().unwrap();
226+
let obj = crate::backend::with_object(tcx.sess, &metadata_cgu_name, |object| {
227+
crate::metadata::write_metadata(tcx, object);
228+
});
229+
235230
std::fs::write(&tmp_file, obj).unwrap();
236231

237232
(metadata_cgu_name, tmp_file)
@@ -251,12 +246,16 @@ fn run_aot(
251246
Box::new(CodegenResults {
252247
crate_name: tcx.crate_name(LOCAL_CRATE),
253248
modules: vec![emit_module(
249+
tcx,
250+
"some_file".to_string(),
254251
ModuleKind::Regular,
255-
faerie_module,
252+
module,
256253
debug,
257254
)],
258255
allocator_module: if created_alloc_shim {
259256
Some(emit_module(
257+
tcx,
258+
"allocator_shim".to_string(),
260259
ModuleKind::Allocator,
261260
allocator_module,
262261
None,

src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(rustc_private, never_type, decl_macro)]
1+
#![feature(rustc_private, never_type, decl_macro, type_alias_impl_trait, associated_type_bounds)]
22
#![allow(intra_doc_link_resolution_failure)]
33

44
extern crate flate2;

0 commit comments

Comments
 (0)