From dda0f1c343bfb3196ce6a7c7e8c2acccfd5c2e5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Thu, 22 Jun 2023 23:37:56 +0200 Subject: [PATCH] refactor(serde_v8): split ZeroCopyBuf into JsBuffer and ToJsBuffer (#19566) `ZeroCopyBuf` was convenient to use, but sometimes it did hide details that some copies were necessary in certain cases. Also it made it way to easy for the caller to pass around and convert into different values. This commit splits `ZeroCopyBuf` into `JsBuffer` (an array buffer coming from V8) and `ToJsBuffer` (a Rust buffer that will be converted into a V8 array buffer). As a result some magical conversions were removed (they were never used) limiting the API surface and preparing for changes in #19534. --- core/examples/http_bench_json_ops/main.rs | 4 +- core/io.rs | 14 +-- core/lib.rs | 3 +- core/ops_builtin.rs | 13 +-- core/ops_builtin_v8.rs | 9 +- core/runtime/tests.rs | 16 +-- ext/broadcast_channel/lib.rs | 4 +- ext/crypto/decrypt.rs | 17 ++-- ext/crypto/ed25519.rs | 6 +- ext/crypto/encrypt.rs | 17 ++-- ext/crypto/export_key.rs | 16 +-- ext/crypto/generate_key.rs | 4 +- ext/crypto/import_key.rs | 49 +++++----- ext/crypto/lib.rs | 39 ++++---- ext/crypto/shared.rs | 45 +++++---- ext/crypto/x25519.rs | 6 +- ext/fetch/lib.rs | 4 +- ext/fs/ops.rs | 11 ++- ext/http/lib.rs | 4 +- ext/kv/lib.rs | 62 +++++++----- ext/net/ops.rs | 6 +- ext/net/ops_unix.rs | 6 +- ext/node/ops/crypto/mod.rs | 92 ++++++++--------- ext/url/lib.rs | 4 +- ext/web/blob.rs | 9 +- ext/web/compression.rs | 6 +- ext/web/lib.rs | 4 +- ext/websocket/lib.rs | 13 +-- runtime/ops/http.rs | 4 +- runtime/ops/process.rs | 6 +- serde_v8/de.rs | 10 +- serde_v8/lib.rs | 3 +- serde_v8/magic/any_value.rs | 13 ++- serde_v8/magic/buffer.rs | 114 +++++++++------------- serde_v8/magic/string_or_buffer.rs | 35 +------ serde_v8/ser.rs | 24 ++--- serde_v8/serializable.rs | 10 +- serde_v8/tests/de.rs | 12 +-- serde_v8/tests/magic.rs | 21 ++-- 39 files changed, 353 insertions(+), 382 deletions(-) diff --git a/core/examples/http_bench_json_ops/main.rs b/core/examples/http_bench_json_ops/main.rs index 36c0996c3a..a4d6afe319 100644 --- a/core/examples/http_bench_json_ops/main.rs +++ b/core/examples/http_bench_json_ops/main.rs @@ -3,11 +3,11 @@ use deno_core::anyhow::Error; use deno_core::op; use deno_core::AsyncRefCell; use deno_core::AsyncResult; +use deno_core::JsBuffer; use deno_core::JsRuntimeForSnapshot; use deno_core::OpState; use deno_core::Resource; use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; use std::cell::RefCell; use std::env; use std::net::SocketAddr; @@ -116,7 +116,7 @@ fn create_js_runtime() -> JsRuntimeForSnapshot { async fn op_read_socket( state: Rc>, rid: ResourceId, - mut data: ZeroCopyBuf, + mut data: JsBuffer, ) -> Result { let resource = state.borrow_mut().resource_table.get::(rid)?; let nread = resource.read(&mut data).await?; diff --git a/core/io.rs b/core/io.rs index 567d50bd48..a02b4b4927 100644 --- a/core/io.rs +++ b/core/io.rs @@ -4,7 +4,7 @@ use std::ops::Deref; use std::ops::DerefMut; use bytes::Buf; -use serde_v8::ZeroCopyBuf; +use serde_v8::JsBuffer; /// BufView is a wrapper around an underlying contiguous chunk of bytes. It can /// be created from a [ZeroCopyBuf], [bytes::Bytes], or [Vec] and implements @@ -22,7 +22,7 @@ pub struct BufView { enum BufViewInner { Empty, Bytes(bytes::Bytes), - ZeroCopy(ZeroCopyBuf), + ZeroCopy(JsBuffer), Vec(Vec), } @@ -100,8 +100,8 @@ impl AsRef<[u8]> for BufView { } } -impl From for BufView { - fn from(buf: ZeroCopyBuf) -> Self { +impl From for BufView { + fn from(buf: JsBuffer) -> Self { Self::from_inner(BufViewInner::ZeroCopy(buf)) } } @@ -145,7 +145,7 @@ pub struct BufMutView { } enum BufMutViewInner { - ZeroCopy(ZeroCopyBuf), + ZeroCopy(JsBuffer), Vec(Vec), } @@ -273,8 +273,8 @@ impl AsMut<[u8]> for BufMutView { } } -impl From for BufMutView { - fn from(buf: ZeroCopyBuf) -> Self { +impl From for BufMutView { + fn from(buf: JsBuffer) -> Self { Self::from_inner(BufMutViewInner::ZeroCopy(buf)) } } diff --git a/core/lib.rs b/core/lib.rs index ddc4d6d910..1f069e6610 100644 --- a/core/lib.rs +++ b/core/lib.rs @@ -32,9 +32,10 @@ pub use serde_json; pub use serde_v8; pub use serde_v8::ByteString; pub use serde_v8::DetachedBuffer; +pub use serde_v8::JsBuffer; pub use serde_v8::StringOrBuffer; +pub use serde_v8::ToJsBuffer; pub use serde_v8::U16String; -pub use serde_v8::ZeroCopyBuf; pub use sourcemap; pub use url; pub use v8; diff --git a/core/ops_builtin.rs b/core/ops_builtin.rs index 70f478acd9..2334c69180 100644 --- a/core/ops_builtin.rs +++ b/core/ops_builtin.rs @@ -6,11 +6,12 @@ use crate::io::BufView; use crate::ops_builtin_v8; use crate::ops_metrics::OpMetrics; use crate::resources::ResourceId; +use crate::JsBuffer; use crate::OpState; use crate::Resource; -use crate::ZeroCopyBuf; use anyhow::Error; use deno_ops::op; +use serde_v8::ToJsBuffer; use std::cell::RefCell; use std::io::stderr; use std::io::stdout; @@ -218,7 +219,7 @@ pub fn op_wasm_streaming_set_url( async fn op_read( state: Rc>, rid: ResourceId, - buf: ZeroCopyBuf, + buf: JsBuffer, ) -> Result { let resource = state.borrow().resource_table.get_any(rid)?; let view = BufMutView::from(buf); @@ -229,7 +230,7 @@ async fn op_read( async fn op_read_all( state: Rc>, rid: ResourceId, -) -> Result { +) -> Result { let resource = state.borrow().resource_table.get_any(rid)?; // The number of bytes we attempt to grow the buffer by each time it fills @@ -291,14 +292,14 @@ async fn op_read_all( vec.truncate(nread); } - Ok(ZeroCopyBuf::from(vec)) + Ok(ToJsBuffer::from(vec)) } #[op] async fn op_write( state: Rc>, rid: ResourceId, - buf: ZeroCopyBuf, + buf: JsBuffer, ) -> Result { let resource = state.borrow().resource_table.get_any(rid)?; let view = BufView::from(buf); @@ -331,7 +332,7 @@ fn op_write_sync( async fn op_write_all( state: Rc>, rid: ResourceId, - buf: ZeroCopyBuf, + buf: JsBuffer, ) -> Result<(), Error> { let resource = state.borrow().resource_table.get_any(rid)?; let view = BufView::from(buf); diff --git a/core/ops_builtin_v8.rs b/core/ops_builtin_v8.rs index 9fd906291b..034a3810d6 100644 --- a/core/ops_builtin_v8.rs +++ b/core/ops_builtin_v8.rs @@ -9,9 +9,10 @@ use crate::resolve_url; use crate::runtime::script_origin; use crate::serde_v8::from_v8; use crate::source_map::apply_source_map; +use crate::JsBuffer; use crate::JsRealm; use crate::JsRuntime; -use crate::ZeroCopyBuf; +use crate::ToJsBuffer; use anyhow::Error; use deno_ops::op; use serde::Deserialize; @@ -375,7 +376,7 @@ fn op_serialize( value: serde_v8::Value, options: Option, error_callback: Option, -) -> Result { +) -> Result { let options = options.unwrap_or_default(); let error_callback = match error_callback { Some(cb) => Some( @@ -448,7 +449,7 @@ fn op_serialize( if scope.has_caught() || scope.has_terminated() { scope.rethrow(); // Dummy value, this result will be discarded because an error was thrown. - Ok(ZeroCopyBuf::empty()) + Ok(ToJsBuffer::empty()) } else if let Some(true) = ret { let vector = value_serializer.release(); Ok(vector.into()) @@ -460,7 +461,7 @@ fn op_serialize( #[op(v8)] fn op_deserialize<'a>( scope: &mut v8::HandleScope<'a>, - zero_copy: ZeroCopyBuf, + zero_copy: JsBuffer, options: Option, ) -> Result, Error> { let options = options.unwrap_or_default(); diff --git a/core/runtime/tests.rs b/core/runtime/tests.rs index 857290b803..d2283365e4 100644 --- a/core/runtime/tests.rs +++ b/core/runtime/tests.rs @@ -18,7 +18,7 @@ use crate::modules::ModuleType; use crate::modules::ResolutionKind; use crate::modules::SymbolicModule; use crate::Extension; -use crate::ZeroCopyBuf; +use crate::JsBuffer; use crate::*; use anyhow::Error; use deno_ops::op; @@ -55,7 +55,7 @@ struct TestState { async fn op_test( rc_op_state: Rc>, control: u8, - buf: Option, + buf: Option, ) -> Result { #![allow(clippy::await_holding_refcell_ref)] // False positive. let op_state_ = rc_op_state.borrow(); @@ -1977,15 +1977,15 @@ fn js_realm_init_snapshot() { #[test] fn js_realm_sync_ops() { - // Test that returning a ZeroCopyBuf and throwing an exception from a sync + // Test that returning a RustToV8Buf and throwing an exception from a sync // op result in objects with prototypes from the right realm. Note that we // don't test the result of returning structs, because they will be // serialized to objects with null prototype. #[op] - fn op_test(fail: bool) -> Result { + fn op_test(fail: bool) -> Result { if !fail { - Ok(ZeroCopyBuf::empty()) + Ok(ToJsBuffer::empty()) } else { Err(crate::error::type_error("Test")) } @@ -2025,15 +2025,15 @@ fn js_realm_sync_ops() { #[tokio::test] async fn js_realm_async_ops() { - // Test that returning a ZeroCopyBuf and throwing an exception from a async + // Test that returning a RustToV8Buf and throwing an exception from a async // op result in objects with prototypes from the right realm. Note that we // don't test the result of returning structs, because they will be // serialized to objects with null prototype. #[op] - async fn op_test(fail: bool) -> Result { + async fn op_test(fail: bool) -> Result { if !fail { - Ok(ZeroCopyBuf::empty()) + Ok(ToJsBuffer::empty()) } else { Err(crate::error::type_error("Test")) } diff --git a/ext/broadcast_channel/lib.rs b/ext/broadcast_channel/lib.rs index 5b38e70f85..56ce4b3bd7 100644 --- a/ext/broadcast_channel/lib.rs +++ b/ext/broadcast_channel/lib.rs @@ -12,10 +12,10 @@ use std::rc::Rc; use async_trait::async_trait; use deno_core::error::AnyError; use deno_core::op; +use deno_core::JsBuffer; use deno_core::OpState; use deno_core::Resource; use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; #[async_trait] pub trait BroadcastChannel: Clone { @@ -81,7 +81,7 @@ pub async fn op_broadcast_send( state: Rc>, rid: ResourceId, name: String, - buf: ZeroCopyBuf, + buf: JsBuffer, ) -> Result<(), AnyError> where BC: BroadcastChannel + 'static, diff --git a/ext/crypto/decrypt.rs b/ext/crypto/decrypt.rs index fc54fe8182..59679614f0 100644 --- a/ext/crypto/decrypt.rs +++ b/ext/crypto/decrypt.rs @@ -21,7 +21,8 @@ use deno_core::error::type_error; use deno_core::error::AnyError; use deno_core::op; use deno_core::task::spawn_blocking; -use deno_core::ZeroCopyBuf; +use deno_core::JsBuffer; +use deno_core::ToJsBuffer; use rsa::pkcs1::DecodeRsaPrivateKey; use rsa::PaddingScheme; use serde::Deserialize; @@ -36,7 +37,7 @@ use crate::shared::*; #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct DecryptOptions { - key: RawKeyData, + key: V8RawKeyData, #[serde(flatten)] algorithm: DecryptAlgorithm, } @@ -77,8 +78,8 @@ pub enum DecryptAlgorithm { #[op] pub async fn op_crypto_decrypt( opts: DecryptOptions, - data: ZeroCopyBuf, -) -> Result { + data: JsBuffer, +) -> Result { let key = opts.key; let fun = move || match opts.algorithm { DecryptAlgorithm::RsaOaep { hash, label } => { @@ -104,7 +105,7 @@ pub async fn op_crypto_decrypt( } fn decrypt_rsa_oaep( - key: RawKeyData, + key: V8RawKeyData, hash: ShaHash, label: Vec, data: &[u8], @@ -143,7 +144,7 @@ fn decrypt_rsa_oaep( } fn decrypt_aes_cbc( - key: RawKeyData, + key: V8RawKeyData, length: usize, iv: Vec, data: &[u8], @@ -281,7 +282,7 @@ fn decrypt_aes_gcm_gen>( } fn decrypt_aes_ctr( - key: RawKeyData, + key: V8RawKeyData, key_length: usize, counter: &[u8], ctr_length: usize, @@ -315,7 +316,7 @@ fn decrypt_aes_ctr( } fn decrypt_aes_gcm( - key: RawKeyData, + key: V8RawKeyData, length: usize, tag_length: usize, iv: Vec, diff --git a/ext/crypto/ed25519.rs b/ext/crypto/ed25519.rs index 784583c6b8..98eabbd593 100644 --- a/ext/crypto/ed25519.rs +++ b/ext/crypto/ed25519.rs @@ -2,7 +2,7 @@ use deno_core::error::AnyError; use deno_core::op; -use deno_core::ZeroCopyBuf; +use deno_core::ToJsBuffer; use elliptic_curve::pkcs8::PrivateKeyInfo; use rand::rngs::OsRng; use rand::RngCore; @@ -105,7 +105,7 @@ pub fn op_crypto_import_pkcs8_ed25519(key_data: &[u8], out: &mut [u8]) -> bool { #[op] pub fn op_crypto_export_spki_ed25519( pubkey: &[u8], -) -> Result { +) -> Result { let key_info = spki::SubjectPublicKeyInfo { algorithm: spki::AlgorithmIdentifier { // id-Ed25519 @@ -120,7 +120,7 @@ pub fn op_crypto_export_spki_ed25519( #[op] pub fn op_crypto_export_pkcs8_ed25519( pkey: &[u8], -) -> Result { +) -> Result { // This should probably use OneAsymmetricKey instead let pk_info = rsa::pkcs8::PrivateKeyInfo { public_key: None, diff --git a/ext/crypto/encrypt.rs b/ext/crypto/encrypt.rs index 2831ca0f4a..0dc3005385 100644 --- a/ext/crypto/encrypt.rs +++ b/ext/crypto/encrypt.rs @@ -20,7 +20,8 @@ use deno_core::error::type_error; use deno_core::error::AnyError; use deno_core::op; use deno_core::task::spawn_blocking; -use deno_core::ZeroCopyBuf; +use deno_core::JsBuffer; +use deno_core::ToJsBuffer; use rand::rngs::OsRng; use rsa::pkcs1::DecodeRsaPublicKey; use rsa::PaddingScheme; @@ -37,7 +38,7 @@ use crate::shared::*; #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct EncryptOptions { - key: RawKeyData, + key: V8RawKeyData, #[serde(flatten)] algorithm: EncryptAlgorithm, } @@ -78,8 +79,8 @@ pub enum EncryptAlgorithm { #[op] pub async fn op_crypto_encrypt( opts: EncryptOptions, - data: ZeroCopyBuf, -) -> Result { + data: JsBuffer, +) -> Result { let key = opts.key; let fun = move || match opts.algorithm { EncryptAlgorithm::RsaOaep { hash, label } => { @@ -105,7 +106,7 @@ pub async fn op_crypto_encrypt( } fn encrypt_rsa_oaep( - key: RawKeyData, + key: V8RawKeyData, hash: ShaHash, label: Vec, data: &[u8], @@ -145,7 +146,7 @@ fn encrypt_rsa_oaep( } fn encrypt_aes_cbc( - key: RawKeyData, + key: V8RawKeyData, length: usize, iv: Vec, data: &[u8], @@ -218,7 +219,7 @@ fn encrypt_aes_gcm_general>( } fn encrypt_aes_gcm( - key: RawKeyData, + key: V8RawKeyData, length: usize, tag_length: usize, iv: Vec, @@ -277,7 +278,7 @@ where } fn encrypt_aes_ctr( - key: RawKeyData, + key: V8RawKeyData, key_length: usize, counter: &[u8], ctr_length: usize, diff --git a/ext/crypto/export_key.rs b/ext/crypto/export_key.rs index ec76bac928..13f7357fa5 100644 --- a/ext/crypto/export_key.rs +++ b/ext/crypto/export_key.rs @@ -5,7 +5,7 @@ use const_oid::ObjectIdentifier; use deno_core::error::custom_error; use deno_core::error::AnyError; use deno_core::op; -use deno_core::ZeroCopyBuf; +use deno_core::ToJsBuffer; use elliptic_curve::sec1::ToEncodedPoint; use p256::pkcs8::DecodePrivateKey; use rsa::pkcs1::UIntRef; @@ -59,9 +59,9 @@ pub enum ExportKeyAlgorithm { #[derive(Serialize)] #[serde(untagged)] pub enum ExportKeyResult { - Raw(ZeroCopyBuf), - Pkcs8(ZeroCopyBuf), - Spki(ZeroCopyBuf), + Raw(ToJsBuffer), + Pkcs8(ToJsBuffer), + Spki(ToJsBuffer), JwkSecret { k: String, }, @@ -93,7 +93,7 @@ pub enum ExportKeyResult { #[op] pub fn op_crypto_export_key( opts: ExportKeyOptions, - key_data: RawKeyData, + key_data: V8RawKeyData, ) -> Result { match opts.algorithm { ExportKeyAlgorithm::RsassaPkcs1v15 {} @@ -119,7 +119,7 @@ fn bytes_to_b64(bytes: &[u8]) -> String { fn export_key_rsa( format: ExportKeyFormat, - key_data: RawKeyData, + key_data: V8RawKeyData, ) -> Result { match format { ExportKeyFormat::Spki => { @@ -212,7 +212,7 @@ fn export_key_rsa( fn export_key_symmetric( format: ExportKeyFormat, - key_data: RawKeyData, + key_data: V8RawKeyData, ) -> Result { match format { ExportKeyFormat::JwkSecret => { @@ -228,7 +228,7 @@ fn export_key_symmetric( fn export_key_ec( format: ExportKeyFormat, - key_data: RawKeyData, + key_data: V8RawKeyData, algorithm: ExportKeyAlgorithm, named_curve: EcNamedCurve, ) -> Result { diff --git a/ext/crypto/generate_key.rs b/ext/crypto/generate_key.rs index 426c61376e..9e2d14ea76 100644 --- a/ext/crypto/generate_key.rs +++ b/ext/crypto/generate_key.rs @@ -3,7 +3,7 @@ use deno_core::error::AnyError; use deno_core::op; use deno_core::task::spawn_blocking; -use deno_core::ZeroCopyBuf; +use deno_core::ToJsBuffer; use elliptic_curve::rand_core::OsRng; use num_traits::FromPrimitive; use once_cell::sync::Lazy; @@ -45,7 +45,7 @@ pub enum GenerateKeyOptions { #[op] pub async fn op_crypto_generate_key( opts: GenerateKeyOptions, -) -> Result { +) -> Result { let fun = || match opts { GenerateKeyOptions::Rsa { modulus_length, diff --git a/ext/crypto/import_key.rs b/ext/crypto/import_key.rs index 42eab0e6ca..c3d60101c8 100644 --- a/ext/crypto/import_key.rs +++ b/ext/crypto/import_key.rs @@ -2,7 +2,8 @@ use deno_core::error::AnyError; use deno_core::op; -use deno_core::ZeroCopyBuf; +use deno_core::JsBuffer; +use deno_core::ToJsBuffer; use elliptic_curve::pkcs8::PrivateKeyInfo; use p256::pkcs8::EncodePrivateKey; use ring::signature::EcdsaKeyPair; @@ -18,9 +19,9 @@ use crate::shared::*; #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub enum KeyData { - Spki(ZeroCopyBuf), - Pkcs8(ZeroCopyBuf), - Raw(ZeroCopyBuf), + Spki(JsBuffer), + Pkcs8(JsBuffer), + Raw(JsBuffer), JwkSecret { k: String, }, @@ -73,17 +74,17 @@ pub enum ImportKeyOptions { pub enum ImportKeyResult { #[serde(rename_all = "camelCase")] Rsa { - raw_data: RawKeyData, + raw_data: RustRawKeyData, modulus_length: usize, - public_exponent: ZeroCopyBuf, + public_exponent: ToJsBuffer, }, #[serde(rename_all = "camelCase")] - Ec { raw_data: RawKeyData }, + Ec { raw_data: RustRawKeyData }, #[serde(rename_all = "camelCase")] #[allow(dead_code)] - Aes { raw_data: RawKeyData }, + Aes { raw_data: RustRawKeyData }, #[serde(rename_all = "camelCase")] - Hmac { raw_data: RawKeyData }, + Hmac { raw_data: RustRawKeyData }, } #[op] @@ -136,7 +137,7 @@ fn import_key_rsa_jwk( let modulus_length = public_key.modulus.as_bytes().len() * 8; Ok(ImportKeyResult::Rsa { - raw_data: RawKeyData::Public(data.into()), + raw_data: RustRawKeyData::Public(data.into()), modulus_length, public_exponent, }) @@ -181,7 +182,7 @@ fn import_key_rsa_jwk( let modulus_length = private_key.modulus.as_bytes().len() * 8; Ok(ImportKeyResult::Rsa { - raw_data: RawKeyData::Private(data.into()), + raw_data: RustRawKeyData::Private(data.into()), modulus_length, public_exponent, }) @@ -228,7 +229,7 @@ fn import_key_rsassa( let modulus_length = public_key.modulus.as_bytes().len() * 8; Ok(ImportKeyResult::Rsa { - raw_data: RawKeyData::Public(data), + raw_data: RustRawKeyData::Public(data), modulus_length, public_exponent, }) @@ -267,7 +268,7 @@ fn import_key_rsassa( let modulus_length = private_key.modulus.as_bytes().len() * 8; Ok(ImportKeyResult::Rsa { - raw_data: RawKeyData::Private(data), + raw_data: RustRawKeyData::Private(data), modulus_length, public_exponent, }) @@ -317,7 +318,7 @@ fn import_key_rsapss( let modulus_length = public_key.modulus.as_bytes().len() * 8; Ok(ImportKeyResult::Rsa { - raw_data: RawKeyData::Public(data), + raw_data: RustRawKeyData::Public(data), modulus_length, public_exponent, }) @@ -356,7 +357,7 @@ fn import_key_rsapss( let modulus_length = private_key.modulus.as_bytes().len() * 8; Ok(ImportKeyResult::Rsa { - raw_data: RawKeyData::Private(data), + raw_data: RustRawKeyData::Private(data), modulus_length, public_exponent, }) @@ -406,7 +407,7 @@ fn import_key_rsaoaep( let modulus_length = public_key.modulus.as_bytes().len() * 8; Ok(ImportKeyResult::Rsa { - raw_data: RawKeyData::Public(data), + raw_data: RustRawKeyData::Public(data), modulus_length, public_exponent, }) @@ -445,7 +446,7 @@ fn import_key_rsaoaep( let modulus_length = private_key.modulus.as_bytes().len() * 8; Ok(ImportKeyResult::Rsa { - raw_data: RawKeyData::Private(data), + raw_data: RustRawKeyData::Private(data), modulus_length, public_exponent, }) @@ -513,7 +514,7 @@ fn import_key_ec_jwk( let point_bytes = import_key_ec_jwk_to_point(x, y, named_curve)?; Ok(ImportKeyResult::Ec { - raw_data: RawKeyData::Public(point_bytes.into()), + raw_data: RustRawKeyData::Public(point_bytes.into()), }) } KeyData::JwkPrivateEc { d, x, y } => { @@ -553,7 +554,7 @@ fn import_key_ec_jwk( ); Ok(ImportKeyResult::Ec { - raw_data: RawKeyData::Private(pkcs8_der.as_bytes().to_vec().into()), + raw_data: RustRawKeyData::Private(pkcs8_der.as_bytes().to_vec().into()), }) } _ => unreachable!(), @@ -606,7 +607,7 @@ fn import_key_ec( _ => return Err(not_supported_error("Unsupported named curve")), }; Ok(ImportKeyResult::Ec { - raw_data: RawKeyData::Public(data), + raw_data: RustRawKeyData::Public(data.to_vec().into()), }) } KeyData::Pkcs8(data) => { @@ -660,7 +661,7 @@ fn import_key_ec( } Ok(ImportKeyResult::Ec { - raw_data: RawKeyData::Private(data), + raw_data: RustRawKeyData::Private(data.to_vec().into()), }) } KeyData::Spki(data) => { @@ -744,7 +745,7 @@ fn import_key_ec( } Ok(ImportKeyResult::Ec { - raw_data: RawKeyData::Public(encoded_key.into()), + raw_data: RustRawKeyData::Public(encoded_key.into()), }) } KeyData::JwkPublicEc { .. } | KeyData::JwkPrivateEc { .. } => { @@ -760,7 +761,7 @@ fn import_key_aes(key_data: KeyData) -> Result { let data = base64::decode_config(k, URL_SAFE_FORGIVING) .map_err(|_| data_error("invalid key data"))?; ImportKeyResult::Hmac { - raw_data: RawKeyData::Secret(data.into()), + raw_data: RustRawKeyData::Secret(data.into()), } } _ => return Err(unsupported_format()), @@ -773,7 +774,7 @@ fn import_key_hmac(key_data: KeyData) -> Result { let data = base64::decode_config(k, URL_SAFE_FORGIVING) .map_err(|_| data_error("invalid key data"))?; ImportKeyResult::Hmac { - raw_data: RawKeyData::Secret(data.into()), + raw_data: RustRawKeyData::Secret(data.into()), } } _ => return Err(unsupported_format()), diff --git a/ext/crypto/lib.rs b/ext/crypto/lib.rs index dc5faf5e7e..1765697c63 100644 --- a/ext/crypto/lib.rs +++ b/ext/crypto/lib.rs @@ -9,10 +9,11 @@ use deno_core::error::not_supported; use deno_core::error::type_error; use deno_core::error::AnyError; use deno_core::op; +use deno_core::ToJsBuffer; use deno_core::task::spawn_blocking; +use deno_core::JsBuffer; use deno_core::OpState; -use deno_core::ZeroCopyBuf; use serde::Deserialize; use shared::operation_error; @@ -69,7 +70,7 @@ use crate::key::Algorithm; use crate::key::CryptoHash; use crate::key::CryptoNamedCurve; use crate::key::HkdfOutput; -use crate::shared::RawKeyData; +use crate::shared::V8RawKeyData; deno_core::extension!(deno_crypto, deps = [ deno_webidl, deno_web ], @@ -118,13 +119,13 @@ deno_core::extension!(deno_crypto, #[op] pub fn op_crypto_base64url_decode( data: String, -) -> Result { +) -> Result { let data: Vec = base64::decode_config(data, base64::URL_SAFE_NO_PAD)?; Ok(data.into()) } #[op] -pub fn op_crypto_base64url_encode(data: ZeroCopyBuf) -> String { +pub fn op_crypto_base64url_encode(data: JsBuffer) -> String { let data: String = base64::encode_config(data, base64::URL_SAFE_NO_PAD); data } @@ -172,7 +173,7 @@ pub enum KeyType { #[serde(rename_all = "lowercase")] pub struct KeyData { r#type: KeyType, - data: ZeroCopyBuf, + data: JsBuffer, } #[derive(Deserialize)] @@ -188,8 +189,8 @@ pub struct SignArg { #[op] pub async fn op_crypto_sign_key( args: SignArg, - zero_copy: ZeroCopyBuf, -) -> Result { + zero_copy: JsBuffer, +) -> Result { let data = &*zero_copy; let algorithm = args.algorithm; @@ -297,14 +298,14 @@ pub struct VerifyArg { key: KeyData, algorithm: Algorithm, hash: Option, - signature: ZeroCopyBuf, + signature: JsBuffer, named_curve: Option, } #[op] pub async fn op_crypto_verify_key( args: VerifyArg, - zero_copy: ZeroCopyBuf, + zero_copy: JsBuffer, ) -> Result { let data = &*zero_copy; let algorithm = args.algorithm; @@ -414,14 +415,14 @@ pub struct DeriveKeyArg { public_key: Option, named_curve: Option, // HKDF - info: Option, + info: Option, } #[op] pub async fn op_crypto_derive_bits( args: DeriveKeyArg, - zero_copy: Option, -) -> Result { + zero_copy: Option, +) -> Result { let algorithm = args.algorithm; match algorithm { Algorithm::Pbkdf2 => { @@ -601,8 +602,8 @@ pub fn op_crypto_random_uuid(state: &mut OpState) -> Result { #[op] pub async fn op_crypto_subtle_digest( algorithm: CryptoHash, - data: ZeroCopyBuf, -) -> Result { + data: JsBuffer, +) -> Result { let output = spawn_blocking(move || { digest::digest(algorithm.into(), &data) .as_ref() @@ -617,15 +618,15 @@ pub async fn op_crypto_subtle_digest( #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct WrapUnwrapKeyArg { - key: RawKeyData, + key: V8RawKeyData, algorithm: Algorithm, } #[op] pub fn op_crypto_wrap_key( args: WrapUnwrapKeyArg, - data: ZeroCopyBuf, -) -> Result { + data: JsBuffer, +) -> Result { let algorithm = args.algorithm; match algorithm { @@ -653,8 +654,8 @@ pub fn op_crypto_wrap_key( #[op] pub fn op_crypto_unwrap_key( args: WrapUnwrapKeyArg, - data: ZeroCopyBuf, -) -> Result { + data: JsBuffer, +) -> Result { let algorithm = args.algorithm; match algorithm { Algorithm::AesKw => { diff --git a/ext/crypto/shared.rs b/ext/crypto/shared.rs index 4ecb35dc27..109f51fa1c 100644 --- a/ext/crypto/shared.rs +++ b/ext/crypto/shared.rs @@ -5,7 +5,8 @@ use std::borrow::Cow; use deno_core::error::custom_error; use deno_core::error::type_error; use deno_core::error::AnyError; -use deno_core::ZeroCopyBuf; +use deno_core::JsBuffer; +use deno_core::ToJsBuffer; use elliptic_curve::sec1::ToEncodedPoint; use rsa::pkcs1::DecodeRsaPrivateKey; use rsa::pkcs1::EncodeRsaPublicKey; @@ -46,19 +47,27 @@ pub enum EcNamedCurve { P521, } -#[derive(Serialize, Deserialize)] +#[derive(Deserialize)] #[serde(rename_all = "lowercase", tag = "type", content = "data")] -pub enum RawKeyData { - Secret(ZeroCopyBuf), - Private(ZeroCopyBuf), - Public(ZeroCopyBuf), +pub enum V8RawKeyData { + Secret(JsBuffer), + Private(JsBuffer), + Public(JsBuffer), } -impl RawKeyData { +#[derive(Serialize)] +#[serde(rename_all = "lowercase", tag = "type", content = "data")] +pub enum RustRawKeyData { + Secret(ToJsBuffer), + Private(ToJsBuffer), + Public(ToJsBuffer), +} + +impl V8RawKeyData { pub fn as_rsa_public_key(&self) -> Result, AnyError> { match self { - RawKeyData::Public(data) => Ok(Cow::Borrowed(data)), - RawKeyData::Private(data) => { + V8RawKeyData::Public(data) => Ok(Cow::Borrowed(data)), + V8RawKeyData::Private(data) => { let private_key = RsaPrivateKey::from_pkcs1_der(data) .map_err(|_| type_error("expected valid private key"))?; @@ -75,55 +84,55 @@ impl RawKeyData { pub fn as_rsa_private_key(&self) -> Result<&[u8], AnyError> { match self { - RawKeyData::Private(data) => Ok(data), + V8RawKeyData::Private(data) => Ok(data), _ => Err(type_error("expected private key")), } } pub fn as_secret_key(&self) -> Result<&[u8], AnyError> { match self { - RawKeyData::Secret(data) => Ok(data), + V8RawKeyData::Secret(data) => Ok(data), _ => Err(type_error("expected secret key")), } } pub fn as_ec_public_key_p256(&self) -> Result { match self { - RawKeyData::Public(data) => { + V8RawKeyData::Public(data) => { // public_key is a serialized EncodedPoint p256::EncodedPoint::from_bytes(data) .map_err(|_| type_error("expected valid public EC key")) } - RawKeyData::Private(data) => { + V8RawKeyData::Private(data) => { let signing_key = p256::SecretKey::from_pkcs8_der(data) .map_err(|_| type_error("expected valid private EC key"))?; Ok(signing_key.public_key().to_encoded_point(false)) } // Should never reach here. - RawKeyData::Secret(_) => unreachable!(), + V8RawKeyData::Secret(_) => unreachable!(), } } pub fn as_ec_public_key_p384(&self) -> Result { match self { - RawKeyData::Public(data) => { + V8RawKeyData::Public(data) => { // public_key is a serialized EncodedPoint p384::EncodedPoint::from_bytes(data) .map_err(|_| type_error("expected valid public EC key")) } - RawKeyData::Private(data) => { + V8RawKeyData::Private(data) => { let signing_key = p384::SecretKey::from_pkcs8_der(data) .map_err(|_| type_error("expected valid private EC key"))?; Ok(signing_key.public_key().to_encoded_point(false)) } // Should never reach here. - RawKeyData::Secret(_) => unreachable!(), + V8RawKeyData::Secret(_) => unreachable!(), } } pub fn as_ec_private_key(&self) -> Result<&[u8], AnyError> { match self { - RawKeyData::Private(data) => Ok(data), + V8RawKeyData::Private(data) => Ok(data), _ => Err(type_error("expected private key")), } } diff --git a/ext/crypto/x25519.rs b/ext/crypto/x25519.rs index 99914e14e5..77554129e0 100644 --- a/ext/crypto/x25519.rs +++ b/ext/crypto/x25519.rs @@ -3,7 +3,7 @@ use curve25519_dalek::montgomery::MontgomeryPoint; use deno_core::error::AnyError; use deno_core::op; -use deno_core::ZeroCopyBuf; +use deno_core::ToJsBuffer; use elliptic_curve::pkcs8::PrivateKeyInfo; use elliptic_curve::subtle::ConstantTimeEq; use rand::rngs::OsRng; @@ -101,7 +101,7 @@ pub fn op_crypto_import_pkcs8_x25519(key_data: &[u8], out: &mut [u8]) -> bool { #[op] pub fn op_crypto_export_spki_x25519( pubkey: &[u8], -) -> Result { +) -> Result { let key_info = spki::SubjectPublicKeyInfo { algorithm: spki::AlgorithmIdentifier { // id-X25519 @@ -116,7 +116,7 @@ pub fn op_crypto_export_spki_x25519( #[op] pub fn op_crypto_export_pkcs8_x25519( pkey: &[u8], -) -> Result { +) -> Result { // This should probably use OneAsymmetricKey instead let pk_info = rsa::pkcs8::PrivateKeyInfo { public_key: None, diff --git a/ext/fetch/lib.rs b/ext/fetch/lib.rs index 538b741a6c..a3daff0406 100644 --- a/ext/fetch/lib.rs +++ b/ext/fetch/lib.rs @@ -32,11 +32,11 @@ use deno_core::CancelFuture; use deno_core::CancelHandle; use deno_core::CancelTryFuture; use deno_core::Canceled; +use deno_core::JsBuffer; use deno_core::OpState; use deno_core::RcRef; use deno_core::Resource; use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; use deno_tls::rustls::RootCertStore; use deno_tls::Proxy; use deno_tls::RootCertStoreProvider; @@ -232,7 +232,7 @@ pub fn op_fetch( client_rid: Option, has_body: bool, body_length: Option, - data: Option, + data: Option, ) -> Result where FP: FetchPermissions + 'static, diff --git a/ext/fs/ops.rs b/ext/fs/ops.rs index 5bf3b1c6fd..083d1b15f9 100644 --- a/ext/fs/ops.rs +++ b/ext/fs/ops.rs @@ -14,9 +14,10 @@ use deno_core::error::AnyError; use deno_core::op; use deno_core::CancelFuture; use deno_core::CancelHandle; +use deno_core::JsBuffer; use deno_core::OpState; use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; +use deno_core::ToJsBuffer; use deno_io::fs::FileResource; use deno_io::fs::FsError; use deno_io::fs::FsStat; @@ -1077,7 +1078,7 @@ fn op_fs_write_file_sync

( append: bool, create: bool, create_new: bool, - data: ZeroCopyBuf, + data: JsBuffer, ) -> Result<(), AnyError> where P: FsPermissions + 'static, @@ -1104,7 +1105,7 @@ async fn op_fs_write_file_async

( append: bool, create: bool, create_new: bool, - data: ZeroCopyBuf, + data: JsBuffer, cancel_rid: Option, ) -> Result<(), AnyError> where @@ -1144,7 +1145,7 @@ where fn op_fs_read_file_sync

( state: &mut OpState, path: String, -) -> Result +) -> Result where P: FsPermissions + 'static, { @@ -1164,7 +1165,7 @@ async fn op_fs_read_file_async

( state: Rc>, path: String, cancel_rid: Option, -) -> Result +) -> Result where P: FsPermissions + 'static, { diff --git a/ext/http/lib.rs b/ext/http/lib.rs index da007ba398..1ae156b861 100644 --- a/ext/http/lib.rs +++ b/ext/http/lib.rs @@ -28,12 +28,12 @@ use deno_core::ByteString; use deno_core::CancelFuture; use deno_core::CancelHandle; use deno_core::CancelTryFuture; +use deno_core::JsBuffer; use deno_core::OpState; use deno_core::RcRef; use deno_core::Resource; use deno_core::ResourceId; use deno_core::StringOrBuffer; -use deno_core::ZeroCopyBuf; use deno_net::raw::NetworkStream; use deno_websocket::ws_create_server_stream; use flate2::write::GzEncoder; @@ -880,7 +880,7 @@ async fn op_http_write_resource( async fn op_http_write( state: Rc>, rid: ResourceId, - buf: ZeroCopyBuf, + buf: JsBuffer, ) -> Result<(), AnyError> { let stream = state .borrow() diff --git a/ext/kv/lib.rs b/ext/kv/lib.rs index 2763fcf50d..db7c5c22ea 100644 --- a/ext/kv/lib.rs +++ b/ext/kv/lib.rs @@ -19,10 +19,11 @@ use deno_core::op; use deno_core::serde_v8::AnyValue; use deno_core::serde_v8::BigInt; use deno_core::ByteString; +use deno_core::JsBuffer; use deno_core::OpState; use deno_core::Resource; use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; +use deno_core::ToJsBuffer; use serde::Deserialize; use serde::Serialize; @@ -122,7 +123,8 @@ impl From for KeyPart { AnyValue::Number(n) => KeyPart::Float(n), AnyValue::BigInt(n) => KeyPart::Int(n), AnyValue::String(s) => KeyPart::String(s), - AnyValue::Buffer(buf) => KeyPart::Bytes(buf.to_vec()), + AnyValue::V8Buffer(buf) => KeyPart::Bytes(buf.to_vec()), + AnyValue::RustBuffer(_) => unreachable!(), } } } @@ -135,51 +137,61 @@ impl From for AnyValue { KeyPart::Float(n) => AnyValue::Number(n), KeyPart::Int(n) => AnyValue::BigInt(n), KeyPart::String(s) => AnyValue::String(s), - KeyPart::Bytes(buf) => AnyValue::Buffer(buf.into()), + KeyPart::Bytes(buf) => AnyValue::RustBuffer(buf.into()), } } } -#[derive(Debug, Deserialize, Serialize)] +#[derive(Debug, Deserialize)] #[serde(tag = "kind", content = "value", rename_all = "snake_case")] -enum V8Value { - V8(ZeroCopyBuf), - Bytes(ZeroCopyBuf), +enum FromV8Value { + V8(JsBuffer), + Bytes(JsBuffer), U64(BigInt), } -impl TryFrom for Value { +#[derive(Debug, Serialize)] +#[serde(tag = "kind", content = "value", rename_all = "snake_case")] +enum ToV8Value { + V8(ToJsBuffer), + Bytes(ToJsBuffer), + U64(BigInt), +} + +impl TryFrom for Value { type Error = AnyError; - fn try_from(value: V8Value) -> Result { + fn try_from(value: FromV8Value) -> Result { Ok(match value { - V8Value::V8(buf) => Value::V8(buf.to_vec()), - V8Value::Bytes(buf) => Value::Bytes(buf.to_vec()), - V8Value::U64(n) => Value::U64(num_bigint::BigInt::from(n).try_into()?), + FromV8Value::V8(buf) => Value::V8(buf.to_vec()), + FromV8Value::Bytes(buf) => Value::Bytes(buf.to_vec()), + FromV8Value::U64(n) => { + Value::U64(num_bigint::BigInt::from(n).try_into()?) + } }) } } -impl From for V8Value { +impl From for ToV8Value { fn from(value: Value) -> Self { match value { - Value::V8(buf) => V8Value::V8(buf.into()), - Value::Bytes(buf) => V8Value::Bytes(buf.into()), - Value::U64(n) => V8Value::U64(num_bigint::BigInt::from(n).into()), + Value::V8(buf) => ToV8Value::V8(buf.into()), + Value::Bytes(buf) => ToV8Value::Bytes(buf.into()), + Value::U64(n) => ToV8Value::U64(num_bigint::BigInt::from(n).into()), } } } -#[derive(Deserialize, Serialize)] -struct V8KvEntry { +#[derive(Serialize)] +struct ToV8KvEntry { key: KvKey, - value: V8Value, + value: ToV8Value, versionstamp: ByteString, } -impl TryFrom for V8KvEntry { +impl TryFrom for ToV8KvEntry { type Error = AnyError; fn try_from(entry: KvEntry) -> Result { - Ok(V8KvEntry { + Ok(ToV8KvEntry { key: decode_key(&entry.key)? .0 .into_iter() @@ -223,7 +235,7 @@ async fn op_kv_snapshot_read( rid: ResourceId, ranges: Vec, consistency: V8Consistency, -) -> Result>, AnyError> +) -> Result>, AnyError> where DBH: DatabaseHandler + 'static, { @@ -301,7 +313,7 @@ impl Resource for QueueMessageResource { async fn op_kv_dequeue_next_message( state: Rc>, rid: ResourceId, -) -> Result<(ZeroCopyBuf, ResourceId), AnyError> +) -> Result<(ToJsBuffer, ResourceId), AnyError> where DBH: DatabaseHandler + 'static, { @@ -364,7 +376,7 @@ impl TryFrom for KvCheck { } } -type V8KvMutation = (KvKey, String, Option); +type V8KvMutation = (KvKey, String, Option); impl TryFrom for KvMutation { type Error = AnyError; @@ -389,7 +401,7 @@ impl TryFrom for KvMutation { } } -type V8Enqueue = (ZeroCopyBuf, u64, Vec, Option>); +type V8Enqueue = (JsBuffer, u64, Vec, Option>); impl TryFrom for Enqueue { type Error = AnyError; diff --git a/ext/net/ops.rs b/ext/net/ops.rs index 05aa416b4b..921b9ea5b2 100644 --- a/ext/net/ops.rs +++ b/ext/net/ops.rs @@ -15,11 +15,11 @@ use deno_core::AsyncRefCell; use deno_core::ByteString; use deno_core::CancelHandle; use deno_core::CancelTryFuture; +use deno_core::JsBuffer; use deno_core::OpState; use deno_core::RcRef; use deno_core::Resource; use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; use serde::Deserialize; use serde::Serialize; use socket2::Domain; @@ -109,7 +109,7 @@ async fn op_net_accept_tcp( async fn op_net_recv_udp( state: Rc>, rid: ResourceId, - mut buf: ZeroCopyBuf, + mut buf: JsBuffer, ) -> Result<(usize, IpAddr), AnyError> { let resource = state .borrow_mut() @@ -130,7 +130,7 @@ async fn op_net_send_udp( state: Rc>, rid: ResourceId, addr: IpAddr, - zero_copy: ZeroCopyBuf, + zero_copy: JsBuffer, ) -> Result where NP: NetPermissions + 'static, diff --git a/ext/net/ops_unix.rs b/ext/net/ops_unix.rs index bed923f8b4..f3ff9617af 100644 --- a/ext/net/ops_unix.rs +++ b/ext/net/ops_unix.rs @@ -9,11 +9,11 @@ use deno_core::op; use deno_core::AsyncRefCell; use deno_core::CancelHandle; use deno_core::CancelTryFuture; +use deno_core::JsBuffer; use deno_core::OpState; use deno_core::RcRef; use deno_core::Resource; use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; use serde::Deserialize; use serde::Serialize; use std::borrow::Cow; @@ -138,7 +138,7 @@ where pub async fn op_net_recv_unixpacket( state: Rc>, rid: ResourceId, - mut buf: ZeroCopyBuf, + mut buf: JsBuffer, ) -> Result<(usize, Option), AnyError> { let resource = state .borrow() @@ -160,7 +160,7 @@ async fn op_net_send_unixpacket( state: Rc>, rid: ResourceId, path: String, - zero_copy: ZeroCopyBuf, + zero_copy: JsBuffer, ) -> Result where NP: NetPermissions + 'static, diff --git a/ext/node/ops/crypto/mod.rs b/ext/node/ops/crypto/mod.rs index 05f2d34f7e..a83263fff6 100644 --- a/ext/node/ops/crypto/mod.rs +++ b/ext/node/ops/crypto/mod.rs @@ -5,10 +5,11 @@ use deno_core::error::AnyError; use deno_core::op; use deno_core::serde_v8; use deno_core::task::spawn_blocking; +use deno_core::JsBuffer; use deno_core::OpState; use deno_core::ResourceId; use deno_core::StringOrBuffer; -use deno_core::ZeroCopyBuf; +use deno_core::ToJsBuffer; use hkdf::Hkdf; use num_bigint::BigInt; use num_bigint_dig::BigUint; @@ -115,7 +116,7 @@ pub fn op_node_hash_update_str( pub fn op_node_hash_digest( state: &mut OpState, rid: ResourceId, -) -> Result { +) -> Result { let context = state.resource_table.take::(rid)?; let context = Rc::try_unwrap(context) .map_err(|_| type_error("Hash context is already in use"))?; @@ -148,7 +149,7 @@ pub fn op_node_private_encrypt( key: StringOrBuffer, msg: StringOrBuffer, padding: u32, -) -> Result { +) -> Result { let key = RsaPrivateKey::from_pkcs8_pem((&key).try_into()?)?; let mut rng = rand::thread_rng(); @@ -172,7 +173,7 @@ pub fn op_node_private_decrypt( key: StringOrBuffer, msg: StringOrBuffer, padding: u32, -) -> Result { +) -> Result { let key = RsaPrivateKey::from_pkcs8_pem((&key).try_into()?)?; match padding { @@ -195,7 +196,7 @@ pub fn op_node_public_encrypt( key: StringOrBuffer, msg: StringOrBuffer, padding: u32, -) -> Result { +) -> Result { let key = RsaPublicKey::from_public_key_pem((&key).try_into()?)?; let mut rng = rand::thread_rng(); @@ -307,7 +308,7 @@ pub fn op_node_sign( key: StringOrBuffer, key_type: &str, key_format: &str, -) -> Result { +) -> Result { match key_type { "rsa" => { use rsa::pkcs1v15::SigningKey; @@ -456,7 +457,7 @@ pub async fn op_node_pbkdf2_async( iterations: u32, digest: String, keylen: usize, -) -> Result { +) -> Result { spawn_blocking(move || { let mut derived_key = vec![0; keylen]; pbkdf2_sync(&password, &salt, iterations, &digest, &mut derived_key) @@ -471,7 +472,7 @@ pub fn op_node_generate_secret(buf: &mut [u8]) { } #[op] -pub async fn op_node_generate_secret_async(len: i32) -> ZeroCopyBuf { +pub async fn op_node_generate_secret_async(len: i32) -> ToJsBuffer { spawn_blocking(move || { let mut buf = vec![0u8; len as usize]; rand::thread_rng().fill(&mut buf[..]); @@ -525,11 +526,11 @@ pub fn op_node_hkdf( #[op] pub async fn op_node_hkdf_async( hash: String, - ikm: ZeroCopyBuf, - salt: ZeroCopyBuf, - info: ZeroCopyBuf, + ikm: JsBuffer, + salt: JsBuffer, + info: JsBuffer, okm_len: usize, -) -> Result { +) -> Result { spawn_blocking(move || { let mut okm = vec![0u8; okm_len]; hkdf_sync(&hash, &ikm, &salt, &info, &mut okm)?; @@ -546,7 +547,7 @@ use self::primes::Prime; fn generate_rsa( modulus_length: usize, public_exponent: usize, -) -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> { +) -> Result<(ToJsBuffer, ToJsBuffer), AnyError> { let mut rng = rand::thread_rng(); let private_key = RsaPrivateKey::new_with_exp( &mut rng, @@ -564,7 +565,7 @@ fn generate_rsa( pub fn op_node_generate_rsa( modulus_length: usize, public_exponent: usize, -) -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> { +) -> Result<(ToJsBuffer, ToJsBuffer), AnyError> { generate_rsa(modulus_length, public_exponent) } @@ -572,14 +573,14 @@ pub fn op_node_generate_rsa( pub async fn op_node_generate_rsa_async( modulus_length: usize, public_exponent: usize, -) -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> { +) -> Result<(ToJsBuffer, ToJsBuffer), AnyError> { spawn_blocking(move || generate_rsa(modulus_length, public_exponent)).await? } fn dsa_generate( modulus_length: usize, divisor_length: usize, -) -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> { +) -> Result<(ToJsBuffer, ToJsBuffer), AnyError> { let mut rng = rand::thread_rng(); use dsa::pkcs8::EncodePrivateKey; use dsa::pkcs8::EncodePublicKey; @@ -618,7 +619,7 @@ fn dsa_generate( pub fn op_node_dsa_generate( modulus_length: usize, divisor_length: usize, -) -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> { +) -> Result<(ToJsBuffer, ToJsBuffer), AnyError> { dsa_generate(modulus_length, divisor_length) } @@ -626,13 +627,13 @@ pub fn op_node_dsa_generate( pub async fn op_node_dsa_generate_async( modulus_length: usize, divisor_length: usize, -) -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> { +) -> Result<(ToJsBuffer, ToJsBuffer), AnyError> { spawn_blocking(move || dsa_generate(modulus_length, divisor_length)).await? } fn ec_generate( named_curve: &str, -) -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> { +) -> Result<(ToJsBuffer, ToJsBuffer), AnyError> { use ring::signature::EcdsaKeyPair; use ring::signature::KeyPair; @@ -658,18 +659,18 @@ fn ec_generate( #[op] pub fn op_node_ec_generate( named_curve: &str, -) -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> { +) -> Result<(ToJsBuffer, ToJsBuffer), AnyError> { ec_generate(named_curve) } #[op] pub async fn op_node_ec_generate_async( named_curve: String, -) -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> { +) -> Result<(ToJsBuffer, ToJsBuffer), AnyError> { spawn_blocking(move || ec_generate(&named_curve)).await? } -fn ed25519_generate() -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> { +fn ed25519_generate() -> Result<(ToJsBuffer, ToJsBuffer), AnyError> { use ring::signature::Ed25519KeyPair; use ring::signature::KeyPair; @@ -685,18 +686,18 @@ fn ed25519_generate() -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> { } #[op] -pub fn op_node_ed25519_generate() -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> +pub fn op_node_ed25519_generate() -> Result<(ToJsBuffer, ToJsBuffer), AnyError> { ed25519_generate() } #[op] pub async fn op_node_ed25519_generate_async( -) -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> { +) -> Result<(ToJsBuffer, ToJsBuffer), AnyError> { spawn_blocking(ed25519_generate).await? } -fn x25519_generate() -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> { +fn x25519_generate() -> Result<(ToJsBuffer, ToJsBuffer), AnyError> { // u-coordinate of the base point. const X25519_BASEPOINT_BYTES: [u8; 32] = [ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -720,20 +721,19 @@ fn x25519_generate() -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> { } #[op] -pub fn op_node_x25519_generate() -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> -{ +pub fn op_node_x25519_generate() -> Result<(ToJsBuffer, ToJsBuffer), AnyError> { x25519_generate() } #[op] pub async fn op_node_x25519_generate_async( -) -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> { +) -> Result<(ToJsBuffer, ToJsBuffer), AnyError> { spawn_blocking(x25519_generate).await? } fn dh_generate_group( group_name: &str, -) -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> { +) -> Result<(ToJsBuffer, ToJsBuffer), AnyError> { let dh = match group_name { "modp5" => dh::DiffieHellman::group::(), "modp14" => dh::DiffieHellman::group::(), @@ -753,14 +753,14 @@ fn dh_generate_group( #[op] pub fn op_node_dh_generate_group( group_name: &str, -) -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> { +) -> Result<(ToJsBuffer, ToJsBuffer), AnyError> { dh_generate_group(group_name) } #[op] pub async fn op_node_dh_generate_group_async( group_name: String, -) -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> { +) -> Result<(ToJsBuffer, ToJsBuffer), AnyError> { spawn_blocking(move || dh_generate_group(&group_name)).await? } @@ -768,7 +768,7 @@ fn dh_generate( prime: Option<&[u8]>, prime_len: usize, generator: usize, -) -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> { +) -> Result<(ToJsBuffer, ToJsBuffer), AnyError> { let prime = prime .map(|p| p.into()) .unwrap_or_else(|| Prime::generate(prime_len)); @@ -785,26 +785,26 @@ pub fn op_node_dh_generate( prime: Option<&[u8]>, prime_len: usize, generator: usize, -) -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> { +) -> Result<(ToJsBuffer, ToJsBuffer), AnyError> { dh_generate(prime, prime_len, generator) } // TODO(lev): This duplication should be avoided. #[op] pub fn op_node_dh_generate2( - prime: ZeroCopyBuf, + prime: JsBuffer, prime_len: usize, generator: usize, -) -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> { +) -> Result<(ToJsBuffer, ToJsBuffer), AnyError> { dh_generate(Some(prime).as_deref(), prime_len, generator) } #[op] pub fn op_node_dh_compute_secret( - prime: ZeroCopyBuf, - private_key: ZeroCopyBuf, - their_public_key: ZeroCopyBuf, -) -> Result { + prime: JsBuffer, + private_key: JsBuffer, + their_public_key: JsBuffer, +) -> Result { let pubkey: BigUint = BigUint::from_bytes_be(their_public_key.as_ref()); let privkey: BigUint = BigUint::from_bytes_be(private_key.as_ref()); let primei: BigUint = BigUint::from_bytes_be(prime.as_ref()); @@ -815,10 +815,10 @@ pub fn op_node_dh_compute_secret( #[op] pub async fn op_node_dh_generate_async( - prime: Option, + prime: Option, prime_len: usize, generator: usize, -) -> Result<(ZeroCopyBuf, ZeroCopyBuf), AnyError> { +) -> Result<(ToJsBuffer, ToJsBuffer), AnyError> { spawn_blocking(move || dh_generate(prime.as_deref(), prime_len, generator)) .await? } @@ -895,7 +895,7 @@ pub async fn op_node_scrypt_async( block_size: u32, parallelization: u32, maxmem: u32, -) -> Result { +) -> Result { spawn_blocking(move || { let mut output_buffer = vec![0u8; keylen as usize]; let res = scrypt( @@ -963,7 +963,7 @@ pub fn op_node_ecdh_generate_keys( #[op] pub fn op_node_ecdh_compute_secret( curve: &str, - this_priv: Option, + this_priv: Option, their_pub: &mut [u8], secret: &mut [u8], ) -> Result<(), AnyError> { @@ -1079,18 +1079,18 @@ pub fn op_node_ecdh_compute_public_key( } #[inline] -fn gen_prime(size: usize) -> ZeroCopyBuf { +fn gen_prime(size: usize) -> ToJsBuffer { primes::Prime::generate(size).0.to_bytes_be().into() } #[op] -pub fn op_node_gen_prime(size: usize) -> ZeroCopyBuf { +pub fn op_node_gen_prime(size: usize) -> ToJsBuffer { gen_prime(size) } #[op] pub async fn op_node_gen_prime_async( size: usize, -) -> Result { +) -> Result { Ok(spawn_blocking(move || gen_prime(size)).await?) } diff --git a/ext/url/lib.rs b/ext/url/lib.rs index cfb6497c3b..b884f79487 100644 --- a/ext/url/lib.rs +++ b/ext/url/lib.rs @@ -8,8 +8,8 @@ use deno_core::op; use deno_core::url::form_urlencoded; use deno_core::url::quirks; use deno_core::url::Url; +use deno_core::JsBuffer; use deno_core::OpState; -use deno_core::ZeroCopyBuf; use std::path::PathBuf; use crate::urlpattern::op_urlpattern_parse; @@ -220,7 +220,7 @@ pub fn op_url_reparse( #[op] pub fn op_url_parse_search_params( args: Option, - zero_copy: Option, + zero_copy: Option, ) -> Result, AnyError> { let params = match (args, zero_copy) { (None, Some(zero_copy)) => form_urlencoded::parse(&zero_copy) diff --git a/ext/web/blob.rs b/ext/web/blob.rs index 7796c18afb..9c5f5a09cf 100644 --- a/ext/web/blob.rs +++ b/ext/web/blob.rs @@ -12,8 +12,9 @@ use deno_core::error::AnyError; use deno_core::op; use deno_core::parking_lot::Mutex; use deno_core::url::Url; +use deno_core::JsBuffer; use deno_core::OpState; -use deno_core::ZeroCopyBuf; +use deno_core::ToJsBuffer; use serde::Deserialize; use serde::Serialize; use uuid::Uuid; @@ -160,7 +161,7 @@ impl BlobPart for SlicedBlobPart { } #[op] -pub fn op_blob_create_part(state: &mut OpState, data: ZeroCopyBuf) -> Uuid { +pub fn op_blob_create_part(state: &mut OpState, data: JsBuffer) -> Uuid { let blob_store = state.borrow::(); let part = InMemoryBlobPart(data.to_vec()); blob_store.insert_part(Arc::new(part)) @@ -203,7 +204,7 @@ pub fn op_blob_slice_part( pub async fn op_blob_read_part( state: Rc>, id: Uuid, -) -> Result { +) -> Result { let part = { let state = state.borrow(); let blob_store = state.borrow::(); @@ -211,7 +212,7 @@ pub async fn op_blob_read_part( } .ok_or_else(|| type_error("Blob part not found"))?; let buf = part.read().await?; - Ok(ZeroCopyBuf::from(buf.to_vec())) + Ok(ToJsBuffer::from(buf.to_vec())) } #[op] diff --git a/ext/web/compression.rs b/ext/web/compression.rs index 11ea9196a5..557bff6ba6 100644 --- a/ext/web/compression.rs +++ b/ext/web/compression.rs @@ -5,7 +5,7 @@ use deno_core::op; use deno_core::OpState; use deno_core::Resource; use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; +use deno_core::ToJsBuffer; use flate2::write::DeflateDecoder; use flate2::write::DeflateEncoder; use flate2::write::GzDecoder; @@ -69,7 +69,7 @@ pub fn op_compression_write( state: &mut OpState, rid: ResourceId, input: &[u8], -) -> Result { +) -> Result { let resource = state.resource_table.get::(rid)?; let mut inner = resource.0.borrow_mut(); let out: Vec = match &mut *inner { @@ -112,7 +112,7 @@ pub fn op_compression_write( pub fn op_compression_finish( state: &mut OpState, rid: ResourceId, -) -> Result { +) -> Result { let resource = state.resource_table.take::(rid)?; let resource = Rc::try_unwrap(resource).unwrap(); let inner = resource.0.into_inner(); diff --git a/ext/web/lib.rs b/ext/web/lib.rs index b1e0dd5d8d..af213b5bec 100644 --- a/ext/web/lib.rs +++ b/ext/web/lib.rs @@ -18,8 +18,8 @@ use deno_core::CancelHandle; use deno_core::OpState; use deno_core::Resource; use deno_core::ResourceId; +use deno_core::ToJsBuffer; use deno_core::U16String; -use deno_core::ZeroCopyBuf; use encoding_rs::CoderResult; use encoding_rs::Decoder; @@ -123,7 +123,7 @@ deno_core::extension!(deno_web, ); #[op] -fn op_base64_decode(input: String) -> Result { +fn op_base64_decode(input: String) -> Result { let mut s = input.into_bytes(); let decoded_len = forgiving_base64_decode_inplace(&mut s)?; s.truncate(decoded_len); diff --git a/ext/websocket/lib.rs b/ext/websocket/lib.rs index cbf9f8ff17..dd975589c3 100644 --- a/ext/websocket/lib.rs +++ b/ext/websocket/lib.rs @@ -11,11 +11,12 @@ use deno_core::AsyncRefCell; use deno_core::ByteString; use deno_core::CancelFuture; use deno_core::CancelHandle; +use deno_core::JsBuffer; use deno_core::OpState; use deno_core::RcRef; use deno_core::Resource; use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; +use deno_core::ToJsBuffer; use deno_net::raw::NetworkStream; use deno_tls::create_client_config; use deno_tls::RootCertStoreProvider; @@ -406,11 +407,7 @@ pub fn ws_create_server_stream( } #[op(fast)] -pub fn op_ws_send_binary( - state: &mut OpState, - rid: ResourceId, - data: ZeroCopyBuf, -) { +pub fn op_ws_send_binary(state: &mut OpState, rid: ResourceId, data: JsBuffer) { let resource = state.resource_table.get::(rid).unwrap(); let data = data.to_vec(); let len = data.len(); @@ -454,7 +451,7 @@ pub fn op_ws_send_text(state: &mut OpState, rid: ResourceId, data: String) { pub async fn op_ws_send_binary_async( state: Rc>, rid: ResourceId, - data: ZeroCopyBuf, + data: JsBuffer, ) -> Result<(), AnyError> { let resource = state .borrow_mut() @@ -547,7 +544,7 @@ pub async fn op_ws_close( } #[op] -pub fn op_ws_get_buffer(state: &mut OpState, rid: ResourceId) -> ZeroCopyBuf { +pub fn op_ws_get_buffer(state: &mut OpState, rid: ResourceId) -> ToJsBuffer { let resource = state.resource_table.get::(rid).unwrap(); resource.buffer.take().unwrap().into() } diff --git a/runtime/ops/http.rs b/runtime/ops/http.rs index eb27112570..35e181d3e9 100644 --- a/runtime/ops/http.rs +++ b/runtime/ops/http.rs @@ -11,7 +11,7 @@ use deno_core::op; use deno_core::OpState; use deno_core::RcRef; use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; +use deno_core::ToJsBuffer; use deno_http::http_create_conn_resource; use deno_http::HttpRequestReader; use deno_http::HttpStreamResource; @@ -93,7 +93,7 @@ fn op_http_start( pub struct HttpUpgradeResult { conn_rid: ResourceId, conn_type: &'static str, - read_buf: ZeroCopyBuf, + read_buf: ToJsBuffer, } #[op] diff --git a/runtime/ops/process.rs b/runtime/ops/process.rs index 44429fdab7..14d773af03 100644 --- a/runtime/ops/process.rs +++ b/runtime/ops/process.rs @@ -12,7 +12,7 @@ use deno_core::OpState; use deno_core::RcRef; use deno_core::Resource; use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; +use deno_core::ToJsBuffer; use deno_io::fs::FileResource; use deno_io::ChildStderrResource; use deno_io::ChildStdinResource; @@ -198,8 +198,8 @@ impl TryFrom for ChildStatus { #[serde(rename_all = "camelCase")] pub struct SpawnOutput { status: ChildStatus, - stdout: Option, - stderr: Option, + stdout: Option, + stderr: Option, } fn create_command( diff --git a/serde_v8/de.rs b/serde_v8/de.rs index edb1263ebb..d36cf64523 100644 --- a/serde_v8/de.rs +++ b/serde_v8/de.rs @@ -18,9 +18,9 @@ use crate::AnyValue; use crate::BigInt; use crate::ByteString; use crate::DetachedBuffer; +use crate::JsBuffer; use crate::StringOrBuffer; use crate::U16String; -use crate::ZeroCopyBuf; pub struct Deserializer<'a, 'b, 's> { input: v8::Local<'a, v8::Value>, @@ -337,8 +337,8 @@ impl<'de, 'a, 'b, 's, 'x> de::Deserializer<'de> V: Visitor<'de>, { match name { - ZeroCopyBuf::MAGIC_NAME => { - visit_magic(visitor, ZeroCopyBuf::from_v8(self.scope, self.input)?) + JsBuffer::MAGIC_NAME => { + visit_magic(visitor, JsBuffer::from_v8(self.scope, self.input)?) } DetachedBuffer::MAGIC_NAME => { visit_magic(visitor, DetachedBuffer::from_v8(self.scope, self.input)?) @@ -452,7 +452,7 @@ impl<'de, 'a, 'b, 's, 'x> de::Deserializer<'de> where V: Visitor<'de>, { - magic::buffer::ZeroCopyBuf::from_v8(self.scope, self.input) + magic::buffer::JsBuffer::from_v8(self.scope, self.input) .and_then(|zb| visitor.visit_bytes(&zb)) } @@ -460,7 +460,7 @@ impl<'de, 'a, 'b, 's, 'x> de::Deserializer<'de> where V: Visitor<'de>, { - magic::buffer::ZeroCopyBuf::from_v8(self.scope, self.input) + magic::buffer::JsBuffer::from_v8(self.scope, self.input) .and_then(|zb| visitor.visit_byte_buf(Vec::from(&*zb))) } } diff --git a/serde_v8/lib.rs b/serde_v8/lib.rs index 26d95c67aa..59c8fd41fe 100644 --- a/serde_v8/lib.rs +++ b/serde_v8/lib.rs @@ -17,7 +17,8 @@ pub use error::Result; pub use keys::KeyCache; pub use magic::any_value::AnyValue; pub use magic::bigint::BigInt; -pub use magic::buffer::ZeroCopyBuf; +pub use magic::buffer::JsBuffer; +pub use magic::buffer::ToJsBuffer; pub use magic::bytestring::ByteString; pub use magic::detached_buffer::DetachedBuffer; pub use magic::string_or_buffer::StringOrBuffer; diff --git a/serde_v8/magic/any_value.rs b/serde_v8/magic/any_value.rs index 31a74cfde0..9ae39bb2e7 100644 --- a/serde_v8/magic/any_value.rs +++ b/serde_v8/magic/any_value.rs @@ -1,17 +1,19 @@ use num_bigint::BigInt; // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -use super::buffer::ZeroCopyBuf; +use super::buffer::JsBuffer; use super::transl8::FromV8; use super::transl8::ToV8; use crate::magic::transl8::impl_magic; use crate::Error; +use crate::ToJsBuffer; /// An untagged enum type that can be any of number, string, bool, bigint, or /// buffer. #[derive(Debug)] pub enum AnyValue { - Buffer(ZeroCopyBuf), + RustBuffer(ToJsBuffer), + V8Buffer(JsBuffer), String(String), Number(f64), BigInt(BigInt), @@ -26,7 +28,8 @@ impl ToV8 for AnyValue { scope: &mut v8::HandleScope<'a>, ) -> Result, crate::Error> { match self { - Self::Buffer(buf) => buf.to_v8(scope), + Self::RustBuffer(buf) => crate::to_v8(scope, buf), + Self::V8Buffer(_) => unreachable!(), Self::String(s) => crate::to_v8(scope, s), Self::Number(num) => crate::to_v8(scope, num), Self::BigInt(bigint) => { @@ -52,8 +55,8 @@ impl FromV8 for AnyValue { let bigint = crate::BigInt::from_v8(scope, value)?; Ok(AnyValue::BigInt(bigint.into())) } else if value.is_array_buffer_view() { - let buf = ZeroCopyBuf::from_v8(scope, value)?; - Ok(AnyValue::Buffer(buf)) + let buf = JsBuffer::from_v8(scope, value)?; + Ok(AnyValue::V8Buffer(buf)) } else if value.is_boolean() { let string = crate::from_v8(scope, value)?; Ok(AnyValue::Bool(string)) diff --git a/serde_v8/magic/buffer.rs b/serde_v8/magic/buffer.rs index d0f0909bc9..032a3be33d 100644 --- a/serde_v8/magic/buffer.rs +++ b/serde_v8/magic/buffer.rs @@ -9,91 +9,93 @@ use super::transl8::ToV8; use super::v8slice::V8Slice; use crate::magic::transl8::impl_magic; -// An asymmetric wrapper around V8Slice, -// allowing us to use a single type for familiarity -pub enum ZeroCopyBuf { - FromV8(V8Slice), - ToV8(Option>), -} +pub struct JsBuffer(V8Slice); -impl_magic!(ZeroCopyBuf); +impl_magic!(JsBuffer); -impl Debug for ZeroCopyBuf { +impl Debug for JsBuffer { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_list().entries(self.as_ref().iter()).finish() + f.debug_list().entries(self.0.as_ref().iter()).finish() } } -impl ZeroCopyBuf { - pub fn empty() -> Self { - ZeroCopyBuf::ToV8(Some(vec![0_u8; 0].into_boxed_slice())) - } -} - -impl Clone for ZeroCopyBuf { +impl Clone for JsBuffer { fn clone(&self) -> Self { - match self { - Self::FromV8(zbuf) => Self::FromV8(zbuf.clone()), - Self::ToV8(_) => panic!("Don't Clone a ZeroCopyBuf sent to v8"), - } + Self(self.0.clone()) } } -impl AsRef<[u8]> for ZeroCopyBuf { +impl AsRef<[u8]> for JsBuffer { fn as_ref(&self) -> &[u8] { - self + &self.0 } } -impl AsMut<[u8]> for ZeroCopyBuf { +impl AsMut<[u8]> for JsBuffer { fn as_mut(&mut self) -> &mut [u8] { - &mut *self + &mut self.0 } } -impl Deref for ZeroCopyBuf { +impl Deref for JsBuffer { type Target = [u8]; fn deref(&self) -> &[u8] { - match self { - Self::FromV8(buf) => buf, - Self::ToV8(_) => panic!("Don't Deref a ZeroCopyBuf sent to v8"), - } + &self.0 } } -impl DerefMut for ZeroCopyBuf { +impl DerefMut for JsBuffer { fn deref_mut(&mut self) -> &mut [u8] { - match self { - Self::FromV8(buf) => &mut *buf, - Self::ToV8(_) => panic!("Don't Deref a ZeroCopyBuf sent to v8"), - } + &mut self.0 } } -impl From> for ZeroCopyBuf { +impl FromV8 for JsBuffer { + fn from_v8( + scope: &mut v8::HandleScope, + value: v8::Local, + ) -> Result { + Ok(Self(V8Slice::from_v8(scope, value)?)) + } +} + +impl From for bytes::Bytes { + fn from(zbuf: JsBuffer) -> bytes::Bytes { + zbuf.0.into() + } +} + +// NOTE(bartlomieju): we use Option here, because `to_v8()` uses `&mut self` +// instead of `self` which is dictated by the `serde` API. +#[derive(Debug)] +pub struct ToJsBuffer(Option>); + +impl_magic!(ToJsBuffer); + +impl ToJsBuffer { + pub fn empty() -> Self { + ToJsBuffer(Some(vec![0_u8; 0].into_boxed_slice())) + } +} + +impl From> for ToJsBuffer { fn from(buf: Box<[u8]>) -> Self { - ZeroCopyBuf::ToV8(Some(buf)) + ToJsBuffer(Some(buf)) } } -impl From> for ZeroCopyBuf { +impl From> for ToJsBuffer { fn from(vec: Vec) -> Self { vec.into_boxed_slice().into() } } -impl ToV8 for ZeroCopyBuf { +impl ToV8 for ToJsBuffer { fn to_v8<'a>( &mut self, scope: &mut v8::HandleScope<'a>, ) -> Result, crate::Error> { - let buf: Box<[u8]> = match self { - Self::FromV8(buf) => { - let value: &[u8] = buf; - value.into() - } - Self::ToV8(ref mut x) => x.take().expect("ZeroCopyBuf was empty"), - }; + let buf: Box<[u8]> = self.0.take().expect("RustToV8Buf was empty"); if buf.is_empty() { let ab = v8::ArrayBuffer::new(scope, 0); @@ -103,7 +105,7 @@ impl ToV8 for ZeroCopyBuf { .into(), ); } - let buf_len = buf.len(); + let buf_len: usize = buf.len(); let backing_store = v8::ArrayBuffer::new_backing_store_from_boxed_slice(buf); let backing_store_shared = backing_store.make_shared(); @@ -115,23 +117,3 @@ impl ToV8 for ZeroCopyBuf { ) } } - -impl FromV8 for ZeroCopyBuf { - fn from_v8( - scope: &mut v8::HandleScope, - value: v8::Local, - ) -> Result { - Ok(Self::FromV8(V8Slice::from_v8(scope, value)?)) - } -} - -impl From for bytes::Bytes { - fn from(zbuf: ZeroCopyBuf) -> bytes::Bytes { - match zbuf { - ZeroCopyBuf::FromV8(v) => v.into(), - ZeroCopyBuf::ToV8(mut v) => { - v.take().expect("ZeroCopyBuf was empty").into() - } - } - } -} diff --git a/serde_v8/magic/string_or_buffer.rs b/serde_v8/magic/string_or_buffer.rs index 02571f6693..986f7d32ad 100644 --- a/serde_v8/magic/string_or_buffer.rs +++ b/serde_v8/magic/string_or_buffer.rs @@ -1,7 +1,6 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -use super::buffer::ZeroCopyBuf; +use super::buffer::JsBuffer; use super::transl8::FromV8; -use super::transl8::ToV8; use crate::error::value_to_type_str; use crate::magic::transl8::impl_magic; use crate::Error; @@ -9,7 +8,7 @@ use std::ops::Deref; #[derive(Debug)] pub enum StringOrBuffer { - Buffer(ZeroCopyBuf), + Buffer(JsBuffer), String(String), } @@ -35,40 +34,12 @@ impl<'a> TryFrom<&'a StringOrBuffer> for &'a str { } } -impl ToV8 for StringOrBuffer { - fn to_v8<'a>( - &mut self, - scope: &mut v8::HandleScope<'a>, - ) -> Result, crate::Error> { - match self { - Self::Buffer(buf) => { - let buf: Box<[u8]> = match buf { - ZeroCopyBuf::FromV8(buf) => { - let value: &[u8] = buf; - value.into() - } - ZeroCopyBuf::ToV8(ref mut x) => { - x.take().expect("ZeroCopyBuf was empty") - } - }; - let backing_store = - v8::ArrayBuffer::new_backing_store_from_boxed_slice(buf); - Ok( - v8::ArrayBuffer::with_backing_store(scope, &backing_store.into()) - .into(), - ) - } - Self::String(s) => crate::to_v8(scope, s), - } - } -} - impl FromV8 for StringOrBuffer { fn from_v8( scope: &mut v8::HandleScope, value: v8::Local, ) -> Result { - if let Ok(buf) = ZeroCopyBuf::from_v8(scope, value) { + if let Ok(buf) = JsBuffer::from_v8(scope, value) { return Ok(Self::Buffer(buf)); } else if let Ok(s) = crate::from_v8(scope, value) { return Ok(Self::String(s)); diff --git a/serde_v8/ser.rs b/serde_v8/ser.rs index 74ad9ec103..51625f2305 100644 --- a/serde_v8/ser.rs +++ b/serde_v8/ser.rs @@ -19,9 +19,8 @@ use crate::BigInt; use crate::ByteString; use crate::DetachedBuffer; use crate::ExternalPointer; -use crate::StringOrBuffer; +use crate::ToJsBuffer; use crate::U16String; -use crate::ZeroCopyBuf; type JsValue<'s> = v8::Local<'s, v8::Value>; type JsResult<'s> = Result>; @@ -274,12 +273,11 @@ impl<'a, 'b, 'c, T: MagicType + ToV8> ser::SerializeStruct 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>), + RustToV8Buf(MagicalSerializer<'a, 'b, 'c, ToJsBuffer>), MagicAnyValue(MagicalSerializer<'a, 'b, 'c, AnyValue>), MagicDetached(MagicalSerializer<'a, 'b, 'c, DetachedBuffer>), MagicByteString(MagicalSerializer<'a, 'b, 'c, ByteString>), MagicU16String(MagicalSerializer<'a, 'b, 'c, U16String>), - MagicStringOrBuffer(MagicalSerializer<'a, 'b, 'c, StringOrBuffer>), MagicBigInt(MagicalSerializer<'a, 'b, 'c, BigInt>), Regular(ObjectSerializer<'a, 'b, 'c>), } @@ -296,14 +294,11 @@ impl<'a, 'b, 'c> ser::SerializeStruct for StructSerializers<'a, 'b, 'c> { 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::RustToV8Buf(s) => s.serialize_field(key, value), StructSerializers::MagicAnyValue(s) => s.serialize_field(key, value), StructSerializers::MagicDetached(s) => s.serialize_field(key, value), StructSerializers::MagicByteString(s) => s.serialize_field(key, value), StructSerializers::MagicU16String(s) => s.serialize_field(key, value), - StructSerializers::MagicStringOrBuffer(s) => { - s.serialize_field(key, value) - } StructSerializers::MagicBigInt(s) => s.serialize_field(key, value), StructSerializers::Regular(s) => s.serialize_field(key, value), } @@ -313,12 +308,11 @@ impl<'a, 'b, 'c> ser::SerializeStruct for StructSerializers<'a, 'b, 'c> { match self { StructSerializers::ExternalPointer(s) => s.end(), StructSerializers::Magic(s) => s.end(), - StructSerializers::ZeroCopyBuf(s) => s.end(), + StructSerializers::RustToV8Buf(s) => s.end(), StructSerializers::MagicAnyValue(s) => s.end(), StructSerializers::MagicDetached(s) => s.end(), StructSerializers::MagicByteString(s) => s.end(), StructSerializers::MagicU16String(s) => s.end(), - StructSerializers::MagicStringOrBuffer(s) => s.end(), StructSerializers::MagicBigInt(s) => s.end(), StructSerializers::Regular(s) => s.end(), } @@ -588,9 +582,9 @@ impl<'a, 'b, 'c> ser::Serializer for Serializer<'a, 'b, 'c> { let m = MagicalSerializer::::new(self.scope); Ok(StructSerializers::MagicU16String(m)) } - ZeroCopyBuf::MAGIC_NAME => { - let m = MagicalSerializer::::new(self.scope); - Ok(StructSerializers::ZeroCopyBuf(m)) + ToJsBuffer::MAGIC_NAME => { + let m = MagicalSerializer::::new(self.scope); + Ok(StructSerializers::RustToV8Buf(m)) } AnyValue::MAGIC_NAME => { let m = MagicalSerializer::::new(self.scope); @@ -600,10 +594,6 @@ impl<'a, 'b, 'c> ser::Serializer for Serializer<'a, 'b, 'c> { let m = MagicalSerializer::::new(self.scope); Ok(StructSerializers::MagicDetached(m)) } - StringOrBuffer::MAGIC_NAME => { - let m = MagicalSerializer::::new(self.scope); - Ok(StructSerializers::MagicStringOrBuffer(m)) - } BigInt::MAGIC_NAME => { let m = MagicalSerializer::::new(self.scope); Ok(StructSerializers::MagicBigInt(m)) diff --git a/serde_v8/serializable.rs b/serde_v8/serializable.rs index b02aa0629e..36a8bc27b5 100644 --- a/serde_v8/serializable.rs +++ b/serde_v8/serializable.rs @@ -4,8 +4,8 @@ use std::mem::transmute_copy; use crate::BigInt; use crate::ByteString; +use crate::ToJsBuffer; use crate::U16String; -use crate::ZeroCopyBuf; /// Serializable exists to allow boxing values as "objects" to be serialized later, /// this is particularly useful for async op-responses. This trait is a more efficient @@ -63,7 +63,7 @@ pub enum Primitive { Float32(f32), Float64(f64), String(String), - ZeroCopyBuf(ZeroCopyBuf), + RustToV8Buf(ToJsBuffer), ByteString(ByteString), U16String(U16String), BigInt(BigInt), @@ -88,7 +88,7 @@ impl serde::Serialize for Primitive { Self::Float32(x) => x.serialize(s), Self::Float64(x) => x.serialize(s), Self::String(x) => x.serialize(s), - Self::ZeroCopyBuf(x) => x.serialize(s), + Self::RustToV8Buf(x) => x.serialize(s), Self::ByteString(x) => x.serialize(s), Self::U16String(x) => x.serialize(s), Self::BigInt(x) => x.serialize(s), @@ -134,8 +134,8 @@ impl From for SerializablePkg { Self::Primitive(Primitive::Float64(tc(x))) } else if tid == TypeId::of::() { Self::Primitive(Primitive::String(tc(x))) - } else if tid == TypeId::of::() { - Self::Primitive(Primitive::ZeroCopyBuf(tc(x))) + } else if tid == TypeId::of::() { + Self::Primitive(Primitive::RustToV8Buf(tc(x))) } else if tid == TypeId::of::() { Self::Primitive(Primitive::ByteString(tc(x))) } else if tid == TypeId::of::() { diff --git a/serde_v8/tests/de.rs b/serde_v8/tests/de.rs index 4c5cf72836..3abaa0979c 100644 --- a/serde_v8/tests/de.rs +++ b/serde_v8/tests/de.rs @@ -7,8 +7,8 @@ use serde_v8::utils::v8_do; use serde_v8::BigInt; use serde_v8::ByteString; use serde_v8::Error; +use serde_v8::JsBuffer; use serde_v8::U16String; -use serde_v8::ZeroCopyBuf; #[derive(Debug, Deserialize, PartialEq)] struct MathOp { @@ -248,31 +248,31 @@ fn de_string_or_buffer() { fn de_buffers() { // ArrayBufferView dedo("new Uint8Array([97])", |scope, v| { - let buf: ZeroCopyBuf = serde_v8::from_v8(scope, v).unwrap(); + let buf: JsBuffer = serde_v8::from_v8(scope, v).unwrap(); assert_eq!(&*buf, &[97]); }); // ArrayBuffer dedo("(new Uint8Array([97])).buffer", |scope, v| { - let buf: ZeroCopyBuf = serde_v8::from_v8(scope, v).unwrap(); + let buf: JsBuffer = serde_v8::from_v8(scope, v).unwrap(); assert_eq!(&*buf, &[97]); }); dedo( "(Uint8Array.from([0x68, 0x65, 0x6C, 0x6C, 0x6F]))", |scope, v| { - let buf: ZeroCopyBuf = serde_v8::from_v8(scope, v).unwrap(); + let buf: JsBuffer = serde_v8::from_v8(scope, v).unwrap(); assert_eq!(&*buf, &[0x68, 0x65, 0x6C, 0x6C, 0x6F]); }, ); dedo("(new ArrayBuffer(4))", |scope, v| { - let buf: ZeroCopyBuf = serde_v8::from_v8(scope, v).unwrap(); + let buf: JsBuffer = serde_v8::from_v8(scope, v).unwrap(); assert_eq!(&*buf, &[0x0, 0x0, 0x0, 0x0]); }); dedo("(new ArrayBuffer(8, { maxByteLength: 16}))", |scope, v| { - let result: Result = serde_v8::from_v8(scope, v); + let result: Result = serde_v8::from_v8(scope, v); matches!(result, Err(Error::ResizableBackingStoreNotSupported)); }); } diff --git a/serde_v8/tests/magic.rs b/serde_v8/tests/magic.rs index 8ae163784e..09e5205616 100644 --- a/serde_v8/tests/magic.rs +++ b/serde_v8/tests/magic.rs @@ -68,27 +68,26 @@ fn magic_buffer() { // Simple buffer let v8_array = js_exec(scope, "new Uint8Array([1,2,3,4,5])"); - let zbuf: serde_v8::ZeroCopyBuf = - serde_v8::from_v8(scope, v8_array).unwrap(); + let zbuf: serde_v8::JsBuffer = serde_v8::from_v8(scope, v8_array).unwrap(); assert_eq!(&*zbuf, &[1, 2, 3, 4, 5]); // Multi buffers let v8_arrays = js_exec(scope, "[new Uint8Array([1,2]), new Uint8Array([3,4,5])]"); - let (z1, z2): (serde_v8::ZeroCopyBuf, serde_v8::ZeroCopyBuf) = + let (z1, z2): (serde_v8::JsBuffer, serde_v8::JsBuffer) = serde_v8::from_v8(scope, v8_arrays).unwrap(); assert_eq!(&*z1, &[1, 2]); assert_eq!(&*z2, &[3, 4, 5]); // Wrapped in option, like our current op-ABI let v8_array = js_exec(scope, "new Uint8Array([1,2,3,4,5])"); - let zbuf: Option = + let zbuf: Option = serde_v8::from_v8(scope, v8_array).unwrap(); assert_eq!(&*zbuf.unwrap(), &[1, 2, 3, 4, 5]); // Observe mutation in JS let v8_array = js_exec(scope, "new Uint8Array([1,2,3,4,5])"); - let mut zbuf: serde_v8::ZeroCopyBuf = + let mut zbuf: serde_v8::JsBuffer = serde_v8::from_v8(scope, v8_array).unwrap(); let key = serde_v8::to_v8(scope, "t1").unwrap(); global.set(scope, key, v8_array); @@ -99,13 +98,12 @@ fn magic_buffer() { // Shared buffers let v8_array = js_exec(scope, "new Uint8Array(new SharedArrayBuffer([1,2,3,4,5]))"); - let zbuf: Result = - serde_v8::from_v8(scope, v8_array); + let zbuf: Result = serde_v8::from_v8(scope, v8_array); assert!(zbuf.is_err()); // Serialization let buf: Vec = vec![1, 2, 3, 99, 5]; - let zbuf: serde_v8::ZeroCopyBuf = buf.into(); + let zbuf: serde_v8::ToJsBuffer = buf.into(); let v8_value = serde_v8::to_v8(scope, zbuf).unwrap(); let key = serde_v8::to_v8(scope, "t2").unwrap(); global.set(scope, key, v8_value); @@ -115,8 +113,8 @@ fn magic_buffer() { // Composite Serialization #[derive(serde::Serialize)] struct Wrapper { - a: serde_v8::ZeroCopyBuf, - b: serde_v8::ZeroCopyBuf, + a: serde_v8::ToJsBuffer, + b: serde_v8::ToJsBuffer, } let buf1: Vec = vec![1, 2, 33, 4, 5]; let buf2: Vec = vec![5, 4, 3, 2, 11]; @@ -134,8 +132,7 @@ fn magic_buffer() { // ZeroCopyBuf as bytes::Bytes let v8_array = js_exec(scope, "new Uint8Array([1,2,3,4,5])"); - let zbuf: serde_v8::ZeroCopyBuf = - serde_v8::from_v8(scope, v8_array).unwrap(); + let zbuf: serde_v8::JsBuffer = serde_v8::from_v8(scope, v8_array).unwrap(); let buf: bytes::Bytes = zbuf.into(); assert_eq!(buf, bytes::Bytes::from_static(&[1, 2, 3, 4, 5])); assert_eq!(buf, bytes::Bytes::from_static(&[1, 2, 3, 4, 5]));