1use crate::ArrayBuffer;
2use crate::Context;
3use crate::Exception;
4use crate::Global;
5use crate::Isolate;
6use crate::Local;
7use crate::Object;
8use crate::PinScope;
9use crate::SharedArrayBuffer;
10use crate::String;
11use crate::Value;
12use crate::WasmModuleObject;
13use crate::isolate::RealIsolate;
14use crate::scope::CallbackScope;
15use crate::scope::ContextScope;
16use crate::scope::GetIsolate;
17
18use crate::support::CxxVTable;
19use crate::support::FieldOffset;
20use crate::support::MaybeBool;
21
22use std::ffi::c_void;
23use std::mem::MaybeUninit;
24use std::pin::Pin;
25use std::pin::pin;
26use std::ptr::addr_of;
27
28#[repr(C)]
31pub struct CxxValueDeserializerDelegate {
32 _cxx_vtable: CxxVTable,
33}
34
35#[unsafe(no_mangle)]
36unsafe extern "C" fn v8__ValueDeserializer__Delegate__ReadHostObject(
37 this: &CxxValueDeserializerDelegate,
38 isolate: *mut RealIsolate,
39) -> *const Object {
40 let value_deserializer_heap =
41 unsafe { ValueDeserializerHeap::dispatch(this) };
42 let mut isolate = unsafe { Isolate::from_raw_ptr(isolate) };
43 let scope = unsafe { CallbackScope::new(&mut isolate) };
44 let scope = pin!(scope);
45 let scope = &mut scope.init();
46 let context = Local::new(scope, &value_deserializer_heap.context);
47 let mut scope = { ContextScope::new(scope, context) };
48
49 match value_deserializer_heap
50 .value_deserializer_impl
51 .read_host_object(
52 &mut scope,
53 &value_deserializer_heap.cxx_value_deserializer,
54 ) {
55 None => std::ptr::null(),
56 Some(x) => x.as_non_null().as_ptr(),
57 }
58}
59
60#[unsafe(no_mangle)]
61unsafe extern "C" fn v8__ValueDeserializer__Delegate__GetSharedArrayBufferFromId(
62 this: &CxxValueDeserializerDelegate,
63 isolate: *mut RealIsolate,
64 transfer_id: u32,
65) -> *const SharedArrayBuffer {
66 let value_deserializer_heap =
67 unsafe { ValueDeserializerHeap::dispatch(this) };
68 let mut isolate = unsafe { Isolate::from_raw_ptr(isolate) };
69 let scope = unsafe { CallbackScope::new(&mut isolate) };
70 let scope = pin!(scope);
71 let scope = &mut scope.init();
72 let context = Local::new(scope, &value_deserializer_heap.context);
74 let mut scope = { ContextScope::new(scope, context) };
75
76 match value_deserializer_heap
77 .value_deserializer_impl
78 .get_shared_array_buffer_from_id(&mut scope, transfer_id)
79 {
80 None => std::ptr::null(),
81 Some(x) => x.as_non_null().as_ptr(),
82 }
83}
84
85#[unsafe(no_mangle)]
86unsafe extern "C" fn v8__ValueDeserializer__Delegate__GetWasmModuleFromId(
87 this: &mut CxxValueDeserializerDelegate,
88 isolate: *mut RealIsolate,
89 clone_id: u32,
90) -> *const WasmModuleObject {
91 let value_deserializer_heap =
92 unsafe { ValueDeserializerHeap::dispatch(this) };
93 let mut isolate = unsafe { Isolate::from_raw_ptr(isolate) };
94 let scope = unsafe { CallbackScope::new(&mut isolate) };
95 let scope = pin!(scope);
96 let scope = &mut scope.init();
97 let context = Local::new(scope, &value_deserializer_heap.context);
98 let mut scope = { ContextScope::new(scope, context) };
99
100 match value_deserializer_heap
101 .value_deserializer_impl
102 .get_wasm_module_from_id(&mut scope, clone_id)
103 {
104 None => std::ptr::null(),
105 Some(x) => x.as_non_null().as_ptr(),
106 }
107}
108
109unsafe extern "C" {
110 fn v8__ValueDeserializer__Delegate__CONSTRUCT(
111 buf: *mut MaybeUninit<CxxValueDeserializerDelegate>,
112 );
113}
114
115#[repr(C)]
118pub struct CxxValueDeserializer {
119 _cxx_vtable: CxxVTable,
120}
121
122unsafe extern "C" {
123 fn v8__ValueDeserializer__CONSTRUCT(
124 buf: *mut MaybeUninit<CxxValueDeserializer>,
125 isolate: *mut RealIsolate,
126 data: *const u8,
127 size: usize,
128 delegate: *mut CxxValueDeserializerDelegate,
129 );
130
131 fn v8__ValueDeserializer__DESTRUCT(this: *mut CxxValueDeserializer);
132
133 fn v8__ValueDeserializer__TransferArrayBuffer(
134 this: *mut CxxValueDeserializer,
135 transfer_id: u32,
136 array_buffer: Local<ArrayBuffer>,
137 );
138
139 fn v8__ValueDeserializer__TransferSharedArrayBuffer(
140 this: *mut CxxValueDeserializer,
141 transfer_id: u32,
142 array_buffer: Local<SharedArrayBuffer>,
143 );
144
145 fn v8__ValueDeserializer__SetSupportsLegacyWireFormat(
146 this: *mut CxxValueDeserializer,
147 supports_legacy_wire_format: bool,
148 );
149
150 fn v8__ValueDeserializer__ReadHeader(
151 this: *mut CxxValueDeserializer,
152 context: Local<Context>,
153 ) -> MaybeBool;
154
155 fn v8__ValueDeserializer__ReadValue(
156 this: *mut CxxValueDeserializer,
157 context: Local<Context>,
158 ) -> *const Value;
159
160 fn v8__ValueDeserializer__ReadUint32(
161 this: *mut CxxValueDeserializer,
162 value: *mut u32,
163 ) -> bool;
164
165 fn v8__ValueDeserializer__ReadUint64(
166 this: *mut CxxValueDeserializer,
167 value: *mut u64,
168 ) -> bool;
169
170 fn v8__ValueDeserializer__ReadDouble(
171 this: *mut CxxValueDeserializer,
172 value: *mut f64,
173 ) -> bool;
174
175 fn v8__ValueDeserializer__ReadRawBytes(
176 this: *mut CxxValueDeserializer,
177 length: usize,
178 data: *mut *const c_void,
179 ) -> bool;
180
181 fn v8__ValueDeserializer__GetWireFormatVersion(
182 this: *mut CxxValueDeserializer,
183 ) -> u32;
184}
185
186pub trait ValueDeserializerImpl {
189 fn read_host_object<'s>(
190 &self,
191 scope: &mut PinScope<'s, '_>,
192 _value_deserializer: &dyn ValueDeserializerHelper,
193 ) -> Option<Local<'s, Object>> {
194 let msg =
195 String::new(scope, "Deno deserializer: read_host_object not implemented")
196 .unwrap();
197 let exc = Exception::error(scope, msg);
198 scope.throw_exception(exc);
199 None
200 }
201
202 fn get_shared_array_buffer_from_id<'s>(
203 &self,
204 scope: &mut PinScope<'s, '_>,
205 _transfer_id: u32,
206 ) -> Option<Local<'s, SharedArrayBuffer>> {
207 let msg = String::new(
208 scope,
209 "Deno deserializer: get_shared_array_buffer_from_id not implemented",
210 )
211 .unwrap();
212 let exc = Exception::error(scope, msg);
213 scope.throw_exception(exc);
214 None
215 }
216
217 fn get_wasm_module_from_id<'s>(
218 &self,
219 scope: &mut PinScope<'s, '_>,
220 _clone_id: u32,
221 ) -> Option<Local<'s, WasmModuleObject>> {
222 let msg = String::new(
223 scope,
224 "Deno deserializer: get_wasm_module_from_id not implemented",
225 )
226 .unwrap();
227 let exc = Exception::error(scope, msg);
228 scope.throw_exception(exc);
229 None
230 }
231}
232
233fn cast_to_ptr<T>(t: &T) -> *mut T {
234 t as *const _ as *mut _
235}
236
237pub struct ValueDeserializerHeap<'a> {
245 value_deserializer_impl: Box<dyn ValueDeserializerImpl + 'a>,
246 cxx_value_deserializer: CxxValueDeserializer,
247 cxx_value_deserializer_delegate: CxxValueDeserializerDelegate,
248 context: Global<Context>,
249}
250
251impl ValueDeserializerHeap<'_> {
252 fn get_cxx_value_deserializer_delegate_offset()
253 -> FieldOffset<CxxValueDeserializerDelegate> {
254 let buf = std::mem::MaybeUninit::<Self>::uninit();
255 let delegate =
256 unsafe { addr_of!((*buf.as_ptr()).cxx_value_deserializer_delegate) };
257 FieldOffset::from_ptrs(buf.as_ptr(), delegate)
258 }
259
260 pub unsafe fn dispatch(
262 value_serializer_delegate: &CxxValueDeserializerDelegate,
263 ) -> &Self {
264 unsafe {
265 Self::get_cxx_value_deserializer_delegate_offset()
266 .to_embedder::<Self>(value_serializer_delegate)
267 }
268 }
269}
270
271impl Drop for ValueDeserializerHeap<'_> {
272 fn drop(&mut self) {
273 unsafe {
274 v8__ValueDeserializer__DESTRUCT(&mut self.cxx_value_deserializer);
275 };
276 }
277}
278
279pub trait ValueDeserializerHelper {
283 fn get_cxx_value_deserializer(&self) -> &CxxValueDeserializer;
284
285 fn read_header(&self, context: Local<Context>) -> Option<bool> {
286 unsafe {
287 v8__ValueDeserializer__ReadHeader(
288 cast_to_ptr(self.get_cxx_value_deserializer()),
289 context,
290 )
291 }
292 .into()
293 }
294
295 fn read_value<'s>(
296 &self,
297 context: Local<'s, Context>,
298 ) -> Option<Local<'s, Value>> {
299 unsafe {
300 Local::from_raw(v8__ValueDeserializer__ReadValue(
301 cast_to_ptr(self.get_cxx_value_deserializer()),
302 context,
303 ))
304 }
305 }
306
307 fn read_uint32(&self, value: &mut u32) -> bool {
308 unsafe {
309 v8__ValueDeserializer__ReadUint32(
310 cast_to_ptr(self.get_cxx_value_deserializer()),
311 value,
312 )
313 }
314 }
315
316 fn read_uint64(&self, value: &mut u64) -> bool {
317 unsafe {
318 v8__ValueDeserializer__ReadUint64(
319 cast_to_ptr(self.get_cxx_value_deserializer()),
320 value,
321 )
322 }
323 }
324
325 fn read_double(&self, value: &mut f64) -> bool {
326 unsafe {
327 v8__ValueDeserializer__ReadDouble(
328 cast_to_ptr(self.get_cxx_value_deserializer()),
329 value,
330 )
331 }
332 }
333
334 fn read_raw_bytes(&self, length: usize) -> Option<&[u8]> {
335 let mut data: *const c_void = std::ptr::null_mut();
336 let ok = unsafe {
337 v8__ValueDeserializer__ReadRawBytes(
338 cast_to_ptr(self.get_cxx_value_deserializer()),
339 length,
340 &mut data,
341 )
342 };
343 if ok {
344 assert!(!data.is_null());
345 unsafe { Some(std::slice::from_raw_parts(data as *const u8, length)) }
346 } else {
347 None
348 }
349 }
350
351 fn transfer_array_buffer(
352 &self,
353 transfer_id: u32,
354 array_buffer: Local<ArrayBuffer>,
355 ) {
356 unsafe {
357 v8__ValueDeserializer__TransferArrayBuffer(
358 cast_to_ptr(self.get_cxx_value_deserializer()),
359 transfer_id,
360 array_buffer,
361 );
362 };
363 }
364
365 fn transfer_shared_array_buffer(
366 &self,
367 transfer_id: u32,
368 shared_array_buffer: Local<SharedArrayBuffer>,
369 ) {
370 unsafe {
371 v8__ValueDeserializer__TransferSharedArrayBuffer(
372 cast_to_ptr(self.get_cxx_value_deserializer()),
373 transfer_id,
374 shared_array_buffer,
375 );
376 };
377 }
378
379 fn get_wire_format_version(&self) -> u32 {
380 unsafe {
381 v8__ValueDeserializer__GetWireFormatVersion(cast_to_ptr(
382 self.get_cxx_value_deserializer(),
383 ))
384 }
385 }
386}
387
388impl ValueDeserializerHelper for CxxValueDeserializer {
389 fn get_cxx_value_deserializer(&self) -> &CxxValueDeserializer {
390 self
391 }
392}
393
394impl ValueDeserializerHelper for ValueDeserializerHeap<'_> {
395 fn get_cxx_value_deserializer(&self) -> &CxxValueDeserializer {
396 &self.cxx_value_deserializer
397 }
398}
399
400impl ValueDeserializerHelper for ValueDeserializer<'_> {
401 fn get_cxx_value_deserializer(&self) -> &CxxValueDeserializer {
402 &self.value_deserializer_heap.cxx_value_deserializer
403 }
404}
405
406pub struct ValueDeserializer<'a> {
412 value_deserializer_heap: Pin<Box<ValueDeserializerHeap<'a>>>,
413 _phantom: std::marker::PhantomData<*mut ()>,
416}
417
418impl<'a> ValueDeserializer<'a> {
419 pub fn new<'s, 'i, D: ValueDeserializerImpl + 'a>(
420 scope: &PinScope<'s, 'i>,
421 value_deserializer_impl: Box<D>,
422 data: &[u8],
423 ) -> Self {
424 let context = scope.get_current_context();
425 let value_deserializer_heap_ptr =
427 Box::into_raw(Box::new(ValueDeserializerHeap {
428 value_deserializer_impl,
429 cxx_value_deserializer: CxxValueDeserializer {
430 _cxx_vtable: CxxVTable(std::ptr::null()),
431 },
432 cxx_value_deserializer_delegate: CxxValueDeserializerDelegate {
433 _cxx_vtable: CxxVTable(std::ptr::null()),
434 },
435 context: Global::new(scope, context),
436 }));
437
438 unsafe {
439 let delegate_ptr = std::ptr::addr_of_mut!(
440 (*value_deserializer_heap_ptr).cxx_value_deserializer_delegate
441 );
442 let deserializer_ptr = std::ptr::addr_of_mut!(
443 (*value_deserializer_heap_ptr).cxx_value_deserializer
444 );
445 v8__ValueDeserializer__Delegate__CONSTRUCT(
446 delegate_ptr
447 .cast::<std::mem::MaybeUninit<CxxValueDeserializerDelegate>>(),
448 );
449
450 v8__ValueDeserializer__CONSTRUCT(
451 deserializer_ptr.cast::<std::mem::MaybeUninit<CxxValueDeserializer>>(),
452 scope.get_isolate_ptr(),
453 data.as_ptr(),
454 data.len(),
455 delegate_ptr,
456 );
457 };
458
459 let value_deserializer_heap =
461 Pin::new(unsafe { Box::from_raw(value_deserializer_heap_ptr) });
462
463 ValueDeserializer {
464 value_deserializer_heap,
465 _phantom: std::marker::PhantomData,
466 }
467 }
468}
469
470impl ValueDeserializer<'_> {
471 pub fn set_supports_legacy_wire_format(
472 &self,
473 supports_legacy_wire_format: bool,
474 ) {
475 unsafe {
476 v8__ValueDeserializer__SetSupportsLegacyWireFormat(
477 cast_to_ptr(&self.value_deserializer_heap.cxx_value_deserializer),
478 supports_legacy_wire_format,
479 );
480 }
481 }
482
483 pub fn read_value<'t>(
484 &self,
485 context: Local<'t, Context>,
486 ) -> Option<Local<'t, Value>> {
487 self.value_deserializer_heap.read_value(context)
488 }
489}