From 3d69ffaaf2a133597320ae756abe375a9a1246df Mon Sep 17 00:00:00 2001 From: kerams Date: Sat, 18 Jul 2020 09:58:07 +0200 Subject: [PATCH] Compile property accessors for PreComputeRecordReader --- src/fsharp/FSharp.Core/reflect.fs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/fsharp/FSharp.Core/reflect.fs b/src/fsharp/FSharp.Core/reflect.fs index d18a0bf16e0..56bcc317d0c 100644 --- a/src/fsharp/FSharp.Core/reflect.fs +++ b/src/fsharp/FSharp.Core/reflect.fs @@ -13,6 +13,7 @@ open Microsoft.FSharp.Core.Operators open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators open Microsoft.FSharp.Collections open Microsoft.FSharp.Primitives.Basics +open System.Linq.Expressions module internal ReflectionUtils = @@ -63,6 +64,19 @@ module internal Impl = | null -> None | prop -> Some(fun (obj: obj) -> prop.GetValue (obj, instancePropertyFlags ||| bindingFlags, null, null, null)) + let compilePropGetterFunc (prop: PropertyInfo) = + let param = Expression.Parameter (typeof, "param") + + let expr = + Expression.Lambda> ( + Expression.Convert ( + Expression.Property ( + Expression.Convert (param, prop.DeclaringType), + prop), + typeof), + param) + expr.Compile () + //----------------------------------------------------------------- // ATTRIBUTE DECOMPILATION @@ -585,6 +599,10 @@ module internal Impl = let props = fieldPropsOfRecordType(typ, bindingFlags) (fun (obj: obj) -> props |> Array.map (fun prop -> prop.GetValue (obj, null))) + let getRecordReaderFromFuncs(typ: Type, bindingFlags) = + let props = fieldPropsOfRecordType(typ, bindingFlags) |> Array.map compilePropGetterFunc + (fun (obj: obj) -> props |> Array.map (fun prop -> prop.Invoke obj)) + let getRecordConstructorMethod(typ: Type, bindingFlags) = let props = fieldPropsOfRecordType(typ, bindingFlags) let ctor = typ.GetConstructor(BindingFlags.Instance ||| bindingFlags, null, props |> Array.map (fun p -> p.PropertyType), null) @@ -806,7 +824,7 @@ type FSharpValue = static member PreComputeRecordReader(recordType: Type, ?bindingFlags) : (obj -> obj[]) = let bindingFlags = defaultArg bindingFlags BindingFlags.Public checkRecordType ("recordType", recordType, bindingFlags) - getRecordReader (recordType, bindingFlags) + getRecordReaderFromFuncs (recordType, bindingFlags) static member PreComputeRecordConstructor(recordType: Type, ?bindingFlags) = let bindingFlags = defaultArg bindingFlags BindingFlags.Public