wasmer_compiler_singlepass/
config.rs1#![allow(unused_imports, dead_code)]
3
4use crate::{compiler::SinglepassCompiler, machine::AssemblyComment};
5use std::{
6 collections::HashMap,
7 fs::File,
8 io::{self, Write},
9 num::NonZero,
10 path::PathBuf,
11 sync::Arc,
12};
13use target_lexicon::Architecture;
14use wasmer_compiler::{
15 Compiler, CompilerConfig, Engine, EngineBuilder, ModuleMiddleware,
16 misc::{CompiledKind, function_kind_to_filename, save_assembly_to_file},
17};
18use wasmer_types::{
19 Features,
20 target::{CpuFeature, Target},
21};
22
23#[derive(Debug, Clone)]
25pub struct SinglepassCallbacks {
26 debug_dir: PathBuf,
27}
28
29impl SinglepassCallbacks {
30 pub fn new(debug_dir: PathBuf) -> Result<Self, io::Error> {
32 std::fs::create_dir_all(&debug_dir)?;
34 Ok(Self { debug_dir })
35 }
36
37 fn base_path(&self, module_hash: &Option<String>) -> PathBuf {
38 let mut path = self.debug_dir.clone();
39 if let Some(hash) = module_hash {
40 path.push(hash);
41 }
42 std::fs::create_dir_all(&path)
43 .unwrap_or_else(|_| panic!("cannot create debug directory: {}", path.display()));
44 path
45 }
46
47 pub fn obj_memory_buffer(
49 &self,
50 kind: &CompiledKind,
51 module_hash: &Option<String>,
52 mem_buffer: &[u8],
53 ) {
54 let mut path = self.base_path(module_hash);
55 path.push(function_kind_to_filename(kind, ".o"));
56 let mut file =
57 File::create(path).expect("Error while creating debug file from Cranelift object");
58 file.write_all(mem_buffer).unwrap();
59 }
60
61 pub fn asm_memory_buffer(
63 &self,
64 kind: &CompiledKind,
65 module_hash: &Option<String>,
66 arch: Architecture,
67 mem_buffer: &[u8],
68 assembly_comments: HashMap<usize, AssemblyComment>,
69 ) -> Result<(), wasmer_types::CompileError> {
70 let mut path = self.base_path(module_hash);
71 path.push(function_kind_to_filename(kind, ".s"));
72 save_assembly_to_file(arch, path, mem_buffer, assembly_comments)
73 }
74}
75
76#[derive(Debug, Clone)]
77pub struct Singlepass {
78 pub(crate) enable_nan_canonicalization: bool,
79
80 pub(crate) middlewares: Vec<Arc<dyn ModuleMiddleware>>,
82
83 pub(crate) callbacks: Option<SinglepassCallbacks>,
84
85 pub num_threads: NonZero<usize>,
87}
88
89impl Singlepass {
90 pub fn new() -> Self {
93 Self {
94 enable_nan_canonicalization: true,
95 middlewares: vec![],
96 callbacks: None,
97 num_threads: std::thread::available_parallelism().unwrap_or(NonZero::new(1).unwrap()),
98 }
99 }
100
101 pub fn canonicalize_nans(&mut self, enable: bool) -> &mut Self {
102 self.enable_nan_canonicalization = enable;
103 self
104 }
105
106 pub fn callbacks(&mut self, callbacks: Option<SinglepassCallbacks>) -> &mut Self {
109 self.callbacks = callbacks;
110 self
111 }
112
113 pub fn num_threads(&mut self, num_threads: NonZero<usize>) -> &mut Self {
115 self.num_threads = num_threads;
116 self
117 }
118}
119
120impl CompilerConfig for Singlepass {
121 fn enable_pic(&mut self) {
122 }
125
126 fn compiler(self: Box<Self>) -> Box<dyn Compiler> {
128 Box::new(SinglepassCompiler::new(*self))
129 }
130
131 fn supported_features_for_target(&self, _target: &Target) -> Features {
133 Features::default()
134 }
135
136 fn push_middleware(&mut self, middleware: Arc<dyn ModuleMiddleware>) {
138 self.middlewares.push(middleware);
139 }
140}
141
142impl Default for Singlepass {
143 fn default() -> Singlepass {
144 Self::new()
145 }
146}
147
148impl From<Singlepass> for Engine {
149 fn from(config: Singlepass) -> Self {
150 EngineBuilder::new(config).engine()
151 }
152}