From 0787d001e36b4b61208c5e18bcc56b210b9ef5bc Mon Sep 17 00:00:00 2001 From: Lachlan Sneff Date: Thu, 28 Mar 2019 11:41:14 -0700 Subject: [PATCH] Add data support to import macro --- lib/runtime-core/src/import.rs | 14 ++++++++++++++ lib/runtime-core/src/macros.rs | 22 ++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/lib/runtime-core/src/import.rs b/lib/runtime-core/src/import.rs index 4c8401f06..32b089462 100644 --- a/lib/runtime-core/src/import.rs +++ b/lib/runtime-core/src/import.rs @@ -4,6 +4,7 @@ use std::collections::VecDeque; use std::{ cell::{Ref, RefCell}, rc::Rc, + ffi::c_void, }; pub trait LikeNamespace { @@ -45,6 +46,7 @@ impl IsExport for Export { /// ``` pub struct ImportObject { map: Rc>>>, + state_creator: Option (*mut c_void, fn(*mut c_void))>>, } impl ImportObject { @@ -52,6 +54,17 @@ impl ImportObject { pub fn new() -> Self { Self { map: Rc::new(RefCell::new(HashMap::new())), + state_creator: None, + } + } + + pub fn new_with_data(state_creator: F) -> Self + where + F: Fn() -> (*mut c_void, fn(*mut c_void)) + 'static, + { + Self { + map: Rc::new(RefCell::new(HashMap::new())), + state_creator: Some(Rc::new(state_creator)), } } @@ -98,6 +111,7 @@ impl ImportObject { pub fn clone_ref(&self) -> Self { Self { map: Rc::clone(&self.map), + state_creator: self.state_creator.clone(), } } diff --git a/lib/runtime-core/src/macros.rs b/lib/runtime-core/src/macros.rs index e23ce1185..6c608fc92 100644 --- a/lib/runtime-core/src/macros.rs +++ b/lib/runtime-core/src/macros.rs @@ -37,6 +37,13 @@ macro_rules! func { /// "foo" => func!(foo), /// }, /// }; +/// +/// let imports_with_state = imports! { +/// || (0 as _, |_a| {}), +/// "env" => { +/// "foo" => func!(foo), +/// }, +/// }; /// /// fn foo(_: &mut Ctx, n: i32) -> i32 { /// n @@ -57,6 +64,21 @@ macro_rules! imports { import_object.register($ns_name, ns); })* + import_object + }}; + ($state_gen:expr, $( $ns_name:expr => $ns:tt, )* ) => {{ + use $crate::{ + import::{ImportObject, Namespace}, + }; + + let mut import_object = ImportObject::new_with_data($state_gen); + + $({ + let ns = $crate::__imports_internal!($ns); + + import_object.register($ns_name, ns); + })* + import_object }}; }