diff --git a/.gitignore b/.gitignore index f280b60475..1372cd1c37 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -/target +**/target /zed.xcworkspace .DS_Store /script/node_modules diff --git a/Cargo.lock b/Cargo.lock index 70cf05fab0..fa9eb96708 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3609,6 +3609,15 @@ dependencies = [ "xml-rs", ] +[[package]] +name = "plugin" +version = "0.1.0" +dependencies = [ + "bincode", + "rust_plugin_macros", + "serde", +] + [[package]] name = "png" version = "0.16.8" @@ -4311,6 +4320,17 @@ dependencies = [ "walkdir", ] +[[package]] +name = "rust_plugin_macros" +version = "0.1.0" +dependencies = [ + "bincode", + "proc-macro2", + "quote", + "serde", + "syn", +] + [[package]] name = "rustc-demangle" version = "0.1.21" diff --git a/crates/plugin/Cargo.toml b/crates/plugin/Cargo.toml new file mode 100644 index 0000000000..28b5be9984 --- /dev/null +++ b/crates/plugin/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "plugin" +version = "0.1.0" +edition = "2021" + +[dependencies] +serde = "1.0" +bincode = "1.3" +rust_plugin_macros = { path = "../plugin_macros" } \ No newline at end of file diff --git a/crates/runner/plugin/cargo_test/src/main.rs b/crates/plugin/src/lib.rs similarity index 52% rename from crates/runner/plugin/cargo_test/src/main.rs rename to crates/plugin/src/lib.rs index a97a194ffc..40d5e17012 100644 --- a/crates/runner/plugin/cargo_test/src/main.rs +++ b/crates/plugin/src/lib.rs @@ -1,5 +1,3 @@ -use core::slice; - #[repr(C)] pub struct Buffer { ptr: *const u8, @@ -15,19 +13,21 @@ pub extern "C" fn __alloc_buffer(len: usize) -> *const u8 { return buffer.ptr; } -/// Frees a given buffer, requires the size. -#[no_mangle] -pub extern "C" fn __free_buffer(ptr: *const u8, len: usize) { - let buffer = Buffer { ptr, len }; - let vec = unsafe { buffer.to_vec() }; - std::mem::drop(vec); -} +// /// Frees a given buffer, requires the size. +// #[no_mangle] +// pub extern "C" fn __free_buffer(ptr: *const u8, len: usize) { +// let buffer = Buffer { ptr, len }; +// let vec = unsafe { buffer.to_vec() }; +// std::mem::drop(vec); +// } impl Buffer { + #[inline(always)] pub unsafe fn to_vec(&self) -> Vec { slice::from_raw_parts(self.ptr, self.len).to_vec() } + #[inline(always)] pub unsafe fn from_vec(mut vec: Vec) -> Buffer { vec.shrink_to(0); let ptr = vec.as_ptr(); @@ -36,6 +36,7 @@ impl Buffer { Buffer { ptr, len } } + #[inline(always)] pub fn leak_to_heap(self) -> *const Buffer { let boxed = Box::new(self); let ptr = Box::::into_raw(boxed) as *const Buffer; @@ -43,21 +44,8 @@ impl Buffer { } } -#[no_mangle] -pub extern "C" fn banana(ptr: *const u8, len: usize) -> *const Buffer { - // setup - let buffer = Buffer { ptr, len }; - let data = unsafe { buffer.to_vec() }; - // operation - // let reversed: Vec = data.into_iter().rev().collect(); - let number: f64 = bincode::deserialize(&data).unwrap(); - let new_number = number * 2.0; - let new_data = bincode::serialize(&new_number).unwrap(); - // teardown - let new_buffer = unsafe { Buffer::from_vec(new_data) }; - return new_buffer.leak_to_heap(); -} - -pub fn main() -> () { - () +pub mod prelude { + pub use super::{Buffer, __alloc_buffer}; + #[macro_use] + pub use plugin_macros::bind; } diff --git a/crates/plugin_macros/Cargo.toml b/crates/plugin_macros/Cargo.toml new file mode 100644 index 0000000000..2d106105ab --- /dev/null +++ b/crates/plugin_macros/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "plugin_macros" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +syn = { version = "1.0", features = ["full"] } +quote = "1.0" +proc-macro2 = "1.0" +serde = "1.0" +bincode = "1.3" \ No newline at end of file diff --git a/crates/plugin_macros/src/lib.rs b/crates/plugin_macros/src/lib.rs new file mode 100644 index 0000000000..c8d0f1f93f --- /dev/null +++ b/crates/plugin_macros/src/lib.rs @@ -0,0 +1,45 @@ +use core::panic; + +use proc_macro::TokenStream; +use quote::{format_ident, quote}; +use syn::{parse_macro_input, ItemFn, VisPublic, Visibility}; + +#[proc_macro_attribute] +pub fn bind(args: TokenStream, function: TokenStream) -> TokenStream { + if !args.is_empty() { + panic!("The bind attribute does not take any arguments"); + } + + let inner_fn = parse_macro_input!(function as ItemFn); + if let Visibility::Public(_) = inner_fn.vis { + } else { + panic!("The bind attribute only works for public functions"); + } + + let inner_fn_name = format_ident!("{}", inner_fn.sig.ident); + let outer_fn_name = format_ident!("__{}", inner_fn_name); + + TokenStream::from(quote! { + use serde; + + #[no_mangle] + #inner_fn + + #[no_mangle] + pub extern "C" fn #outer_fn_name(ptr: *const u8, len: usize) -> *const Buffer { + // setup + let buffer = Buffer { ptr, len }; + let data = unsafe { buffer.to_vec() }; + + // operation + let argument = bincode::deserialize(&data).unwrap(); + let result = #inner_fn_name(argument); + let new_data: Result, _> = bincode::serialize(&result); + let new_data = new_data.unwrap(); + + // teardown + let new_buffer = unsafe { Buffer::from_vec(new_data) }; + return new_buffer.leak_to_heap(); + } + }) +} diff --git a/crates/runner/Cargo.toml b/crates/plugin_runtime/Cargo.toml similarity index 100% rename from crates/runner/Cargo.toml rename to crates/plugin_runtime/Cargo.toml diff --git a/crates/runner/README.md b/crates/plugin_runtime/README.md similarity index 100% rename from crates/runner/README.md rename to crates/plugin_runtime/README.md diff --git a/crates/runner/build.rs b/crates/plugin_runtime/build.rs similarity index 100% rename from crates/runner/build.rs rename to crates/plugin_runtime/build.rs diff --git a/crates/plugin_runtime/heck.txt b/crates/plugin_runtime/heck.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/crates/plugin_runtime/plugin/Cargo.lock b/crates/plugin_runtime/plugin/Cargo.lock new file mode 100644 index 0000000000..8cc9507c21 --- /dev/null +++ b/crates/plugin_runtime/plugin/Cargo.lock @@ -0,0 +1,180 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" + +[[package]] +name = "cargo_test" +version = "0.1.0" +dependencies = [ + "bincode", + "rust_plugin_macros", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "itoa" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "proc-macro2" +version = "1.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rust_plugin_macros" +version = "0.1.0" +dependencies = [ + "bincode", + "proc-macro2", + "quote", + "serde", + "syn", +] + +[[package]] +name = "ryu" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" + +[[package]] +name = "serde" +version = "1.0.137" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" + +[[package]] +name = "serde_json" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "syn" +version = "1.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" + +[[package]] +name = "wasm-bindgen" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" +dependencies = [ + "cfg-if", + "serde", + "serde_json", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" diff --git a/crates/runner/plugin/Cargo.toml b/crates/plugin_runtime/plugin/Cargo.toml similarity index 100% rename from crates/runner/plugin/Cargo.toml rename to crates/plugin_runtime/plugin/Cargo.toml diff --git a/crates/runner/plugin/cargo_test.lua b/crates/plugin_runtime/plugin/cargo_test.lua similarity index 100% rename from crates/runner/plugin/cargo_test.lua rename to crates/plugin_runtime/plugin/cargo_test.lua diff --git a/crates/runner/plugin/cargo_test/Cargo.lock b/crates/plugin_runtime/plugin/cargo_test/Cargo.lock similarity index 100% rename from crates/runner/plugin/cargo_test/Cargo.lock rename to crates/plugin_runtime/plugin/cargo_test/Cargo.lock diff --git a/crates/runner/plugin/cargo_test/Cargo.toml b/crates/plugin_runtime/plugin/cargo_test/Cargo.toml similarity index 54% rename from crates/runner/plugin/cargo_test/Cargo.toml rename to crates/plugin_runtime/plugin/cargo_test/Cargo.toml index 9d13904251..9a94cad78d 100644 --- a/crates/runner/plugin/cargo_test/Cargo.toml +++ b/crates/plugin_runtime/plugin/cargo_test/Cargo.toml @@ -4,4 +4,6 @@ version = "0.1.0" edition = "2021" [dependencies] -bincode = "1.3" \ No newline at end of file +serde = "1.0" +bincode = "1.3" +plugin = { path = "../../../plugin" } diff --git a/crates/plugin_runtime/plugin/cargo_test/src/main.rs b/crates/plugin_runtime/plugin/cargo_test/src/main.rs new file mode 100644 index 0000000000..ba4fd20d3a --- /dev/null +++ b/crates/plugin_runtime/plugin/cargo_test/src/main.rs @@ -0,0 +1,34 @@ +use core::slice; +use plugin::prelude::*; + +#[no_mangle] +pub extern "C" fn banana(ptr: *const u8, len: usize) -> *const Buffer { + // setup + let buffer = Buffer { ptr, len }; + let data = unsafe { buffer.to_vec() }; + // operation + // let reversed: Vec = data.into_iter().rev().collect(); + let number: f64 = bincode::deserialize(&data).unwrap(); + let new_number = number * 2.0; + let new_data = bincode::serialize(&new_number).unwrap(); + // teardown + let new_buffer = unsafe { Buffer::from_vec(new_data) }; + return new_buffer.leak_to_heap(); +} + +pub fn banana2(number: f64) -> f64 { + number * 2.0 +} + +#[bind] +pub fn sum_lengths(strings: Vec) -> usize { + let mut total = 0; + for string in strings { + total += string.len(); + } + return total; +} + +pub fn main() -> () { + () +} diff --git a/crates/runner/src/lib.rs b/crates/plugin_runtime/src/lib.rs similarity index 100% rename from crates/runner/src/lib.rs rename to crates/plugin_runtime/src/lib.rs diff --git a/crates/runner/src/lua.rs b/crates/plugin_runtime/src/lua.rs similarity index 100% rename from crates/runner/src/lua.rs rename to crates/plugin_runtime/src/lua.rs diff --git a/crates/runner/src/main.rs b/crates/plugin_runtime/src/main.rs similarity index 100% rename from crates/runner/src/main.rs rename to crates/plugin_runtime/src/main.rs diff --git a/crates/runner/src/runtime.rs b/crates/plugin_runtime/src/runtime.rs similarity index 100% rename from crates/runner/src/runtime.rs rename to crates/plugin_runtime/src/runtime.rs diff --git a/crates/runner/src/wasm.rs b/crates/plugin_runtime/src/wasm.rs similarity index 93% rename from crates/runner/src/wasm.rs rename to crates/plugin_runtime/src/wasm.rs index d196bfe42a..6e2506cb58 100644 --- a/crates/runner/src/wasm.rs +++ b/crates/plugin_runtime/src/wasm.rs @@ -12,7 +12,7 @@ pub struct Wasm { store: Store, instance: Instance, alloc_buffer: TypedFunc, - free_buffer: TypedFunc<(i32, i32), ()>, + // free_buffer: TypedFunc<(i32, i32), ()>, } pub struct WasmPlugin { @@ -50,7 +50,7 @@ impl Runtime for Wasm { let instance = Instance::new(&mut store, &module, &[])?; let alloc_buffer = instance.get_typed_func(&mut store, "__alloc_buffer")?; - let free_buffer = instance.get_typed_func(&mut store, "__free_buffer")?; + // let free_buffer = instance.get_typed_func(&mut store, "__free_buffer")?; Ok(Wasm { engine, @@ -58,7 +58,7 @@ impl Runtime for Wasm { store, instance, alloc_buffer, - free_buffer, + // free_buffer, }) } @@ -141,7 +141,8 @@ impl Runtime for Wasm { // call the function, passing in the buffer and its length // this should return a pointer to a (ptr, lentgh) pair - let result_buffer = fun.call(&mut self.store, (arg_buffer_ptr, arg_buffer_len as i32))?; + let arg_buffer = (arg_buffer_ptr, arg_buffer_len as i32); + let result_buffer = fun.call(&mut self.store, arg_buffer)?; dbg!(result_buffer); // panic!(); @@ -163,10 +164,13 @@ impl Runtime for Wasm { dbg!(result_buffer_len); // read the buffer at this point into a byte array - let result = &plugin_memory.data(&mut self.store)[result_buffer_ptr..result_buffer_end]; - // deserialize the byte array into the provided serde type + let result = &plugin_memory.data(&mut self.store)[result_buffer_ptr..result_buffer_end]; let result = bincode::deserialize(result)?; + + // // deallocate the argument buffer + // self.free_buffer.call(&mut self.store, arg_buffer); + return Ok(result); } diff --git a/crates/runner/plugin/Cargo.lock b/crates/runner/plugin/Cargo.lock deleted file mode 100644 index d027f6bd0f..0000000000 --- a/crates/runner/plugin/Cargo.lock +++ /dev/null @@ -1,25 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo_test" -version = "0.1.0" -dependencies = [ - "bincode", -] - -[[package]] -name = "serde" -version = "1.0.137" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"