Created
June 13, 2024 05:23
-
-
Save fzyzcjy/10b49b8a34a6f7c62028aee26046fc7c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::sync::{Arc, RwLock}; | |
// ----------------------------------------------------------------------------------------- | |
// Suppose we have such user code | |
pub struct One(String); | |
impl One { | |
fn f(&self) -> Two { | |
// users can put arbitrarily complex computation here | |
Two { one: self } | |
} | |
} | |
pub struct Two<'a> { | |
// users can put arbitrarily complex type here | |
one: &'a One, | |
} | |
impl Two<'_> { | |
fn g(&self) { | |
// users can put arbitrarily complex computation here | |
println!("Two.g called"); | |
println!("Access some data: {}", self.one.0); | |
} | |
} | |
// ----------------------------------------------------------------------------------------- | |
// And suppose we want to call `one.f()` and then `two.g()` | |
// Here, we use Rust to mimic real Dart code | |
fn pseudo_dart_code() { | |
// Rust `Arc<RwLock<Something>>` is roughly treated as an integer in Dart | |
let one_usize = rust_create_one(); | |
let two_usize = rust_call_method_f(one_usize); | |
rust_call_method_g(two_usize); | |
} | |
// ----------------------------------------------------------------------------------------- | |
fn rust_create_one() -> usize { | |
let one_arc_rwlock = Arc::new(RwLock::new(One("hello_one".to_owned()))); | |
Arc::into_raw(one_arc_rwlock) as _ | |
} | |
fn rust_call_method_f(one_usize: usize) -> usize { | |
unsafe { Arc::<RwLock<crate::naive_arc::One>>::increment_strong_count(one_usize as _); } | |
let one_arc_rwlock: Arc<RwLock<One>> = unsafe { Arc::from_raw(one_usize as _) }; | |
let one_read_guard = one_arc_rwlock.read().unwrap(); | |
let two: Two = one_read_guard.f(); | |
let two_arc_rwlock: Arc<RwLock<Two>> = Arc::new(RwLock::new(two)); | |
// this is wrong | |
Arc::into_raw(two_arc_rwlock) as _ | |
} | |
fn rust_call_method_g(two_usize: usize) { | |
let two_arc_rwlock: Arc<RwLock<Two>> = unsafe { Arc::from_raw(two_usize as _) }; | |
let two_read_guard = two_arc_rwlock.read().unwrap(); | |
two_read_guard.g(); | |
} | |
// ----------------------------------------------------------------------------------------- | |
pub fn main() { | |
pseudo_dart_code(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::sync::{Arc, RwLock, RwLockReadGuard}; | |
// ----------------------------------------------------------------------------------------- | |
// Suppose we have such user code | |
pub struct One(String); | |
impl One { | |
fn f(&self) -> Two { | |
// users can put arbitrarily complex computation here | |
Two { one: self } | |
} | |
} | |
pub struct Two<'a> { | |
// users can put arbitrarily complex type here | |
one: &'a One, | |
} | |
impl Two<'_> { | |
fn g(&self) { | |
// users can put arbitrarily complex computation here | |
println!("Two.g called"); | |
println!("Access some data: {}", self.one.0); | |
} | |
} | |
// ----------------------------------------------------------------------------------------- | |
// And suppose we want to call `one.f()` and then `two.g()` | |
// Here, we use Rust to mimic real Dart code | |
fn pseudo_dart_code() { | |
// Rust `Arc<RwLock<Something>>` is roughly treated as an integer in Dart | |
let one_usize = rust_create_one(); | |
let two_usize = rust_call_method_f(one_usize); | |
rust_call_method_g(two_usize); | |
} | |
// ----------------------------------------------------------------------------------------- | |
fn rust_create_one() -> usize { | |
let one_arc_rwlock = Arc::new(RwLock::new(One("hello_one".to_owned()))); | |
Arc::into_raw(one_arc_rwlock) as _ | |
} | |
fn rust_call_method_f(one_usize: usize) -> usize { | |
let one_arc_rwlock: Arc<RwLock<One>> = unsafe { Arc::from_raw(one_usize as _) }; | |
let one_arc_read_guard = Arc::new(one_arc_rwlock.read().unwrap()); | |
let two: Two = one_arc_read_guard.f(); | |
let pack: Arc<RwLock<Pack>> = Arc::new(RwLock::new((one_arc_rwlock.clone(), one_arc_read_guard.clone(), two))); | |
// this is wrong | |
Arc::into_raw(pack) as _ | |
} | |
type Pack<'a, 'b> = (Arc<RwLock<One>>, Arc<RwLockReadGuard<'a, One>>, Two<'b>); | |
fn rust_call_method_g(two_usize: usize) { | |
let pack_arc_rwlock: Arc<RwLock<Pack>> = unsafe { Arc::from_raw(two_usize as _) }; | |
let guard = pack_arc_rwlock.read().unwrap(); | |
guard.2.g(); | |
} | |
// ----------------------------------------------------------------------------------------- | |
pub fn main() { | |
pseudo_dart_code(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment