mirror of
https://github.com/Smaug123/WoofWare.PawPrint
synced 2025-10-10 00:08:39 +00:00
WIP
This commit is contained in:
@@ -37,6 +37,7 @@ type FieldInfo<'typeGeneric, 'fieldGeneric when 'typeGeneric : comparison and 't
|
||||
}
|
||||
|
||||
member this.HasFieldRVA = this.Attributes.HasFlag FieldAttributes.HasFieldRVA
|
||||
member this.IsStatic = this.Attributes.HasFlag FieldAttributes.Static
|
||||
|
||||
override this.ToString () : string =
|
||||
$"%s{this.DeclaringType.Assembly.Name}.{this.DeclaringType.Name}.%s{this.Name}"
|
||||
|
@@ -53,7 +53,7 @@ module AllConcreteTypes =
|
||||
|
||||
let findExistingConcreteType
|
||||
(concreteTypes : AllConcreteTypes)
|
||||
(asm : AssemblyName, ns : string, name : string, generics : ConcreteTypeHandle ImmutableArray as key)
|
||||
(asm : AssemblyName, ns : string, name : string, generics : ConcreteTypeHandle ImmutableArray)
|
||||
: ConcreteTypeHandle option
|
||||
=
|
||||
concreteTypes.Mapping
|
||||
@@ -149,6 +149,23 @@ module ConcreteActivePatterns =
|
||||
| None -> None
|
||||
| _ -> None
|
||||
|
||||
let (|ConcreteChar|_|) (concreteTypes : AllConcreteTypes) (handle : ConcreteTypeHandle) : unit option =
|
||||
match handle with
|
||||
| ConcreteTypeHandle.Concrete id ->
|
||||
match concreteTypes.Mapping |> Map.tryFind id with
|
||||
| Some ct ->
|
||||
if
|
||||
ct.Assembly.Name = "System.Private.CoreLib"
|
||||
&& ct.Namespace = "System"
|
||||
&& ct.Name = "Char"
|
||||
&& ct.Generics.IsEmpty
|
||||
then
|
||||
Some ()
|
||||
else
|
||||
None
|
||||
| None -> None
|
||||
| _ -> None
|
||||
|
||||
let (|ConcreteString|_|) (concreteTypes : AllConcreteTypes) (handle : ConcreteTypeHandle) : unit option =
|
||||
match handle with
|
||||
| ConcreteTypeHandle.Concrete id ->
|
||||
|
@@ -1,6 +1,7 @@
|
||||
namespace WoofWare.PawPrint
|
||||
|
||||
open System
|
||||
open System.Collections.Immutable
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module Intrinsics =
|
||||
@@ -261,20 +262,71 @@ module Intrinsics =
|
||||
| [], ConcreteBool state.ConcreteTypes -> ()
|
||||
| _ -> failwith "bad signature for System.Private.CoreLib.RuntimeHelpers.IsReferenceOrContainsReference"
|
||||
|
||||
let generic =
|
||||
AllConcreteTypes.lookup (Seq.exactlyOne methodToCall.Generics) state.ConcreteTypes
|
||||
let arg = Seq.exactlyOne methodToCall.Generics
|
||||
|
||||
let generic =
|
||||
match generic with
|
||||
| None -> failwith "somehow have not already concretised type in IsReferenceOrContainsReferences"
|
||||
| Some generic -> generic
|
||||
let result =
|
||||
// Some types appear circular, because they're hardcoded in the runtime. We have to special-case them.
|
||||
match arg with
|
||||
| ConcreteChar state.ConcreteTypes ->
|
||||
false
|
||||
| _ ->
|
||||
|
||||
failwith $"TODO: do the thing on %O{generic}"
|
||||
let generic =
|
||||
AllConcreteTypes.lookup arg state.ConcreteTypes
|
||||
|
||||
let generic =
|
||||
match generic with
|
||||
| None -> failwith "somehow have not already concretised type in IsReferenceOrContainsReferences"
|
||||
| Some generic -> generic
|
||||
|
||||
let td = state.LoadedAssembly(generic.Assembly) |> Option.get |> fun a -> a.TypeDefs.[generic.Definition.Get]
|
||||
let baseType =
|
||||
td.BaseType
|
||||
|> DumpedAssembly.resolveBaseType baseClassTypes state._LoadedAssemblies generic.Assembly
|
||||
|
||||
match baseType with
|
||||
| ResolvedBaseType.Enum -> false
|
||||
| ResolvedBaseType.ValueType ->
|
||||
let nonStaticFields =
|
||||
td.Fields
|
||||
|> List.choose (fun field ->
|
||||
if field.IsStatic then
|
||||
None
|
||||
else
|
||||
Some field.Signature
|
||||
)
|
||||
|
||||
failwith $"TODO: search the fields on {td.Namespace}.{td.Name}: {nonStaticFields}"
|
||||
| ResolvedBaseType.Object
|
||||
| ResolvedBaseType.Delegate -> true
|
||||
|
||||
let state =
|
||||
state
|
||||
|> IlMachineState.pushToEvalStack (CliType.ofBool result) currentThread
|
||||
|> IlMachineState.advanceProgramCounter currentThread
|
||||
|
||||
Some state
|
||||
| "System.Private.CoreLib", "RuntimeHelpers", "InitializeArray" ->
|
||||
// https://github.com/dotnet/runtime/blob/9e5e6aa7bc36aeb2a154709a9d1192030c30a2ef/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs#L18
|
||||
failwith "TODO: array initialization"
|
||||
| "System.Private.CoreLib", "RuntimeHelpers", "CreateSpan" ->
|
||||
// https://github.com/dotnet/runtime/blob/9e5e6aa7bc36aeb2a154709a9d1192030c30a2ef/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs#L153
|
||||
None
|
||||
| "System.Private.CoreLib", "Unsafe", "As" ->
|
||||
// https://github.com/dotnet/runtime/blob/721fdf6dcb032da1f883d30884e222e35e3d3c99/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/Unsafe.cs#L64
|
||||
let inputType, retType =
|
||||
match methodToCall.Signature.ParameterTypes, methodToCall.Signature.ReturnType with
|
||||
| [input], ret -> input, ret
|
||||
| _ -> failwith "bad signature Unsafe.As"
|
||||
let genericArg = Seq.exactlyOne methodToCall.Generics
|
||||
|
||||
state
|
||||
|> IlMachineState.loadArgument currentThread 0
|
||||
let state =
|
||||
state
|
||||
|> IlMachineState.pushToEvalStack (CliType.ofBool result) currentThread
|
||||
|> IlMachineState.advanceProgramCounter currentThread
|
||||
|
||||
Some state
|
||||
| a, b, c -> failwith $"TODO: implement JIT intrinsic {a}.{b}.{c}"
|
||||
|> Option.map (fun s -> s.WithThreadSwitchedToAssembly callerAssy currentThread |> fst)
|
||||
|
@@ -773,8 +773,7 @@ module internal UnaryMetadataIlOp =
|
||||
| EvalStackValue.ManagedPointer (ManagedPointerSource.Argument (sourceThread, methodFrame, whichVar)) ->
|
||||
let currentValue =
|
||||
state.ThreadState.[sourceThread].MethodStates.[methodFrame].Arguments.[int<uint16> whichVar]
|
||||
|
||||
failwith $"TODO: need to get a field on {currentValue}"
|
||||
|> CliType.getField field.Name
|
||||
|
||||
IlMachineState.pushToEvalStack currentValue thread state
|
||||
| EvalStackValue.ObjectRef managedHeapAddress
|
||||
|
Reference in New Issue
Block a user