mirror of
https://github.com/Smaug123/WoofWare.PawPrint
synced 2025-10-05 22:28:38 +00:00
Add another generic for MethodInfo (#85)
This commit is contained in:
@@ -67,7 +67,7 @@ type DumpedAssembly =
|
||||
Methods :
|
||||
IReadOnlyDictionary<
|
||||
MethodDefinitionHandle,
|
||||
WoofWare.PawPrint.MethodInfo<FakeUnit, WoofWare.PawPrint.GenericParameter>
|
||||
WoofWare.PawPrint.MethodInfo<FakeUnit, WoofWare.PawPrint.GenericParameter, TypeDefn>
|
||||
>
|
||||
|
||||
/// <summary>
|
||||
|
@@ -117,7 +117,7 @@ type ExceptionRegion =
|
||||
| ExceptionRegionKind.Fault -> ExceptionRegion.Fault offset
|
||||
| _ -> raise (ArgumentOutOfRangeException ())
|
||||
|
||||
type MethodInstructions =
|
||||
type MethodInstructions<'methodVars> =
|
||||
{
|
||||
/// <summary>
|
||||
/// The IL instructions that compose the method body, along with their offset positions.
|
||||
@@ -137,12 +137,14 @@ type MethodInstructions =
|
||||
/// </summary>
|
||||
LocalsInit : bool
|
||||
|
||||
LocalVars : ImmutableArray<TypeDefn> option
|
||||
LocalVars : ImmutableArray<'methodVars> option
|
||||
|
||||
ExceptionRegions : ImmutableArray<ExceptionRegion>
|
||||
}
|
||||
|
||||
static member OnlyRet : MethodInstructions =
|
||||
[<RequireQualifiedAccess>]
|
||||
module MethodInstructions =
|
||||
let onlyRet () : MethodInstructions<'methodVars> =
|
||||
let op = IlOp.Nullary NullaryIlOp.Ret
|
||||
|
||||
{
|
||||
@@ -153,11 +155,20 @@ type MethodInstructions =
|
||||
ExceptionRegions = ImmutableArray.Empty
|
||||
}
|
||||
|
||||
let setLocalVars<'a, 'b> (v : ImmutableArray<'b> option) (s : MethodInstructions<'a>) : MethodInstructions<'b> =
|
||||
{
|
||||
Instructions = s.Instructions
|
||||
Locations = s.Locations
|
||||
LocalsInit = s.LocalsInit
|
||||
LocalVars = v
|
||||
ExceptionRegions = s.ExceptionRegions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents detailed information about a method in a .NET assembly.
|
||||
/// This is a strongly-typed representation of MethodDefinition from System.Reflection.Metadata.
|
||||
/// </summary>
|
||||
type MethodInfo<'typeGenerics, 'methodGenerics
|
||||
type MethodInfo<'typeGenerics, 'methodGenerics, 'methodVars
|
||||
when 'typeGenerics :> IComparable<'typeGenerics> and 'typeGenerics : comparison> =
|
||||
{
|
||||
/// <summary>
|
||||
@@ -178,7 +189,7 @@ type MethodInfo<'typeGenerics, 'methodGenerics
|
||||
///
|
||||
/// There may be no instructions for this method, e.g. if it's an `InternalCall`.
|
||||
/// </summary>
|
||||
Instructions : MethodInstructions option
|
||||
Instructions : MethodInstructions<'methodVars> option
|
||||
|
||||
/// <summary>
|
||||
/// The parameters of this method.
|
||||
@@ -193,7 +204,12 @@ type MethodInfo<'typeGenerics, 'methodGenerics
|
||||
/// <summary>
|
||||
/// The signature of the method, including return type and parameter types.
|
||||
/// </summary>
|
||||
Signature : TypeMethodSignature<TypeDefn>
|
||||
Signature : TypeMethodSignature<'methodVars>
|
||||
|
||||
/// <summary>
|
||||
/// The signature as it was read from assembly metadata.
|
||||
/// </summary>
|
||||
RawSignature : TypeMethodSignature<TypeDefn>
|
||||
|
||||
/// <summary>
|
||||
/// Custom attributes defined on the method. I've never yet seen one of these in practice.
|
||||
@@ -230,8 +246,8 @@ type MethodInfo<'typeGenerics, 'methodGenerics
|
||||
module MethodInfo =
|
||||
let isJITIntrinsic
|
||||
(getMemberRefParentType : MemberReferenceHandle -> TypeRef)
|
||||
(methodDefs : IReadOnlyDictionary<MethodDefinitionHandle, MethodInfo<'a, 'b>>)
|
||||
(this : MethodInfo<'d, 'e>)
|
||||
(methodDefs : IReadOnlyDictionary<MethodDefinitionHandle, MethodInfo<'a, 'b, 'c>>)
|
||||
(this : MethodInfo<'d, 'e, 'f>)
|
||||
: bool
|
||||
=
|
||||
this.CustomAttributes
|
||||
@@ -251,11 +267,11 @@ module MethodInfo =
|
||||
| con -> failwith $"TODO: {con}"
|
||||
)
|
||||
|
||||
let mapTypeGenerics<'a, 'b, 'methodGen
|
||||
let mapTypeGenerics<'a, 'b, 'methodGen, 'vars
|
||||
when 'a :> IComparable<'a> and 'a : comparison and 'b : comparison and 'b :> IComparable<'b>>
|
||||
(f : int -> 'a -> 'b)
|
||||
(m : MethodInfo<'a, 'methodGen>)
|
||||
: MethodInfo<'b, 'methodGen>
|
||||
(m : MethodInfo<'a, 'methodGen, 'vars>)
|
||||
: MethodInfo<'b, 'methodGen, 'vars>
|
||||
=
|
||||
{
|
||||
DeclaringType = m.DeclaringType |> ConcreteType.mapGeneric f
|
||||
@@ -265,16 +281,17 @@ module MethodInfo =
|
||||
Parameters = m.Parameters
|
||||
Generics = m.Generics
|
||||
Signature = m.Signature
|
||||
RawSignature = m.RawSignature
|
||||
CustomAttributes = m.CustomAttributes
|
||||
MethodAttributes = m.MethodAttributes
|
||||
ImplAttributes = m.ImplAttributes
|
||||
IsStatic = m.IsStatic
|
||||
}
|
||||
|
||||
let mapMethodGenerics<'a, 'b, 'typeGen when 'typeGen :> IComparable<'typeGen> and 'typeGen : comparison>
|
||||
let mapMethodGenerics<'a, 'b, 'vars, 'typeGen when 'typeGen :> IComparable<'typeGen> and 'typeGen : comparison>
|
||||
(f : int -> 'a -> 'b)
|
||||
(m : MethodInfo<'typeGen, 'a>)
|
||||
: MethodInfo<'typeGen, 'b>
|
||||
(m : MethodInfo<'typeGen, 'a, 'vars>)
|
||||
: MethodInfo<'typeGen, 'b, 'vars>
|
||||
=
|
||||
{
|
||||
DeclaringType = m.DeclaringType
|
||||
@@ -284,12 +301,33 @@ module MethodInfo =
|
||||
Parameters = m.Parameters
|
||||
Generics = m.Generics |> Seq.mapi f |> ImmutableArray.CreateRange
|
||||
Signature = m.Signature
|
||||
RawSignature = m.RawSignature
|
||||
CustomAttributes = m.CustomAttributes
|
||||
MethodAttributes = m.MethodAttributes
|
||||
ImplAttributes = m.ImplAttributes
|
||||
IsStatic = m.IsStatic
|
||||
}
|
||||
|
||||
let setMethodVars
|
||||
(vars2 : MethodInstructions<'vars2> option)
|
||||
(signature : TypeMethodSignature<'vars2>)
|
||||
(m : MethodInfo<'typeGen, 'methodGen, 'vars1>)
|
||||
: MethodInfo<'typeGen, 'methodGen, 'vars2>
|
||||
=
|
||||
{
|
||||
DeclaringType = m.DeclaringType
|
||||
Handle = m.Handle
|
||||
Name = m.Name
|
||||
Instructions = vars2
|
||||
Parameters = m.Parameters
|
||||
Generics = m.Generics
|
||||
Signature = signature
|
||||
RawSignature = m.RawSignature
|
||||
CustomAttributes = m.CustomAttributes
|
||||
MethodAttributes = m.MethodAttributes
|
||||
ImplAttributes = m.ImplAttributes
|
||||
IsStatic = m.IsStatic
|
||||
}
|
||||
|
||||
type private Dummy = class end
|
||||
|
||||
@@ -638,7 +676,7 @@ module MethodInfo =
|
||||
(peReader : PEReader)
|
||||
(metadataReader : MetadataReader)
|
||||
(methodHandle : MethodDefinitionHandle)
|
||||
: MethodInfo<FakeUnit, GenericParameter> option
|
||||
: MethodInfo<FakeUnit, GenericParameter, TypeDefn> option
|
||||
=
|
||||
let logger = loggerFactory.CreateLogger "MethodInfo"
|
||||
let assemblyName = metadataReader.GetAssemblyDefinition().GetAssemblyName ()
|
||||
@@ -715,6 +753,7 @@ module MethodInfo =
|
||||
Parameters = methodParams
|
||||
Generics = methodGenericParams
|
||||
Signature = typeSig
|
||||
RawSignature = typeSig
|
||||
MethodAttributes = methodDef.Attributes
|
||||
CustomAttributes = attrs
|
||||
IsStatic = not methodSig.Header.IsInstance
|
||||
@@ -724,7 +763,7 @@ module MethodInfo =
|
||||
|
||||
let rec resolveBaseType
|
||||
(methodGenerics : TypeDefn ImmutableArray option)
|
||||
(executingMethod : MethodInfo<TypeDefn, 'methodGen>)
|
||||
(executingMethod : MethodInfo<TypeDefn, 'methodGen, 'vars>)
|
||||
(td : TypeDefn)
|
||||
: ResolvedBaseType
|
||||
=
|
||||
|
@@ -34,7 +34,7 @@ type TypeInfo<'generic, 'fieldGeneric> =
|
||||
/// <summary>
|
||||
/// All methods defined within this type.
|
||||
/// </summary>
|
||||
Methods : WoofWare.PawPrint.MethodInfo<FakeUnit, WoofWare.PawPrint.GenericParameter> list
|
||||
Methods : WoofWare.PawPrint.MethodInfo<FakeUnit, WoofWare.PawPrint.GenericParameter, TypeDefn> list
|
||||
|
||||
/// <summary>
|
||||
/// Method implementation mappings for this type, often used for interface implementations
|
||||
|
@@ -63,7 +63,7 @@ type UnsignedNativeIntSource =
|
||||
type NativeIntSource =
|
||||
| Verbatim of int64
|
||||
| ManagedPointer of ManagedPointerSource
|
||||
| FunctionPointer of MethodInfo<FakeUnit, WoofWare.PawPrint.GenericParameter>
|
||||
| FunctionPointer of MethodInfo<FakeUnit, WoofWare.PawPrint.GenericParameter, TypeDefn>
|
||||
| TypeHandlePtr of int64<typeHandle>
|
||||
|
||||
override this.ToString () : string =
|
||||
|
@@ -1,29 +1,32 @@
|
||||
namespace WoofWare.PawPrint
|
||||
|
||||
open System
|
||||
open System.Collections.Immutable
|
||||
|
||||
/// Represents a location in the code where an exception occurred
|
||||
type ExceptionStackFrame =
|
||||
type ExceptionStackFrame<'typeGen, 'methodGen, 'methodVar
|
||||
when 'typeGen : comparison and 'typeGen :> IComparable<'typeGen>> =
|
||||
{
|
||||
Method : WoofWare.PawPrint.MethodInfo<TypeDefn, TypeDefn>
|
||||
Method : WoofWare.PawPrint.MethodInfo<'typeGen, 'methodGen, 'methodVar>
|
||||
/// The number of bytes into the IL of the method we were in
|
||||
IlOffset : int
|
||||
}
|
||||
|
||||
/// Represents a CLI exception being propagated
|
||||
type CliException =
|
||||
type CliException<'typeGen, 'methodGen, 'methodVar when 'typeGen : comparison and 'typeGen :> IComparable<'typeGen>> =
|
||||
{
|
||||
/// The exception object allocated on the heap
|
||||
ExceptionObject : ManagedHeapAddress
|
||||
/// Stack trace built during unwinding
|
||||
StackTrace : ExceptionStackFrame list
|
||||
StackTrace : ExceptionStackFrame<'typeGen, 'methodGen, 'methodVar> list
|
||||
}
|
||||
|
||||
/// Represents what to do after executing a finally/filter block
|
||||
type ExceptionContinuation =
|
||||
type ExceptionContinuation<'typeGen, 'methodGen, 'methodVar
|
||||
when 'typeGen : comparison and 'typeGen :> IComparable<'typeGen>> =
|
||||
| ResumeAfterFinally of targetPC : int
|
||||
| PropagatingException of exn : CliException
|
||||
| ResumeAfterFilter of handlerPC : int * exn : CliException
|
||||
| PropagatingException of exn : CliException<'typeGen, 'methodGen, 'methodVar>
|
||||
| ResumeAfterFilter of handlerPC : int * exn : CliException<'typeGen, 'methodGen, 'methodVar>
|
||||
|
||||
/// Helper functions for exception handling
|
||||
[<RequireQualifiedAccess>]
|
||||
@@ -44,7 +47,7 @@ module ExceptionHandling =
|
||||
let findExceptionHandler
|
||||
(currentPC : int)
|
||||
(exceptionTypeCrate : TypeInfoCrate)
|
||||
(method : WoofWare.PawPrint.MethodInfo<TypeDefn, 'methodGeneric>)
|
||||
(method : WoofWare.PawPrint.MethodInfo<'typeGen, 'methodGeneric, 'methodVar>)
|
||||
(assemblies : ImmutableDictionary<string, DumpedAssembly>)
|
||||
: (WoofWare.PawPrint.ExceptionRegion * bool) option // handler, isFinally
|
||||
=
|
||||
@@ -92,7 +95,7 @@ module ExceptionHandling =
|
||||
let findFinallyBlocksToRun
|
||||
(currentPC : int)
|
||||
(targetPC : int)
|
||||
(method : WoofWare.PawPrint.MethodInfo<TypeDefn, 'methodGeneric>)
|
||||
(method : WoofWare.PawPrint.MethodInfo<'typeGeneric, 'methodGeneric, 'methodVar>)
|
||||
: ExceptionOffset list
|
||||
=
|
||||
match method.Instructions with
|
||||
@@ -122,7 +125,7 @@ module ExceptionHandling =
|
||||
/// Get the active exception regions at a given offset
|
||||
let getActiveRegionsAtOffset
|
||||
(offset : int)
|
||||
(method : WoofWare.PawPrint.MethodInfo<TypeDefn, 'methodGeneric>)
|
||||
(method : WoofWare.PawPrint.MethodInfo<'a, 'b, 'c>)
|
||||
: WoofWare.PawPrint.ExceptionRegion list
|
||||
=
|
||||
match method.Instructions with
|
||||
|
@@ -549,7 +549,7 @@ module IlMachineState =
|
||||
|
||||
let callIntrinsic
|
||||
(baseClassTypes : BaseClassTypes<_>)
|
||||
(methodToCall : WoofWare.PawPrint.MethodInfo<TypeDefn, WoofWare.PawPrint.GenericParameter>)
|
||||
(methodToCall : WoofWare.PawPrint.MethodInfo<TypeDefn, WoofWare.PawPrint.GenericParameter, TypeDefn>)
|
||||
(currentThread : ThreadId)
|
||||
(state : IlMachineState)
|
||||
: IlMachineState option
|
||||
@@ -741,7 +741,7 @@ module IlMachineState =
|
||||
(wasClassConstructor : bool)
|
||||
(advanceProgramCounterOfCaller : bool)
|
||||
(methodGenerics : ImmutableArray<TypeDefn> option)
|
||||
(methodToCall : WoofWare.PawPrint.MethodInfo<TypeDefn, WoofWare.PawPrint.GenericParameter>)
|
||||
(methodToCall : WoofWare.PawPrint.MethodInfo<TypeDefn, WoofWare.PawPrint.GenericParameter, TypeDefn>)
|
||||
(thread : ThreadId)
|
||||
(threadState : ThreadState)
|
||||
(state : IlMachineState)
|
||||
@@ -1093,7 +1093,7 @@ module IlMachineState =
|
||||
(thread : ThreadId)
|
||||
(advanceProgramCounterOfCaller : bool)
|
||||
(methodGenerics : TypeDefn ImmutableArray option)
|
||||
(methodToCall : WoofWare.PawPrint.MethodInfo<TypeDefn, WoofWare.PawPrint.GenericParameter>)
|
||||
(methodToCall : WoofWare.PawPrint.MethodInfo<TypeDefn, WoofWare.PawPrint.GenericParameter, TypeDefn>)
|
||||
(weAreConstructingObj : ManagedHeapAddress option)
|
||||
(state : IlMachineState)
|
||||
: IlMachineState * WhatWeDid
|
||||
@@ -1289,7 +1289,7 @@ module IlMachineState =
|
||||
: IlMachineState *
|
||||
AssemblyName *
|
||||
Choice<
|
||||
WoofWare.PawPrint.MethodInfo<TypeDefn, WoofWare.PawPrint.GenericParameter>,
|
||||
WoofWare.PawPrint.MethodInfo<TypeDefn, WoofWare.PawPrint.GenericParameter, TypeDefn>,
|
||||
WoofWare.PawPrint.FieldInfo<TypeDefn, TypeDefn>
|
||||
>
|
||||
=
|
||||
|
@@ -19,7 +19,7 @@ and MethodState =
|
||||
_IlOpIndex : int
|
||||
EvaluationStack : EvalStack
|
||||
Arguments : CliType ImmutableArray
|
||||
ExecutingMethod : WoofWare.PawPrint.MethodInfo<TypeDefn, TypeDefn>
|
||||
ExecutingMethod : WoofWare.PawPrint.MethodInfo<TypeDefn, TypeDefn, TypeDefn>
|
||||
/// We don't implement the local memory pool right now
|
||||
LocalMemoryPool : unit
|
||||
/// On return, we restore this state. This should be Some almost always; an exception is the entry point.
|
||||
@@ -28,7 +28,7 @@ and MethodState =
|
||||
/// Track which exception regions are currently active (innermost first)
|
||||
ActiveExceptionRegions : ExceptionRegion list
|
||||
/// When executing a finally/fault/filter, we need to know where to return
|
||||
ExceptionContinuation : ExceptionContinuation option
|
||||
ExceptionContinuation : ExceptionContinuation<TypeDefn, TypeDefn, TypeDefn> option
|
||||
}
|
||||
|
||||
member this.IlOpIndex = this._IlOpIndex
|
||||
@@ -64,7 +64,7 @@ and MethodState =
|
||||
EvaluationStack = EvalStack.Empty
|
||||
}
|
||||
|
||||
static member setExceptionContinuation (cont : ExceptionContinuation) (state : MethodState) : MethodState =
|
||||
static member setExceptionContinuation (cont : ExceptionContinuation<_, _, _>) (state : MethodState) : MethodState =
|
||||
{ state with
|
||||
ExceptionContinuation = Some cont
|
||||
}
|
||||
@@ -139,7 +139,7 @@ and MethodState =
|
||||
(corelib : BaseClassTypes<DumpedAssembly>)
|
||||
(loadedAssemblies : ImmutableDictionary<string, DumpedAssembly>)
|
||||
(containingAssembly : DumpedAssembly)
|
||||
(method : WoofWare.PawPrint.MethodInfo<TypeDefn, TypeDefn>)
|
||||
(method : WoofWare.PawPrint.MethodInfo<TypeDefn, TypeDefn, TypeDefn>)
|
||||
(methodGenerics : ImmutableArray<TypeDefn> option)
|
||||
(args : ImmutableArray<CliType>)
|
||||
(returnState : MethodReturnState option)
|
||||
|
@@ -106,7 +106,7 @@ module Program =
|
||||
dumped
|
||||
// pretend there are no instructions, so we avoid preparing anything
|
||||
{ mainMethod with
|
||||
Instructions = Some MethodInstructions.OnlyRet
|
||||
Instructions = Some (MethodInstructions.onlyRet ())
|
||||
}
|
||||
None
|
||||
(ImmutableArray.CreateRange [ CliType.ObjectRef None ])
|
||||
|
Reference in New Issue
Block a user