diff --git a/Cargo.toml b/Cargo.toml index ee9a158..d356f3f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,11 +7,6 @@ members = [ resolver = "3" -[turing.profile.release] -strip = true -lto = true -opt-level = 3 - [tests.profile.release] opt-level = "z" # 0 = no optimization diff --git a/README.md b/README.md index 4e79446..d9d7aaf 100644 --- a/README.md +++ b/README.md @@ -158,3 +158,8 @@ pub struct FfiParam { ``` +### Compiling for Windows from Linux +Download the `mingw-64` package and compile using: +``` +cargo x w +``` \ No newline at end of file diff --git a/turing/Cargo.toml b/turing/Cargo.toml index 3564379..10af176 100644 --- a/turing/Cargo.toml +++ b/turing/Cargo.toml @@ -5,6 +5,17 @@ edition = "2024" [lib] crate-type = ["cdylib", "staticlib", "rlib"] +name = "turing_rs" + +[profile.release] +strip = true +lto = true +opt-level = 3 + +split-debuginfo = "packed" +debug = "line-tables-only" +panic = "abort" +codegen-units = 1 [features] default = ["wasm", "lua", "global_ffi"] @@ -23,7 +34,7 @@ harness = false [dependencies] -anyhow = "1.0" +anyhow = {version = "1.0", features = ["backtrace"] } serde_json = "1.0.149" glam = "0.30.10" diff --git a/turing/benches/lua_api_bench.rs b/turing/benches/lua_api_bench.rs index 0e503dc..07dc06a 100644 --- a/turing/benches/lua_api_bench.rs +++ b/turing/benches/lua_api_bench.rs @@ -1,9 +1,9 @@ use criterion::{Criterion, criterion_group, criterion_main}; use std::ffi::{c_void, CString}; use std::hint::black_box; -use turing::engine::types::ScriptFnMetadata; -use turing::interop::params::{DataType, FreeableDataType, Param, Params}; -use turing::{ExternalFunctions, Turing}; +use turing_rs::engine::types::ScriptFnMetadata; +use turing_rs::interop::params::{DataType, FreeableDataType, Param, Params}; +use turing_rs::{ExternalFunctions, Turing}; struct DirectExt {} impl ExternalFunctions for DirectExt { @@ -28,14 +28,14 @@ impl ExternalFunctions for DirectExt { } extern "C" fn log_info_wasm( - _params: turing::interop::params::FfiParamArray, -) -> turing::interop::params::FfiParam { + _params: turing_rs::interop::params::FfiParamArray, +) -> turing_rs::interop::params::FfiParam { Param::Void.to_ext_param() } extern "C" fn fetch_string( - _params: turing::interop::params::FfiParamArray, -) -> turing::interop::params::FfiParam { + _params: turing_rs::interop::params::FfiParamArray, +) -> turing_rs::interop::params::FfiParam { Param::String("this is a host provided string!".to_string()).to_ext_param() } diff --git a/turing/benches/wasm_api_bench.rs b/turing/benches/wasm_api_bench.rs index 50390b0..e85bee9 100644 --- a/turing/benches/wasm_api_bench.rs +++ b/turing/benches/wasm_api_bench.rs @@ -1,12 +1,12 @@ use criterion::{Criterion, criterion_group, criterion_main}; -use turing::engine::types::ScriptFnMetadata; +use turing_rs::engine::types::ScriptFnMetadata; use std::env; use std::ffi::{c_void, CString}; use std::fs::File; use std::hint::black_box; use std::io::Write; -use turing::interop::params::{DataType, FfiParam, FfiParamArray, FreeableDataType, Param, Params}; -use turing::{ExternalFunctions, Turing}; +use turing_rs::interop::params::{DataType, FfiParam, FfiParamArray, FreeableDataType, Param, Params}; +use turing_rs::{ExternalFunctions, Turing}; struct DirectExt {} impl ExternalFunctions for DirectExt { diff --git a/turing/src/engine/lua_engine.rs b/turing/src/engine/lua_engine.rs index ff0026b..c93e36f 100644 --- a/turing/src/engine/lua_engine.rs +++ b/turing/src/engine/lua_engine.rs @@ -381,9 +381,7 @@ impl LuaInterpreter { }; // we assume the function exists because we cached it earlier - let Some((name, _)) = &self.func_cache.get(&cache_key) else { - return Param::Error(format!("Function with key '{cache_key:?}' not found")) - }; + let (name, _) = &self.func_cache.get(&cache_key); let name = name.as_str(); let func = module.get::(name); diff --git a/turing/src/engine/wasm_engine.rs b/turing/src/engine/wasm_engine.rs index 88fe3de..b22f2f9 100644 --- a/turing/src/engine/wasm_engine.rs +++ b/turing/src/engine/wasm_engine.rs @@ -82,8 +82,9 @@ impl DataType { DataType::F32 => Ok(ValType::F32), DataType::F64 => Ok(ValType::F64), + DataType::Void => Err(anyhow!("Void is only allowed as a singular return type for WASM.")), // voids are represented as i32 0 - _ => Err(anyhow!("Invalid wasm value type: {}", self)) + _ => Err(anyhow!("Invalid wasm value type: {}", self)), } } @@ -591,8 +592,13 @@ impl WasmInterpreter { name.insert(0, '_'); let p_types = metadata.param_types.iter().map(|d| d.to_val_type()).collect::>>()?; - let r_types = metadata.return_type.iter().map(|d| d.to_val_type()).collect::>>()?; + // if the only return type is void, we treat it as no return types + let r_types = if metadata.return_type.len() == 1 && metadata.return_type.first().cloned() == Some(DataType::Void) { + Vec::new() + } else { + metadata.return_type.iter().map(|d| d.to_val_type()).collect::>>()? + }; let ft = FuncType::new(engine, p_types, r_types); let cap = metadata.capability.clone(); let callback = metadata.callback; @@ -689,18 +695,9 @@ impl WasmInterpreter { } // Try cache first to avoid repeated name lookup and Val boxing/unboxing. - let Some((_, f)) = self.func_cache.get(&cache_key) // This shouldn't be necessary as all exported functions are indexed on load + let (_, f) = self.func_cache.get(&cache_key); - // .or_else(|| { - // let name = d.fn_name_cache.get(cache_key)?; - // let found = instance.get_func(&mut self.store, name)?; - // self.func_cache.insert(cache_key, found); - // Some(found) - // }) - else { - return Param::Error("Function does not exist".to_string()); - }; let args = params.to_wasm_args(data); if let Err(e) = args { diff --git a/turing/src/global_ffi/ffi.rs b/turing/src/global_ffi/ffi.rs index 581e238..4c390d2 100644 --- a/turing/src/global_ffi/ffi.rs +++ b/turing/src/global_ffi/ffi.rs @@ -204,7 +204,7 @@ unsafe extern "C" fn turing_script_load(turing: *mut TuringInstance, source: *co }; if let Err(e) = turing.load_script(source, &capabilities) { - Param::Error(format!("{}", e)) + Param::Error(format!("{}\n{}", e, e.backtrace())) } else { Param::Void }.to_rs_param() diff --git a/turing/src/key_vec.rs b/turing/src/key_vec.rs index 5452428..b3a7110 100644 --- a/turing/src/key_vec.rs +++ b/turing/src/key_vec.rs @@ -48,13 +48,13 @@ where } #[inline] - pub fn get(&self, key: &K) -> Option<&V> { - self.values.get(key.clone().into() as usize) + pub fn get(&self, key: &K) -> &V { + unsafe { self.values.get_unchecked(key.clone().into() as usize) } } #[inline] - pub fn get_mut(&mut self, key: &K) -> Option<&mut V> { - self.values.get_mut(key.clone().into() as usize) + pub fn get_mut(&mut self, key: &K) -> &mut V { + unsafe { self.values.get_unchecked_mut(key.clone().into() as usize) } } /// Clears all values from the KeyVec. diff --git a/xtask/src/main.rs b/xtask/src/main.rs index d1fbe34..8690b51 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -5,7 +5,8 @@ use serde::Deserialize; #[derive(Deserialize)] struct CargoToml { - package: Package + package: Package, + lib: Lib, } #[derive(Deserialize)] @@ -14,6 +15,11 @@ struct Package { name: String, } +#[derive(Deserialize)] +struct Lib { + name: String, +} + fn main() { let mut args = env::args().skip(1); let task = args.next().unwrap_or_else(|| { @@ -70,14 +76,14 @@ fn build_windows() { .expect("Failed to parse Cargo.toml"); let version = cargo.package.version; - let lib_name = cargo.package.name; + let lib_name = cargo.lib.name; let built = format!("target/{}/release/{}.dll", target, lib_name); let output = Path::new("dist").join(format!("{}-{}.dll", lib_name, version)); fs::create_dir_all("dist").expect("Failed to create dist directory"); fs::copy(&built, &output) - .unwrap_or_else(|e| panic!("Failed to copy DLL: {}", e)); + .unwrap_or_else(|e| panic!("Failed to copy DLL: {}.dll {}", lib_name, e)); println!("Windows dll generated in dist");