mirror of
https://github.com/denoland/deno.git
synced 2025-01-03 12:58:54 -05:00
tidy up deno_core modules (#5923)
This commit is contained in:
parent
86c6f05404
commit
2610ceac20
8 changed files with 235 additions and 225 deletions
|
@ -1,71 +0,0 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use std::any::Any;
|
||||
use std::any::TypeId;
|
||||
use std::convert::From;
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::ops::Deref;
|
||||
|
||||
// The Send and Sync traits are required because deno is multithreaded and we
|
||||
// need to be able to handle errors across threads.
|
||||
pub trait AnyError: Any + Error + Send + Sync + 'static {}
|
||||
impl<T> AnyError for T where T: Any + Error + Send + Sync + Sized + 'static {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ErrBox(Box<dyn AnyError>);
|
||||
|
||||
impl dyn AnyError {
|
||||
pub fn downcast_ref<T: AnyError>(&self) -> Option<&T> {
|
||||
if Any::type_id(self) == TypeId::of::<T>() {
|
||||
let target = self as *const Self as *const T;
|
||||
let target = unsafe { &*target };
|
||||
Some(target)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ErrBox {
|
||||
pub fn downcast<T: AnyError>(self) -> Result<T, Self> {
|
||||
if Any::type_id(&*self.0) == TypeId::of::<T>() {
|
||||
let target = Box::into_raw(self.0) as *mut T;
|
||||
let target = unsafe { Box::from_raw(target) };
|
||||
Ok(*target)
|
||||
} else {
|
||||
Err(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<dyn AnyError> for ErrBox {
|
||||
fn as_ref(&self) -> &dyn AnyError {
|
||||
self.0.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for ErrBox {
|
||||
type Target = Box<dyn AnyError>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AnyError> From<T> for ErrBox {
|
||||
fn from(error: T) -> Self {
|
||||
Self(Box::new(error))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Box<dyn AnyError>> for ErrBox {
|
||||
fn from(boxed: Box<dyn AnyError>) -> Self {
|
||||
Self(boxed)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ErrBox {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::es_isolate::EsIsolate;
|
||||
use crate::isolate::CoreIsolate;
|
||||
use crate::isolate::ZeroCopyBuf;
|
||||
use crate::js_errors::JSError;
|
||||
use crate::CoreIsolate;
|
||||
use crate::EsIsolate;
|
||||
use crate::JSError;
|
||||
use crate::ZeroCopyBuf;
|
||||
|
||||
use rusty_v8 as v8;
|
||||
use v8::MapFnTo;
|
||||
|
|
|
@ -7,13 +7,14 @@
|
|||
|
||||
use rusty_v8 as v8;
|
||||
|
||||
use crate::any_error::ErrBox;
|
||||
use crate::bindings;
|
||||
use crate::js_errors::JSError;
|
||||
use crate::ops::*;
|
||||
use crate::shared_queue::SharedQueue;
|
||||
use crate::shared_queue::RECOMMENDED_SIZE;
|
||||
use crate::ErrBox;
|
||||
use crate::JSError;
|
||||
use crate::ResourceTable;
|
||||
use crate::ZeroCopyBuf;
|
||||
use futures::future::FutureExt;
|
||||
use futures::stream::select;
|
||||
use futures::stream::FuturesUnordered;
|
||||
|
@ -24,10 +25,7 @@ use libc::c_void;
|
|||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::convert::From;
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::mem::forget;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::option::Option;
|
||||
use std::pin::Pin;
|
||||
use std::rc::Rc;
|
||||
|
@ -37,69 +35,6 @@ use std::task::Poll;
|
|||
|
||||
type PendingOpFuture = Pin<Box<dyn Future<Output = (OpId, Buf)>>>;
|
||||
|
||||
/// A ZeroCopyBuf encapsulates a slice that's been borrowed from a JavaScript
|
||||
/// ArrayBuffer object. JavaScript objects can normally be garbage collected,
|
||||
/// but the existence of a ZeroCopyBuf inhibits this until it is dropped. It
|
||||
/// behaves much like an Arc<[u8]>, although a ZeroCopyBuf currently can't be
|
||||
/// cloned.
|
||||
pub struct ZeroCopyBuf {
|
||||
backing_store: v8::SharedRef<v8::BackingStore>,
|
||||
byte_offset: usize,
|
||||
byte_length: usize,
|
||||
}
|
||||
|
||||
unsafe impl Send for ZeroCopyBuf {}
|
||||
|
||||
impl ZeroCopyBuf {
|
||||
pub fn new(view: v8::Local<v8::ArrayBufferView>) -> Self {
|
||||
let backing_store = view.buffer().unwrap().get_backing_store();
|
||||
let byte_offset = view.byte_offset();
|
||||
let byte_length = view.byte_length();
|
||||
Self {
|
||||
backing_store,
|
||||
byte_offset,
|
||||
byte_length,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for ZeroCopyBuf {
|
||||
type Target = [u8];
|
||||
fn deref(&self) -> &[u8] {
|
||||
unsafe {
|
||||
bindings::get_backing_store_slice(
|
||||
&self.backing_store,
|
||||
self.byte_offset,
|
||||
self.byte_length,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for ZeroCopyBuf {
|
||||
fn deref_mut(&mut self) -> &mut [u8] {
|
||||
unsafe {
|
||||
bindings::get_backing_store_slice_mut(
|
||||
&self.backing_store,
|
||||
self.byte_offset,
|
||||
self.byte_length,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for ZeroCopyBuf {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
&*self
|
||||
}
|
||||
}
|
||||
|
||||
impl AsMut<[u8]> for ZeroCopyBuf {
|
||||
fn as_mut(&mut self) -> &mut [u8] {
|
||||
&mut *self
|
||||
}
|
||||
}
|
||||
|
||||
/// Stores a script used to initialize a Isolate
|
||||
pub struct Script<'a> {
|
||||
pub source: &'a str,
|
||||
|
@ -627,14 +562,6 @@ fn drain_macrotasks<'s>(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn attach_handle_to_error(
|
||||
scope: &mut impl v8::InIsolate,
|
||||
err: ErrBox,
|
||||
handle: v8::Local<v8::Value>,
|
||||
) -> ErrBox {
|
||||
ErrWithV8Handle::new(scope, err, handle).into()
|
||||
}
|
||||
|
||||
pub(crate) fn exception_to_err_result<'s, T>(
|
||||
scope: &mut impl v8::ToLocal<'s>,
|
||||
exception: v8::Local<v8::Value>,
|
||||
|
@ -1183,42 +1110,3 @@ pub mod tests {
|
|||
js_check(isolate2.execute("check.js", "if (a != 3) throw Error('x')"));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(piscisaureus): rusty_v8 should implement the Error trait on
|
||||
// values of type v8::Global<T>.
|
||||
pub struct ErrWithV8Handle {
|
||||
err: ErrBox,
|
||||
handle: v8::Global<v8::Value>,
|
||||
}
|
||||
|
||||
impl ErrWithV8Handle {
|
||||
pub fn new(
|
||||
scope: &mut impl v8::InIsolate,
|
||||
err: ErrBox,
|
||||
handle: v8::Local<v8::Value>,
|
||||
) -> Self {
|
||||
let handle = v8::Global::new_from(scope, handle);
|
||||
Self { err, handle }
|
||||
}
|
||||
|
||||
pub fn get_handle(&self) -> &v8::Global<v8::Value> {
|
||||
&self.handle
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for ErrWithV8Handle {}
|
||||
unsafe impl Sync for ErrWithV8Handle {}
|
||||
|
||||
impl Error for ErrWithV8Handle {}
|
||||
|
||||
impl fmt::Display for ErrWithV8Handle {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.err.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ErrWithV8Handle {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.err.fmt(f)
|
||||
}
|
||||
}
|
|
@ -1,11 +1,76 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::ErrBox;
|
||||
use rusty_v8 as v8;
|
||||
use std::any::Any;
|
||||
use std::any::TypeId;
|
||||
use std::convert::TryFrom;
|
||||
use std::convert::TryInto;
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::ops::Deref;
|
||||
|
||||
// The Send and Sync traits are required because deno is multithreaded and we
|
||||
// need to be able to handle errors across threads.
|
||||
pub trait AnyError: Any + Error + Send + Sync + 'static {}
|
||||
impl<T> AnyError for T where T: Any + Error + Send + Sync + Sized + 'static {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ErrBox(Box<dyn AnyError>);
|
||||
|
||||
impl dyn AnyError {
|
||||
pub fn downcast_ref<T: AnyError>(&self) -> Option<&T> {
|
||||
if Any::type_id(self) == TypeId::of::<T>() {
|
||||
let target = self as *const Self as *const T;
|
||||
let target = unsafe { &*target };
|
||||
Some(target)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ErrBox {
|
||||
pub fn downcast<T: AnyError>(self) -> Result<T, Self> {
|
||||
if Any::type_id(&*self.0) == TypeId::of::<T>() {
|
||||
let target = Box::into_raw(self.0) as *mut T;
|
||||
let target = unsafe { Box::from_raw(target) };
|
||||
Ok(*target)
|
||||
} else {
|
||||
Err(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<dyn AnyError> for ErrBox {
|
||||
fn as_ref(&self) -> &dyn AnyError {
|
||||
self.0.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for ErrBox {
|
||||
type Target = Box<dyn AnyError>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AnyError> From<T> for ErrBox {
|
||||
fn from(error: T) -> Self {
|
||||
Self(Box::new(error))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Box<dyn AnyError>> for ErrBox {
|
||||
fn from(boxed: Box<dyn AnyError>) -> Self {
|
||||
Self(boxed)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ErrBox {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
/// A `JSError` represents an exception coming from V8, with stack frames and
|
||||
/// line numbers. The deno_cli crate defines another `JSError` type, which wraps
|
||||
|
@ -298,3 +363,50 @@ impl fmt::Display for JSError {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn attach_handle_to_error(
|
||||
scope: &mut impl v8::InIsolate,
|
||||
err: ErrBox,
|
||||
handle: v8::Local<v8::Value>,
|
||||
) -> ErrBox {
|
||||
ErrWithV8Handle::new(scope, err, handle).into()
|
||||
}
|
||||
|
||||
// TODO(piscisaureus): rusty_v8 should implement the Error trait on
|
||||
// values of type v8::Global<T>.
|
||||
pub struct ErrWithV8Handle {
|
||||
err: ErrBox,
|
||||
handle: v8::Global<v8::Value>,
|
||||
}
|
||||
|
||||
impl ErrWithV8Handle {
|
||||
pub fn new(
|
||||
scope: &mut impl v8::InIsolate,
|
||||
err: ErrBox,
|
||||
handle: v8::Local<v8::Value>,
|
||||
) -> Self {
|
||||
let handle = v8::Global::new_from(scope, handle);
|
||||
Self { err, handle }
|
||||
}
|
||||
|
||||
pub fn get_handle(&self) -> &v8::Global<v8::Value> {
|
||||
&self.handle
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for ErrWithV8Handle {}
|
||||
unsafe impl Sync for ErrWithV8Handle {}
|
||||
|
||||
impl Error for ErrWithV8Handle {}
|
||||
|
||||
impl fmt::Display for ErrWithV8Handle {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.err.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ErrWithV8Handle {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.err.fmt(f)
|
||||
}
|
||||
}
|
|
@ -6,10 +6,10 @@
|
|||
|
||||
use rusty_v8 as v8;
|
||||
|
||||
use crate::any_error::ErrBox;
|
||||
use crate::bindings;
|
||||
use crate::errors::ErrBox;
|
||||
use crate::errors::ErrWithV8Handle;
|
||||
use crate::futures::FutureExt;
|
||||
use crate::ErrWithV8Handle;
|
||||
use futures::ready;
|
||||
use futures::stream::FuturesUnordered;
|
||||
use futures::stream::StreamExt;
|
||||
|
@ -26,20 +26,19 @@ use std::rc::Rc;
|
|||
use std::task::Context;
|
||||
use std::task::Poll;
|
||||
|
||||
use crate::isolate::attach_handle_to_error;
|
||||
use crate::isolate::exception_to_err_result;
|
||||
use crate::isolate::CoreIsolate;
|
||||
use crate::isolate::StartupData;
|
||||
use crate::core_isolate::exception_to_err_result;
|
||||
use crate::errors::attach_handle_to_error;
|
||||
use crate::module_specifier::ModuleSpecifier;
|
||||
use crate::modules::LoadState;
|
||||
use crate::modules::ModuleId;
|
||||
use crate::modules::ModuleLoadId;
|
||||
use crate::modules::ModuleLoader;
|
||||
use crate::modules::ModuleSource;
|
||||
use crate::modules::Modules;
|
||||
use crate::modules::PrepareLoadFuture;
|
||||
use crate::modules::RecursiveModuleLoad;
|
||||
|
||||
pub type ModuleId = i32;
|
||||
pub type ModuleLoadId = i32;
|
||||
use crate::CoreIsolate;
|
||||
use crate::StartupData;
|
||||
|
||||
/// More specialized version of `CoreIsolate` that provides loading
|
||||
/// and execution of ES Modules.
|
||||
|
@ -597,11 +596,11 @@ impl Future for EsIsolate {
|
|||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
use super::*;
|
||||
use crate::isolate::js_check;
|
||||
use crate::isolate::tests::run_in_task;
|
||||
use crate::isolate::ZeroCopyBuf;
|
||||
use crate::core_isolate::tests::run_in_task;
|
||||
use crate::js_check;
|
||||
use crate::modules::ModuleSourceFuture;
|
||||
use crate::ops::*;
|
||||
use crate::ZeroCopyBuf;
|
||||
use std::io;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
|
36
core/lib.rs
36
core/lib.rs
|
@ -8,30 +8,44 @@ extern crate lazy_static;
|
|||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
mod any_error;
|
||||
mod bindings;
|
||||
mod core_isolate;
|
||||
mod errors;
|
||||
mod es_isolate;
|
||||
mod flags;
|
||||
mod isolate;
|
||||
mod js_errors;
|
||||
mod module_specifier;
|
||||
mod modules;
|
||||
mod ops;
|
||||
pub mod plugin_api;
|
||||
mod resources;
|
||||
mod shared_queue;
|
||||
mod zero_copy_buf;
|
||||
|
||||
pub use rusty_v8 as v8;
|
||||
|
||||
pub use crate::any_error::*;
|
||||
pub use crate::es_isolate::*;
|
||||
pub use crate::core_isolate::js_check;
|
||||
pub use crate::core_isolate::CoreIsolate;
|
||||
pub use crate::core_isolate::Script;
|
||||
pub use crate::core_isolate::Snapshot;
|
||||
pub use crate::core_isolate::StartupData;
|
||||
pub use crate::errors::ErrBox;
|
||||
pub use crate::errors::JSError;
|
||||
pub use crate::es_isolate::EsIsolate;
|
||||
pub use crate::flags::v8_set_flags;
|
||||
pub use crate::isolate::*;
|
||||
pub use crate::js_errors::*;
|
||||
pub use crate::module_specifier::*;
|
||||
pub use crate::modules::*;
|
||||
pub use crate::ops::*;
|
||||
pub use crate::resources::*;
|
||||
pub use crate::module_specifier::ModuleResolutionError;
|
||||
pub use crate::module_specifier::ModuleSpecifier;
|
||||
pub use crate::modules::ModuleId;
|
||||
pub use crate::modules::ModuleLoadId;
|
||||
pub use crate::modules::ModuleLoader;
|
||||
pub use crate::modules::ModuleSource;
|
||||
pub use crate::modules::ModuleSourceFuture;
|
||||
pub use crate::modules::RecursiveModuleLoad;
|
||||
pub use crate::ops::Buf;
|
||||
pub use crate::ops::Op;
|
||||
pub use crate::ops::OpAsyncFuture;
|
||||
pub use crate::ops::OpId;
|
||||
pub use crate::resources::ResourceTable;
|
||||
pub use crate::zero_copy_buf::ZeroCopyBuf;
|
||||
|
||||
pub fn v8_version() -> &'static str {
|
||||
v8::V8::get_version()
|
||||
|
|
|
@ -2,10 +2,8 @@
|
|||
|
||||
use rusty_v8 as v8;
|
||||
|
||||
use crate::any_error::ErrBox;
|
||||
use crate::es_isolate::ModuleId;
|
||||
use crate::es_isolate::ModuleLoadId;
|
||||
use crate::module_specifier::ModuleSpecifier;
|
||||
use crate::ErrBox;
|
||||
use futures::future::FutureExt;
|
||||
use futures::stream::FuturesUnordered;
|
||||
use futures::stream::Stream;
|
||||
|
@ -25,6 +23,9 @@ lazy_static! {
|
|||
pub static ref NEXT_LOAD_ID: AtomicI32 = AtomicI32::new(0);
|
||||
}
|
||||
|
||||
pub type ModuleId = i32;
|
||||
pub type ModuleLoadId = i32;
|
||||
|
||||
/// EsModule source code that will be loaded into V8.
|
||||
///
|
||||
/// Users can implement `Into<ModuleInfo>` for different file types that
|
||||
|
@ -548,7 +549,8 @@ macro_rules! include_crate_modules {
|
|||
mod tests {
|
||||
use super::*;
|
||||
use crate::es_isolate::EsIsolate;
|
||||
use crate::isolate::js_check;
|
||||
use crate::js_check;
|
||||
use crate::StartupData;
|
||||
use futures::future::FutureExt;
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
|
@ -556,6 +558,12 @@ mod tests {
|
|||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
|
||||
// TODO(ry) Sadly FuturesUnordered requires the current task to be set. So
|
||||
// even though we are only using poll() in these tests and not Tokio, we must
|
||||
// nevertheless run it in the tokio executor. Ideally run_in_task can be
|
||||
// removed in the future.
|
||||
use crate::core_isolate::tests::run_in_task;
|
||||
|
||||
struct MockLoader {
|
||||
pub loads: Arc<Mutex<Vec<String>>>,
|
||||
}
|
||||
|
@ -716,13 +724,6 @@ mod tests {
|
|||
if (import.meta.url != 'file:///d.js') throw Error();
|
||||
"#;
|
||||
|
||||
// TODO(ry) Sadly FuturesUnordered requires the current task to be set. So
|
||||
// even though we are only using poll() in these tests and not Tokio, we must
|
||||
// nevertheless run it in the tokio executor. Ideally run_in_task can be
|
||||
// removed in the future.
|
||||
use crate::isolate::tests::run_in_task;
|
||||
use crate::isolate::StartupData;
|
||||
|
||||
#[test]
|
||||
fn test_recursive_load() {
|
||||
let loader = MockLoader::new();
|
||||
|
|
67
core/zero_copy_buf.rs
Normal file
67
core/zero_copy_buf.rs
Normal file
|
@ -0,0 +1,67 @@
|
|||
use crate::bindings;
|
||||
use rusty_v8 as v8;
|
||||
use std::ops::Deref;
|
||||
use std::ops::DerefMut;
|
||||
|
||||
/// A ZeroCopyBuf encapsulates a slice that's been borrowed from a JavaScript
|
||||
/// ArrayBuffer object. JavaScript objects can normally be garbage collected,
|
||||
/// but the existence of a ZeroCopyBuf inhibits this until it is dropped. It
|
||||
/// behaves much like an Arc<[u8]>, although a ZeroCopyBuf currently can't be
|
||||
/// cloned.
|
||||
pub struct ZeroCopyBuf {
|
||||
backing_store: v8::SharedRef<v8::BackingStore>,
|
||||
byte_offset: usize,
|
||||
byte_length: usize,
|
||||
}
|
||||
|
||||
unsafe impl Send for ZeroCopyBuf {}
|
||||
|
||||
impl ZeroCopyBuf {
|
||||
pub fn new(view: v8::Local<v8::ArrayBufferView>) -> Self {
|
||||
let backing_store = view.buffer().unwrap().get_backing_store();
|
||||
let byte_offset = view.byte_offset();
|
||||
let byte_length = view.byte_length();
|
||||
Self {
|
||||
backing_store,
|
||||
byte_offset,
|
||||
byte_length,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for ZeroCopyBuf {
|
||||
type Target = [u8];
|
||||
fn deref(&self) -> &[u8] {
|
||||
unsafe {
|
||||
bindings::get_backing_store_slice(
|
||||
&self.backing_store,
|
||||
self.byte_offset,
|
||||
self.byte_length,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for ZeroCopyBuf {
|
||||
fn deref_mut(&mut self) -> &mut [u8] {
|
||||
unsafe {
|
||||
bindings::get_backing_store_slice_mut(
|
||||
&self.backing_store,
|
||||
self.byte_offset,
|
||||
self.byte_length,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for ZeroCopyBuf {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
&*self
|
||||
}
|
||||
}
|
||||
|
||||
impl AsMut<[u8]> for ZeroCopyBuf {
|
||||
fn as_mut(&mut self) -> &mut [u8] {
|
||||
&mut *self
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue