mirror of
https://github.com/Smaug123/WoofWare.PawPrint
synced 2025-10-11 16:48:41 +00:00
Compare commits
35 Commits
net10
...
a9b2598525
Author | SHA1 | Date | |
---|---|---|---|
|
a9b2598525 | ||
|
e05abbb724 | ||
|
55677a507b | ||
|
3930cc5fbb | ||
|
735449d4df | ||
|
6c73f14a4e | ||
|
5bd0f779c5 | ||
|
4e8c852b56 | ||
|
1b1b00b4dd | ||
|
6e98652691 | ||
|
ec5f6ed752 | ||
|
99e46b3756 | ||
|
35128afab4 | ||
|
57b0e545c9 | ||
|
f1db433711 | ||
|
64339bf4ee | ||
|
2e8e6f3919 | ||
|
02ae05893b | ||
|
4b7e2ac1e6 | ||
|
027a49c51a | ||
|
f020d560a6 | ||
|
2e8245d341 | ||
|
fca9a6dc47 | ||
|
cc14fb0edd | ||
|
1dbd4b008b | ||
|
064deee8d5 | ||
|
407c37a5fb | ||
|
59fd8a23b7 | ||
|
bdedea098a | ||
|
6f48c89ef3 | ||
|
07c5e931e4 | ||
|
e0e954b131 | ||
|
95f422efa9 | ||
|
e89fac2780 | ||
|
9bafd0f4b0 |
@@ -331,6 +331,13 @@ module ConcreteActivePatterns =
|
|||||||
| ConcreteTypeHandle.Pointer inner -> Some inner
|
| ConcreteTypeHandle.Pointer inner -> Some inner
|
||||||
| _ -> None
|
| _ -> None
|
||||||
|
|
||||||
|
type IAssemblyLoad =
|
||||||
|
abstract LoadAssembly :
|
||||||
|
loadedAssemblies : ImmutableDictionary<string, DumpedAssembly> ->
|
||||||
|
referencedIn : AssemblyName ->
|
||||||
|
handle : AssemblyReferenceHandle ->
|
||||||
|
ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly
|
||||||
|
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
module TypeConcretization =
|
module TypeConcretization =
|
||||||
|
|
||||||
@@ -406,8 +413,7 @@ module TypeConcretization =
|
|||||||
|
|
||||||
// Helper function for assembly loading with retry pattern
|
// Helper function for assembly loading with retry pattern
|
||||||
let private loadAssemblyAndResolveTypeRef
|
let private loadAssemblyAndResolveTypeRef
|
||||||
(loadAssembly :
|
(loadAssembly : IAssemblyLoad)
|
||||||
AssemblyName -> AssemblyReferenceHandle -> ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly)
|
|
||||||
(ctx : ConcretizationContext<'corelib>)
|
(ctx : ConcretizationContext<'corelib>)
|
||||||
(currentAssembly : AssemblyName)
|
(currentAssembly : AssemblyName)
|
||||||
(typeRef : TypeRef)
|
(typeRef : TypeRef)
|
||||||
@@ -428,7 +434,8 @@ module TypeConcretization =
|
|||||||
// Need to load the assembly
|
// Need to load the assembly
|
||||||
match typeRef.ResolutionScope with
|
match typeRef.ResolutionScope with
|
||||||
| TypeRefResolutionScope.Assembly assyRef ->
|
| TypeRefResolutionScope.Assembly assyRef ->
|
||||||
let newAssemblies, _ = loadAssembly currentAssembly assyRef
|
let newAssemblies, _ =
|
||||||
|
loadAssembly.LoadAssembly ctx.LoadedAssemblies currentAssembly assyRef
|
||||||
|
|
||||||
let newCtx =
|
let newCtx =
|
||||||
{ ctx with
|
{ ctx with
|
||||||
@@ -584,8 +591,7 @@ module TypeConcretization =
|
|||||||
ImmutableArray.Empty // No generic parameters
|
ImmutableArray.Empty // No generic parameters
|
||||||
|
|
||||||
let private concretizeTypeReference
|
let private concretizeTypeReference
|
||||||
(loadAssembly :
|
(loadAssembly : IAssemblyLoad)
|
||||||
AssemblyName -> AssemblyReferenceHandle -> ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly)
|
|
||||||
(ctx : ConcretizationContext<'corelib>)
|
(ctx : ConcretizationContext<'corelib>)
|
||||||
(currentAssembly : AssemblyName)
|
(currentAssembly : AssemblyName)
|
||||||
(typeRef : TypeRef)
|
(typeRef : TypeRef)
|
||||||
@@ -609,8 +615,7 @@ module TypeConcretization =
|
|||||||
/// Concretize a type in a specific generic context
|
/// Concretize a type in a specific generic context
|
||||||
let rec concretizeType
|
let rec concretizeType
|
||||||
(ctx : ConcretizationContext<DumpedAssembly>)
|
(ctx : ConcretizationContext<DumpedAssembly>)
|
||||||
(loadAssembly :
|
(loadAssembly : IAssemblyLoad)
|
||||||
AssemblyName -> AssemblyReferenceHandle -> ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly)
|
|
||||||
(assembly : AssemblyName)
|
(assembly : AssemblyName)
|
||||||
(typeGenerics : ImmutableArray<ConcreteTypeHandle>)
|
(typeGenerics : ImmutableArray<ConcreteTypeHandle>)
|
||||||
(methodGenerics : ImmutableArray<ConcreteTypeHandle>)
|
(methodGenerics : ImmutableArray<ConcreteTypeHandle>)
|
||||||
@@ -706,8 +711,7 @@ module TypeConcretization =
|
|||||||
|
|
||||||
and private concretizeGenericInstantiation
|
and private concretizeGenericInstantiation
|
||||||
(ctx : ConcretizationContext<DumpedAssembly>)
|
(ctx : ConcretizationContext<DumpedAssembly>)
|
||||||
(loadAssembly :
|
(loadAssembly : IAssemblyLoad)
|
||||||
AssemblyName -> AssemblyReferenceHandle -> ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly)
|
|
||||||
(assembly : AssemblyName)
|
(assembly : AssemblyName)
|
||||||
(typeGenerics : ImmutableArray<ConcreteTypeHandle>)
|
(typeGenerics : ImmutableArray<ConcreteTypeHandle>)
|
||||||
(methodGenerics : ImmutableArray<ConcreteTypeHandle>)
|
(methodGenerics : ImmutableArray<ConcreteTypeHandle>)
|
||||||
@@ -786,7 +790,8 @@ module TypeConcretization =
|
|||||||
|
|
||||||
| false, _ ->
|
| false, _ ->
|
||||||
// Need to load the assembly
|
// Need to load the assembly
|
||||||
let newAssemblies, loadedAssy = loadAssembly assembly assyRef
|
let newAssemblies, loadedAssy =
|
||||||
|
loadAssembly.LoadAssembly ctx.LoadedAssemblies assembly assyRef
|
||||||
|
|
||||||
let ctxWithNewAssy =
|
let ctxWithNewAssy =
|
||||||
{ ctxAfterArgs with
|
{ ctxAfterArgs with
|
||||||
@@ -865,8 +870,7 @@ module Concretization =
|
|||||||
/// Helper to concretize an array of types
|
/// Helper to concretize an array of types
|
||||||
let private concretizeTypeArray
|
let private concretizeTypeArray
|
||||||
(ctx : TypeConcretization.ConcretizationContext<DumpedAssembly>)
|
(ctx : TypeConcretization.ConcretizationContext<DumpedAssembly>)
|
||||||
(loadAssembly :
|
(loadAssembly : IAssemblyLoad)
|
||||||
AssemblyName -> AssemblyReferenceHandle -> ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly)
|
|
||||||
(assembly : AssemblyName)
|
(assembly : AssemblyName)
|
||||||
(typeArgs : ImmutableArray<ConcreteTypeHandle>)
|
(typeArgs : ImmutableArray<ConcreteTypeHandle>)
|
||||||
(methodArgs : ImmutableArray<ConcreteTypeHandle>)
|
(methodArgs : ImmutableArray<ConcreteTypeHandle>)
|
||||||
@@ -889,8 +893,7 @@ module Concretization =
|
|||||||
/// Helper to concretize a method signature
|
/// Helper to concretize a method signature
|
||||||
let private concretizeMethodSignature
|
let private concretizeMethodSignature
|
||||||
(ctx : TypeConcretization.ConcretizationContext<DumpedAssembly>)
|
(ctx : TypeConcretization.ConcretizationContext<DumpedAssembly>)
|
||||||
(loadAssembly :
|
(loadAssembly : IAssemblyLoad)
|
||||||
AssemblyName -> AssemblyReferenceHandle -> ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly)
|
|
||||||
(assembly : AssemblyName)
|
(assembly : AssemblyName)
|
||||||
(typeArgs : ImmutableArray<ConcreteTypeHandle>)
|
(typeArgs : ImmutableArray<ConcreteTypeHandle>)
|
||||||
(methodArgs : ImmutableArray<ConcreteTypeHandle>)
|
(methodArgs : ImmutableArray<ConcreteTypeHandle>)
|
||||||
@@ -926,8 +929,7 @@ module Concretization =
|
|||||||
|
|
||||||
/// Helper to ensure base type assembly is loaded
|
/// Helper to ensure base type assembly is loaded
|
||||||
let rec private ensureBaseTypeAssembliesLoaded
|
let rec private ensureBaseTypeAssembliesLoaded
|
||||||
(loadAssembly :
|
(loadAssembly : IAssemblyLoad)
|
||||||
AssemblyName -> AssemblyReferenceHandle -> ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly)
|
|
||||||
(assemblies : ImmutableDictionary<string, DumpedAssembly>)
|
(assemblies : ImmutableDictionary<string, DumpedAssembly>)
|
||||||
(assyName : AssemblyName)
|
(assyName : AssemblyName)
|
||||||
(baseTypeInfo : BaseTypeInfo option)
|
(baseTypeInfo : BaseTypeInfo option)
|
||||||
@@ -947,7 +949,7 @@ module Concretization =
|
|||||||
| true, _ -> assemblies
|
| true, _ -> assemblies
|
||||||
| false, _ ->
|
| false, _ ->
|
||||||
// Need to load the assembly - pass the assembly that contains the reference
|
// Need to load the assembly - pass the assembly that contains the reference
|
||||||
let newAssemblies, _ = loadAssembly assy.Name assyRef
|
let newAssemblies, _ = loadAssembly.LoadAssembly assemblies assy.Name assyRef
|
||||||
newAssemblies
|
newAssemblies
|
||||||
| _ -> assemblies
|
| _ -> assemblies
|
||||||
| Some (BaseTypeInfo.TypeDef _)
|
| Some (BaseTypeInfo.TypeDef _)
|
||||||
@@ -957,8 +959,7 @@ module Concretization =
|
|||||||
/// Concretize a method's signature and body
|
/// Concretize a method's signature and body
|
||||||
let concretizeMethod
|
let concretizeMethod
|
||||||
(ctx : AllConcreteTypes)
|
(ctx : AllConcreteTypes)
|
||||||
(loadAssembly :
|
(loadAssembly : IAssemblyLoad)
|
||||||
AssemblyName -> AssemblyReferenceHandle -> ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly)
|
|
||||||
(assemblies : ImmutableDictionary<string, DumpedAssembly>)
|
(assemblies : ImmutableDictionary<string, DumpedAssembly>)
|
||||||
(baseTypes : BaseClassTypes<DumpedAssembly>)
|
(baseTypes : BaseClassTypes<DumpedAssembly>)
|
||||||
(method : WoofWare.PawPrint.MethodInfo<'ty, GenericParamFromMetadata, TypeDefn>)
|
(method : WoofWare.PawPrint.MethodInfo<'ty, GenericParamFromMetadata, TypeDefn>)
|
||||||
|
@@ -22,12 +22,17 @@ module TestPureCases =
|
|||||||
NativeImpls = MockEnv.make ()
|
NativeImpls = MockEnv.make ()
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
FileName = "InitializeArray.cs"
|
FileName = "OverlappingStructs.cs"
|
||||||
ExpectedReturnCode = 0
|
ExpectedReturnCode = 0
|
||||||
NativeImpls = MockEnv.make ()
|
NativeImpls = MockEnv.make ()
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
FileName = "GenericEdgeCases.cs"
|
FileName = "AdvancedStructLayout.cs"
|
||||||
|
ExpectedReturnCode = 0
|
||||||
|
NativeImpls = MockEnv.make ()
|
||||||
|
}
|
||||||
|
{
|
||||||
|
FileName = "InitializeArray.cs"
|
||||||
ExpectedReturnCode = 0
|
ExpectedReturnCode = 0
|
||||||
NativeImpls = MockEnv.make ()
|
NativeImpls = MockEnv.make ()
|
||||||
}
|
}
|
||||||
@@ -56,21 +61,6 @@ module TestPureCases =
|
|||||||
ExpectedReturnCode = 0
|
ExpectedReturnCode = 0
|
||||||
NativeImpls = MockEnv.make ()
|
NativeImpls = MockEnv.make ()
|
||||||
}
|
}
|
||||||
{
|
|
||||||
FileName = "AdvancedStructLayout.cs"
|
|
||||||
ExpectedReturnCode = 0
|
|
||||||
NativeImpls = MockEnv.make ()
|
|
||||||
}
|
|
||||||
{
|
|
||||||
FileName = "OverlappingStructs.cs"
|
|
||||||
ExpectedReturnCode = 0
|
|
||||||
NativeImpls = MockEnv.make ()
|
|
||||||
}
|
|
||||||
{
|
|
||||||
FileName = "UnsafeAs.cs"
|
|
||||||
ExpectedReturnCode = 0
|
|
||||||
NativeImpls = MockEnv.make ()
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
|
|
||||||
let cases : EndToEndTestCase list =
|
let cases : EndToEndTestCase list =
|
||||||
@@ -80,6 +70,21 @@ module TestPureCases =
|
|||||||
ExpectedReturnCode = 1
|
ExpectedReturnCode = 1
|
||||||
NativeImpls = MockEnv.make ()
|
NativeImpls = MockEnv.make ()
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
FileName = "UnsafeAs.cs"
|
||||||
|
ExpectedReturnCode = 0
|
||||||
|
NativeImpls = MockEnv.make ()
|
||||||
|
}
|
||||||
|
{
|
||||||
|
FileName = "Initobj.cs"
|
||||||
|
ExpectedReturnCode = 0
|
||||||
|
NativeImpls = MockEnv.make ()
|
||||||
|
}
|
||||||
|
{
|
||||||
|
FileName = "GenericEdgeCases.cs"
|
||||||
|
ExpectedReturnCode = 0
|
||||||
|
NativeImpls = MockEnv.make ()
|
||||||
|
}
|
||||||
{
|
{
|
||||||
FileName = "TestShl.cs"
|
FileName = "TestShl.cs"
|
||||||
ExpectedReturnCode = 0
|
ExpectedReturnCode = 0
|
||||||
@@ -165,11 +170,6 @@ module TestPureCases =
|
|||||||
ExpectedReturnCode = 0
|
ExpectedReturnCode = 0
|
||||||
NativeImpls = MockEnv.make ()
|
NativeImpls = MockEnv.make ()
|
||||||
}
|
}
|
||||||
{
|
|
||||||
FileName = "Initobj.cs"
|
|
||||||
ExpectedReturnCode = 0
|
|
||||||
NativeImpls = MockEnv.make ()
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
|
|
||||||
let runTest (case : EndToEndTestCase) : unit =
|
let runTest (case : EndToEndTestCase) : unit =
|
||||||
|
@@ -222,5 +222,5 @@ module AbstractMachine =
|
|||||||
|> ExecutionResult.Stepped
|
|> ExecutionResult.Stepped
|
||||||
| IlOp.Switch immutableArray -> failwith "TODO: Switch unimplemented"
|
| IlOp.Switch immutableArray -> failwith "TODO: Switch unimplemented"
|
||||||
| IlOp.UnaryStringToken (unaryStringTokenIlOp, stringHandle) ->
|
| IlOp.UnaryStringToken (unaryStringTokenIlOp, stringHandle) ->
|
||||||
UnaryStringTokenIlOp.execute baseClassTypes unaryStringTokenIlOp stringHandle state thread
|
UnaryStringTokenIlOp.execute loggerFactory baseClassTypes unaryStringTokenIlOp stringHandle state thread
|
||||||
|> ExecutionResult.Stepped
|
|> ExecutionResult.Stepped
|
||||||
|
@@ -460,20 +460,22 @@ module CliType =
|
|||||||
// The field type might reference generic parameters of the declaring type
|
// The field type might reference generic parameters of the declaring type
|
||||||
let methodGenerics = ImmutableArray.Empty // Fields don't have method generics
|
let methodGenerics = ImmutableArray.Empty // Fields don't have method generics
|
||||||
|
|
||||||
let loadAssembly
|
let loadAssembly =
|
||||||
(assyName : AssemblyName)
|
{ new IAssemblyLoad with
|
||||||
(ref : AssemblyReferenceHandle)
|
member _.LoadAssembly loaded assyName ref =
|
||||||
: ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly
|
match loaded.TryGetValue assyName.FullName with
|
||||||
=
|
| true, currentAssy ->
|
||||||
match assemblies.TryGetValue assyName.FullName with
|
let targetAssyRef = currentAssy.AssemblyReferences.[ref]
|
||||||
| true, currentAssy ->
|
|
||||||
let targetAssyRef = currentAssy.AssemblyReferences.[ref]
|
|
||||||
|
|
||||||
match assemblies.TryGetValue targetAssyRef.Name.FullName with
|
match loaded.TryGetValue targetAssyRef.Name.FullName with
|
||||||
| true, targetAssy -> assemblies, targetAssy
|
| true, targetAssy -> loaded, targetAssy
|
||||||
| false, _ ->
|
| false, _ ->
|
||||||
failwithf "Assembly %s not loaded when trying to resolve reference" targetAssyRef.Name.FullName
|
failwithf
|
||||||
| false, _ -> failwithf "Current assembly %s not loaded when trying to resolve reference" assyName.FullName
|
"Assembly %s not loaded when trying to resolve reference"
|
||||||
|
targetAssyRef.Name.FullName
|
||||||
|
| false, _ ->
|
||||||
|
failwithf "Current assembly %s not loaded when trying to resolve reference" assyName.FullName
|
||||||
|
}
|
||||||
|
|
||||||
let handle, newCtx =
|
let handle, newCtx =
|
||||||
TypeConcretization.concretizeType
|
TypeConcretization.concretizeType
|
||||||
|
@@ -149,7 +149,73 @@ type StateLoadResult =
|
|||||||
module IlMachineState =
|
module IlMachineState =
|
||||||
type private Dummy = class end
|
type private Dummy = class end
|
||||||
|
|
||||||
|
let private loadAssembly'
|
||||||
|
(loggerFactory : ILoggerFactory)
|
||||||
|
(dotnetRuntimeDirs : string seq)
|
||||||
|
(referencedInAssembly : DumpedAssembly)
|
||||||
|
(r : AssemblyReferenceHandle)
|
||||||
|
(assemblies : ImmutableDictionary<string, DumpedAssembly>)
|
||||||
|
=
|
||||||
|
let assemblyRef = referencedInAssembly.AssemblyReferences.[r]
|
||||||
|
let assemblyName = assemblyRef.Name
|
||||||
|
|
||||||
|
match assemblies.TryGetValue assemblyName.FullName with
|
||||||
|
| true, v -> v, assemblyName
|
||||||
|
| false, _ ->
|
||||||
|
let logger = loggerFactory.CreateLogger typeof<Dummy>.DeclaringType
|
||||||
|
|
||||||
|
let assy =
|
||||||
|
dotnetRuntimeDirs
|
||||||
|
|> Seq.choose (fun dir ->
|
||||||
|
let file = Path.Combine (dir, assemblyName.Name + ".dll")
|
||||||
|
|
||||||
|
try
|
||||||
|
use f = File.OpenRead file
|
||||||
|
logger.LogInformation ("Loading assembly from file {AssemblyFileLoadPath}", file)
|
||||||
|
Assembly.read loggerFactory (Some file) f |> Some
|
||||||
|
with :? FileNotFoundException ->
|
||||||
|
None
|
||||||
|
)
|
||||||
|
|> Seq.toList
|
||||||
|
|
||||||
|
match assy |> List.tryHead with
|
||||||
|
| None -> failwith $"Could not find a readable DLL in any runtime dir with name %s{assemblyName.Name}.dll"
|
||||||
|
| Some assy -> assy, assemblyName
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new IlMachineState which has loaded the given assembly.
|
||||||
|
/// This involves reading assemblies from the disk and doing a complete parse of them, so it might be quite slow!
|
||||||
|
///
|
||||||
|
/// This function doesn't do anything if the referenced assembly has already been loaded.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="loggerFactory">LoggerFactory into which to emit logs.</param>
|
||||||
|
/// <param name="referencedInAssembly">The assembly which contains an AssemblyReference which causes us to want to load a new assembly.</param>
|
||||||
|
/// <param name="r">The AssemblyReferenceHandle pointing at an assembly we want to load. *Important*: this is an AssemblyReferenceHandle from <c>referencedInAssembly</c>; in general, AssemblyReferenceHandles are only well-defined if you know what assembly they were defined in.</param>
|
||||||
|
/// <param name="state">The immutable state to augment with the new assembly.</param>
|
||||||
|
let loadAssembly
|
||||||
|
(loggerFactory : ILoggerFactory)
|
||||||
|
(referencedInAssembly : DumpedAssembly)
|
||||||
|
(r : AssemblyReferenceHandle)
|
||||||
|
(state : IlMachineState)
|
||||||
|
: IlMachineState * DumpedAssembly * AssemblyName
|
||||||
|
=
|
||||||
|
let dumped, assy =
|
||||||
|
loadAssembly' loggerFactory state.DotnetRuntimeDirs referencedInAssembly r state._LoadedAssemblies
|
||||||
|
|
||||||
|
state.WithLoadedAssembly assy dumped, dumped, assy
|
||||||
|
|
||||||
|
let private loader (loggerFactory : ILoggerFactory) (state : IlMachineState) : IAssemblyLoad =
|
||||||
|
{ new IAssemblyLoad with
|
||||||
|
member _.LoadAssembly loaded assyName ref =
|
||||||
|
let targetAssy, name =
|
||||||
|
loadAssembly' loggerFactory state.DotnetRuntimeDirs loaded.[assyName.FullName] ref loaded
|
||||||
|
|
||||||
|
let newAssys = loaded.SetItem (name.FullName, targetAssy)
|
||||||
|
newAssys, targetAssy
|
||||||
|
}
|
||||||
|
|
||||||
let concretizeType
|
let concretizeType
|
||||||
|
(loggerFactory : ILoggerFactory)
|
||||||
(baseClassTypes : BaseClassTypes<DumpedAssembly>)
|
(baseClassTypes : BaseClassTypes<DumpedAssembly>)
|
||||||
(state : IlMachineState)
|
(state : IlMachineState)
|
||||||
(declaringAssembly : AssemblyName)
|
(declaringAssembly : AssemblyName)
|
||||||
@@ -169,14 +235,7 @@ module IlMachineState =
|
|||||||
let handle, ctx =
|
let handle, ctx =
|
||||||
TypeConcretization.concretizeType
|
TypeConcretization.concretizeType
|
||||||
ctx
|
ctx
|
||||||
(fun assyName ref ->
|
(loader loggerFactory state)
|
||||||
let currentAssy = state.LoadedAssembly assyName |> Option.get
|
|
||||||
|
|
||||||
let targetAssy =
|
|
||||||
currentAssy.AssemblyReferences.[ref].Name |> state.LoadedAssembly |> Option.get
|
|
||||||
|
|
||||||
state._LoadedAssemblies, targetAssy
|
|
||||||
)
|
|
||||||
declaringAssembly
|
declaringAssembly
|
||||||
typeGenerics
|
typeGenerics
|
||||||
methodGenerics
|
methodGenerics
|
||||||
@@ -190,51 +249,6 @@ module IlMachineState =
|
|||||||
|
|
||||||
state, handle
|
state, handle
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new IlMachineState which has loaded the given assembly.
|
|
||||||
/// This involves reading assemblies from the disk and doing a complete parse of them, so it might be quite slow!
|
|
||||||
///
|
|
||||||
/// This function doesn't do anything if the referenced assembly has already been loaded.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="loggerFactory">LoggerFactory into which to emit logs.</param>
|
|
||||||
/// <param name="referencedInAssembly">The assembly which contains an AssemblyReference which causes us to want to load a new assembly.</param>
|
|
||||||
/// <param name="r">The AssemblyReferenceHandle pointing at an assembly we want to load. *Important*: this is an AssemblyReferenceHandle from <c>referencedInAssembly</c>; in general, AssemblyReferenceHandles are only well-defined if you know what assembly they were defined in.</param>
|
|
||||||
/// <param name="state">The immutable state to augment with the new assembly.</param>
|
|
||||||
let loadAssembly
|
|
||||||
(loggerFactory : ILoggerFactory)
|
|
||||||
(referencedInAssembly : DumpedAssembly)
|
|
||||||
(r : AssemblyReferenceHandle)
|
|
||||||
(state : IlMachineState)
|
|
||||||
: IlMachineState * DumpedAssembly * AssemblyName
|
|
||||||
=
|
|
||||||
let assemblyRef = referencedInAssembly.AssemblyReferences.[r]
|
|
||||||
let assemblyName = assemblyRef.Name
|
|
||||||
|
|
||||||
match state.LoadedAssembly assemblyName with
|
|
||||||
| Some v -> state, v, assemblyName
|
|
||||||
| None ->
|
|
||||||
let logger = loggerFactory.CreateLogger typeof<Dummy>.DeclaringType
|
|
||||||
|
|
||||||
let assy =
|
|
||||||
state.DotnetRuntimeDirs
|
|
||||||
|> Seq.choose (fun dir ->
|
|
||||||
let file = Path.Combine (dir, assemblyName.Name + ".dll")
|
|
||||||
|
|
||||||
try
|
|
||||||
use f = File.OpenRead file
|
|
||||||
logger.LogInformation ("Loading assembly from file {AssemblyFileLoadPath}", file)
|
|
||||||
Assembly.read loggerFactory (Some file) f |> Some
|
|
||||||
with :? FileNotFoundException ->
|
|
||||||
None
|
|
||||||
)
|
|
||||||
|> Seq.toList
|
|
||||||
|
|
||||||
match assy |> List.tryHead with
|
|
||||||
| None -> failwith $"Could not find a readable DLL in any runtime dir with name %s{assemblyName.Name}.dll"
|
|
||||||
| Some assy ->
|
|
||||||
|
|
||||||
state.WithLoadedAssembly assemblyName assy, assy, assemblyName
|
|
||||||
|
|
||||||
let rec internal resolveTypeFromName
|
let rec internal resolveTypeFromName
|
||||||
(loggerFactory : ILoggerFactory)
|
(loggerFactory : ILoggerFactory)
|
||||||
(ns : string option)
|
(ns : string option)
|
||||||
@@ -440,6 +454,54 @@ module IlMachineState =
|
|||||||
|
|
||||||
resolveTypeFromDefn loggerFactory baseClassTypes sign typeGenericArgsAsDefn methodGenericArgsAsDefn assy state
|
resolveTypeFromDefn loggerFactory baseClassTypes sign typeGenericArgsAsDefn methodGenericArgsAsDefn assy state
|
||||||
|
|
||||||
|
/// Resolve a TypeDefinition using concrete type handles from execution context
|
||||||
|
let resolveTypeFromDefnConcrete
|
||||||
|
(loggerFactory : ILoggerFactory)
|
||||||
|
(baseClassTypes : BaseClassTypes<DumpedAssembly>)
|
||||||
|
(ty : TypeDefinitionHandle)
|
||||||
|
(assy : DumpedAssembly)
|
||||||
|
(typeGenericArgs : ConcreteTypeHandle ImmutableArray)
|
||||||
|
(methodGenericArgs : ConcreteTypeHandle ImmutableArray)
|
||||||
|
(state : IlMachineState)
|
||||||
|
: IlMachineState * DumpedAssembly * WoofWare.PawPrint.TypeInfo<TypeDefn, TypeDefn>
|
||||||
|
=
|
||||||
|
let typeDef = assy.TypeDefs.[ty]
|
||||||
|
|
||||||
|
// Convert ConcreteTypeHandle to TypeDefn for the generics
|
||||||
|
let typeGenericArgsAsDefn =
|
||||||
|
typeGenericArgs
|
||||||
|
|> Seq.map (fun handle ->
|
||||||
|
Concretization.concreteHandleToTypeDefn
|
||||||
|
baseClassTypes
|
||||||
|
handle
|
||||||
|
state.ConcreteTypes
|
||||||
|
state._LoadedAssemblies
|
||||||
|
)
|
||||||
|
|> ImmutableArray.CreateRange
|
||||||
|
|
||||||
|
let methodGenericArgsAsDefn =
|
||||||
|
methodGenericArgs
|
||||||
|
|> Seq.map (fun handle ->
|
||||||
|
Concretization.concreteHandleToTypeDefn
|
||||||
|
baseClassTypes
|
||||||
|
handle
|
||||||
|
state.ConcreteTypes
|
||||||
|
state._LoadedAssemblies
|
||||||
|
)
|
||||||
|
|> ImmutableArray.CreateRange
|
||||||
|
|
||||||
|
// Map the type definition's generics using the provided type generic arguments
|
||||||
|
let resolvedTypeDef =
|
||||||
|
typeDef
|
||||||
|
|> TypeInfo.mapGeneric (fun (param, _) ->
|
||||||
|
if param.SequenceNumber < typeGenericArgsAsDefn.Length then
|
||||||
|
typeGenericArgsAsDefn.[param.SequenceNumber]
|
||||||
|
else
|
||||||
|
failwithf "Generic type parameter %d out of range" param.SequenceNumber
|
||||||
|
)
|
||||||
|
|
||||||
|
state, assy, resolvedTypeDef
|
||||||
|
|
||||||
/// Get zero value for a type that's already been concretized
|
/// Get zero value for a type that's already been concretized
|
||||||
let cliTypeZeroOfHandle
|
let cliTypeZeroOfHandle
|
||||||
(state : IlMachineState)
|
(state : IlMachineState)
|
||||||
@@ -482,26 +544,6 @@ module IlMachineState =
|
|||||||
BaseTypes = baseClassTypes
|
BaseTypes = baseClassTypes
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to get assembly from reference
|
|
||||||
let loadAssembly
|
|
||||||
(currentAssembly : AssemblyName)
|
|
||||||
(assyRef : AssemblyReferenceHandle)
|
|
||||||
: ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly
|
|
||||||
=
|
|
||||||
let assyToLoad =
|
|
||||||
match state.LoadedAssembly currentAssembly with
|
|
||||||
| Some assy -> assy
|
|
||||||
| None -> failwithf "Assembly %s not loaded" currentAssembly.FullName
|
|
||||||
|
|
||||||
let referencedAssy = assyToLoad.AssemblyReferences.[assyRef]
|
|
||||||
|
|
||||||
match state.LoadedAssembly referencedAssy.Name with
|
|
||||||
| Some assy -> state._LoadedAssemblies, assy
|
|
||||||
| None ->
|
|
||||||
// Need to load the assembly
|
|
||||||
let newState, loadedAssy, _ = loadAssembly loggerFactory assyToLoad assyRef state
|
|
||||||
newState._LoadedAssemblies, loadedAssy
|
|
||||||
|
|
||||||
// Concretize each generic argument first
|
// Concretize each generic argument first
|
||||||
let mutable currentCtx = ctx
|
let mutable currentCtx = ctx
|
||||||
let genericHandles = ImmutableArray.CreateBuilder declaringType.Generics.Length
|
let genericHandles = ImmutableArray.CreateBuilder declaringType.Generics.Length
|
||||||
@@ -510,7 +552,7 @@ module IlMachineState =
|
|||||||
let handle, newCtx =
|
let handle, newCtx =
|
||||||
TypeConcretization.concretizeType
|
TypeConcretization.concretizeType
|
||||||
currentCtx
|
currentCtx
|
||||||
loadAssembly
|
(loader loggerFactory state)
|
||||||
declaringType.Assembly
|
declaringType.Assembly
|
||||||
ImmutableArray.Empty // No type generics in this context
|
ImmutableArray.Empty // No type generics in this context
|
||||||
ImmutableArray.Empty // No method generics in this context
|
ImmutableArray.Empty // No method generics in this context
|
||||||
@@ -522,12 +564,13 @@ module IlMachineState =
|
|||||||
// Now we need to concretize the type definition itself
|
// Now we need to concretize the type definition itself
|
||||||
// If it's a non-generic type, we can use concretizeTypeDefinition directly
|
// If it's a non-generic type, we can use concretizeTypeDefinition directly
|
||||||
if declaringType.Generics.IsEmpty then
|
if declaringType.Generics.IsEmpty then
|
||||||
let handle, newCtx =
|
let handle, currentCtx =
|
||||||
TypeConcretization.concretizeTypeDefinition currentCtx declaringType.Assembly declaringType.Definition
|
TypeConcretization.concretizeTypeDefinition currentCtx declaringType.Assembly declaringType.Definition
|
||||||
|
|
||||||
let newState =
|
let newState =
|
||||||
{ state with
|
{ state with
|
||||||
ConcreteTypes = newCtx.ConcreteTypes
|
ConcreteTypes = currentCtx.ConcreteTypes
|
||||||
|
_LoadedAssemblies = currentCtx.LoadedAssemblies
|
||||||
}
|
}
|
||||||
|
|
||||||
handle, newState
|
handle, newState
|
||||||
@@ -583,7 +626,7 @@ module IlMachineState =
|
|||||||
state.WithLoadedAssembly assy.Name assy
|
state.WithLoadedAssembly assy.Name assy
|
||||||
|
|
||||||
let state, handle =
|
let state, handle =
|
||||||
concretizeType baseClassTypes state assy.Name typeGenerics methodGenerics ty
|
concretizeType loggerFactory baseClassTypes state assy.Name typeGenerics methodGenerics ty
|
||||||
|
|
||||||
// Now get the zero value
|
// Now get the zero value
|
||||||
let zero, state = cliTypeZeroOfHandle state baseClassTypes handle
|
let zero, state = cliTypeZeroOfHandle state baseClassTypes handle
|
||||||
@@ -759,22 +802,7 @@ module IlMachineState =
|
|||||||
let concretizedMethod, newConcreteTypes, newAssemblies =
|
let concretizedMethod, newConcreteTypes, newAssemblies =
|
||||||
Concretization.concretizeMethod
|
Concretization.concretizeMethod
|
||||||
state.ConcreteTypes
|
state.ConcreteTypes
|
||||||
(fun assyName ref ->
|
(loader loggerFactory state)
|
||||||
match state.LoadedAssembly assyName with
|
|
||||||
| Some currentAssy ->
|
|
||||||
let targetAssyRef = currentAssy.AssemblyReferences.[ref]
|
|
||||||
|
|
||||||
match state.LoadedAssembly targetAssyRef.Name with
|
|
||||||
| Some _ ->
|
|
||||||
// Assembly already loaded, return existing state
|
|
||||||
state._LoadedAssemblies, state._LoadedAssemblies.[targetAssyRef.Name.FullName]
|
|
||||||
| None ->
|
|
||||||
// Need to load the assembly
|
|
||||||
let newState, loadedAssy, _ = loadAssembly loggerFactory currentAssy ref state
|
|
||||||
newState._LoadedAssemblies, loadedAssy
|
|
||||||
| None ->
|
|
||||||
failwithf "Current assembly %s not loaded when trying to resolve reference" assyName.FullName
|
|
||||||
)
|
|
||||||
state._LoadedAssemblies
|
state._LoadedAssemblies
|
||||||
baseClassTypes
|
baseClassTypes
|
||||||
methodToCall
|
methodToCall
|
||||||
@@ -820,6 +848,7 @@ module IlMachineState =
|
|||||||
for i = 0 to generics.Length - 1 do
|
for i = 0 to generics.Length - 1 do
|
||||||
let state2, handle =
|
let state2, handle =
|
||||||
concretizeType
|
concretizeType
|
||||||
|
loggerFactory
|
||||||
baseClassTypes
|
baseClassTypes
|
||||||
state
|
state
|
||||||
callingAssembly
|
callingAssembly
|
||||||
@@ -875,14 +904,7 @@ module IlMachineState =
|
|||||||
let handle, newCtx =
|
let handle, newCtx =
|
||||||
TypeConcretization.concretizeType
|
TypeConcretization.concretizeType
|
||||||
ctx
|
ctx
|
||||||
(fun assyName ref ->
|
(loader loggerFactory state)
|
||||||
let currentAssy = state.LoadedAssembly assyName |> Option.get
|
|
||||||
|
|
||||||
let targetAssy =
|
|
||||||
currentAssy.AssemblyReferences.[ref].Name |> state.LoadedAssembly |> Option.get
|
|
||||||
|
|
||||||
state._LoadedAssemblies, targetAssy
|
|
||||||
)
|
|
||||||
(state.ActiveAssembly thread).Name
|
(state.ActiveAssembly thread).Name
|
||||||
ImmutableArray.Empty // No type generics for the concretization context
|
ImmutableArray.Empty // No type generics for the concretization context
|
||||||
ImmutableArray.Empty // No method generics for the concretization context
|
ImmutableArray.Empty // No method generics for the concretization context
|
||||||
@@ -893,6 +915,7 @@ module IlMachineState =
|
|||||||
state <-
|
state <-
|
||||||
{ state with
|
{ state with
|
||||||
ConcreteTypes = newCtx.ConcreteTypes
|
ConcreteTypes = newCtx.ConcreteTypes
|
||||||
|
_LoadedAssemblies = newCtx.LoadedAssemblies
|
||||||
}
|
}
|
||||||
|
|
||||||
handles.ToImmutable (), state
|
handles.ToImmutable (), state
|
||||||
@@ -997,14 +1020,7 @@ module IlMachineState =
|
|||||||
let declaringHandle, newCtx =
|
let declaringHandle, newCtx =
|
||||||
TypeConcretization.concretizeType
|
TypeConcretization.concretizeType
|
||||||
ctx
|
ctx
|
||||||
(fun assyName ref ->
|
(loader loggerFactory state)
|
||||||
let currentAssy = state.LoadedAssembly assyName |> Option.get
|
|
||||||
|
|
||||||
let targetAssy =
|
|
||||||
currentAssy.AssemblyReferences.[ref].Name |> state.LoadedAssembly |> Option.get
|
|
||||||
|
|
||||||
state._LoadedAssemblies, targetAssy
|
|
||||||
)
|
|
||||||
field.DeclaringType.Assembly
|
field.DeclaringType.Assembly
|
||||||
contextTypeGenerics
|
contextTypeGenerics
|
||||||
contextMethodGenerics
|
contextMethodGenerics
|
||||||
@@ -1190,6 +1206,7 @@ module IlMachineState =
|
|||||||
(baseClassTypes : BaseClassTypes<DumpedAssembly>)
|
(baseClassTypes : BaseClassTypes<DumpedAssembly>)
|
||||||
(currentThread : ThreadId)
|
(currentThread : ThreadId)
|
||||||
(assy : DumpedAssembly)
|
(assy : DumpedAssembly)
|
||||||
|
(genericMethodTypeArgs : ImmutableArray<ConcreteTypeHandle>)
|
||||||
(m : MemberReferenceHandle)
|
(m : MemberReferenceHandle)
|
||||||
(state : IlMachineState)
|
(state : IlMachineState)
|
||||||
: IlMachineState *
|
: IlMachineState *
|
||||||
@@ -1253,6 +1270,7 @@ module IlMachineState =
|
|||||||
// TODO: generics?
|
// TODO: generics?
|
||||||
let state, t =
|
let state, t =
|
||||||
concretizeType
|
concretizeType
|
||||||
|
loggerFactory
|
||||||
baseClassTypes
|
baseClassTypes
|
||||||
state
|
state
|
||||||
targetType.Assembly
|
targetType.Assembly
|
||||||
@@ -1270,6 +1288,7 @@ module IlMachineState =
|
|||||||
// Concretize the field signature from the member reference
|
// Concretize the field signature from the member reference
|
||||||
let state, concreteFieldSig =
|
let state, concreteFieldSig =
|
||||||
concretizeType
|
concretizeType
|
||||||
|
loggerFactory
|
||||||
baseClassTypes
|
baseClassTypes
|
||||||
state
|
state
|
||||||
(state.ActiveAssembly(currentThread).Name)
|
(state.ActiveAssembly(currentThread).Name)
|
||||||
@@ -1287,6 +1306,7 @@ module IlMachineState =
|
|||||||
// Concretize the field's signature for comparison
|
// Concretize the field's signature for comparison
|
||||||
let state, fieldSigConcrete =
|
let state, fieldSigConcrete =
|
||||||
concretizeType
|
concretizeType
|
||||||
|
loggerFactory
|
||||||
baseClassTypes
|
baseClassTypes
|
||||||
state
|
state
|
||||||
assy.Name
|
assy.Name
|
||||||
@@ -1324,11 +1344,12 @@ module IlMachineState =
|
|||||||
state
|
state
|
||||||
(fun state ty ->
|
(fun state ty ->
|
||||||
concretizeType
|
concretizeType
|
||||||
|
loggerFactory
|
||||||
baseClassTypes
|
baseClassTypes
|
||||||
state
|
state
|
||||||
(state.ActiveAssembly(currentThread).Name)
|
(state.ActiveAssembly(currentThread).Name)
|
||||||
concreteExtractedTypeArgs
|
concreteExtractedTypeArgs
|
||||||
ImmutableArray.Empty
|
genericMethodTypeArgs
|
||||||
ty
|
ty
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1341,11 +1362,12 @@ module IlMachineState =
|
|||||||
state
|
state
|
||||||
(fun state ty ->
|
(fun state ty ->
|
||||||
concretizeType
|
concretizeType
|
||||||
|
loggerFactory
|
||||||
baseClassTypes
|
baseClassTypes
|
||||||
state
|
state
|
||||||
assy.Name
|
assy.Name
|
||||||
concreteExtractedTypeArgs
|
concreteExtractedTypeArgs
|
||||||
ImmutableArray.Empty
|
genericMethodTypeArgs
|
||||||
ty
|
ty
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1507,6 +1529,7 @@ module IlMachineState =
|
|||||||
|
|
||||||
/// Returns the type handle and an allocated System.RuntimeType.
|
/// Returns the type handle and an allocated System.RuntimeType.
|
||||||
let getOrAllocateType
|
let getOrAllocateType
|
||||||
|
(loggerFactory : ILoggerFactory)
|
||||||
(baseClassTypes : BaseClassTypes<DumpedAssembly>)
|
(baseClassTypes : BaseClassTypes<DumpedAssembly>)
|
||||||
(defn : ConcreteTypeHandle)
|
(defn : ConcreteTypeHandle)
|
||||||
(state : IlMachineState)
|
(state : IlMachineState)
|
||||||
@@ -1518,7 +1541,13 @@ module IlMachineState =
|
|||||||
baseClassTypes.Corelib.Name.FullName,
|
baseClassTypes.Corelib.Name.FullName,
|
||||||
SignatureTypeKind.Class
|
SignatureTypeKind.Class
|
||||||
)
|
)
|
||||||
|> concretizeType baseClassTypes state baseClassTypes.Corelib.Name ImmutableArray.Empty ImmutableArray.Empty
|
|> concretizeType
|
||||||
|
loggerFactory
|
||||||
|
baseClassTypes
|
||||||
|
state
|
||||||
|
baseClassTypes.Corelib.Name
|
||||||
|
ImmutableArray.Empty
|
||||||
|
ImmutableArray.Empty
|
||||||
|
|
||||||
let result, reg, state =
|
let result, reg, state =
|
||||||
TypeHandleRegistry.getOrAllocate
|
TypeHandleRegistry.getOrAllocate
|
||||||
@@ -1562,7 +1591,13 @@ module IlMachineState =
|
|||||||
baseClassTypes.Corelib.Name.FullName,
|
baseClassTypes.Corelib.Name.FullName,
|
||||||
SignatureTypeKind.Class
|
SignatureTypeKind.Class
|
||||||
)
|
)
|
||||||
|> concretizeType baseClassTypes state baseClassTypes.Corelib.Name ImmutableArray.Empty ImmutableArray.Empty
|
|> concretizeType
|
||||||
|
loggerFactory
|
||||||
|
baseClassTypes
|
||||||
|
state
|
||||||
|
baseClassTypes.Corelib.Name
|
||||||
|
ImmutableArray.Empty
|
||||||
|
ImmutableArray.Empty
|
||||||
|
|
||||||
let result, reg, state =
|
let result, reg, state =
|
||||||
FieldHandleRegistry.getOrAllocate
|
FieldHandleRegistry.getOrAllocate
|
||||||
|
@@ -10,6 +10,7 @@ open Microsoft.Extensions.Logging
|
|||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
module IlMachineStateExecution =
|
module IlMachineStateExecution =
|
||||||
let getTypeOfObj
|
let getTypeOfObj
|
||||||
|
(loggerFactory : ILoggerFactory)
|
||||||
(baseClassTypes : BaseClassTypes<DumpedAssembly>)
|
(baseClassTypes : BaseClassTypes<DumpedAssembly>)
|
||||||
(state : IlMachineState)
|
(state : IlMachineState)
|
||||||
(esv : EvalStackValue)
|
(esv : EvalStackValue)
|
||||||
@@ -19,6 +20,7 @@ module IlMachineStateExecution =
|
|||||||
| EvalStackValue.Int32 _ ->
|
| EvalStackValue.Int32 _ ->
|
||||||
DumpedAssembly.typeInfoToTypeDefn' baseClassTypes state._LoadedAssemblies baseClassTypes.Int32
|
DumpedAssembly.typeInfoToTypeDefn' baseClassTypes state._LoadedAssemblies baseClassTypes.Int32
|
||||||
|> IlMachineState.concretizeType
|
|> IlMachineState.concretizeType
|
||||||
|
loggerFactory
|
||||||
baseClassTypes
|
baseClassTypes
|
||||||
state
|
state
|
||||||
baseClassTypes.Corelib.Name
|
baseClassTypes.Corelib.Name
|
||||||
@@ -27,6 +29,7 @@ module IlMachineStateExecution =
|
|||||||
| EvalStackValue.Int64 _ ->
|
| EvalStackValue.Int64 _ ->
|
||||||
DumpedAssembly.typeInfoToTypeDefn' baseClassTypes state._LoadedAssemblies baseClassTypes.Int64
|
DumpedAssembly.typeInfoToTypeDefn' baseClassTypes state._LoadedAssemblies baseClassTypes.Int64
|
||||||
|> IlMachineState.concretizeType
|
|> IlMachineState.concretizeType
|
||||||
|
loggerFactory
|
||||||
baseClassTypes
|
baseClassTypes
|
||||||
state
|
state
|
||||||
baseClassTypes.Corelib.Name
|
baseClassTypes.Corelib.Name
|
||||||
@@ -36,6 +39,7 @@ module IlMachineStateExecution =
|
|||||||
| EvalStackValue.Float _ ->
|
| EvalStackValue.Float _ ->
|
||||||
DumpedAssembly.typeInfoToTypeDefn' baseClassTypes state._LoadedAssemblies baseClassTypes.Double
|
DumpedAssembly.typeInfoToTypeDefn' baseClassTypes state._LoadedAssemblies baseClassTypes.Double
|
||||||
|> IlMachineState.concretizeType
|
|> IlMachineState.concretizeType
|
||||||
|
loggerFactory
|
||||||
baseClassTypes
|
baseClassTypes
|
||||||
state
|
state
|
||||||
baseClassTypes.Corelib.Name
|
baseClassTypes.Corelib.Name
|
||||||
@@ -156,7 +160,8 @@ module IlMachineStateExecution =
|
|||||||
| None -> failwith "unexpectedly no `this` on the eval stack of instance method"
|
| None -> failwith "unexpectedly no `this` on the eval stack of instance method"
|
||||||
| Some this -> this
|
| Some this -> this
|
||||||
|
|
||||||
let state, callingObjTyHandle = getTypeOfObj baseClassTypes state callingObj
|
let state, callingObjTyHandle =
|
||||||
|
getTypeOfObj loggerFactory baseClassTypes state callingObj
|
||||||
|
|
||||||
let callingObjTy =
|
let callingObjTy =
|
||||||
let ty =
|
let ty =
|
||||||
@@ -200,6 +205,7 @@ module IlMachineStateExecution =
|
|||||||
let state, retType =
|
let state, retType =
|
||||||
meth.Signature.ReturnType
|
meth.Signature.ReturnType
|
||||||
|> IlMachineState.concretizeType
|
|> IlMachineState.concretizeType
|
||||||
|
loggerFactory
|
||||||
baseClassTypes
|
baseClassTypes
|
||||||
state
|
state
|
||||||
meth.DeclaringType.Assembly
|
meth.DeclaringType.Assembly
|
||||||
@@ -211,6 +217,7 @@ module IlMachineStateExecution =
|
|||||||
||> Seq.mapFold (fun state ty ->
|
||> Seq.mapFold (fun state ty ->
|
||||||
ty
|
ty
|
||||||
|> IlMachineState.concretizeType
|
|> IlMachineState.concretizeType
|
||||||
|
loggerFactory
|
||||||
baseClassTypes
|
baseClassTypes
|
||||||
state
|
state
|
||||||
meth.DeclaringType.Assembly
|
meth.DeclaringType.Assembly
|
||||||
@@ -573,6 +580,7 @@ module IlMachineStateExecution =
|
|||||||
// Concretize the base type
|
// Concretize the base type
|
||||||
let state, baseTypeHandle =
|
let state, baseTypeHandle =
|
||||||
IlMachineState.concretizeType
|
IlMachineState.concretizeType
|
||||||
|
loggerFactory
|
||||||
baseClassTypes
|
baseClassTypes
|
||||||
state
|
state
|
||||||
sourceAssembly.Name
|
sourceAssembly.Name
|
||||||
@@ -612,6 +620,7 @@ module IlMachineStateExecution =
|
|||||||
// Concretize the base type
|
// Concretize the base type
|
||||||
let state, baseTypeHandle =
|
let state, baseTypeHandle =
|
||||||
IlMachineState.concretizeType
|
IlMachineState.concretizeType
|
||||||
|
loggerFactory
|
||||||
baseClassTypes
|
baseClassTypes
|
||||||
state
|
state
|
||||||
sourceAssembly.Name
|
sourceAssembly.Name
|
||||||
@@ -663,6 +672,7 @@ module IlMachineStateExecution =
|
|||||||
state
|
state
|
||||||
(fun state typeDefn ->
|
(fun state typeDefn ->
|
||||||
IlMachineState.concretizeType
|
IlMachineState.concretizeType
|
||||||
|
loggerFactory
|
||||||
baseClassTypes
|
baseClassTypes
|
||||||
state
|
state
|
||||||
concreteType.Assembly
|
concreteType.Assembly
|
||||||
@@ -687,6 +697,7 @@ module IlMachineStateExecution =
|
|||||||
||> Seq.fold (fun (state, acc) typeDefn ->
|
||> Seq.fold (fun (state, acc) typeDefn ->
|
||||||
let state, handle =
|
let state, handle =
|
||||||
IlMachineState.concretizeType
|
IlMachineState.concretizeType
|
||||||
|
loggerFactory
|
||||||
baseClassTypes
|
baseClassTypes
|
||||||
state
|
state
|
||||||
concreteType.Assembly
|
concreteType.Assembly
|
||||||
|
@@ -14,6 +14,10 @@ module Intrinsics =
|
|||||||
"System.Private.CoreLib", "ArgumentNullException", "ThrowIfNull"
|
"System.Private.CoreLib", "ArgumentNullException", "ThrowIfNull"
|
||||||
// https://github.com/dotnet/runtime/blob/ec11903827fc28847d775ba17e0cd1ff56cfbc2e/src/coreclr/System.Private.CoreLib/src/System/Type.CoreCLR.cs#L82
|
// https://github.com/dotnet/runtime/blob/ec11903827fc28847d775ba17e0cd1ff56cfbc2e/src/coreclr/System.Private.CoreLib/src/System/Type.CoreCLR.cs#L82
|
||||||
"System.Private.CoreLib", "Type", "GetTypeFromHandle"
|
"System.Private.CoreLib", "Type", "GetTypeFromHandle"
|
||||||
|
// https://github.com/dotnet/runtime/blob/108fa7856efcfd39bc991c2d849eabbf7ba5989c/src/libraries/System.Private.CoreLib/src/System/ReadOnlySpan.cs#L161
|
||||||
|
"System.Private.CoreLib", "ReadOnlySpan`1", "get_Length"
|
||||||
|
// https://github.com/dotnet/runtime/blob/9e5e6aa7bc36aeb2a154709a9d1192030c30a2ef/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs#L153
|
||||||
|
"System.Private.CoreLib", "RuntimeHelpers", "CreateSpan"
|
||||||
]
|
]
|
||||||
|> Set.ofList
|
|> Set.ofList
|
||||||
|
|
||||||
@@ -299,15 +303,47 @@ module Intrinsics =
|
|||||||
| [], ConcreteBool state.ConcreteTypes -> ()
|
| [], ConcreteBool state.ConcreteTypes -> ()
|
||||||
| _ -> failwith "bad signature for System.Private.CoreLib.RuntimeHelpers.IsReferenceOrContainsReference"
|
| _ -> failwith "bad signature for System.Private.CoreLib.RuntimeHelpers.IsReferenceOrContainsReference"
|
||||||
|
|
||||||
let generic =
|
let arg = Seq.exactlyOne methodToCall.Generics
|
||||||
AllConcreteTypes.lookup (Seq.exactlyOne methodToCall.Generics) state.ConcreteTypes
|
|
||||||
|
|
||||||
let generic =
|
let result =
|
||||||
match generic with
|
// Some types appear circular, because they're hardcoded in the runtime. We have to special-case them.
|
||||||
| None -> failwith "somehow have not already concretised type in IsReferenceOrContainsReferences"
|
match arg with
|
||||||
| Some generic -> generic
|
| 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" ->
|
| "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
|
// https://github.com/dotnet/runtime/blob/9e5e6aa7bc36aeb2a154709a9d1192030c30a2ef/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs#L18
|
||||||
match methodToCall.Signature.ParameterTypes, methodToCall.Signature.ReturnType with
|
match methodToCall.Signature.ParameterTypes, methodToCall.Signature.ReturnType with
|
||||||
@@ -319,6 +355,57 @@ module Intrinsics =
|
|||||||
failwith "TODO: if arg1 contains null handle, throw ArgumentException"
|
failwith "TODO: if arg1 contains null handle, throw ArgumentException"
|
||||||
|
|
||||||
failwith "TODO: array initialization"
|
failwith "TODO: array initialization"
|
||||||
|
| "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 from, to_ =
|
||||||
|
match Seq.toList methodToCall.Generics with
|
||||||
|
| [ from ; to_ ] -> from, to_
|
||||||
|
| _ -> failwith "bad generics"
|
||||||
|
|
||||||
|
if ConcreteTypeHandle.Byref to_ <> retType then
|
||||||
|
failwith "bad return type"
|
||||||
|
|
||||||
|
if ConcreteTypeHandle.Byref from <> inputType then
|
||||||
|
failwith "bad input type"
|
||||||
|
|
||||||
|
let from =
|
||||||
|
match AllConcreteTypes.lookup from state.ConcreteTypes with
|
||||||
|
| None -> failwith "somehow have not concretised input type"
|
||||||
|
| Some t -> t
|
||||||
|
|
||||||
|
let to_ =
|
||||||
|
match AllConcreteTypes.lookup to_ state.ConcreteTypes with
|
||||||
|
| None -> failwith "somehow have not concretised ret type"
|
||||||
|
| Some t -> t
|
||||||
|
|
||||||
|
failwith "TODO: transmute fields etc"
|
||||||
|
let state = state |> IlMachineState.advanceProgramCounter currentThread
|
||||||
|
|
||||||
|
Some state
|
||||||
|
| "System.Private.CoreLib", "Unsafe", "SizeOf" ->
|
||||||
|
// https://github.com/dotnet/runtime/blob/721fdf6dcb032da1f883d30884e222e35e3d3c99/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/Unsafe.cs#L51
|
||||||
|
match methodToCall.Signature.ParameterTypes, methodToCall.Signature.ReturnType with
|
||||||
|
| [], ConcreteInt32 state.ConcreteTypes -> ()
|
||||||
|
| _ -> failwith "bad signature Unsafe.SizeOf"
|
||||||
|
|
||||||
|
let ty =
|
||||||
|
match Seq.toList methodToCall.Generics with
|
||||||
|
| [ ty ] -> ty
|
||||||
|
| _ -> failwith "bad generics"
|
||||||
|
|
||||||
|
let zero, state = IlMachineState.cliTypeZeroOfHandle state baseClassTypes ty
|
||||||
|
|
||||||
|
let size = CliType.sizeOf zero
|
||||||
|
|
||||||
|
state
|
||||||
|
|> IlMachineState.pushToEvalStack (CliType.Numeric (CliNumericType.Int32 size)) currentThread
|
||||||
|
|> IlMachineState.advanceProgramCounter currentThread
|
||||||
|
|> Some
|
||||||
| "System.Private.CoreLib", "RuntimeHelpers", "CreateSpan" ->
|
| "System.Private.CoreLib", "RuntimeHelpers", "CreateSpan" ->
|
||||||
// https://github.com/dotnet/runtime/blob/9e5e6aa7bc36aeb2a154709a9d1192030c30a2ef/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs#L153
|
// https://github.com/dotnet/runtime/blob/9e5e6aa7bc36aeb2a154709a9d1192030c30a2ef/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs#L153
|
||||||
None
|
None
|
||||||
|
@@ -52,7 +52,7 @@ module NullaryIlOp =
|
|||||||
| EvalStackValue.NativeInt nativeIntSource ->
|
| EvalStackValue.NativeInt nativeIntSource ->
|
||||||
failwith $"TODO: Native int pointer dereferencing not implemented for {targetType}"
|
failwith $"TODO: Native int pointer dereferencing not implemented for {targetType}"
|
||||||
| EvalStackValue.ObjectRef managedHeapAddress ->
|
| EvalStackValue.ObjectRef managedHeapAddress ->
|
||||||
failwith "TODO: Object reference dereferencing not implemented"
|
IlMachineState.dereferencePointer state (ManagedPointerSource.Heap managedHeapAddress)
|
||||||
| other -> failwith $"Unexpected eval stack value for Ldind operation: {other}"
|
| other -> failwith $"Unexpected eval stack value for Ldind operation: {other}"
|
||||||
|
|
||||||
let loadedValue = loadedValue |> EvalStackValue.ofCliType
|
let loadedValue = loadedValue |> EvalStackValue.ofCliType
|
||||||
|
@@ -10,6 +10,7 @@ open Microsoft.Extensions.Logging
|
|||||||
module Program =
|
module Program =
|
||||||
/// Returns the pointer to the resulting array on the heap.
|
/// Returns the pointer to the resulting array on the heap.
|
||||||
let allocateArgs
|
let allocateArgs
|
||||||
|
(loggerFactory : ILoggerFactory)
|
||||||
(args : string list)
|
(args : string list)
|
||||||
(corelib : BaseClassTypes<DumpedAssembly>)
|
(corelib : BaseClassTypes<DumpedAssembly>)
|
||||||
(state : IlMachineState)
|
(state : IlMachineState)
|
||||||
@@ -18,6 +19,7 @@ module Program =
|
|||||||
let state, stringType =
|
let state, stringType =
|
||||||
DumpedAssembly.typeInfoToTypeDefn' corelib state._LoadedAssemblies corelib.String
|
DumpedAssembly.typeInfoToTypeDefn' corelib state._LoadedAssemblies corelib.String
|
||||||
|> IlMachineState.concretizeType
|
|> IlMachineState.concretizeType
|
||||||
|
loggerFactory
|
||||||
corelib
|
corelib
|
||||||
state
|
state
|
||||||
corelib.Corelib.Name
|
corelib.Corelib.Name
|
||||||
@@ -285,7 +287,7 @@ module Program =
|
|||||||
let arrayAllocation, state =
|
let arrayAllocation, state =
|
||||||
match mainMethodFromMetadata.Signature.ParameterTypes |> Seq.toList with
|
match mainMethodFromMetadata.Signature.ParameterTypes |> Seq.toList with
|
||||||
| [ TypeDefn.OneDimensionalArrayLowerBoundZero (TypeDefn.PrimitiveType PrimitiveType.String) ] ->
|
| [ TypeDefn.OneDimensionalArrayLowerBoundZero (TypeDefn.PrimitiveType PrimitiveType.String) ] ->
|
||||||
allocateArgs argv baseClassTypes state
|
allocateArgs loggerFactory argv baseClassTypes state
|
||||||
| _ -> failwith "Main method must take an array of strings; other signatures not yet implemented"
|
| _ -> failwith "Main method must take an array of strings; other signatures not yet implemented"
|
||||||
|
|
||||||
match mainMethodFromMetadata.Signature.ReturnType with
|
match mainMethodFromMetadata.Signature.ReturnType with
|
||||||
|
@@ -28,6 +28,24 @@ module internal UnaryMetadataIlOp =
|
|||||||
| MetadataToken.MethodSpecification h ->
|
| MetadataToken.MethodSpecification h ->
|
||||||
let spec = activeAssy.MethodSpecs.[h]
|
let spec = activeAssy.MethodSpecs.[h]
|
||||||
|
|
||||||
|
let state, methodGenerics =
|
||||||
|
((state, []), spec.Signature)
|
||||||
|
||> Seq.fold (fun (state, acc) typeDefn ->
|
||||||
|
let state, concreteType =
|
||||||
|
IlMachineState.concretizeType
|
||||||
|
loggerFactory
|
||||||
|
baseClassTypes
|
||||||
|
state
|
||||||
|
(state.ActiveAssembly thread).Name
|
||||||
|
currentMethod.DeclaringType.Generics
|
||||||
|
currentMethod.Generics
|
||||||
|
typeDefn
|
||||||
|
|
||||||
|
state, concreteType :: acc
|
||||||
|
)
|
||||||
|
|
||||||
|
let methodGenerics = List.rev methodGenerics |> ImmutableArray.CreateRange
|
||||||
|
|
||||||
match spec.Method with
|
match spec.Method with
|
||||||
| MetadataToken.MethodDef token ->
|
| MetadataToken.MethodDef token ->
|
||||||
let method =
|
let method =
|
||||||
@@ -44,6 +62,7 @@ module internal UnaryMetadataIlOp =
|
|||||||
baseClassTypes
|
baseClassTypes
|
||||||
thread
|
thread
|
||||||
(state.ActiveAssembly thread)
|
(state.ActiveAssembly thread)
|
||||||
|
methodGenerics
|
||||||
ref
|
ref
|
||||||
state
|
state
|
||||||
|
|
||||||
@@ -58,6 +77,7 @@ module internal UnaryMetadataIlOp =
|
|||||||
baseClassTypes
|
baseClassTypes
|
||||||
thread
|
thread
|
||||||
(state.ActiveAssembly thread)
|
(state.ActiveAssembly thread)
|
||||||
|
currentMethod.DeclaringType.Generics
|
||||||
h
|
h
|
||||||
state
|
state
|
||||||
|
|
||||||
@@ -114,6 +134,24 @@ module internal UnaryMetadataIlOp =
|
|||||||
| MetadataToken.MethodSpecification h ->
|
| MetadataToken.MethodSpecification h ->
|
||||||
let spec = activeAssy.MethodSpecs.[h]
|
let spec = activeAssy.MethodSpecs.[h]
|
||||||
|
|
||||||
|
let state, methodGenerics =
|
||||||
|
((state, []), spec.Signature)
|
||||||
|
||> Seq.fold (fun (state, acc) typeDefn ->
|
||||||
|
let state, concreteType =
|
||||||
|
IlMachineState.concretizeType
|
||||||
|
loggerFactory
|
||||||
|
baseClassTypes
|
||||||
|
state
|
||||||
|
(state.ActiveAssembly thread).Name
|
||||||
|
currentMethod.DeclaringType.Generics
|
||||||
|
ImmutableArray.Empty
|
||||||
|
typeDefn
|
||||||
|
|
||||||
|
state, concreteType :: acc
|
||||||
|
)
|
||||||
|
|
||||||
|
let methodGenerics = List.rev methodGenerics |> ImmutableArray.CreateRange
|
||||||
|
|
||||||
match spec.Method with
|
match spec.Method with
|
||||||
| MetadataToken.MethodDef token ->
|
| MetadataToken.MethodDef token ->
|
||||||
let method =
|
let method =
|
||||||
@@ -128,6 +166,7 @@ module internal UnaryMetadataIlOp =
|
|||||||
baseClassTypes
|
baseClassTypes
|
||||||
thread
|
thread
|
||||||
(state.ActiveAssembly thread)
|
(state.ActiveAssembly thread)
|
||||||
|
methodGenerics
|
||||||
ref
|
ref
|
||||||
state
|
state
|
||||||
|
|
||||||
@@ -142,6 +181,7 @@ module internal UnaryMetadataIlOp =
|
|||||||
baseClassTypes
|
baseClassTypes
|
||||||
thread
|
thread
|
||||||
(state.ActiveAssembly thread)
|
(state.ActiveAssembly thread)
|
||||||
|
ImmutableArray.Empty
|
||||||
h
|
h
|
||||||
state
|
state
|
||||||
|
|
||||||
@@ -203,6 +243,7 @@ module internal UnaryMetadataIlOp =
|
|||||||
baseClassTypes
|
baseClassTypes
|
||||||
thread
|
thread
|
||||||
(state.ActiveAssembly thread)
|
(state.ActiveAssembly thread)
|
||||||
|
ImmutableArray.Empty
|
||||||
mr
|
mr
|
||||||
state
|
state
|
||||||
|
|
||||||
@@ -436,6 +477,7 @@ module internal UnaryMetadataIlOp =
|
|||||||
|
|
||||||
let state, targetConcreteType =
|
let state, targetConcreteType =
|
||||||
IlMachineState.concretizeType
|
IlMachineState.concretizeType
|
||||||
|
loggerFactory
|
||||||
baseClassTypes
|
baseClassTypes
|
||||||
state
|
state
|
||||||
activeAssy.Name
|
activeAssy.Name
|
||||||
@@ -481,7 +523,14 @@ module internal UnaryMetadataIlOp =
|
|||||||
state, field
|
state, field
|
||||||
| MetadataToken.MemberReference mr ->
|
| MetadataToken.MemberReference mr ->
|
||||||
let state, _, field, _ =
|
let state, _, field, _ =
|
||||||
IlMachineState.resolveMember loggerFactory baseClassTypes thread activeAssy mr state
|
IlMachineState.resolveMember
|
||||||
|
loggerFactory
|
||||||
|
baseClassTypes
|
||||||
|
thread
|
||||||
|
activeAssy
|
||||||
|
ImmutableArray.Empty
|
||||||
|
mr
|
||||||
|
state
|
||||||
|
|
||||||
match field with
|
match field with
|
||||||
| Choice1Of2 _method -> failwith "member reference was unexpectedly a method"
|
| Choice1Of2 _method -> failwith "member reference was unexpectedly a method"
|
||||||
@@ -498,6 +547,7 @@ module internal UnaryMetadataIlOp =
|
|||||||
)
|
)
|
||||||
|
|
||||||
let valueToStore, state = IlMachineState.popEvalStack thread state
|
let valueToStore, state = IlMachineState.popEvalStack thread state
|
||||||
|
let currentObj, state = IlMachineState.popEvalStack thread state
|
||||||
|
|
||||||
let state, declaringTypeHandle, typeGenerics =
|
let state, declaringTypeHandle, typeGenerics =
|
||||||
IlMachineState.concretizeFieldForExecution loggerFactory baseClassTypes thread field state
|
IlMachineState.concretizeFieldForExecution loggerFactory baseClassTypes thread field state
|
||||||
@@ -514,8 +564,6 @@ module internal UnaryMetadataIlOp =
|
|||||||
|
|
||||||
let valueToStore = EvalStackValue.toCliTypeCoerced zero valueToStore
|
let valueToStore = EvalStackValue.toCliTypeCoerced zero valueToStore
|
||||||
|
|
||||||
let currentObj, state = IlMachineState.popEvalStack thread state
|
|
||||||
|
|
||||||
if field.Attributes.HasFlag FieldAttributes.Static then
|
if field.Attributes.HasFlag FieldAttributes.Static then
|
||||||
let state =
|
let state =
|
||||||
IlMachineState.setStatic declaringTypeHandle field.Name valueToStore state
|
IlMachineState.setStatic declaringTypeHandle field.Name valueToStore state
|
||||||
@@ -601,6 +649,7 @@ module internal UnaryMetadataIlOp =
|
|||||||
baseClassTypes
|
baseClassTypes
|
||||||
thread
|
thread
|
||||||
(state.ActiveAssembly thread)
|
(state.ActiveAssembly thread)
|
||||||
|
ImmutableArray.Empty
|
||||||
mr
|
mr
|
||||||
state
|
state
|
||||||
|
|
||||||
@@ -660,7 +709,14 @@ module internal UnaryMetadataIlOp =
|
|||||||
state, field
|
state, field
|
||||||
| MetadataToken.MemberReference mr ->
|
| MetadataToken.MemberReference mr ->
|
||||||
let state, assyName, field, _ =
|
let state, assyName, field, _ =
|
||||||
IlMachineState.resolveMember loggerFactory baseClassTypes thread activeAssy mr state
|
IlMachineState.resolveMember
|
||||||
|
loggerFactory
|
||||||
|
baseClassTypes
|
||||||
|
thread
|
||||||
|
activeAssy
|
||||||
|
ImmutableArray.Empty
|
||||||
|
mr
|
||||||
|
state
|
||||||
|
|
||||||
match field with
|
match field with
|
||||||
| Choice1Of2 _method -> failwith "member reference was unexpectedly a method"
|
| Choice1Of2 _method -> failwith "member reference was unexpectedly a method"
|
||||||
@@ -750,6 +806,7 @@ module internal UnaryMetadataIlOp =
|
|||||||
IlMachineState.pushToEvalStack currentValue thread state
|
IlMachineState.pushToEvalStack currentValue thread state
|
||||||
| EvalStackValue.UserDefinedValueType vt ->
|
| EvalStackValue.UserDefinedValueType vt ->
|
||||||
let result = vt |> EvalStackValueUserType.DereferenceField field.Name
|
let result = vt |> EvalStackValueUserType.DereferenceField field.Name
|
||||||
|
|
||||||
IlMachineState.pushToEvalStack' result thread state
|
IlMachineState.pushToEvalStack' result thread state
|
||||||
|
|
||||||
state
|
state
|
||||||
@@ -779,7 +836,15 @@ module internal UnaryMetadataIlOp =
|
|||||||
state, field
|
state, field
|
||||||
| MetadataToken.MemberReference mr ->
|
| MetadataToken.MemberReference mr ->
|
||||||
let state, assyName, field, _ =
|
let state, assyName, field, _ =
|
||||||
IlMachineState.resolveMember loggerFactory baseClassTypes thread activeAssy mr state
|
// TODO: generics
|
||||||
|
IlMachineState.resolveMember
|
||||||
|
loggerFactory
|
||||||
|
baseClassTypes
|
||||||
|
thread
|
||||||
|
activeAssy
|
||||||
|
ImmutableArray.Empty
|
||||||
|
mr
|
||||||
|
state
|
||||||
|
|
||||||
match field with
|
match field with
|
||||||
| Choice1Of2 _method -> failwith "member reference was unexpectedly a method"
|
| Choice1Of2 _method -> failwith "member reference was unexpectedly a method"
|
||||||
@@ -793,6 +858,7 @@ module internal UnaryMetadataIlOp =
|
|||||||
|> IlMachineState.pushToEvalStack' result thread
|
|> IlMachineState.pushToEvalStack' result thread
|
||||||
|> IlMachineState.advanceProgramCounter thread
|
|> IlMachineState.advanceProgramCounter thread
|
||||||
|> Tuple.withRight WhatWeDid.Executed
|
|> Tuple.withRight WhatWeDid.Executed
|
||||||
|
|
||||||
| Ldsfld ->
|
| Ldsfld ->
|
||||||
let state, field =
|
let state, field =
|
||||||
match metadataToken with
|
match metadataToken with
|
||||||
@@ -807,7 +873,14 @@ module internal UnaryMetadataIlOp =
|
|||||||
state, field
|
state, field
|
||||||
| MetadataToken.MemberReference mr ->
|
| MetadataToken.MemberReference mr ->
|
||||||
let state, _, field, _ =
|
let state, _, field, _ =
|
||||||
IlMachineState.resolveMember loggerFactory baseClassTypes thread activeAssy mr state
|
IlMachineState.resolveMember
|
||||||
|
loggerFactory
|
||||||
|
baseClassTypes
|
||||||
|
thread
|
||||||
|
activeAssy
|
||||||
|
ImmutableArray.Empty
|
||||||
|
mr
|
||||||
|
state
|
||||||
|
|
||||||
match field with
|
match field with
|
||||||
| Choice1Of2 _method -> failwith "member reference was unexpectedly a method"
|
| Choice1Of2 _method -> failwith "member reference was unexpectedly a method"
|
||||||
@@ -983,6 +1056,7 @@ module internal UnaryMetadataIlOp =
|
|||||||
IlMachineState.pushToEvalStack toPush thread state
|
IlMachineState.pushToEvalStack toPush thread state
|
||||||
|> IlMachineState.advanceProgramCounter thread
|
|> IlMachineState.advanceProgramCounter thread
|
||||||
|> Tuple.withRight WhatWeDid.Executed
|
|> Tuple.withRight WhatWeDid.Executed
|
||||||
|
|
||||||
| Initobj ->
|
| Initobj ->
|
||||||
let popped, state = IlMachineState.popEvalStack thread state
|
let popped, state = IlMachineState.popEvalStack thread state
|
||||||
let declaringTypeGenerics = currentMethod.DeclaringType.Generics
|
let declaringTypeGenerics = currentMethod.DeclaringType.Generics
|
||||||
@@ -1046,6 +1120,7 @@ module internal UnaryMetadataIlOp =
|
|||||||
state
|
state
|
||||||
|> IlMachineState.advanceProgramCounter thread
|
|> IlMachineState.advanceProgramCounter thread
|
||||||
|> Tuple.withRight WhatWeDid.Executed
|
|> Tuple.withRight WhatWeDid.Executed
|
||||||
|
|
||||||
| Ldsflda ->
|
| Ldsflda ->
|
||||||
|
|
||||||
// TODO: check whether we should throw FieldAccessException
|
// TODO: check whether we should throw FieldAccessException
|
||||||
@@ -1142,6 +1217,42 @@ module internal UnaryMetadataIlOp =
|
|||||||
| Stobj -> failwith "TODO: Stobj unimplemented"
|
| Stobj -> failwith "TODO: Stobj unimplemented"
|
||||||
| Constrained -> failwith "TODO: Constrained unimplemented"
|
| Constrained -> failwith "TODO: Constrained unimplemented"
|
||||||
| Ldtoken ->
|
| Ldtoken ->
|
||||||
|
// Helper function to handle type tokens and create RuntimeTypeHandle
|
||||||
|
let handleTypeToken (typeDefn : TypeDefn) (state : IlMachineState) : IlMachineState =
|
||||||
|
let ty = baseClassTypes.RuntimeTypeHandle
|
||||||
|
let field = ty.Fields |> List.exactlyOne
|
||||||
|
|
||||||
|
if field.Name <> "m_type" then
|
||||||
|
failwith $"unexpected field name ${field.Name} for BCL type RuntimeTypeHandle"
|
||||||
|
|
||||||
|
let methodGenerics = currentMethod.Generics
|
||||||
|
let typeGenerics = currentMethod.DeclaringType.Generics
|
||||||
|
|
||||||
|
let state, handle =
|
||||||
|
IlMachineState.concretizeType
|
||||||
|
loggerFactory
|
||||||
|
baseClassTypes
|
||||||
|
state
|
||||||
|
activeAssy.Name
|
||||||
|
typeGenerics
|
||||||
|
methodGenerics
|
||||||
|
typeDefn
|
||||||
|
|
||||||
|
let alloc, state =
|
||||||
|
IlMachineState.getOrAllocateType loggerFactory baseClassTypes handle state
|
||||||
|
|
||||||
|
let vt =
|
||||||
|
// https://github.com/dotnet/runtime/blob/2b21c73fa2c32fa0195e4a411a435dda185efd08/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs#L92
|
||||||
|
{
|
||||||
|
Name = "m_type"
|
||||||
|
Contents = CliType.ObjectRef (Some alloc)
|
||||||
|
Offset = None
|
||||||
|
}
|
||||||
|
|> List.singleton
|
||||||
|
|> CliValueType.OfFields
|
||||||
|
|
||||||
|
IlMachineState.pushToEvalStack (CliType.ValueType vt) thread state
|
||||||
|
|
||||||
let state =
|
let state =
|
||||||
match metadataToken with
|
match metadataToken with
|
||||||
| MetadataToken.FieldDefinition h ->
|
| MetadataToken.FieldDefinition h ->
|
||||||
@@ -1179,6 +1290,7 @@ module internal UnaryMetadataIlOp =
|
|||||||
|
|
||||||
let state, handle =
|
let state, handle =
|
||||||
IlMachineState.concretizeType
|
IlMachineState.concretizeType
|
||||||
|
loggerFactory
|
||||||
baseClassTypes
|
baseClassTypes
|
||||||
state
|
state
|
||||||
assy.Name
|
assy.Name
|
||||||
@@ -1186,7 +1298,8 @@ module internal UnaryMetadataIlOp =
|
|||||||
methodGenerics
|
methodGenerics
|
||||||
typeDefn
|
typeDefn
|
||||||
|
|
||||||
let alloc, state = IlMachineState.getOrAllocateType baseClassTypes handle state
|
let alloc, state =
|
||||||
|
IlMachineState.getOrAllocateType loggerFactory baseClassTypes handle state
|
||||||
|
|
||||||
let vt =
|
let vt =
|
||||||
{
|
{
|
||||||
@@ -1214,6 +1327,7 @@ module internal UnaryMetadataIlOp =
|
|||||||
|
|
||||||
let state, handle =
|
let state, handle =
|
||||||
IlMachineState.concretizeType
|
IlMachineState.concretizeType
|
||||||
|
loggerFactory
|
||||||
baseClassTypes
|
baseClassTypes
|
||||||
state
|
state
|
||||||
assy.Name
|
assy.Name
|
||||||
@@ -1221,7 +1335,8 @@ module internal UnaryMetadataIlOp =
|
|||||||
methodGenerics
|
methodGenerics
|
||||||
typeDefn
|
typeDefn
|
||||||
|
|
||||||
let alloc, state = IlMachineState.getOrAllocateType baseClassTypes handle state
|
let alloc, state =
|
||||||
|
IlMachineState.getOrAllocateType loggerFactory baseClassTypes handle state
|
||||||
|
|
||||||
let vt =
|
let vt =
|
||||||
{
|
{
|
||||||
@@ -1234,40 +1349,10 @@ module internal UnaryMetadataIlOp =
|
|||||||
|
|
||||||
IlMachineState.pushToEvalStack (CliType.ValueType vt) thread state
|
IlMachineState.pushToEvalStack (CliType.ValueType vt) thread state
|
||||||
| MetadataToken.TypeDefinition h ->
|
| MetadataToken.TypeDefinition h ->
|
||||||
let ty = baseClassTypes.RuntimeTypeHandle
|
|
||||||
let field = ty.Fields |> List.exactlyOne
|
|
||||||
|
|
||||||
if field.Name <> "m_type" then
|
|
||||||
failwith $"unexpected field name ${field.Name} for BCL type RuntimeTypeHandle"
|
|
||||||
|
|
||||||
let methodGenerics = currentMethod.Generics
|
|
||||||
|
|
||||||
let typeGenerics = currentMethod.DeclaringType.Generics
|
|
||||||
|
|
||||||
let state, typeDefn =
|
let state, typeDefn =
|
||||||
IlMachineState.lookupTypeDefn baseClassTypes state activeAssy h
|
IlMachineState.lookupTypeDefn baseClassTypes state activeAssy h
|
||||||
|
|
||||||
let state, handle =
|
handleTypeToken typeDefn state
|
||||||
IlMachineState.concretizeType
|
|
||||||
baseClassTypes
|
|
||||||
state
|
|
||||||
activeAssy.Name
|
|
||||||
typeGenerics
|
|
||||||
methodGenerics
|
|
||||||
typeDefn
|
|
||||||
|
|
||||||
let alloc, state = IlMachineState.getOrAllocateType baseClassTypes handle state
|
|
||||||
|
|
||||||
let vt =
|
|
||||||
{
|
|
||||||
Name = "m_type"
|
|
||||||
Contents = CliType.ObjectRef (Some alloc)
|
|
||||||
Offset = None
|
|
||||||
}
|
|
||||||
|> List.singleton
|
|
||||||
|> CliValueType.OfFields
|
|
||||||
|
|
||||||
IlMachineState.pushToEvalStack (CliType.ValueType vt) thread state
|
|
||||||
| _ -> failwith $"Unexpected metadata token %O{metadataToken} in LdToken"
|
| _ -> failwith $"Unexpected metadata token %O{metadataToken} in LdToken"
|
||||||
|
|
||||||
state
|
state
|
||||||
@@ -1293,6 +1378,7 @@ module internal UnaryMetadataIlOp =
|
|||||||
|
|
||||||
let state, typeHandle =
|
let state, typeHandle =
|
||||||
IlMachineState.concretizeType
|
IlMachineState.concretizeType
|
||||||
|
loggerFactory
|
||||||
baseClassTypes
|
baseClassTypes
|
||||||
state
|
state
|
||||||
assy.Name
|
assy.Name
|
||||||
|
@@ -2,12 +2,13 @@ namespace WoofWare.PawPrint
|
|||||||
|
|
||||||
open System.Collections.Immutable
|
open System.Collections.Immutable
|
||||||
open System.Reflection
|
open System.Reflection
|
||||||
open System.Reflection.Metadata
|
open Microsoft.Extensions.Logging
|
||||||
|
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
|
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
|
||||||
module internal UnaryStringTokenIlOp =
|
module internal UnaryStringTokenIlOp =
|
||||||
let execute
|
let execute
|
||||||
|
(loggerFactory : ILoggerFactory)
|
||||||
(baseClassTypes : BaseClassTypes<DumpedAssembly>)
|
(baseClassTypes : BaseClassTypes<DumpedAssembly>)
|
||||||
(op : UnaryStringTokenIlOp)
|
(op : UnaryStringTokenIlOp)
|
||||||
(sh : StringToken)
|
(sh : StringToken)
|
||||||
@@ -66,6 +67,7 @@ module internal UnaryStringTokenIlOp =
|
|||||||
let state, stringType =
|
let state, stringType =
|
||||||
DumpedAssembly.typeInfoToTypeDefn' baseClassTypes state._LoadedAssemblies baseClassTypes.String
|
DumpedAssembly.typeInfoToTypeDefn' baseClassTypes state._LoadedAssemblies baseClassTypes.String
|
||||||
|> IlMachineState.concretizeType
|
|> IlMachineState.concretizeType
|
||||||
|
loggerFactory
|
||||||
baseClassTypes
|
baseClassTypes
|
||||||
state
|
state
|
||||||
baseClassTypes.Corelib.Name
|
baseClassTypes.Corelib.Name
|
||||||
|
Reference in New Issue
Block a user