mod support; use gluon::{ vm::{ api::{FunctionRef, OpaqueValue, IO}, reference::Reference, }, RootedThread, Thread, ThreadExt, }; use crate::support::*; fn verify_value_cloned(from: &Thread, to: &Thread) { from.get_database_mut().run_io(true); to.get_database_mut().run_io(true); from.run_expr::<()>("load", r#"let _ = import! std.reference in () "#) .unwrap_or_else(|err| panic!("{}", err)); to.run_expr::<()>("load", r#"let _ = import! std.reference in () "#) .unwrap_or_else(|err| panic!("{}", err)); let expr = r#" let { ref } = import! std.reference ref 0 "#; let value: OpaqueValue<_, _> = from .run_expr::>>>("example", expr) .and_then(|(io, _)| Result::from(io).map_err(From::from)) .unwrap_or_else(|err| panic!("{}", err)); // Load the prelude type Fn<'t> = FunctionRef<'t, fn(OpaqueValue>) -> IO<()>>; let store_expr = r#" let { (<-) } = import! std.reference \r -> r <- 1 "#; let (mut store_1, _) = to .run_expr::("store_1", store_expr) .unwrap_or_else(|err| panic!("{}", err)); assert_eq!(store_1.call(value.clone()), Ok(IO::Value(()))); let mut load: FunctionRef>) -> IO> = from.get_global("std.reference.load").unwrap(); assert_eq!(load.call(value), Ok(IO::Value(0))); } #[test] fn cant_transfer_opaque_value_between_sibling_threads() { let _ = ::env_logger::try_init(); // vm // / \ // vm1 vm2 // Passing a value directly from vm1 to vm2 requires the value to be cloned in its entirety let vm = make_vm(); let vm1 = vm.new_thread().unwrap(); let vm2 = vm.new_thread().unwrap(); verify_value_cloned(&vm1, &vm2); } #[test] fn cant_transfer_opaque_value_between_disjoint_threads() { let _ = ::env_logger::try_init(); // vm1 vm2 // Passing a value directly from vm1 to vm2 requires the value to be cloned in its entirety // since the vms do not share the same global vm let vm1 = make_vm(); let vm2 = make_vm(); verify_value_cloned(&vm1, &vm2); }