diff options
Diffstat (limited to 'serde_v8')
| -rw-r--r-- | serde_v8/error.rs | 1 | ||||
| -rw-r--r-- | serde_v8/lib.rs | 1 | ||||
| -rw-r--r-- | serde_v8/magic/external_pointer.rs | 56 | ||||
| -rw-r--r-- | serde_v8/magic/mod.rs | 2 | ||||
| -rw-r--r-- | serde_v8/ser.rs | 12 |
5 files changed, 70 insertions, 2 deletions
diff --git a/serde_v8/error.rs b/serde_v8/error.rs index 2cd8eab65..145524abb 100644 --- a/serde_v8/error.rs +++ b/serde_v8/error.rs @@ -22,6 +22,7 @@ pub enum Error { ExpectedObject, ExpectedBuffer, ExpectedDetachable, + ExpectedExternal, ExpectedUtf8, ExpectedLatin1, diff --git a/serde_v8/lib.rs b/serde_v8/lib.rs index c15ca715a..b857acbe8 100644 --- a/serde_v8/lib.rs +++ b/serde_v8/lib.rs @@ -20,6 +20,7 @@ pub use magic::bytestring::ByteString; pub use magic::detached_buffer::DetachedBuffer; pub use magic::string_or_buffer::StringOrBuffer; pub use magic::u16string::U16String; +pub use magic::ExternalPointer; pub use magic::Global; pub use magic::Value; pub use ser::to_v8; diff --git a/serde_v8/magic/external_pointer.rs b/serde_v8/magic/external_pointer.rs new file mode 100644 index 000000000..fca6028d6 --- /dev/null +++ b/serde_v8/magic/external_pointer.rs @@ -0,0 +1,56 @@ +// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. + +use std::ffi::c_void; + +use super::transl8::impl_magic; +use super::transl8::FromV8; +use super::transl8::ToV8; + +pub struct ExternalPointer(*mut c_void); + +// SAFETY: Nonblocking FFI is user controller and we must trust user to have it right. +unsafe impl Send for ExternalPointer {} +// SAFETY: Nonblocking FFI is user controller and we must trust user to have it right. +unsafe impl Sync for ExternalPointer {} + +impl_magic!(ExternalPointer); + +impl ToV8 for ExternalPointer { + fn to_v8<'a>( + &mut self, + scope: &mut v8::HandleScope<'a>, + ) -> Result<v8::Local<'a, v8::Value>, crate::Error> { + if self.0.is_null() { + Ok(v8::null(scope).into()) + } else { + Ok(v8::External::new(scope, self.0).into()) + } + } +} + +impl FromV8 for ExternalPointer { + fn from_v8( + _scope: &mut v8::HandleScope, + value: v8::Local<v8::Value>, + ) -> Result<Self, crate::Error> { + if value.is_null() { + Ok(ExternalPointer(std::ptr::null_mut())) + } else if let Ok(external) = v8::Local::<v8::External>::try_from(value) { + Ok(ExternalPointer(external.value())) + } else { + Err(crate::Error::ExpectedExternal) + } + } +} + +impl From<*mut c_void> for ExternalPointer { + fn from(value: *mut c_void) -> Self { + ExternalPointer(value) + } +} + +impl From<*const c_void> for ExternalPointer { + fn from(value: *const c_void) -> Self { + ExternalPointer(value as *mut c_void) + } +} diff --git a/serde_v8/magic/mod.rs b/serde_v8/magic/mod.rs index fe4577672..f96e422b1 100644 --- a/serde_v8/magic/mod.rs +++ b/serde_v8/magic/mod.rs @@ -2,6 +2,7 @@ pub mod buffer; pub mod bytestring; pub mod detached_buffer; +mod external_pointer; mod global; pub(super) mod rawbytes; pub mod string_or_buffer; @@ -9,5 +10,6 @@ pub mod transl8; pub mod u16string; pub mod v8slice; mod value; +pub use external_pointer::ExternalPointer; pub use global::Global; pub use value::Value; diff --git a/serde_v8/ser.rs b/serde_v8/ser.rs index 834efa78a..fa4cfecde 100644 --- a/serde_v8/ser.rs +++ b/serde_v8/ser.rs @@ -16,6 +16,7 @@ use crate::magic::transl8::ToV8; use crate::magic::transl8::MAGIC_FIELD; use crate::ByteString; use crate::DetachedBuffer; +use crate::ExternalPointer; use crate::StringOrBuffer; use crate::U16String; use crate::ZeroCopyBuf; @@ -269,6 +270,7 @@ impl<'a, 'b, 'c, T: MagicType + ToV8> ser::SerializeStruct // Dispatches between magic and regular struct serializers pub enum StructSerializers<'a, 'b, 'c> { + ExternalPointer(MagicalSerializer<'a, 'b, 'c, magic::ExternalPointer>), Magic(MagicalSerializer<'a, 'b, 'c, magic::Value<'a>>), ZeroCopyBuf(MagicalSerializer<'a, 'b, 'c, ZeroCopyBuf>), MagicDetached(MagicalSerializer<'a, 'b, 'c, DetachedBuffer>), @@ -288,6 +290,7 @@ impl<'a, 'b, 'c> ser::SerializeStruct for StructSerializers<'a, 'b, 'c> { value: &T, ) -> Result<()> { match self { + StructSerializers::ExternalPointer(s) => s.serialize_field(key, value), StructSerializers::Magic(s) => s.serialize_field(key, value), StructSerializers::ZeroCopyBuf(s) => s.serialize_field(key, value), StructSerializers::MagicDetached(s) => s.serialize_field(key, value), @@ -302,6 +305,7 @@ impl<'a, 'b, 'c> ser::SerializeStruct for StructSerializers<'a, 'b, 'c> { fn end(self) -> JsResult<'a> { match self { + StructSerializers::ExternalPointer(s) => s.end(), StructSerializers::Magic(s) => s.end(), StructSerializers::ZeroCopyBuf(s) => s.end(), StructSerializers::MagicDetached(s) => s.end(), @@ -385,8 +389,8 @@ macro_rules! forward_to { }; } -const MAX_SAFE_INTEGER: i64 = (1 << 53) - 1; -const MIN_SAFE_INTEGER: i64 = -MAX_SAFE_INTEGER; +pub(crate) const MAX_SAFE_INTEGER: i64 = (1 << 53) - 1; +pub(crate) const MIN_SAFE_INTEGER: i64 = -MAX_SAFE_INTEGER; impl<'a, 'b, 'c> ser::Serializer for Serializer<'a, 'b, 'c> { type Ok = v8::Local<'a, v8::Value>; @@ -564,6 +568,10 @@ impl<'a, 'b, 'c> ser::Serializer for Serializer<'a, 'b, 'c> { len: usize, ) -> Result<Self::SerializeStruct> { match name { + magic::ExternalPointer::MAGIC_NAME => { + let m = MagicalSerializer::<ExternalPointer>::new(self.scope); + Ok(StructSerializers::ExternalPointer(m)) + } ByteString::MAGIC_NAME => { let m = MagicalSerializer::<ByteString>::new(self.scope); Ok(StructSerializers::MagicByteString(m)) |
