Skip to content

Instantly share code, notes, and snippets.

@wyatt-herkamp
Created October 1, 2023 13:55
Show Gist options
  • Save wyatt-herkamp/586e49366bf36d6b065988baca16a65e to your computer and use it in GitHub Desktop.
Save wyatt-herkamp/586e49366bf36d6b065988baca16a65e to your computer and use it in GitHub Desktop.
#[doc(hidden)]
#[cfg(any(target_arch = "wasm32", target_arch = "wasm64"))]
pub mod abi_module {
use std::boxed::Box;
use type_it_module::ffi;
use type_it_module::language_module::LanguageModule;
use super::TestLanguageModule;
type ModuleConfig = <TestLanguageModule as LanguageModule>::Config;
#[no_mangle]
pub fn language_config() -> Box<ffi::FFIValue> {
let arguments = <ModuleConfig as type_it_module::argument::LanguageArguments>::get_arguments();
let raw_value: type_it_core::value::Value = type_it_core::value::ToFromValue::to_value(&arguments).unwrap();
Box::new(ffi::FFIValue::from(raw_value))
}
#[no_mangle]
pub fn default_config() -> Box<ffi::FFIString> { Box::new(ffi::FFIString::from(<TestLanguageModule as LanguageModule>::default_config())) }
#[no_mangle]
pub extern fn language_module() -> Box<ffi::FFIString> { Box::new(ffi::FFIString::from(super::LANGUAGE_MODULE.to_string())) }
#[no_mangle]
pub extern fn build_types(config: Box<ffi::FFIMap>, file: Box<ffi::FFIString>, parsed_data: Box<ffi::FFIMap>) -> ffi::BuildResponses {
let mut config = *config;
let file = *file;
let parsed_data = *parsed_data;
type_it_module::log::debug!("Starting Build Types" );
let file: Result<String, _> = file.try_into();
let Ok(file) = file else { return ffi::BuildResponses::BuildPathError; };
let file = std::path::PathBuf::from(file);
type_it_module::log::debug!("File: {:?}" , file );
let parsed_data = match ffi::parse_ffi_map::<type_it_core::parsed_types::ParsedData>(parsed_data) {
Ok(v) => {
type_it_module::log::debug!("Parsed Data: {:#?}" , v );
v
}
Err(err) => {
type_it_module::log::error!("Unable to Construct Parsed Data {:#?}" , err );
return ffi::BuildResponses::ParseDataError;
}
};
let config = match ffi::parse_ffi_map::<ModuleConfig>(config) {
Ok(v) => {
type_it_module::log::debug!("Parsed Config: {:#?}" , v );
v
}
Err(err) => {
type_it_module::log::error!("Unable to Construct Parsed Data {:#?}" , err );
return ffi::BuildResponses::ParseConfigError;
}
};
let result = <TestLanguageModule as LanguageModule>::build_types(config, parsed_data);
match result {
Ok(write) => {
match write.write_parse_with_default_file(file) {
Ok(_) => { return ffi::BuildResponses::Ok; }
Err(err) => {
type_it_module::log::error!("{:#?}" , err );
return ffi::BuildResponses::WriteError;
}
}
}
Err(err) => {
type_it_module::log::error!("{:#?}" , err );
return ffi::BuildResponses::BuildError;
}
}
}
}
#[derive(Debug, Clone)]
#[repr(C)]
pub enum FFIValue {
String(FFIString),
Array(FFIArray<FFIValue>),
Map(FFIMap),
Bool(bool),
Int(u64),
SignedInt(i64),
Float(f64),
Null,
}
#[repr(C)]
pub struct FFIArray<T: FFIType> {
entries: *mut T,
size: usize,
}
#[derive(Default, Clone, PartialEq)]
#[repr(transparent)]
pub struct FFIString(FFIArray<u8>);
#[derive(PartialEq, Debug)]
#[repr(C)]
pub struct FFIEntry {
pub key: FFIString,
pub value: FFIValue,
}
#[derive(Clone)]
#[repr(transparent)]
pub struct FFIMap(FFIArray<FFIEntry>);
#[derive(Clone, Copy, ValueType, Debug)]
#[repr(C)]
pub struct WASMArray<T: ValueType> {
entries: WasmPtr<T>,
size: i32,
}
impl<T: ValueType + FFIType> WASMArray<T> {
pub fn to_vec(&self, view: &MemoryView) -> Result<Vec<T::SafeType>, MemoryAccessError> {
let mut entries = Vec::with_capacity(self.size as usize);
let result = self.entries.slice(view, self.size as u32)?;
for entry in result.iter() {
entries.push(entry.read()?.into());
}
Ok(entries)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment