mirror of
https://github.com/Smaug123/WoofWare.PawPrint
synced 2025-10-13 17:48:39 +00:00
Resolve more types during startup (#47)
This commit is contained in:
@@ -151,7 +151,21 @@ module CliType =
|
|||||||
| SignatureTypeKind.Unknown -> failwith "todo"
|
| SignatureTypeKind.Unknown -> failwith "todo"
|
||||||
| SignatureTypeKind.ValueType ->
|
| SignatureTypeKind.ValueType ->
|
||||||
match Assembly.resolveTypeRef assemblies assy typeRef typeGenerics with
|
match Assembly.resolveTypeRef assemblies assy typeRef typeGenerics with
|
||||||
| TypeResolutionResult.Resolved (_, ty) -> failwith $"TODO: {ty}"
|
| TypeResolutionResult.Resolved (sourceAssy, ty) ->
|
||||||
|
let fields =
|
||||||
|
ty.Fields
|
||||||
|
|> List.filter (fun field -> not (field.Attributes.HasFlag FieldAttributes.Static))
|
||||||
|
|> List.map (fun fi ->
|
||||||
|
match zeroOf assemblies corelib sourceAssy typeGenerics methodGenerics fi.Signature with
|
||||||
|
| CliTypeResolutionResult.Resolved ty -> Ok ty
|
||||||
|
| CliTypeResolutionResult.FirstLoad a -> Error a
|
||||||
|
)
|
||||||
|
|> Result.allOkOrError
|
||||||
|
|
||||||
|
match fields with
|
||||||
|
| Error (_, []) -> failwith "logic error"
|
||||||
|
| Error (_, f :: _) -> CliTypeResolutionResult.FirstLoad f
|
||||||
|
| Ok fields -> CliType.ValueType fields |> CliTypeResolutionResult.Resolved
|
||||||
| TypeResolutionResult.FirstLoadAssy assy -> CliTypeResolutionResult.FirstLoad assy
|
| TypeResolutionResult.FirstLoadAssy assy -> CliTypeResolutionResult.FirstLoad assy
|
||||||
| SignatureTypeKind.Class -> CliType.ObjectRef None |> CliTypeResolutionResult.Resolved
|
| SignatureTypeKind.Class -> CliType.ObjectRef None |> CliTypeResolutionResult.Resolved
|
||||||
| _ -> raise (ArgumentOutOfRangeException ())
|
| _ -> raise (ArgumentOutOfRangeException ())
|
||||||
|
@@ -69,47 +69,75 @@ module Program =
|
|||||||
mainMethod
|
mainMethod
|
||||||
|> MethodInfo.mapTypeGenerics (fun _ -> failwith "Refusing to execute generic main method")
|
|> MethodInfo.mapTypeGenerics (fun _ -> failwith "Refusing to execute generic main method")
|
||||||
|
|
||||||
let state, mainThread =
|
let rec computeState (baseClassTypes : BaseClassTypes<DumpedAssembly> option) (state : IlMachineState) =
|
||||||
IlMachineState.initial loggerFactory dotnetRuntimeDirs dumped
|
|
||||||
// The thread's state is slightly fake: we will need to put arguments onto the stack before actually
|
// The thread's state is slightly fake: we will need to put arguments onto the stack before actually
|
||||||
// executing the main method.
|
// executing the main method.
|
||||||
// We construct the thread here before we are entirely ready, because we need a thread from which to
|
// We construct the thread here before we are entirely ready, because we need a thread from which to
|
||||||
// initialise the class containing the main method.
|
// initialise the class containing the main method.
|
||||||
// Once we've obtained e.g. the String and Array classes, we can populate the args array.
|
// Once we've obtained e.g. the String and Array classes, we can populate the args array.
|
||||||
|> fun s ->
|
match
|
||||||
match
|
MethodState.Empty
|
||||||
MethodState.Empty
|
(Option.toObj baseClassTypes)
|
||||||
Unchecked.defaultof<_>
|
state._LoadedAssemblies
|
||||||
s._LoadedAssemblies
|
dumped
|
||||||
dumped
|
mainMethod
|
||||||
mainMethod
|
None
|
||||||
None
|
(ImmutableArray.CreateRange [ CliType.ObjectRef None ])
|
||||||
(ImmutableArray.CreateRange [ CliType.ObjectRef None ])
|
None
|
||||||
None
|
with
|
||||||
with
|
| Ok meth -> IlMachineState.addThread meth dumped.Name state, baseClassTypes
|
||||||
| Ok meth -> IlMachineState.addThread meth dumped.Name s
|
| Error requiresRefs ->
|
||||||
| Error requiresRefs -> failwith "TODO: I'd be surprised if this could ever happen in a valid program"
|
let state =
|
||||||
|
(state, requiresRefs)
|
||||||
|
||> List.fold (fun state ref ->
|
||||||
|
let handle, referencingAssy = ref.Handle
|
||||||
|
let referencingAssy = state.LoadedAssembly referencingAssy |> Option.get
|
||||||
|
|
||||||
|
let state, _, _ =
|
||||||
|
IlMachineState.loadAssembly loggerFactory referencingAssy handle state
|
||||||
|
|
||||||
|
state
|
||||||
|
)
|
||||||
|
|
||||||
|
let corelib =
|
||||||
|
let coreLib =
|
||||||
|
state._LoadedAssemblies.Keys
|
||||||
|
|> Seq.tryFind (fun x -> x.StartsWith ("System.Private.CoreLib, ", StringComparison.Ordinal))
|
||||||
|
|
||||||
|
coreLib
|
||||||
|
|> Option.map (fun coreLib -> state._LoadedAssemblies.[coreLib] |> Corelib.getBaseTypes)
|
||||||
|
|
||||||
|
computeState corelib state
|
||||||
|
|
||||||
|
let (state, mainThread), baseClassTypes =
|
||||||
|
IlMachineState.initial loggerFactory dotnetRuntimeDirs dumped
|
||||||
|
|> computeState None
|
||||||
|
|
||||||
let rec loadInitialState (state : IlMachineState) =
|
let rec loadInitialState (state : IlMachineState) =
|
||||||
match
|
match
|
||||||
state
|
state
|
||||||
|> IlMachineState.loadClass loggerFactory Unchecked.defaultof<_> mainMethod.DeclaringType mainThread
|
|> IlMachineState.loadClass
|
||||||
|
loggerFactory
|
||||||
|
(Option.toObj baseClassTypes)
|
||||||
|
mainMethod.DeclaringType
|
||||||
|
mainThread
|
||||||
with
|
with
|
||||||
| StateLoadResult.NothingToDo ilMachineState -> ilMachineState
|
| StateLoadResult.NothingToDo ilMachineState -> ilMachineState
|
||||||
| StateLoadResult.FirstLoadThis ilMachineState -> loadInitialState ilMachineState
|
| StateLoadResult.FirstLoadThis ilMachineState -> loadInitialState ilMachineState
|
||||||
|
|
||||||
let state = loadInitialState state
|
let state = loadInitialState state
|
||||||
|
|
||||||
// Now that the object has been loaded, we can identify the String type from System.Private.CoreLib.
|
// Now that the object has been loaded, we can identify the critical types like `string` from System.Private.CoreLib.
|
||||||
|
|
||||||
let corelib =
|
let baseClassTypes =
|
||||||
let coreLib =
|
match baseClassTypes with
|
||||||
state._LoadedAssemblies.Keys
|
| None ->
|
||||||
|> Seq.find (fun x -> x.StartsWith ("System.Private.CoreLib, ", StringComparison.Ordinal))
|
let coreLib =
|
||||||
|
state._LoadedAssemblies.Keys
|
||||||
|
|> Seq.find (fun x -> x.StartsWith ("System.Private.CoreLib, ", StringComparison.Ordinal))
|
||||||
|
|
||||||
state._LoadedAssemblies.[coreLib]
|
state._LoadedAssemblies.[coreLib] |> Corelib.getBaseTypes
|
||||||
|
| Some c -> c
|
||||||
let baseClassTypes = Corelib.getBaseTypes corelib
|
|
||||||
|
|
||||||
let arrayAllocation, state =
|
let arrayAllocation, state =
|
||||||
match mainMethod.Signature.ParameterTypes |> Seq.toList with
|
match mainMethod.Signature.ParameterTypes |> Seq.toList with
|
||||||
|
Reference in New Issue
Block a user