diff --git a/ops/lib.rs b/ops/lib.rs index 387707e1a3..df8abf61ea 100644 --- a/ops/lib.rs +++ b/ops/lib.rs @@ -359,9 +359,19 @@ fn codegen_sync_ret( return quote! {}; } + if is_u32_rv(output) { + return quote! { + rv.set_uint32(result as u32); + }; + } + // Optimize Result<(), Err> to skip serde_v8 when Ok(...) let ok_block = if is_unit_result(output) { quote! {} + } else if is_u32_rv_result(output) { + quote! { + rv.set_uint32(result as u32); + } } else { quote! { match #core::serde_v8::to_v8(scope, result) { @@ -408,11 +418,31 @@ fn is_result(ty: impl ToTokens) -> bool { } } +/// Detects if the type can be set using `rv.set_uint32` fast path +fn is_u32_rv(ty: impl ToTokens) -> bool { + ["u32", "u8", "u16"].iter().any(|&s| tokens(&ty) == s) || is_resource_id(&ty) +} + +/// Detects if the type is of the format Result +fn is_u32_rv_result(ty: impl ToTokens) -> bool { + is_result(&ty) + && (tokens(&ty).contains("Result < u32") + || tokens(&ty).contains("Result < u8") + || tokens(&ty).contains("Result < u16") + || is_resource_id(&ty)) +} + /// Detects if a type is of the form Result<(), Err> fn is_unit_result(ty: impl ToTokens) -> bool { is_result(&ty) && tokens(&ty).contains("Result < ()") } +fn is_resource_id(arg: impl ToTokens) -> bool { + static RE: Lazy = + Lazy::new(|| Regex::new(r#": (?:deno_core :: )?ResourceId$"#).unwrap()); + RE.is_match(&tokens(arg)) +} + fn is_mut_ref_opstate(arg: &syn::FnArg) -> bool { static RE: Lazy = Lazy::new(|| Regex::new(r#": & mut (?:deno_core :: )?OpState$"#).unwrap());