gaia_assembler/assembler/
mod.rs1use crate::{backends::*, program::GaiaModule};
6use gaia_types::{helpers::CompilationTarget, GaiaErrorKind, *};
7
8pub struct GaiaAssembler {
10 backends: Vec<Box<dyn Backend>>,
11}
12
13impl GaiaAssembler {
14 pub fn new() -> Self {
16 #[allow(unused_mut)]
17 let mut backends: Vec<Box<dyn Backend>> = vec![];
18
19 #[cfg(feature = "jvm-assembler")]
20 backends.push(Box::new(JvmBackend {}));
21 #[cfg(feature = "pe-assembler")]
22 backends.push(Box::new(WindowsBackend {}));
23 #[cfg(feature = "wasi-assembler")]
24 backends.push(Box::new(WasiBackend {}));
25 #[cfg(feature = "x86_64-assembler")]
26 backends.push(Box::new(X64Backend {}));
27 #[cfg(feature = "gcn-assembler")]
28 backends.push(Box::new(GcnBackend::new()));
29 #[cfg(feature = "sass-assembler")]
30 backends.push(Box::new(SassBackend::new()));
31 #[cfg(feature = "clr-assembler")]
32 backends.push(Box::new(ClrBackend {}));
33 #[cfg(feature = "elf-assembler")]
34 backends.push(Box::new(ElfBackend {}));
35 #[cfg(feature = "macho-assembler")]
36 backends.push(Box::new(MachoBackend {}));
37 #[cfg(feature = "lua-assembler")]
38 backends.push(Box::new(LuaBackend {}));
39 #[cfg(feature = "llvm-assembler")]
40 backends.push(Box::new(LlvmBackend {}));
41 #[cfg(feature = "msl-assembler")]
42 backends.push(Box::new(MslBackend {}));
43 #[cfg(feature = "spirv-assembler")]
44 backends.push(Box::new(SpirvBackend {}));
45 #[cfg(feature = "python-assembler")]
46 backends.push(Box::new(PythonBackend {}));
47
48 Self { backends }
49 }
50
51 pub fn compile(&self, program: &GaiaModule, target: &CompilationTarget) -> Result<GeneratedFiles> {
53 let mut best_backend: Option<&Box<dyn Backend>> = None;
55 let mut best_score = 0.0;
56
57 if let Some(candidate) = self.backends.iter().find(|b| {
59 let pt = b.primary_target();
60 pt.host == target.host && pt.build == target.build
61 }) {
62 best_backend = Some(candidate);
63 best_score = 100.0; }
65
66 if best_backend.is_none() {
68 for backend in &self.backends {
69 let score = backend.match_score(target);
70 if score > best_score {
71 best_score = score;
72 best_backend = Some(backend);
73 }
74 }
75 }
76
77 if best_backend.is_none() || best_score <= 0.0 {
78 return Err(GaiaErrorKind::UnsupportedTarget { target: target.clone() }.into());
79 }
80
81 let mut config = crate::config::GaiaConfig::default();
83 config.target = target.clone();
84
85 best_backend.unwrap().generate(program, &config)
87 }
88
89 pub fn backends(&self) -> &[Box<dyn Backend>] {
91 &self.backends
92 }
93}
94
95pub fn compile_to_platform(program: &GaiaModule, target: CompilationTarget) -> Result<Vec<u8>> {
97 let compiler = GaiaAssembler::new();
98 let generated_files = compiler.compile(program, &target)?;
99
100 if let Some((_, bytes)) = generated_files.files.iter().next() {
103 Ok(bytes.clone())
104 }
105 else {
106 Err(GaiaError::invalid_data("No output files generated"))
107 }
108}