From 6cdb55ed6200bc7e02d35e596f3a8a85a6adf5eb Mon Sep 17 00:00:00 2001 From: Andy Finch Date: Wed, 25 Dec 2019 20:37:25 -0500 Subject: [PATCH] add v8::Uint8Array (#133) --- src/binding.cc | 4 ++++ src/lib.rs | 2 ++ src/uint8_array.rs | 29 +++++++++++++++++++++++++++++ tests/test_api.rs | 40 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 src/uint8_array.rs diff --git a/src/binding.cc b/src/binding.cc index ba7bb1c9..221d5c09 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -546,6 +546,10 @@ void v8__TryCatch__SetCaptureMessage(v8::TryCatch& self, bool value) { self.SetCaptureMessage(value); } +v8::Uint8Array* v8__Uint8Array__New(v8::ArrayBuffer* buf_ptr, size_t byte_offset, size_t length) { + return local_to_ptr(v8::Uint8Array::New(ptr_to_local(buf_ptr), byte_offset, length)); +} + v8::Script* v8__Script__Compile(v8::Context* context, v8::String* source, v8::ScriptOrigin* origin) { return maybe_local_to_ptr( diff --git a/src/lib.rs b/src/lib.rs index 77f1cde8..0b05d191 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,6 +32,7 @@ mod snapshot; mod string; mod support; mod try_catch; +mod uint8_array; mod value; pub mod array_buffer_view; @@ -75,4 +76,5 @@ pub use string::String; pub use support::MaybeBool; pub use support::UniqueRef; pub use try_catch::{TryCatch, TryCatchScope}; +pub use uint8_array::Uint8Array; pub use value::Value; diff --git a/src/uint8_array.rs b/src/uint8_array.rs new file mode 100644 index 00000000..7f83910e --- /dev/null +++ b/src/uint8_array.rs @@ -0,0 +1,29 @@ +use std::ops::DerefMut; + +use crate::support::Opaque; +use crate::ArrayBuffer; +use crate::Local; + +extern "C" { + fn v8__Uint8Array__New( + buf: *mut ArrayBuffer, + byte_offset: usize, + length: usize, + ) -> *mut Uint8Array; +} + +/// An instance of Uint8Array constructor (ES6 draft 15.13.6). +#[repr(C)] +pub struct Uint8Array(Opaque); + +impl Uint8Array { + pub fn new<'sc>( + mut buf: Local, + byte_offset: usize, + length: usize, + ) -> Option> { + unsafe { + Local::from_raw(v8__Uint8Array__New(buf.deref_mut(), byte_offset, length)) + } + } +} diff --git a/tests/test_api.rs b/tests/test_api.rs index 7374f6ea..0c156e2d 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -1191,7 +1191,7 @@ fn array_buffer_view() { let result = script.run(s, context).unwrap(); // TODO: safer casts. let result: v8::Local = - unsafe { std::mem::transmute_copy(&result) }; + cast(result); assert_eq!(result.byte_length(), 4); assert_eq!(result.byte_offset(), 0); let mut dest = [0; 4]; @@ -1267,3 +1267,41 @@ fn snapshot_creator() { drop(g); } + +#[test] +fn uint8_array() { + let g = setup(); + let mut params = v8::Isolate::create_params(); + params.set_array_buffer_allocator(v8::new_default_allocator()); + let mut isolate = v8::Isolate::new(params); + isolate.enter(); + let mut locker = v8::Locker::new(&isolate); + { + let mut hs = v8::HandleScope::new(&mut locker); + let s = hs.enter(); + let mut context = v8::Context::new(s); + context.enter(); + let source = v8::String::new(s, "new Uint8Array([23,23,23,23])").unwrap(); + let mut script = v8::Script::compile(s, context, source, None).unwrap(); + source.to_rust_string_lossy(s); + let result = script.run(s, context).unwrap(); + // TODO: safer casts. + let result: v8::Local = + cast(result); + assert_eq!(result.byte_length(), 4); + assert_eq!(result.byte_offset(), 0); + let mut dest = [0; 4]; + let copy_bytes = result.copy_contents(&mut dest); + assert_eq!(copy_bytes, 4); + assert_eq!(dest, [23, 23, 23, 23]); + let maybe_ab = result.buffer(); + assert!(maybe_ab.is_some()); + let ab = maybe_ab.unwrap(); + let uint8_array = v8::Uint8Array::new(ab, 0, 0); + assert!(uint8_array.is_some()); + context.exit(); + } + drop(locker); + isolate.exit(); + drop(g); +}