1use crate::{config::GaiaSettings, instruction::GaiaInstruction, program::GaiaModule};
7use gaia_types::{
8 helpers::{AbiCompatible, ApiCompatible, Architecture, CompilationTarget},
9 GaiaError, Result,
10};
11use serde::{Deserialize, Serialize};
12use std::collections::HashMap;
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
18pub struct AdapterConfig {
19 pub name: String,
21 pub compilation_target: CompilationTarget,
23 pub parameters: HashMap<String, String>,
25 pub enabled: bool,
27}
28
29#[derive(Debug, Clone)]
33pub struct AdapterMetadata {
34 pub name: String,
36 pub version: String,
38 pub compilation_target: CompilationTarget,
40 pub description: String,
42 pub supported_instructions: Vec<String>,
44}
45
46#[derive(Debug)]
48pub struct FunctionMapper {
49 mappings: HashMap<CompilationTarget, HashMap<String, String>>,
51}
52
53impl FunctionMapper {
54 pub fn new() -> Self {
56 Self::from_settings(&GaiaSettings::default())
59 }
60
61 pub fn from_config(config: &GaiaSettings) -> Result<Self> {
63 Ok(Self::from_settings(config))
64 }
65
66 fn from_settings(settings: &GaiaSettings) -> Self {
68 let mut mapper = Self { mappings: HashMap::new() };
69
70 let il_target = CompilationTarget {
72 build: Architecture::CLR,
73 host: AbiCompatible::MicrosoftIntermediateLanguage,
74 target: ApiCompatible::ClrRuntime(4),
75 };
76 let jvm_target = CompilationTarget {
77 build: Architecture::JVM,
78 host: AbiCompatible::JavaAssembly,
79 target: ApiCompatible::JvmRuntime(8),
80 };
81 let pe_target =
82 CompilationTarget { build: Architecture::X86_64, host: AbiCompatible::PE, target: ApiCompatible::MicrosoftVisualC };
83 let wasi_target = CompilationTarget {
84 build: Architecture::WASM32,
85 host: AbiCompatible::WebAssemblyTextFormat,
86 target: ApiCompatible::WASI,
87 };
88
89 let mut platform_index: HashMap<String, CompilationTarget> = HashMap::new();
90 platform_index.insert("IL".to_string(), il_target.clone());
91 platform_index.insert("JVM".to_string(), jvm_target.clone());
92 platform_index.insert("PE".to_string(), pe_target.clone());
93 platform_index.insert("WASI".to_string(), wasi_target.clone());
94
95 mapper.add_mapping(&il_target, "console.log", "void [mscorlib]System.Console::WriteLine(string)");
98 mapper.add_mapping(&il_target, "console.write", "void [mscorlib]System.Console::WriteLine(string)");
99 mapper.add_mapping(&il_target, "conosole.read", "string [mscorlib]System.Console::ReadLine()");
100 mapper.add_mapping(&il_target, "malloc", "System.Runtime.InteropServices.Marshal.AllocHGlobal");
101 mapper.add_mapping(&il_target, "free", "System.Runtime.InteropServices.Marshal.FreeHGlobal");
102 mapper.add_mapping(&il_target, "print", "void [mscorlib]System.Console::WriteLine(string)");
103 mapper.add_mapping(&il_target, "println", "void [mscorlib]System.Console::WriteLine(string)");
104
105 mapper.add_mapping(&jvm_target, "console.log", "java.lang.System.out.println");
107 mapper.add_mapping(&jvm_target, "console.write", "java.lang.System.out.println");
108 mapper.add_mapping(&jvm_target, "console.read", "java.util.Scanner.nextLine");
109 mapper.add_mapping(&jvm_target, "malloc", "java.nio.ByteBuffer.allocateDirect");
110 mapper.add_mapping(&jvm_target, "free", "System.gc");
111 mapper.add_mapping(&jvm_target, "print", "java.lang.System.out.println");
112 mapper.add_mapping(&jvm_target, "println", "java.lang.System.out.println");
113
114 mapper.add_mapping(&pe_target, "console.log", "puts");
116 mapper.add_mapping(&pe_target, "console.write", "printf");
117 mapper.add_mapping(&pe_target, "console.read", "gets_s");
118 mapper.add_mapping(&pe_target, "malloc", "HeapAlloc");
119 mapper.add_mapping(&pe_target, "free", "HeapFree");
120 mapper.add_mapping(&pe_target, "print", "puts");
121 mapper.add_mapping(&pe_target, "println", "puts");
122
123 mapper.add_mapping(&wasi_target, "console.log", "wasi_println");
125 mapper.add_mapping(&wasi_target, "console.write", "wasi_print");
126 mapper.add_mapping(&wasi_target, "console.read", "wasi_read");
127 mapper.add_mapping(&wasi_target, "malloc", "malloc");
128 mapper.add_mapping(&wasi_target, "free", "free");
129 mapper.add_mapping(&wasi_target, "print", "wasi_println");
130 mapper.add_mapping(&wasi_target, "println", "wasi_println");
131
132 for fm in &settings.function_mappings {
134 for (platform_name, target_func) in &fm.platform_mappings {
135 let key = platform_name.to_ascii_uppercase();
136 if let Some(platform_target) = platform_index.get(&key) {
137 mapper.add_mapping(platform_target, &fm.common_name, target_func);
139
140 if fm.common_name == "__builtin_print" {
142 let is_il = matches!(platform_target.host, AbiCompatible::MicrosoftIntermediateLanguage);
143 if !is_il {
145 mapper.add_mapping(platform_target, "print", target_func);
146 }
147 mapper.add_mapping(platform_target, "console.log", target_func);
148 mapper.add_mapping(platform_target, "console.write", target_func);
149 }
150 }
151 }
152 }
153
154 mapper
155 }
156
157 pub fn add_mapping(&mut self, target: &CompilationTarget, source_func: &str, target_func: &str) {
159 self.mappings
160 .entry(target.clone())
161 .or_insert_with(HashMap::new)
162 .insert(source_func.to_string(), target_func.to_string());
163 }
164
165 pub fn map_function(&self, target: &CompilationTarget, function_name: &str) -> Option<&str> {
167 self.mappings.get(target).and_then(|platform_mappings| platform_mappings.get(function_name)).map(|s| s.as_str())
168 }
169}
170
171impl Default for FunctionMapper {
172 fn default() -> Self {
173 Self::new()
174 }
175}
176
177pub trait ExportAdapter: Send + Sync {
181 fn metadata(&self) -> &AdapterMetadata;
183
184 fn configure(&mut self, config: AdapterConfig) -> Result<()>;
192
193 fn export_instruction(&self, instruction: &GaiaInstruction) -> Result<Vec<u8>>;
201
202 fn export_program(&self, program: &GaiaModule) -> Result<Vec<u8>>;
211
212 fn supports_instruction(&self, instruction: &GaiaInstruction) -> bool;
220
221 fn file_extension(&self) -> &str;
226
227 fn cleanup(&mut self) -> Result<()> {
231 Ok(())
232 }
233}
234
235pub trait ImportAdapter: Send + Sync {
239 fn metadata(&self) -> &AdapterMetadata;
241
242 fn configure(&mut self, config: AdapterConfig) -> Result<()>;
250
251 fn import_instruction(&self, data: &[u8]) -> Result<GaiaInstruction>;
259
260 fn import_program(&self, data: &[u8]) -> Result<GaiaModule>;
268
269 fn validate_format(&self, data: &[u8]) -> bool;
277
278 fn supported_extensions(&self) -> Vec<&str>;
283
284 fn cleanup(&mut self) -> Result<()> {
288 Ok(())
289 }
290}
291
292pub struct AdapterManager {
294 export_adapters: HashMap<CompilationTarget, Box<dyn ExportAdapter>>,
296 import_adapters: HashMap<CompilationTarget, Box<dyn ImportAdapter>>,
298}
299
300impl AdapterManager {
301 pub fn new() -> Self {
303 Self { export_adapters: HashMap::new(), import_adapters: HashMap::new() }
304 }
305
306 pub fn register_export_adapter(&mut self, target: CompilationTarget, adapter: Box<dyn ExportAdapter>) -> Result<()> {
315 if self.export_adapters.contains_key(&target) {
316 return Err(GaiaError::adapter_error(&format!("{:?}", target), "导出适配器已存在", None));
317 }
318 self.export_adapters.insert(target, adapter);
319 Ok(())
320 }
321
322 pub fn register_import_adapter(&mut self, target: CompilationTarget, adapter: Box<dyn ImportAdapter>) -> Result<()> {
331 if self.import_adapters.contains_key(&target) {
332 return Err(GaiaError::adapter_error(&format!("{:?}", target), "导入适配器已存在", None));
333 }
334 self.import_adapters.insert(target, adapter);
335 Ok(())
336 }
337
338 pub fn get_export_adapter(&self, target: &CompilationTarget) -> Result<&dyn ExportAdapter> {
346 self.export_adapters
347 .get(target)
348 .map(|adapter| adapter.as_ref())
349 .ok_or_else(|| GaiaError::adapter_error(&format!("{:?}", target), "导出适配器未找到", None))
350 }
351
352 pub fn get_export_adapter_mut(&mut self, target: &CompilationTarget) -> Result<&mut (dyn ExportAdapter + '_)> {
360 match self.export_adapters.get_mut(target) {
361 Some(adapter) => Ok(adapter.as_mut()),
362 None => Err(GaiaError::adapter_error(&format!("{:?}", target), "导出适配器未找到", None)),
363 }
364 }
365
366 pub fn get_import_adapter(&self, target: &CompilationTarget) -> Result<&dyn ImportAdapter> {
374 self.import_adapters
375 .get(target)
376 .map(|adapter| adapter.as_ref())
377 .ok_or_else(|| GaiaError::adapter_error(&format!("{:?}", target), "导入适配器未找到", None))
378 }
379
380 pub fn get_import_adapter_mut(&mut self, target: &CompilationTarget) -> Result<&mut (dyn ImportAdapter + '_)> {
388 match self.import_adapters.get_mut(target) {
389 Some(adapter) => Ok(adapter.as_mut()),
390 None => Err(GaiaError::adapter_error(&format!("{:?}", target), "导入适配器未找到", None)),
391 }
392 }
393
394 pub fn list_supported_targets(&self) -> Vec<CompilationTarget> {
399 let mut targets = Vec::new();
400 targets.extend(self.export_adapters.keys().cloned());
401 targets.extend(self.import_adapters.keys().cloned());
402 targets.sort_by_key(|t| format!("{:?}", t));
403 targets.dedup();
404 targets
405 }
406
407 pub fn cleanup_all(&mut self) -> Result<()> {
412 for (target, adapter) in &mut self.export_adapters {
413 if let Err(e) = adapter.cleanup() {
414 return Err(GaiaError::adapter_error(&format!("{:?}", target), "清理导出适配器失败", Some(Box::new(e))));
415 }
416 }
417
418 for (target, adapter) in &mut self.import_adapters {
419 if let Err(e) = adapter.cleanup() {
420 return Err(GaiaError::adapter_error(&format!("{:?}", target), "清理导入适配器失败", Some(Box::new(e))));
421 }
422 }
423
424 Ok(())
425 }
426}
427
428impl Default for AdapterManager {
429 fn default() -> Self {
430 Self::new()
431 }
432}