From 5ac153388fff52c70300232b3996ad094aa0882a Mon Sep 17 00:00:00 2001 From: LongYinan Date: Thu, 15 Feb 2024 23:40:45 +0800 Subject: [PATCH] feat(napi): accept slice as TypedArray (#1951) --- crates/backend/src/codegen/fn.rs | 69 +++++++++++++++--- .../bindgen_runtime/js_values/arraybuffer.rs | 52 +++++++++++++ .../__snapshots__/typegen.spec.ts.md | 23 ++++++ .../__snapshots__/typegen.spec.ts.snap | Bin 4352 -> 4431 bytes examples/napi/__tests__/values.spec.ts | 29 ++++++++ examples/napi/index.d.ts | 23 ++++++ examples/napi/src/class.rs | 5 ++ examples/napi/src/typed_array.rs | 55 ++++++++++++++ 8 files changed, 244 insertions(+), 12 deletions(-) diff --git a/crates/backend/src/codegen/fn.rs b/crates/backend/src/codegen/fn.rs index 5fb803a3..16cc3e22 100644 --- a/crates/backend/src/codegen/fn.rs +++ b/crates/backend/src/codegen/fn.rs @@ -268,7 +268,7 @@ impl NapiFn { if let Some(p) = path.path.segments.first() { if p.ident == *self.parent.as_ref().unwrap() { args.push( - quote! { napi::bindgen_prelude::Reference::from_value_ptr(this_ptr as *mut std::ffi::c_void, env)? }, + quote! { napi::bindgen_prelude::Reference::from_value_ptr(this_ptr.cast(), env)? }, ); skipped_arg_count += 1; continue; @@ -344,7 +344,7 @@ impl NapiFn { } } } - let (arg_conversion, arg_type) = self.gen_ty_arg_conversion(&ident, i, path); + let (arg_conversion, arg_type) = self.gen_ty_arg_conversion(&ident, i, path)?; if NapiArgType::MutRef == arg_type { mut_ref_spans.push(path.ty.span()); } @@ -378,7 +378,7 @@ impl NapiFn { arg_name: &Ident, index: usize, path: &syn::PatType, - ) -> (TokenStream, NapiArgType) { + ) -> BindgenResult<(TokenStream, NapiArgType)> { let ty = &*path.ty; let type_check = if self.return_if_invalid { quote! { @@ -402,6 +402,15 @@ impl NapiFn { }; match ty { + syn::Type::Reference(syn::TypeReference { + lifetime: Some(lifetime), + .. + }) => { + return Err(Diagnostic::span_error( + lifetime.span(), + "lifetime is not allowed in napi function arguments", + )); + } syn::Type::Reference(syn::TypeReference { mutability: Some(_), elem, @@ -413,16 +422,52 @@ impl NapiFn { <#elem as napi::bindgen_prelude::FromNapiMutRef>::from_napi_mut_ref(env, cb.get_arg(#index))? }; }; - (q, NapiArgType::MutRef) + Ok((q, NapiArgType::MutRef)) } - syn::Type::Reference(syn::TypeReference { elem, .. }) => { - let q = quote! { - let #arg_name = { - #type_check - <#elem as napi::bindgen_prelude::FromNapiRef>::from_napi_ref(env, cb.get_arg(#index))? - }; + syn::Type::Reference(syn::TypeReference { + mutability, elem, .. + }) => { + if let syn::Type::Slice(slice) = &**elem { + if let syn::Type::Path(ele) = &*slice.elem { + if let Some(syn::PathSegment { ident, .. }) = ele.path.segments.first() { + static TYPEDARRAY_SLICE_TYPES: &[&str] = &[ + "u8", "i8", "u16", "i16", "u32", "i32", "f32", "f64", "u64", "i64", + ]; + if TYPEDARRAY_SLICE_TYPES.contains(&&*ident.to_string()) { + let q = quote! { + let #arg_name = { + #type_check + <&mut #elem as napi::bindgen_prelude::FromNapiValue>::from_napi_value(env, cb.get_arg(#index))? + }; + }; + return Ok((q, NapiArgType::Ref)); + } + } + } + } + let q = if mutability.is_some() { + quote! { + let #arg_name = { + #type_check + <#elem as napi::bindgen_prelude::FromNapiMutRef>::from_napi_mut_ref(env, cb.get_arg(#index))? + } + } + } else { + quote! { + let #arg_name = { + #type_check + <#elem as napi::bindgen_prelude::FromNapiRef>::from_napi_ref(env, cb.get_arg(#index))? + }; + } }; - (q, NapiArgType::Ref) + Ok(( + q, + if mutability.is_some() { + NapiArgType::MutRef + } else { + NapiArgType::Ref + }, + )) } _ => { let q = quote! { @@ -431,7 +476,7 @@ impl NapiFn { <#ty as napi::bindgen_prelude::FromNapiValue>::from_napi_value(env, cb.get_arg(#index))? }; }; - (q, NapiArgType::Value) + Ok((q, NapiArgType::Value)) } } } diff --git a/crates/napi/src/bindgen_runtime/js_values/arraybuffer.rs b/crates/napi/src/bindgen_runtime/js_values/arraybuffer.rs index ba57e3ca..e2d73c8c 100644 --- a/crates/napi/src/bindgen_runtime/js_values/arraybuffer.rs +++ b/crates/napi/src/bindgen_runtime/js_values/arraybuffer.rs @@ -457,6 +457,46 @@ macro_rules! impl_typed_array { }; } +macro_rules! impl_from_slice { + ($name:ident, $rust_type:ident, $typed_array_type:expr) => { + impl FromNapiValue for &mut [$rust_type] { + unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result { + let mut typed_array_type = 0; + let mut length = 0; + let mut data = ptr::null_mut(); + let mut array_buffer = ptr::null_mut(); + let mut byte_offset = 0; + let mut ref_ = ptr::null_mut(); + check_status!( + unsafe { sys::napi_create_reference(env, napi_val, 1, &mut ref_) }, + "Failed to create reference from Buffer" + )?; + check_status!( + unsafe { + sys::napi_get_typedarray_info( + env, + napi_val, + &mut typed_array_type, + &mut length, + &mut data, + &mut array_buffer, + &mut byte_offset, + ) + }, + "Get TypedArray info failed" + )?; + if typed_array_type != $typed_array_type as i32 { + return Err(Error::new( + Status::InvalidArg, + format!("Expected $name, got {}", typed_array_type), + )); + } + Ok(unsafe { core::slice::from_raw_parts_mut(data as *mut $rust_type, length) }) + } + } + }; +} + unsafe extern "C" fn finalizer>( _env: sys::napi_env, finalize_data: *mut c_void, @@ -494,18 +534,30 @@ enum DataManagedType { } impl_typed_array!(Int8Array, i8, TypedArrayType::Int8); +impl_from_slice!(Int8Array, i8, TypedArrayType::Int8); impl_typed_array!(Uint8Array, u8, TypedArrayType::Uint8); +impl_from_slice!(Uint8Array, u8, TypedArrayType::Uint8); impl_typed_array!(Uint8ClampedArray, u8, TypedArrayType::Uint8Clamped); impl_typed_array!(Int16Array, i16, TypedArrayType::Int16); +impl_from_slice!(Int16Array, i16, TypedArrayType::Int16); impl_typed_array!(Uint16Array, u16, TypedArrayType::Uint16); +impl_from_slice!(Uint16Array, u16, TypedArrayType::Uint16); impl_typed_array!(Int32Array, i32, TypedArrayType::Int32); +impl_from_slice!(Int32Array, i32, TypedArrayType::Int32); impl_typed_array!(Uint32Array, u32, TypedArrayType::Uint32); +impl_from_slice!(Uint32Array, u32, TypedArrayType::Uint32); impl_typed_array!(Float32Array, f32, TypedArrayType::Float32); +impl_from_slice!(Float32Array, f32, TypedArrayType::Float32); impl_typed_array!(Float64Array, f64, TypedArrayType::Float64); +impl_from_slice!(Float64Array, f64, TypedArrayType::Float64); #[cfg(feature = "napi6")] impl_typed_array!(BigInt64Array, i64, TypedArrayType::BigInt64); #[cfg(feature = "napi6")] +impl_from_slice!(BigInt64Array, i64, TypedArrayType::BigInt64); +#[cfg(feature = "napi6")] impl_typed_array!(BigUint64Array, u64, TypedArrayType::BigUint64); +#[cfg(feature = "napi6")] +impl_from_slice!(BigUint64Array, u64, TypedArrayType::BigUint64); impl>> From for Uint8Array { fn from(data: T) -> Self { diff --git a/examples/napi/__tests__/__snapshots__/typegen.spec.ts.md b/examples/napi/__tests__/__snapshots__/typegen.spec.ts.md index 9c63b059..c9d8768e 100644 --- a/examples/napi/__tests__/__snapshots__/typegen.spec.ts.md +++ b/examples/napi/__tests__/__snapshots__/typegen.spec.ts.md @@ -85,6 +85,7 @@ Generated by [AVA](https://avajs.dev). constructor(name: string)␊ getCount(): number␊ getNameAsync(): Promise␊ + acceptSliceMethod(slice: any): number␊ }␊ ␊ /** Smoking test for type generation */␊ @@ -221,6 +222,8 @@ Generated by [AVA](https://avajs.dev). foo: number␊ }␊ ␊ + export function acceptSlice(fixture: any): bigint␊ + ␊ export function acceptThreadsafeFunction(func: (err: Error | null, arg: number) => any): void␊ ␊ export function acceptThreadsafeFunctionFatal(func: (arg: number) => any): void␊ @@ -388,6 +391,10 @@ Generated by [AVA](https://avajs.dev). ␊ export function enumToI32(e: CustomNumEnum): number␊ ␊ + export function f32ArrayToArray(input: any): Array␊ + ␊ + export function f64ArrayToArray(input: any): Array␊ + ␊ export function fibonacci(n: number): number␊ ␊ export function fnReceivedAliased(s: AliasedStruct, e: ALIAS): void␊ @@ -429,6 +436,14 @@ Generated by [AVA](https://avajs.dev). ␊ export function getWords(): Array␊ ␊ + export function i16ArrayToArray(input: any): Array␊ + ␊ + export function i32ArrayToArray(input: any): Array␊ + ␊ + export function i64ArrayToArray(input: any): Array␊ + ␊ + export function i8ArrayToArray(input: any): Array␊ + ␊ export function indexmapPassthrough(fixture: IndexMap): IndexMap␊ ␊ /** default enum values are continuos i32s start from 0 */␊ @@ -595,6 +610,14 @@ Generated by [AVA](https://avajs.dev). typeOverrideOptional?: object␊ }␊ ␊ + export function u16ArrayToArray(input: any): Array␊ + ␊ + export function u32ArrayToArray(input: any): Array␊ + ␊ + export function u64ArrayToArray(input: any): Array␊ + ␊ + export function u8ArrayToArray(input: any): Array␊ + ␊ export function validateArray(arr: Array): number␊ ␊ export function validateBigint(input: bigint): bigint␊ diff --git a/examples/napi/__tests__/__snapshots__/typegen.spec.ts.snap b/examples/napi/__tests__/__snapshots__/typegen.spec.ts.snap index f74ab62bee9a3cfb0fedb961feef0b9dc9637953..25cdfede321ea6cedb44a78f1d839baf82bba167 100644 GIT binary patch literal 4431 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 Vd=3Bf>}kj1{XfkX#u9@@0063Dq96bO literal 4352 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 { t.true(Array.isArray(asyncBufferToArray(Buffer.from([1, 2, 3]).buffer))) }) +test('TypedArray', (t) => { + t.is(acceptSlice(new Uint8Array([1, 2, 3])), 3n) + t.deepEqual(u8ArrayToArray(new Uint8Array([1, 2, 3])), [1, 2, 3]) + t.deepEqual(i8ArrayToArray(new Int8Array([1, 2, 3])), [1, 2, 3]) + t.deepEqual(u16ArrayToArray(new Uint16Array([1, 2, 3])), [1, 2, 3]) + t.deepEqual(i16ArrayToArray(new Int16Array([1, 2, 3])), [1, 2, 3]) + t.deepEqual(u32ArrayToArray(new Uint32Array([1, 2, 3])), [1, 2, 3]) + t.deepEqual(i32ArrayToArray(new Int32Array([1, 2, 3])), [1, 2, 3]) + t.deepEqual(u64ArrayToArray(new BigUint64Array([1n, 2n, 3n])), [1n, 2n, 3n]) + t.deepEqual(i64ArrayToArray(new BigInt64Array([1n, 2n, 3n])), [1, 2, 3]) + t.deepEqual(f32ArrayToArray(new Float32Array([1, 2, 3])), [1, 2, 3]) + t.deepEqual(f64ArrayToArray(new Float64Array([1, 2, 3])), [1, 2, 3]) + + const bird = new Bird('Carolyn') + + t.is(bird.acceptSliceMethod(new Uint8Array([1, 2, 3])), 3) +}) + test('reset empty buffer', (t) => { const empty = getEmptyBuffer() diff --git a/examples/napi/index.d.ts b/examples/napi/index.d.ts index 8dd4e2f9..2f305b25 100644 --- a/examples/napi/index.d.ts +++ b/examples/napi/index.d.ts @@ -75,6 +75,7 @@ export class Bird { constructor(name: string) getCount(): number getNameAsync(): Promise + acceptSliceMethod(slice: any): number } /** Smoking test for type generation */ @@ -211,6 +212,8 @@ export interface A { foo: number } +export function acceptSlice(fixture: any): bigint + export function acceptThreadsafeFunction(func: (err: Error | null, arg: number) => any): void export function acceptThreadsafeFunctionFatal(func: (arg: number) => any): void @@ -378,6 +381,10 @@ export const enum Empty { export function enumToI32(e: CustomNumEnum): number +export function f32ArrayToArray(input: any): Array + +export function f64ArrayToArray(input: any): Array + export function fibonacci(n: number): number export function fnReceivedAliased(s: AliasedStruct, e: ALIAS): void @@ -419,6 +426,14 @@ export function getUndefined(): void export function getWords(): Array +export function i16ArrayToArray(input: any): Array + +export function i32ArrayToArray(input: any): Array + +export function i64ArrayToArray(input: any): Array + +export function i8ArrayToArray(input: any): Array + export function indexmapPassthrough(fixture: IndexMap): IndexMap /** default enum values are continuos i32s start from 0 */ @@ -585,6 +600,14 @@ export interface TsTypeChanged { typeOverrideOptional?: object } +export function u16ArrayToArray(input: any): Array + +export function u32ArrayToArray(input: any): Array + +export function u64ArrayToArray(input: any): Array + +export function u8ArrayToArray(input: any): Array + export function validateArray(arr: Array): number export function validateBigint(input: bigint): bigint diff --git a/examples/napi/src/class.rs b/examples/napi/src/class.rs index a0956262..4999c3aa 100644 --- a/examples/napi/src/class.rs +++ b/examples/napi/src/class.rs @@ -130,6 +130,11 @@ impl Bird { tokio::time::sleep(std::time::Duration::new(1, 0)).await; self.name.as_str() } + + #[napi] + pub fn accept_slice_method(&self, slice: &[u8]) -> u32 { + slice.len() as u32 + } } /// Smoking test for type generation diff --git a/examples/napi/src/typed_array.rs b/examples/napi/src/typed_array.rs index ba2029a0..e814aa08 100644 --- a/examples/napi/src/typed_array.rs +++ b/examples/napi/src/typed_array.rs @@ -49,6 +49,61 @@ async fn array_buffer_pass_through(buf: Uint8Array) -> Result { Ok(buf) } +#[napi] +fn accept_slice(fixture: &[u8]) -> usize { + fixture.len() +} + +#[napi] +fn u8_array_to_array(input: &[u8]) -> Vec { + input.to_vec() +} + +#[napi] +fn i8_array_to_array(input: &[i8]) -> Vec { + input.to_vec() +} + +#[napi] +fn u16_array_to_array(input: &[u16]) -> Vec { + input.to_vec() +} + +#[napi] +fn i16_array_to_array(input: &[i16]) -> Vec { + input.to_vec() +} + +#[napi] +fn u32_array_to_array(input: &[u32]) -> Vec { + input.to_vec() +} + +#[napi] +fn i32_array_to_array(input: &[i32]) -> Vec { + input.to_vec() +} + +#[napi] +fn f32_array_to_array(input: &[f32]) -> Vec { + input.to_vec() +} + +#[napi] +fn f64_array_to_array(input: &[f64]) -> Vec { + input.to_vec() +} + +#[napi] +fn u64_array_to_array(input: &[u64]) -> Vec { + input.to_vec() +} + +#[napi] +fn i64_array_to_array(input: &[i64]) -> Vec { + input.to_vec() +} + struct AsyncBuffer { buf: Buffer, }