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
5pub struct AllocatedBytesPtr(pub u32, pub u32);
7
8#[cfg(target_arch = "wasm32")]
9extern "C" {
10 fn __free(ptr: *mut u8, size: i32) -> i32;
11}
12#[cfg(target_arch = "wasm32")]
13impl Drop for AllocatedBytesPtr {
14 fn drop(&mut self) {
15 unsafe {
16 __free(self.0 as _, self.1 as _);
17 }
18 }
19}
20
21#[cfg(not(feature = "encoding-impl"))]
22fn read_returned_result_from_host_inner<F>(f: F) -> Option<AllocatedBytesPtr> {
23 unimplemented!("Plugin proxy does not work without serialization support")
24}
25
26#[cfg(all(
35 feature = "encoding-impl",
36 feature = "__plugin_mode",
37 target_arch = "wasm32"
38))]
39#[tracing::instrument(level = "info", skip_all)]
40fn read_returned_result_from_host_inner<F>(f: F) -> Option<AllocatedBytesPtr>
41where
42 F: FnOnce(u32) -> u32,
43{
44 use std::cell::UnsafeCell;
45
46 let allocated_bytes_ptr: UnsafeCell<[u32; 2]> = UnsafeCell::new([0; 2]);
51 let serialized_allocated_bytes_raw_ptr = allocated_bytes_ptr.get();
52
53 assert_eq!(std::mem::size_of::<*mut u32>(), std::mem::size_of::<u32>());
54
55 let ret = f(serialized_allocated_bytes_raw_ptr as _);
56
57 if ret == 0 {
62 return None;
63 }
64
65 let allocated_bytes_ptr = allocated_bytes_ptr.into_inner();
66
67 Some(AllocatedBytesPtr(
69 allocated_bytes_ptr[0],
70 allocated_bytes_ptr[1],
71 ))
72}
73
74#[cfg(not(feature = "encoding-impl"))]
75pub fn read_returned_result_from_host<F, R>(f: F) -> Option<R> {
76 unimplemented!("Plugin proxy does not work without serialization support")
77}
78
79#[cfg(all(
83 feature = "encoding-impl",
84 feature = "__plugin_mode",
85 target_arch = "wasm32"
86))]
87#[cfg_attr(not(target_arch = "wasm32"), allow(unused))]
88#[tracing::instrument(level = "info", skip_all)]
89pub fn read_returned_result_from_host<F, R>(f: F) -> Option<R>
90where
91 F: FnOnce(u32) -> u32,
92 R: for<'de> cbor4ii::core::dec::Decode<'de>,
93{
94 let allocated_returned_value_ptr = read_returned_result_from_host_inner(f);
95
96 allocated_returned_value_ptr.map(|allocated_returned_value_ptr| {
98 PluginSerializedBytes::from_raw_ptr(
99 allocated_returned_value_ptr.0 as _,
100 allocated_returned_value_ptr
101 .1
102 .try_into()
103 .expect("Should able to convert ptr length"),
104 )
105 .deserialize()
106 .expect("Returned value should be serializable")
107 .into_inner()
108 })
109}