Skip to content

Commit 912ff07

Browse files
keramsbaronfel
authored andcommitted
Compile property accessors for PreComputeRecordReader (#9714)
1 parent 687fb9b commit 912ff07

1 file changed

Lines changed: 19 additions & 1 deletion

File tree

src/fsharp/FSharp.Core/reflect.fs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ open Microsoft.FSharp.Core.Operators
1313
open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
1414
open Microsoft.FSharp.Collections
1515
open Microsoft.FSharp.Primitives.Basics
16+
open System.Linq.Expressions
1617

1718
module internal ReflectionUtils =
1819

@@ -63,6 +64,19 @@ module internal Impl =
6364
| null -> None
6465
| prop -> Some(fun (obj: obj) -> prop.GetValue (obj, instancePropertyFlags ||| bindingFlags, null, null, null))
6566

67+
let compilePropGetterFunc (prop: PropertyInfo) =
68+
let param = Expression.Parameter (typeof<obj>, "param")
69+
70+
let expr =
71+
Expression.Lambda<Func<obj, obj>> (
72+
Expression.Convert (
73+
Expression.Property (
74+
Expression.Convert (param, prop.DeclaringType),
75+
prop),
76+
typeof<obj>),
77+
param)
78+
expr.Compile ()
79+
6680
//-----------------------------------------------------------------
6781
// ATTRIBUTE DECOMPILATION
6882

@@ -585,6 +599,10 @@ module internal Impl =
585599
let props = fieldPropsOfRecordType(typ, bindingFlags)
586600
(fun (obj: obj) -> props |> Array.map (fun prop -> prop.GetValue (obj, null)))
587601

602+
let getRecordReaderFromFuncs(typ: Type, bindingFlags) =
603+
let props = fieldPropsOfRecordType(typ, bindingFlags) |> Array.map compilePropGetterFunc
604+
(fun (obj: obj) -> props |> Array.map (fun prop -> prop.Invoke obj))
605+
588606
let getRecordConstructorMethod(typ: Type, bindingFlags) =
589607
let props = fieldPropsOfRecordType(typ, bindingFlags)
590608
let ctor = typ.GetConstructor(BindingFlags.Instance ||| bindingFlags, null, props |> Array.map (fun p -> p.PropertyType), null)
@@ -806,7 +824,7 @@ type FSharpValue =
806824
static member PreComputeRecordReader(recordType: Type, ?bindingFlags) : (obj -> obj[]) =
807825
let bindingFlags = defaultArg bindingFlags BindingFlags.Public
808826
checkRecordType ("recordType", recordType, bindingFlags)
809-
getRecordReader (recordType, bindingFlags)
827+
getRecordReaderFromFuncs (recordType, bindingFlags)
810828

811829
static member PreComputeRecordConstructor(recordType: Type, ?bindingFlags) =
812830
let bindingFlags = defaultArg bindingFlags BindingFlags.Public

0 commit comments

Comments
 (0)