swc_plugin_proxy/memory_interop/
read_returned_result_from_host.rs1#[cfg_attr(not(target_arch = "wasm32"), allow(unused))]
2#[cfg(any(feature = "__plugin_rt", feature = "__plugin_mode"))]
3use swc_common::plugin::serialized::PluginSerializedBytes;
4
5#[cfg_attr(
7 feature = "__rkyv",
8 derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
9)]
10#[cfg_attr(feature = "__rkyv", repr(C))]
11pub struct AllocatedBytesPtr(pub u32, pub u32);
12
13#[cfg(target_arch = "wasm32")]
14extern "C" {
15 fn __free(ptr: *mut u8, size: i32) -> i32;
16}
17#[cfg(target_arch = "wasm32")]
18impl Drop for AllocatedBytesPtr {
19 fn drop(&mut self) {
20 unsafe {
21 __free(self.0 as _, self.1 as _);
22 }
23 }
24}
25
26#[cfg(not(feature = "__rkyv"))]
27fn read_returned_result_from_host_inner<F>(f: F) -> Option<AllocatedBytesPtr> {
28 unimplemented!("Plugin proxy does not work without serialization support")
29}
30
31#[cfg(all(feature = "__rkyv", feature = "__plugin_mode", target_arch = "wasm32"))]
40#[tracing::instrument(level = "info", skip_all)]
41fn read_returned_result_from_host_inner<F>(f: F) -> Option<AllocatedBytesPtr>
42where
43 F: FnOnce(u32) -> u32,
44{
45 let allocated_bytes_ptr =
47 swc_common::plugin::serialized::VersionedSerializable::new(AllocatedBytesPtr(0, 0));
48 let serialized_allocated_bytes_ptr = PluginSerializedBytes::try_serialize(&allocated_bytes_ptr)
49 .expect("Should able to serialize AllocatedBytesPtr");
50 let (serialized_allocated_bytes_raw_ptr, serialized_allocated_bytes_raw_ptr_size) =
51 serialized_allocated_bytes_ptr.as_ptr();
52
53 std::mem::forget(allocated_bytes_ptr); let ret = f(serialized_allocated_bytes_raw_ptr as _);
56
57 if ret == 0 {
62 return None;
63 }
64
65 Some(
67 PluginSerializedBytes::from_raw_ptr(
68 serialized_allocated_bytes_raw_ptr,
69 serialized_allocated_bytes_raw_ptr_size
70 .try_into()
71 .expect("Should able to convert ptr length"),
72 )
73 .deserialize()
74 .expect("Should able to deserialize AllocatedBytesPtr")
75 .into_inner(),
76 )
77}
78
79#[cfg(not(feature = "__rkyv"))]
80pub fn read_returned_result_from_host<F, R>(f: F) -> Option<R> {
81 unimplemented!("Plugin proxy does not work without serialization support")
82}
83
84#[cfg(all(feature = "__rkyv", feature = "__plugin_mode", target_arch = "wasm32"))]
88#[cfg_attr(not(target_arch = "wasm32"), allow(unused))]
89#[tracing::instrument(level = "info", skip_all)]
90pub fn read_returned_result_from_host<F, R>(f: F) -> Option<R>
91where
92 F: FnOnce(u32) -> u32,
93 R: rkyv::Archive,
94 R::Archived: rkyv::Deserialize<R, rancor::Strategy<rkyv::de::Pool, rancor::Error>>,
95 for<'a> R::Archived: bytecheck::CheckBytes<
96 rancor::Strategy<
97 rkyv::validation::Validator<
98 rkyv::validation::archive::ArchiveValidator<'a>,
99 rkyv::validation::shared::SharedValidator,
100 >,
101 rancor::Error,
102 >,
103 >,
104{
105 let allocated_returned_value_ptr = read_returned_result_from_host_inner(f);
106
107 allocated_returned_value_ptr.map(|allocated_returned_value_ptr| {
109 PluginSerializedBytes::from_raw_ptr(
110 allocated_returned_value_ptr.0 as _,
111 allocated_returned_value_ptr
112 .1
113 .try_into()
114 .expect("Should able to convert ptr length"),
115 )
116 .deserialize()
117 .expect("Returned value should be serializable")
118 .into_inner()
119 })
120}