diff options
Diffstat (limited to 'ops/lib.rs')
-rw-r--r-- | ops/lib.rs | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/ops/lib.rs b/ops/lib.rs index d8f28dd37..28cb3c320 100644 --- a/ops/lib.rs +++ b/ops/lib.rs @@ -474,6 +474,13 @@ fn codegen_arg( let #ident = #blk; }; } + // Fast path for `*const c_void` and `*mut c_void` + if is_ptr_cvoid(&**ty) { + let blk = codegen_cvoid_ptr(core, idx); + return quote! { + let #ident = #blk; + }; + } // Otherwise deserialize it via serde_v8 quote! { let #ident = args.get(#idx as i32); @@ -560,6 +567,19 @@ fn codegen_u8_ptr(core: &TokenStream2, idx: usize) -> TokenStream2 { }} } +fn codegen_cvoid_ptr(core: &TokenStream2, idx: usize) -> TokenStream2 { + quote! {{ + let value = args.get(#idx as i32); + if value.is_null() { + std::ptr::null_mut() + } else if let Ok(b) = #core::v8::Local::<#core::v8::External>::try_from(value) { + b.value() + } else { + return #core::_ops::throw_type_error(scope, format!("Expected External at position {}", #idx)); + } + }} +} + fn codegen_u32_mut_slice(core: &TokenStream2, idx: usize) -> TokenStream2 { quote! { if let Ok(view) = #core::v8::Local::<#core::v8::Uint32Array>::try_from(args.get(#idx as i32)) { @@ -626,6 +646,15 @@ fn codegen_sync_ret( quote! { rv.set_uint32(result as u32); } + } else if is_ptr_cvoid(output) || is_ptr_cvoid_rv(output) { + quote! { + if result.is_null() { + // External canot contain a null pointer, null pointers are instead represented as null. + rv.set_null(); + } else { + rv.set(v8::External::new(scope, result as *mut ::std::ffi::c_void).into()); + } + } } else { quote! { match #core::serde_v8::to_v8(scope, result) { @@ -723,6 +752,15 @@ fn is_ptr_u8(ty: impl ToTokens) -> bool { tokens(ty) == "* const u8" } +fn is_ptr_cvoid(ty: impl ToTokens) -> bool { + tokens(&ty) == "* const c_void" || tokens(&ty) == "* mut c_void" +} + +fn is_ptr_cvoid_rv(ty: impl ToTokens) -> bool { + tokens(&ty).contains("Result < * const c_void") + || tokens(&ty).contains("Result < * mut c_void") +} + fn is_optional_fast_callback_option(ty: impl ToTokens) -> bool { tokens(&ty).contains("Option < & mut FastApiCallbackOptions") } |