diff --git a/.gitignore b/.gitignore index d064be13f..76ad4d1ca 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ Cargo.lock **/.DS_Store **/build **/index.node +**/artifacts.json npm-debug.log diff --git a/Cargo.toml b/Cargo.toml index b934f13bf..6f5742549 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,9 @@ build = "build.rs" # See also: http://doc.crates.io/build-script.html#the-links-manifest-key links = "neon-runtime" +[build-dependencies] +neon-build = { version = "=0.1.17", path = "crates/neon-build" } + [dependencies] cslice = "0.2" neon-runtime = { version = "=0.1.17", path = "crates/neon-runtime" } diff --git a/Makefile b/Makefile index 3d988ac70..ca77dfd28 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ all: doc publish: doc cd target/doc && surge -doc: neon_api neon_sys_api $(HTML_FILES) target/doc/rust.css target/doc/CNAME +doc: neon_api neon_build_api neon_runtime_api $(HTML_FILES) target/doc/rust.css target/doc/CNAME clean: rm -rf target/doc @@ -14,9 +14,13 @@ clean: neon_api: cargo doc -neon_sys_api: - cd crates/neon-sys && cargo doc - cp -R crates/neon-sys/target/doc/neon_sys ./target/doc/ +neon_build_api: + cd crates/neon_build && cargo doc + cp -R crates/neon-build/target/doc/neon_build ./target/doc + +neon_runtime_api: + cd crates/neon-runtime && cargo doc + cp -R crates/neon-runtime/target/doc/neon_runtime ./target/doc/ target/doc/%.html: doc/%.md rustdoc --markdown-playground-url='https://play.rust-lang.org' --markdown-css rust.css $< --output=target/doc diff --git a/crates/neon-runtime/src/arraybuffer.rs b/crates/neon-runtime/src/arraybuffer.rs new file mode 100644 index 000000000..a3a8fc589 --- /dev/null +++ b/crates/neon-runtime/src/arraybuffer.rs @@ -0,0 +1,20 @@ +//! Facilities for working with `v8::ArrayBuffer`s. + +use raw::Local; +use cslice::CMutSlice; +use std::os::raw::c_void; + +// Suppress a spurious rustc warning about the use of CMutSlice. +#[allow(improper_ctypes)] +extern "C" { + + /// Mutates the `out` argument provided to refer to a newly created `v8::ArrayBuffer` object. + /// Returns `false` if the value couldn't be created. + #[link_name = "Neon_ArrayBuffer_New"] + pub fn new(out: &mut Local, isolate: *mut c_void, size: u32) -> bool; + + /// Mutates the `out` argument provided populating the `data` and `len` properties. + #[link_name = "Neon_ArrayBuffer_Data"] + pub fn data<'a, 'b>(out: &'a mut CMutSlice<'b, u8>, obj: Local); + +} diff --git a/crates/neon-runtime/src/lib.rs b/crates/neon-runtime/src/lib.rs index f92e6ccc9..b31649030 100644 --- a/crates/neon-runtime/src/lib.rs +++ b/crates/neon-runtime/src/lib.rs @@ -8,6 +8,7 @@ pub mod array; pub mod string; pub mod primitive; pub mod error; +pub mod arraybuffer; pub mod buffer; pub mod tag; pub mod module; diff --git a/crates/neon-runtime/src/neon.cc b/crates/neon-runtime/src/neon.cc index 8d0af1950..9db944868 100644 --- a/crates/neon-runtime/src/neon.cc +++ b/crates/neon-runtime/src/neon.cc @@ -201,6 +201,21 @@ extern "C" bool Neon_Tag_IsBuffer(v8::Local obj) { return node::Buffer::HasInstance(obj); } +extern "C" bool Neon_ArrayBuffer_New(v8::Local *out, v8::Isolate *isolate, uint32_t size) { + *out = v8::ArrayBuffer::New(isolate, size); + return true; +} + +extern "C" void Neon_ArrayBuffer_Data(buf_t *out, v8::Local buffer) { + v8::ArrayBuffer::Contents contents = buffer->GetContents(); + out->data = contents.Data(); + out->len = contents.ByteLength(); +} + +extern "C" bool Neon_Tag_IsArrayBuffer(v8::Local value) { + return value->IsArrayBuffer(); +} + extern "C" void Neon_Scope_Escape(v8::Local *out, Nan::EscapableHandleScope *scope, v8::Local value) { *out = scope->Escape(value); } diff --git a/crates/neon-runtime/src/neon.h b/crates/neon-runtime/src/neon.h index 536cf78f4..4e0bd5bb1 100644 --- a/crates/neon-runtime/src/neon.h +++ b/crates/neon-runtime/src/neon.h @@ -68,6 +68,9 @@ extern "C" { bool Neon_Buffer_New(v8::Local *out, uint32_t size); void Neon_Buffer_Data(buf_t *out, v8::Local obj); + bool Neon_ArrayBuffer_New(v8::Local *out, v8::Isolate *isolate, uint32_t size); + void Neon_ArrayBuffer_Data(buf_t *out, v8::Local buffer); + typedef void(*Neon_ChainedScopeCallback)(void *, void *, void *, void *); typedef void(*Neon_NestedScopeCallback)(void *, void *, void *); typedef void(*Neon_RootScopeCallback)(void *, void *, void *); @@ -132,6 +135,7 @@ extern "C" { bool Neon_Tag_IsArray(v8::Local val); bool Neon_Tag_IsFunction(v8::Local val); bool Neon_Tag_IsBuffer(v8::Local obj); + bool Neon_Tag_IsArrayBuffer(v8::Local obj); bool Neon_Tag_IsError(v8::Local val); void Neon_Error_NewError(v8::Local *out, v8::Local msg); diff --git a/crates/neon-runtime/src/tag.rs b/crates/neon-runtime/src/tag.rs index b468cada4..d10cb38ba 100644 --- a/crates/neon-runtime/src/tag.rs +++ b/crates/neon-runtime/src/tag.rs @@ -68,4 +68,8 @@ extern "C" { #[link_name = "Neon_Tag_IsBuffer"] pub fn is_buffer(obj: Local) -> bool; + /// Indicates if the value type is `ArrayBuffer`. + #[link_name = "Neon_Tag_IsArrayBuffer"] + pub fn is_arraybuffer(obj: Local) -> bool; + } diff --git a/src/internal/js/binary.rs b/src/internal/js/binary.rs index 3655203aa..ceb66206a 100644 --- a/src/internal/js/binary.rs +++ b/src/internal/js/binary.rs @@ -44,3 +44,40 @@ impl<'a> Lock for &'a mut JsBuffer { result } } + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct JsArrayBuffer(raw::Local); + +impl JsArrayBuffer { + pub fn new<'a, T: Scope<'a>>(scope: &mut T, size: u32) -> VmResult> { + build(|out| { unsafe { neon_runtime::arraybuffer::new(out, mem::transmute(scope.isolate()), size) } }) + } +} + +impl Managed for JsArrayBuffer { + fn to_raw(self) -> raw::Local { self.0 } + + fn from_raw(h: raw::Local) -> Self { JsArrayBuffer(h) } +} + +impl ValueInternal for JsArrayBuffer { + fn is_typeof(other: Other) -> bool { + unsafe { neon_runtime::tag::is_arraybuffer(other.to_raw()) } + } +} + +impl Value for JsArrayBuffer { } + +impl Object for JsArrayBuffer { } + +impl<'a> Lock for &'a mut JsArrayBuffer { + type Internals = CMutSlice<'a, u8>; + + unsafe fn expose(self, state: &mut LockState) -> Self::Internals { + let mut result = mem::uninitialized(); + neon_runtime::arraybuffer::data(&mut result, self.to_raw()); + state.use_buffer(result); + result + } +} diff --git a/src/js/binary.rs b/src/js/binary.rs index 5da3a147f..569548885 100644 --- a/src/js/binary.rs +++ b/src/js/binary.rs @@ -1 +1 @@ -pub use internal::js::binary::JsBuffer; +pub use internal::js::binary::{JsBuffer, JsArrayBuffer}; diff --git a/tests/package.json b/tests/package.json index 0c98a1f25..c7dfe6a10 100644 --- a/tests/package.json +++ b/tests/package.json @@ -6,11 +6,11 @@ "author": "The Neon Community", "license": "MIT", "dependencies": { - "neon-cli": "^0.1.7" + "neon-cli": "git://github.com/neon-bindings/neon-cli" }, "scripts": { - "install": "neon build", - "test": "npm i && mocha --recursive lib" + "install": "cd node_modules/neon-cli && npm i && npm run transpile", + "test": "npm i && neon build && mocha --recursive lib" }, "devDependencies": { "chai": "^3.5.0",