1use crate::ArrayBuffer;
4use crate::Local;
5use crate::PinScope;
6use crate::Value;
7use crate::WasmMemoryObject;
8use crate::WasmModuleObject;
9use crate::function::FunctionCallbackArguments;
10use crate::function::FunctionCallbackInfo;
11use crate::isolate::RealIsolate;
12use crate::scope::GetIsolate;
13use crate::scope::callback_scope;
14use crate::support::Opaque;
15use crate::support::UnitType;
16use crate::support::char;
17use std::ptr::null;
18use std::ptr::null_mut;
19
20#[repr(C)]
31struct WasmStreamingSharedPtr([*mut u8; 2]);
32
33#[repr(C)]
38pub struct WasmStreaming(WasmStreamingSharedPtr);
39
40impl WasmStreaming {
41 #[inline(always)]
43 pub fn on_bytes_received(&mut self, data: &[u8]) {
44 unsafe {
45 v8__WasmStreaming__OnBytesReceived(
46 &mut self.0,
47 data.as_ptr(),
48 data.len(),
49 );
50 }
51 }
52
53 #[inline(always)]
58 pub fn finish(mut self) {
59 unsafe { v8__WasmStreaming__Finish(&mut self.0) }
60 }
61
62 #[inline(always)]
66 pub fn abort(mut self, exception: Option<Local<Value>>) {
67 let exception = exception.map_or(null(), |v| &*v as *const Value);
68 unsafe { v8__WasmStreaming__Abort(&mut self.0, exception) }
69 }
70
71 #[inline(always)]
74 pub fn set_url(&mut self, url: &str) {
75 let null_terminated_url = format!("{url}\0");
78 unsafe {
79 v8__WasmStreaming__SetUrl(
80 &mut self.0,
81 null_terminated_url.as_ptr() as *const char,
82 url.len(),
83 );
84 }
85 }
86}
87
88impl Drop for WasmStreaming {
89 fn drop(&mut self) {
90 unsafe { v8__WasmStreaming__shared_ptr_DESTRUCT(&mut self.0) }
91 }
92}
93
94impl WasmModuleObject {
95 #[inline(always)]
98 pub fn from_compiled_module<'s>(
99 scope: &PinScope<'s, '_>,
100 compiled_module: &CompiledWasmModule,
101 ) -> Option<Local<'s, WasmModuleObject>> {
102 unsafe {
103 scope.cast_local(|sd| {
104 v8__WasmModuleObject__FromCompiledModule(
105 sd.get_isolate_ptr(),
106 compiled_module.0,
107 )
108 })
109 }
110 }
111
112 #[inline(always)]
115 pub fn get_compiled_module(&self) -> CompiledWasmModule {
116 let ptr = unsafe { v8__WasmModuleObject__GetCompiledModule(self) };
117 CompiledWasmModule(ptr)
118 }
119
120 #[inline(always)]
122 pub fn compile<'s>(
123 scope: &PinScope<'s, '_>,
124 wire_bytes: &[u8],
125 ) -> Option<Local<'s, WasmModuleObject>> {
126 unsafe {
127 scope.cast_local(|sd| {
128 v8__WasmModuleObject__Compile(
129 sd.get_isolate_ptr(),
130 wire_bytes.as_ptr(),
131 wire_bytes.len(),
132 )
133 })
134 }
135 }
136}
137
138#[repr(C)]
145struct InternalCompiledWasmModule(Opaque);
146
147pub struct CompiledWasmModule(*mut InternalCompiledWasmModule);
150
151impl CompiledWasmModule {
152 #[inline(always)]
154 pub fn get_wire_bytes_ref(&self) -> &[u8] {
155 let mut len = 0isize;
156 unsafe {
157 let ptr = v8__CompiledWasmModule__GetWireBytesRef(self.0, &mut len);
158 std::slice::from_raw_parts(ptr, len.try_into().unwrap())
159 }
160 }
161
162 #[inline(always)]
163 pub fn source_url(&self) -> &str {
164 let mut len = 0;
165 unsafe {
166 let ptr = v8__CompiledWasmModule__SourceUrl(self.0, &mut len);
167 let bytes = std::slice::from_raw_parts(ptr as _, len);
168 std::str::from_utf8_unchecked(bytes)
169 }
170 }
171}
172
173unsafe impl Send for CompiledWasmModule {}
175unsafe impl Sync for CompiledWasmModule {}
176
177impl Drop for CompiledWasmModule {
178 fn drop(&mut self) {
179 unsafe { v8__CompiledWasmModule__DELETE(self.0) }
180 }
181}
182
183impl WasmMemoryObject {
184 #[inline(always)]
186 pub fn buffer(&self) -> Local<'_, ArrayBuffer> {
187 unsafe { Local::from_raw(v8__WasmMemoryObject__Buffer(self)) }.unwrap()
188 }
189}
190
191pub(crate) fn trampoline<F>()
192-> unsafe extern "C" fn(*const FunctionCallbackInfo)
193where
194 F: UnitType
195 + for<'a, 'b, 'c> Fn(
196 &'c mut PinScope<'a, 'b>,
197 Local<'a, Value>,
198 WasmStreaming,
199 ),
200{
201 unsafe extern "C" fn c_fn<F>(info: *const FunctionCallbackInfo)
202 where
203 F: UnitType
204 + for<'a, 'b, 'c> Fn(
205 &'c mut PinScope<'a, 'b>,
206 Local<'a, Value>,
207 WasmStreaming,
208 ),
209 {
210 let info = unsafe { &*info };
211 callback_scope!(unsafe scope, info);
212 let args = FunctionCallbackArguments::from_function_callback_info(info);
213 let data = args.data();
214 let zero = null_mut();
215 let mut that = WasmStreamingSharedPtr([zero, zero]);
216 unsafe {
217 v8__WasmStreaming__Unpack(scope.get_isolate_ptr(), &*data, &mut that);
218 };
219 let source = args.get(0);
220 (F::get())(scope, source, WasmStreaming(that));
221 }
222 c_fn::<F>
223}
224
225unsafe extern "C" {
226 fn v8__WasmStreaming__Unpack(
227 isolate: *mut RealIsolate,
228 value: *const Value,
229 that: *mut WasmStreamingSharedPtr, );
231 fn v8__WasmStreaming__shared_ptr_DESTRUCT(this: *mut WasmStreamingSharedPtr);
232 fn v8__WasmStreaming__OnBytesReceived(
233 this: *mut WasmStreamingSharedPtr,
234 data: *const u8,
235 len: usize,
236 );
237 fn v8__WasmStreaming__Finish(this: *mut WasmStreamingSharedPtr);
238 fn v8__WasmStreaming__Abort(
239 this: *mut WasmStreamingSharedPtr,
240 exception: *const Value,
241 );
242 fn v8__WasmStreaming__SetUrl(
243 this: *mut WasmStreamingSharedPtr,
244 url: *const char,
245 len: usize,
246 );
247
248 fn v8__WasmModuleObject__FromCompiledModule(
249 isolate: *mut RealIsolate,
250 compiled_module: *const InternalCompiledWasmModule,
251 ) -> *const WasmModuleObject;
252 fn v8__WasmModuleObject__GetCompiledModule(
253 this: *const WasmModuleObject,
254 ) -> *mut InternalCompiledWasmModule;
255 fn v8__WasmModuleObject__Compile(
256 isolate: *mut RealIsolate,
257 wire_bytes_data: *const u8,
258 length: usize,
259 ) -> *mut WasmModuleObject;
260
261 fn v8__CompiledWasmModule__GetWireBytesRef(
262 this: *mut InternalCompiledWasmModule,
263 length: *mut isize,
264 ) -> *const u8;
265 fn v8__CompiledWasmModule__SourceUrl(
266 this: *mut InternalCompiledWasmModule,
267 length: *mut usize,
268 ) -> *const char;
269 fn v8__CompiledWasmModule__DELETE(this: *mut InternalCompiledWasmModule);
270
271 fn v8__WasmMemoryObject__Buffer(
272 this: *const WasmMemoryObject,
273 ) -> *mut ArrayBuffer;
274}