From 4d591eee1a452d06c87266a8ea3adbb6e0a017eb Mon Sep 17 00:00:00 2001 From: Wodann Date: Thu, 30 Apr 2020 12:37:38 +0200 Subject: [PATCH] improvement: return Rc> from builder --- crates/mun/src/main.rs | 4 ++-- crates/mun_runtime/examples/hot_reloading.rs | 3 --- crates/mun_runtime/src/lib.rs | 19 ++++++++++++------- crates/mun_runtime/tests/util.rs | 2 +- crates/mun_runtime_capi/src/lib.rs | 12 +++++++++--- 5 files changed, 24 insertions(+), 16 deletions(-) diff --git a/crates/mun/src/main.rs b/crates/mun/src/main.rs index 50d44ca3a..42dc10890 100644 --- a/crates/mun/src/main.rs +++ b/crates/mun/src/main.rs @@ -94,7 +94,7 @@ fn build(matches: &ArgMatches) -> Result<(), failure::Error> { /// Starts the runtime with the specified library and invokes function `entry`. fn start(matches: &ArgMatches) -> Result<(), failure::Error> { - let runtime = Rc::new(RefCell::new(runtime(matches)?)); + let runtime = runtime(matches)?; let borrowed = runtime.borrow(); let entry_point = matches.value_of("entry").unwrap_or("main"); @@ -168,7 +168,7 @@ fn compiler_options(matches: &ArgMatches) -> Result Result { +fn runtime(matches: &ArgMatches) -> Result>, failure::Error> { let builder = RuntimeBuilder::new( matches.value_of("LIBRARY").unwrap(), // Safe because its a required arg ); diff --git a/crates/mun_runtime/examples/hot_reloading.rs b/crates/mun_runtime/examples/hot_reloading.rs index cc0c63e7a..8090e33f3 100644 --- a/crates/mun_runtime/examples/hot_reloading.rs +++ b/crates/mun_runtime/examples/hot_reloading.rs @@ -1,7 +1,5 @@ use mun_runtime::{invoke_fn, RetryResultExt, RuntimeBuilder}; -use std::cell::RefCell; use std::env; -use std::rc::Rc; // How to run? // 1. On the CLI, navigate to the `crates/mun_runtime/examples` directory. @@ -15,7 +13,6 @@ fn main() { .spawn() .expect("Failed to spawn Runtime"); - let runtime = Rc::new(RefCell::new(runtime)); loop { let n: i64 = invoke_fn!(runtime, "nth").wait(); let result: i64 = invoke_fn!(runtime, "fibonacci", n).wait(); diff --git a/crates/mun_runtime/src/lib.rs b/crates/mun_runtime/src/lib.rs index 68522aef1..2074245d0 100644 --- a/crates/mun_runtime/src/lib.rs +++ b/crates/mun_runtime/src/lib.rs @@ -19,10 +19,12 @@ use memory::gc::{self, GcRuntime}; use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher}; use rustc_hash::FxHashMap; use std::{ + cell::RefCell, collections::HashMap, ffi, io, mem, path::{Path, PathBuf}, ptr::NonNull, + rc::Rc, string::ToString, sync::{ mpsc::{channel, Receiver}, @@ -64,10 +66,6 @@ impl RuntimeBuilder { user_functions: Default::default(), }, } - .insert_fn( - "new", - new as extern "C" fn(*const abi::TypeInfo, *mut ffi::c_void) -> *const *mut ffi::c_void, - ) } /// Sets the `delay`. @@ -85,8 +83,8 @@ impl RuntimeBuilder { } /// Spawns a [`Runtime`] with the builder's options. - pub fn spawn(self) -> Result { - Runtime::new(self.options) + pub fn spawn(self) -> Result>, Error> { + Runtime::new(self.options).map(|runtime| Rc::new(RefCell::new(runtime))) } } @@ -201,11 +199,18 @@ impl Runtime { /// Constructs a new `Runtime` that loads the library at `library_path` and its /// dependencies. The `Runtime` contains a file watcher that is triggered with an interval /// of `dur`. - pub fn new(options: RuntimeOptions) -> Result { + pub fn new(mut options: RuntimeOptions) -> Result { let (tx, rx) = channel(); let mut dispatch_table = DispatchTable::default(); + // Add internal functions + options.user_functions.push(IntoFunctionInfo::into( + new as extern "C" fn(*const abi::TypeInfo, *mut ffi::c_void) -> *const *mut ffi::c_void, + "new", + abi::Privacy::Public, + )); + let mut storages = Vec::with_capacity(options.user_functions.len()); for (info, storage) in options.user_functions.into_iter() { dispatch_table.insert_fn(info.signature.name().to_string(), info); diff --git a/crates/mun_runtime/tests/util.rs b/crates/mun_runtime/tests/util.rs index fb5ca33a0..188857a51 100644 --- a/crates/mun_runtime/tests/util.rs +++ b/crates/mun_runtime/tests/util.rs @@ -25,7 +25,7 @@ impl RuntimeOrBuilder { let previous = std::mem::replace(self, RuntimeOrBuilder::Pending); let runtime = match previous { RuntimeOrBuilder::Runtime(runtime) => runtime, - RuntimeOrBuilder::Builder(builder) => Rc::new(RefCell::new(builder.spawn()?)), + RuntimeOrBuilder::Builder(builder) => builder.spawn()?, _ => unreachable!(), }; std::mem::replace(self, RuntimeOrBuilder::Runtime(runtime)); diff --git a/crates/mun_runtime_capi/src/lib.rs b/crates/mun_runtime_capi/src/lib.rs index 67b4d0d31..3cf5f5e14 100644 --- a/crates/mun_runtime_capi/src/lib.rs +++ b/crates/mun_runtime_capi/src/lib.rs @@ -11,13 +11,13 @@ pub mod hub; mod tests; use std::ffi::{c_void, CStr, CString}; -use std::os::raw::c_char; +use std::{os::raw::c_char, time::Duration}; use crate::error::ErrorHandle; use crate::hub::HUB; use failure::err_msg; use mun_abi::{FunctionInfo, StructInfo, TypeInfo}; -use mun_runtime::{Runtime, RuntimeBuilder}; +use mun_runtime::{Runtime, RuntimeOptions}; pub(crate) type Token = usize; @@ -77,7 +77,13 @@ pub unsafe extern "C" fn mun_runtime_create( } }; - let runtime = match RuntimeBuilder::new(library_path).spawn() { + let options = RuntimeOptions { + library_path: library_path.into(), + delay: Duration::from_millis(10), + user_functions: Default::default(), + }; + + let runtime = match Runtime::new(options) { Ok(runtime) => runtime, Err(e) => return HUB.errors.register(Box::new(e)), };