35 Commits

Author SHA1 Message Date
Smaug123
a9b2598525 Progress 2025-08-24 23:47:05 +01:00
Smaug123
e05abbb724 Rejig assembly load 2025-08-24 23:20:14 +01:00
Smaug123
55677a507b Revert 2025-08-24 20:43:06 +01:00
Smaug123
3930cc5fbb More 2025-08-24 20:40:52 +01:00
Smaug123
735449d4df Revert 2025-08-24 20:40:32 +01:00
Smaug123
6c73f14a4e Merge branch 'main' into generic-edge-cases 2025-08-24 20:39:27 +01:00
Smaug123
5bd0f779c5 Merge branch 'main' into generic-edge-cases 2025-08-24 20:27:48 +01:00
Smaug123
4e8c852b56 Merge branch 'main' into generic-edge-cases 2025-08-24 20:27:39 +01:00
Smaug123
1b1b00b4dd Merge branch 'main' into generic-edge-cases 2025-08-24 10:54:23 +01:00
Smaug123
6e98652691 Revert 2025-08-24 10:07:21 +01:00
Smaug123
ec5f6ed752 Merge branch 'main' into generic-edge-cases 2025-08-24 10:06:32 +01:00
Smaug123
99e46b3756 more 2025-08-24 09:08:52 +01:00
Smaug123
35128afab4 Merge commit '9afc7efea128e46f9cd1a00adcce8e7e50aa7418' into generic-edge-cases 2025-08-24 09:06:52 +01:00
Smaug123
57b0e545c9 Merge commit '2190f148e13ed6aab310c2e867f178c7a551ec1e' into generic-edge-cases 2025-08-23 22:53:34 +01:00
Smaug123
f1db433711 Merge commit 'e2e3d5c3bf7c07fcbf89c0c69d04273aa20b0d2f' into generic-edge-cases 2025-08-23 22:53:30 +01:00
Smaug123
64339bf4ee Merge commit '92f22cff42e73c533f0d9c28e37991046a8008d7' into generic-edge-cases 2025-08-23 22:52:32 +01:00
Smaug123
2e8e6f3919 Merge commit '3bdfeaf8a1cb802ce4dce2cd12d6abd639edc75e' into generic-edge-cases 2025-08-23 22:51:41 +01:00
Smaug123
02ae05893b Merge commit '174e415c70843d905a6d40790cbdfdcf0f21cbdb' into generic-edge-cases 2025-08-23 22:51:31 +01:00
Smaug123
4b7e2ac1e6 Merge commit 'cfd67166162b7c28a6e044e5904cac53da2a194d' into generic-edge-cases 2025-08-23 22:50:11 +01:00
Smaug123
027a49c51a Merge commit 'd711d6fff5c59378a601a6366e01354cd2a43d88' into generic-edge-cases 2025-08-23 22:48:56 +01:00
Smaug123
f020d560a6 WIP 2025-08-18 23:08:15 +01:00
Smaug123
2e8245d341 WIP 2025-08-15 14:11:48 +01:00
Smaug123
fca9a6dc47 WIP 2025-08-14 08:31:32 +01:00
Smaug123
cc14fb0edd Start initobj 2025-08-12 08:39:25 +01:00
Smaug123
1dbd4b008b resolveTypeFromDefnConcrete 2025-08-12 08:15:38 +01:00
Smaug123
064deee8d5 WIP 2025-08-11 22:12:37 +01:00
Smaug123
407c37a5fb WIP 2025-08-11 21:21:12 +01:00
Smaug123
59fd8a23b7 WIP 2025-08-11 08:18:13 +01:00
Smaug123
bdedea098a Merge branch 'main' into generic-edge-cases 2025-08-10 23:29:28 +01:00
Smaug123
6f48c89ef3 More 2025-08-10 23:22:04 +01:00
Smaug123
07c5e931e4 Feature parity 2025-08-10 23:03:23 +01:00
Smaug123
e0e954b131 Remove another spare test 2025-08-10 22:52:45 +01:00
Smaug123
95f422efa9 Revert example 2025-08-10 22:50:44 +01:00
Smaug123
e89fac2780 Fix a couple of TODOs 2025-08-10 22:50:26 +01:00
Smaug123
9bafd0f4b0 WIP 2025-08-02 20:57:53 +01:00
11 changed files with 444 additions and 218 deletions

View File

@@ -331,6 +331,13 @@ module ConcreteActivePatterns =
| ConcreteTypeHandle.Pointer inner -> Some inner
| _ -> None
type IAssemblyLoad =
abstract LoadAssembly :
loadedAssemblies : ImmutableDictionary<string, DumpedAssembly> ->
referencedIn : AssemblyName ->
handle : AssemblyReferenceHandle ->
ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly
[<RequireQualifiedAccess>]
module TypeConcretization =
@@ -406,8 +413,7 @@ module TypeConcretization =
// Helper function for assembly loading with retry pattern
let private loadAssemblyAndResolveTypeRef
(loadAssembly :
AssemblyName -> AssemblyReferenceHandle -> ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly)
(loadAssembly : IAssemblyLoad)
(ctx : ConcretizationContext<'corelib>)
(currentAssembly : AssemblyName)
(typeRef : TypeRef)
@@ -428,7 +434,8 @@ module TypeConcretization =
// Need to load the assembly
match typeRef.ResolutionScope with
| TypeRefResolutionScope.Assembly assyRef ->
let newAssemblies, _ = loadAssembly currentAssembly assyRef
let newAssemblies, _ =
loadAssembly.LoadAssembly ctx.LoadedAssemblies currentAssembly assyRef
let newCtx =
{ ctx with
@@ -584,8 +591,7 @@ module TypeConcretization =
ImmutableArray.Empty // No generic parameters
let private concretizeTypeReference
(loadAssembly :
AssemblyName -> AssemblyReferenceHandle -> ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly)
(loadAssembly : IAssemblyLoad)
(ctx : ConcretizationContext<'corelib>)
(currentAssembly : AssemblyName)
(typeRef : TypeRef)
@@ -609,8 +615,7 @@ module TypeConcretization =
/// Concretize a type in a specific generic context
let rec concretizeType
(ctx : ConcretizationContext<DumpedAssembly>)
(loadAssembly :
AssemblyName -> AssemblyReferenceHandle -> ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly)
(loadAssembly : IAssemblyLoad)
(assembly : AssemblyName)
(typeGenerics : ImmutableArray<ConcreteTypeHandle>)
(methodGenerics : ImmutableArray<ConcreteTypeHandle>)
@@ -706,8 +711,7 @@ module TypeConcretization =
and private concretizeGenericInstantiation
(ctx : ConcretizationContext<DumpedAssembly>)
(loadAssembly :
AssemblyName -> AssemblyReferenceHandle -> ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly)
(loadAssembly : IAssemblyLoad)
(assembly : AssemblyName)
(typeGenerics : ImmutableArray<ConcreteTypeHandle>)
(methodGenerics : ImmutableArray<ConcreteTypeHandle>)
@@ -786,7 +790,8 @@ module TypeConcretization =
| false, _ ->
// Need to load the assembly
let newAssemblies, loadedAssy = loadAssembly assembly assyRef
let newAssemblies, loadedAssy =
loadAssembly.LoadAssembly ctx.LoadedAssemblies assembly assyRef
let ctxWithNewAssy =
{ ctxAfterArgs with
@@ -865,8 +870,7 @@ module Concretization =
/// Helper to concretize an array of types
let private concretizeTypeArray
(ctx : TypeConcretization.ConcretizationContext<DumpedAssembly>)
(loadAssembly :
AssemblyName -> AssemblyReferenceHandle -> ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly)
(loadAssembly : IAssemblyLoad)
(assembly : AssemblyName)
(typeArgs : ImmutableArray<ConcreteTypeHandle>)
(methodArgs : ImmutableArray<ConcreteTypeHandle>)
@@ -889,8 +893,7 @@ module Concretization =
/// Helper to concretize a method signature
let private concretizeMethodSignature
(ctx : TypeConcretization.ConcretizationContext<DumpedAssembly>)
(loadAssembly :
AssemblyName -> AssemblyReferenceHandle -> ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly)
(loadAssembly : IAssemblyLoad)
(assembly : AssemblyName)
(typeArgs : ImmutableArray<ConcreteTypeHandle>)
(methodArgs : ImmutableArray<ConcreteTypeHandle>)
@@ -926,8 +929,7 @@ module Concretization =
/// Helper to ensure base type assembly is loaded
let rec private ensureBaseTypeAssembliesLoaded
(loadAssembly :
AssemblyName -> AssemblyReferenceHandle -> ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly)
(loadAssembly : IAssemblyLoad)
(assemblies : ImmutableDictionary<string, DumpedAssembly>)
(assyName : AssemblyName)
(baseTypeInfo : BaseTypeInfo option)
@@ -947,7 +949,7 @@ module Concretization =
| true, _ -> assemblies
| false, _ ->
// 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
| _ -> assemblies
| Some (BaseTypeInfo.TypeDef _)
@@ -957,8 +959,7 @@ module Concretization =
/// Concretize a method's signature and body
let concretizeMethod
(ctx : AllConcreteTypes)
(loadAssembly :
AssemblyName -> AssemblyReferenceHandle -> ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly)
(loadAssembly : IAssemblyLoad)
(assemblies : ImmutableDictionary<string, DumpedAssembly>)
(baseTypes : BaseClassTypes<DumpedAssembly>)
(method : WoofWare.PawPrint.MethodInfo<'ty, GenericParamFromMetadata, TypeDefn>)

View File

@@ -22,12 +22,17 @@ module TestPureCases =
NativeImpls = MockEnv.make ()
}
{
FileName = "InitializeArray.cs"
FileName = "OverlappingStructs.cs"
ExpectedReturnCode = 0
NativeImpls = MockEnv.make ()
}
{
FileName = "GenericEdgeCases.cs"
FileName = "AdvancedStructLayout.cs"
ExpectedReturnCode = 0
NativeImpls = MockEnv.make ()
}
{
FileName = "InitializeArray.cs"
ExpectedReturnCode = 0
NativeImpls = MockEnv.make ()
}
@@ -56,21 +61,6 @@ module TestPureCases =
ExpectedReturnCode = 0
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 =
@@ -80,6 +70,21 @@ module TestPureCases =
ExpectedReturnCode = 1
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"
ExpectedReturnCode = 0
@@ -165,11 +170,6 @@ module TestPureCases =
ExpectedReturnCode = 0
NativeImpls = MockEnv.make ()
}
{
FileName = "Initobj.cs"
ExpectedReturnCode = 0
NativeImpls = MockEnv.make ()
}
]
let runTest (case : EndToEndTestCase) : unit =

View File

@@ -222,5 +222,5 @@ module AbstractMachine =
|> ExecutionResult.Stepped
| IlOp.Switch immutableArray -> failwith "TODO: Switch unimplemented"
| IlOp.UnaryStringToken (unaryStringTokenIlOp, stringHandle) ->
UnaryStringTokenIlOp.execute baseClassTypes unaryStringTokenIlOp stringHandle state thread
UnaryStringTokenIlOp.execute loggerFactory baseClassTypes unaryStringTokenIlOp stringHandle state thread
|> ExecutionResult.Stepped

View File

@@ -460,20 +460,22 @@ module CliType =
// The field type might reference generic parameters of the declaring type
let methodGenerics = ImmutableArray.Empty // Fields don't have method generics
let loadAssembly
(assyName : AssemblyName)
(ref : AssemblyReferenceHandle)
: ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly
=
match assemblies.TryGetValue assyName.FullName with
| true, currentAssy ->
let targetAssyRef = currentAssy.AssemblyReferences.[ref]
let loadAssembly =
{ new IAssemblyLoad with
member _.LoadAssembly loaded assyName ref =
match loaded.TryGetValue assyName.FullName with
| true, currentAssy ->
let targetAssyRef = currentAssy.AssemblyReferences.[ref]
match assemblies.TryGetValue targetAssyRef.Name.FullName with
| true, targetAssy -> assemblies, targetAssy
| false, _ ->
failwithf "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
match loaded.TryGetValue targetAssyRef.Name.FullName with
| true, targetAssy -> loaded, targetAssy
| false, _ ->
failwithf
"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 =
TypeConcretization.concretizeType

View File

@@ -149,7 +149,73 @@ type StateLoadResult =
module IlMachineState =
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
(loggerFactory : ILoggerFactory)
(baseClassTypes : BaseClassTypes<DumpedAssembly>)
(state : IlMachineState)
(declaringAssembly : AssemblyName)
@@ -169,14 +235,7 @@ module IlMachineState =
let handle, ctx =
TypeConcretization.concretizeType
ctx
(fun assyName ref ->
let currentAssy = state.LoadedAssembly assyName |> Option.get
let targetAssy =
currentAssy.AssemblyReferences.[ref].Name |> state.LoadedAssembly |> Option.get
state._LoadedAssemblies, targetAssy
)
(loader loggerFactory state)
declaringAssembly
typeGenerics
methodGenerics
@@ -190,51 +249,6 @@ module IlMachineState =
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
(loggerFactory : ILoggerFactory)
(ns : string option)
@@ -440,6 +454,54 @@ module IlMachineState =
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
let cliTypeZeroOfHandle
(state : IlMachineState)
@@ -482,26 +544,6 @@ module IlMachineState =
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
let mutable currentCtx = ctx
let genericHandles = ImmutableArray.CreateBuilder declaringType.Generics.Length
@@ -510,7 +552,7 @@ module IlMachineState =
let handle, newCtx =
TypeConcretization.concretizeType
currentCtx
loadAssembly
(loader loggerFactory state)
declaringType.Assembly
ImmutableArray.Empty // No type 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
// If it's a non-generic type, we can use concretizeTypeDefinition directly
if declaringType.Generics.IsEmpty then
let handle, newCtx =
let handle, currentCtx =
TypeConcretization.concretizeTypeDefinition currentCtx declaringType.Assembly declaringType.Definition
let newState =
{ state with
ConcreteTypes = newCtx.ConcreteTypes
ConcreteTypes = currentCtx.ConcreteTypes
_LoadedAssemblies = currentCtx.LoadedAssemblies
}
handle, newState
@@ -583,7 +626,7 @@ module IlMachineState =
state.WithLoadedAssembly assy.Name assy
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
let zero, state = cliTypeZeroOfHandle state baseClassTypes handle
@@ -759,22 +802,7 @@ module IlMachineState =
let concretizedMethod, newConcreteTypes, newAssemblies =
Concretization.concretizeMethod
state.ConcreteTypes
(fun assyName ref ->
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
)
(loader loggerFactory state)
state._LoadedAssemblies
baseClassTypes
methodToCall
@@ -820,6 +848,7 @@ module IlMachineState =
for i = 0 to generics.Length - 1 do
let state2, handle =
concretizeType
loggerFactory
baseClassTypes
state
callingAssembly
@@ -875,14 +904,7 @@ module IlMachineState =
let handle, newCtx =
TypeConcretization.concretizeType
ctx
(fun assyName ref ->
let currentAssy = state.LoadedAssembly assyName |> Option.get
let targetAssy =
currentAssy.AssemblyReferences.[ref].Name |> state.LoadedAssembly |> Option.get
state._LoadedAssemblies, targetAssy
)
(loader loggerFactory state)
(state.ActiveAssembly thread).Name
ImmutableArray.Empty // No type generics for the concretization context
ImmutableArray.Empty // No method generics for the concretization context
@@ -893,6 +915,7 @@ module IlMachineState =
state <-
{ state with
ConcreteTypes = newCtx.ConcreteTypes
_LoadedAssemblies = newCtx.LoadedAssemblies
}
handles.ToImmutable (), state
@@ -997,14 +1020,7 @@ module IlMachineState =
let declaringHandle, newCtx =
TypeConcretization.concretizeType
ctx
(fun assyName ref ->
let currentAssy = state.LoadedAssembly assyName |> Option.get
let targetAssy =
currentAssy.AssemblyReferences.[ref].Name |> state.LoadedAssembly |> Option.get
state._LoadedAssemblies, targetAssy
)
(loader loggerFactory state)
field.DeclaringType.Assembly
contextTypeGenerics
contextMethodGenerics
@@ -1190,6 +1206,7 @@ module IlMachineState =
(baseClassTypes : BaseClassTypes<DumpedAssembly>)
(currentThread : ThreadId)
(assy : DumpedAssembly)
(genericMethodTypeArgs : ImmutableArray<ConcreteTypeHandle>)
(m : MemberReferenceHandle)
(state : IlMachineState)
: IlMachineState *
@@ -1253,6 +1270,7 @@ module IlMachineState =
// TODO: generics?
let state, t =
concretizeType
loggerFactory
baseClassTypes
state
targetType.Assembly
@@ -1270,6 +1288,7 @@ module IlMachineState =
// Concretize the field signature from the member reference
let state, concreteFieldSig =
concretizeType
loggerFactory
baseClassTypes
state
(state.ActiveAssembly(currentThread).Name)
@@ -1287,6 +1306,7 @@ module IlMachineState =
// Concretize the field's signature for comparison
let state, fieldSigConcrete =
concretizeType
loggerFactory
baseClassTypes
state
assy.Name
@@ -1324,11 +1344,12 @@ module IlMachineState =
state
(fun state ty ->
concretizeType
loggerFactory
baseClassTypes
state
(state.ActiveAssembly(currentThread).Name)
concreteExtractedTypeArgs
ImmutableArray.Empty
genericMethodTypeArgs
ty
)
@@ -1341,11 +1362,12 @@ module IlMachineState =
state
(fun state ty ->
concretizeType
loggerFactory
baseClassTypes
state
assy.Name
concreteExtractedTypeArgs
ImmutableArray.Empty
genericMethodTypeArgs
ty
)
@@ -1507,6 +1529,7 @@ module IlMachineState =
/// Returns the type handle and an allocated System.RuntimeType.
let getOrAllocateType
(loggerFactory : ILoggerFactory)
(baseClassTypes : BaseClassTypes<DumpedAssembly>)
(defn : ConcreteTypeHandle)
(state : IlMachineState)
@@ -1518,7 +1541,13 @@ module IlMachineState =
baseClassTypes.Corelib.Name.FullName,
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 =
TypeHandleRegistry.getOrAllocate
@@ -1562,7 +1591,13 @@ module IlMachineState =
baseClassTypes.Corelib.Name.FullName,
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 =
FieldHandleRegistry.getOrAllocate

View File

@@ -10,6 +10,7 @@ open Microsoft.Extensions.Logging
[<RequireQualifiedAccess>]
module IlMachineStateExecution =
let getTypeOfObj
(loggerFactory : ILoggerFactory)
(baseClassTypes : BaseClassTypes<DumpedAssembly>)
(state : IlMachineState)
(esv : EvalStackValue)
@@ -19,6 +20,7 @@ module IlMachineStateExecution =
| EvalStackValue.Int32 _ ->
DumpedAssembly.typeInfoToTypeDefn' baseClassTypes state._LoadedAssemblies baseClassTypes.Int32
|> IlMachineState.concretizeType
loggerFactory
baseClassTypes
state
baseClassTypes.Corelib.Name
@@ -27,6 +29,7 @@ module IlMachineStateExecution =
| EvalStackValue.Int64 _ ->
DumpedAssembly.typeInfoToTypeDefn' baseClassTypes state._LoadedAssemblies baseClassTypes.Int64
|> IlMachineState.concretizeType
loggerFactory
baseClassTypes
state
baseClassTypes.Corelib.Name
@@ -36,6 +39,7 @@ module IlMachineStateExecution =
| EvalStackValue.Float _ ->
DumpedAssembly.typeInfoToTypeDefn' baseClassTypes state._LoadedAssemblies baseClassTypes.Double
|> IlMachineState.concretizeType
loggerFactory
baseClassTypes
state
baseClassTypes.Corelib.Name
@@ -156,7 +160,8 @@ module IlMachineStateExecution =
| None -> failwith "unexpectedly no `this` on the eval stack of instance method"
| Some this -> this
let state, callingObjTyHandle = getTypeOfObj baseClassTypes state callingObj
let state, callingObjTyHandle =
getTypeOfObj loggerFactory baseClassTypes state callingObj
let callingObjTy =
let ty =
@@ -200,6 +205,7 @@ module IlMachineStateExecution =
let state, retType =
meth.Signature.ReturnType
|> IlMachineState.concretizeType
loggerFactory
baseClassTypes
state
meth.DeclaringType.Assembly
@@ -211,6 +217,7 @@ module IlMachineStateExecution =
||> Seq.mapFold (fun state ty ->
ty
|> IlMachineState.concretizeType
loggerFactory
baseClassTypes
state
meth.DeclaringType.Assembly
@@ -573,6 +580,7 @@ module IlMachineStateExecution =
// Concretize the base type
let state, baseTypeHandle =
IlMachineState.concretizeType
loggerFactory
baseClassTypes
state
sourceAssembly.Name
@@ -612,6 +620,7 @@ module IlMachineStateExecution =
// Concretize the base type
let state, baseTypeHandle =
IlMachineState.concretizeType
loggerFactory
baseClassTypes
state
sourceAssembly.Name
@@ -663,6 +672,7 @@ module IlMachineStateExecution =
state
(fun state typeDefn ->
IlMachineState.concretizeType
loggerFactory
baseClassTypes
state
concreteType.Assembly
@@ -687,6 +697,7 @@ module IlMachineStateExecution =
||> Seq.fold (fun (state, acc) typeDefn ->
let state, handle =
IlMachineState.concretizeType
loggerFactory
baseClassTypes
state
concreteType.Assembly

View File

@@ -14,6 +14,10 @@ module Intrinsics =
"System.Private.CoreLib", "ArgumentNullException", "ThrowIfNull"
// https://github.com/dotnet/runtime/blob/ec11903827fc28847d775ba17e0cd1ff56cfbc2e/src/coreclr/System.Private.CoreLib/src/System/Type.CoreCLR.cs#L82
"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
@@ -299,15 +303,47 @@ 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
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: 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" ->
// https://github.com/dotnet/runtime/blob/9e5e6aa7bc36aeb2a154709a9d1192030c30a2ef/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs#L153
None

View File

@@ -52,7 +52,7 @@ module NullaryIlOp =
| EvalStackValue.NativeInt nativeIntSource ->
failwith $"TODO: Native int pointer dereferencing not implemented for {targetType}"
| 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}"
let loadedValue = loadedValue |> EvalStackValue.ofCliType

View File

@@ -10,6 +10,7 @@ open Microsoft.Extensions.Logging
module Program =
/// Returns the pointer to the resulting array on the heap.
let allocateArgs
(loggerFactory : ILoggerFactory)
(args : string list)
(corelib : BaseClassTypes<DumpedAssembly>)
(state : IlMachineState)
@@ -18,6 +19,7 @@ module Program =
let state, stringType =
DumpedAssembly.typeInfoToTypeDefn' corelib state._LoadedAssemblies corelib.String
|> IlMachineState.concretizeType
loggerFactory
corelib
state
corelib.Corelib.Name
@@ -285,7 +287,7 @@ module Program =
let arrayAllocation, state =
match mainMethodFromMetadata.Signature.ParameterTypes |> Seq.toList with
| [ 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"
match mainMethodFromMetadata.Signature.ReturnType with

View File

@@ -28,6 +28,24 @@ module internal UnaryMetadataIlOp =
| MetadataToken.MethodSpecification 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
| MetadataToken.MethodDef token ->
let method =
@@ -44,6 +62,7 @@ module internal UnaryMetadataIlOp =
baseClassTypes
thread
(state.ActiveAssembly thread)
methodGenerics
ref
state
@@ -58,6 +77,7 @@ module internal UnaryMetadataIlOp =
baseClassTypes
thread
(state.ActiveAssembly thread)
currentMethod.DeclaringType.Generics
h
state
@@ -114,6 +134,24 @@ module internal UnaryMetadataIlOp =
| MetadataToken.MethodSpecification 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
| MetadataToken.MethodDef token ->
let method =
@@ -128,6 +166,7 @@ module internal UnaryMetadataIlOp =
baseClassTypes
thread
(state.ActiveAssembly thread)
methodGenerics
ref
state
@@ -142,6 +181,7 @@ module internal UnaryMetadataIlOp =
baseClassTypes
thread
(state.ActiveAssembly thread)
ImmutableArray.Empty
h
state
@@ -203,6 +243,7 @@ module internal UnaryMetadataIlOp =
baseClassTypes
thread
(state.ActiveAssembly thread)
ImmutableArray.Empty
mr
state
@@ -436,6 +477,7 @@ module internal UnaryMetadataIlOp =
let state, targetConcreteType =
IlMachineState.concretizeType
loggerFactory
baseClassTypes
state
activeAssy.Name
@@ -481,7 +523,14 @@ module internal UnaryMetadataIlOp =
state, field
| MetadataToken.MemberReference mr ->
let state, _, field, _ =
IlMachineState.resolveMember loggerFactory baseClassTypes thread activeAssy mr state
IlMachineState.resolveMember
loggerFactory
baseClassTypes
thread
activeAssy
ImmutableArray.Empty
mr
state
match field with
| Choice1Of2 _method -> failwith "member reference was unexpectedly a method"
@@ -498,6 +547,7 @@ module internal UnaryMetadataIlOp =
)
let valueToStore, state = IlMachineState.popEvalStack thread state
let currentObj, state = IlMachineState.popEvalStack thread state
let state, declaringTypeHandle, typeGenerics =
IlMachineState.concretizeFieldForExecution loggerFactory baseClassTypes thread field state
@@ -514,8 +564,6 @@ module internal UnaryMetadataIlOp =
let valueToStore = EvalStackValue.toCliTypeCoerced zero valueToStore
let currentObj, state = IlMachineState.popEvalStack thread state
if field.Attributes.HasFlag FieldAttributes.Static then
let state =
IlMachineState.setStatic declaringTypeHandle field.Name valueToStore state
@@ -601,6 +649,7 @@ module internal UnaryMetadataIlOp =
baseClassTypes
thread
(state.ActiveAssembly thread)
ImmutableArray.Empty
mr
state
@@ -660,7 +709,14 @@ module internal UnaryMetadataIlOp =
state, field
| MetadataToken.MemberReference mr ->
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
| Choice1Of2 _method -> failwith "member reference was unexpectedly a method"
@@ -750,6 +806,7 @@ module internal UnaryMetadataIlOp =
IlMachineState.pushToEvalStack currentValue thread state
| EvalStackValue.UserDefinedValueType vt ->
let result = vt |> EvalStackValueUserType.DereferenceField field.Name
IlMachineState.pushToEvalStack' result thread state
state
@@ -779,7 +836,15 @@ module internal UnaryMetadataIlOp =
state, field
| MetadataToken.MemberReference mr ->
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
| Choice1Of2 _method -> failwith "member reference was unexpectedly a method"
@@ -793,6 +858,7 @@ module internal UnaryMetadataIlOp =
|> IlMachineState.pushToEvalStack' result thread
|> IlMachineState.advanceProgramCounter thread
|> Tuple.withRight WhatWeDid.Executed
| Ldsfld ->
let state, field =
match metadataToken with
@@ -807,7 +873,14 @@ module internal UnaryMetadataIlOp =
state, field
| MetadataToken.MemberReference mr ->
let state, _, field, _ =
IlMachineState.resolveMember loggerFactory baseClassTypes thread activeAssy mr state
IlMachineState.resolveMember
loggerFactory
baseClassTypes
thread
activeAssy
ImmutableArray.Empty
mr
state
match field with
| Choice1Of2 _method -> failwith "member reference was unexpectedly a method"
@@ -983,6 +1056,7 @@ module internal UnaryMetadataIlOp =
IlMachineState.pushToEvalStack toPush thread state
|> IlMachineState.advanceProgramCounter thread
|> Tuple.withRight WhatWeDid.Executed
| Initobj ->
let popped, state = IlMachineState.popEvalStack thread state
let declaringTypeGenerics = currentMethod.DeclaringType.Generics
@@ -1046,6 +1120,7 @@ module internal UnaryMetadataIlOp =
state
|> IlMachineState.advanceProgramCounter thread
|> Tuple.withRight WhatWeDid.Executed
| Ldsflda ->
// TODO: check whether we should throw FieldAccessException
@@ -1142,6 +1217,42 @@ module internal UnaryMetadataIlOp =
| Stobj -> failwith "TODO: Stobj unimplemented"
| Constrained -> failwith "TODO: Constrained unimplemented"
| 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 =
match metadataToken with
| MetadataToken.FieldDefinition h ->
@@ -1179,6 +1290,7 @@ module internal UnaryMetadataIlOp =
let state, handle =
IlMachineState.concretizeType
loggerFactory
baseClassTypes
state
assy.Name
@@ -1186,7 +1298,8 @@ module internal UnaryMetadataIlOp =
methodGenerics
typeDefn
let alloc, state = IlMachineState.getOrAllocateType baseClassTypes handle state
let alloc, state =
IlMachineState.getOrAllocateType loggerFactory baseClassTypes handle state
let vt =
{
@@ -1214,6 +1327,7 @@ module internal UnaryMetadataIlOp =
let state, handle =
IlMachineState.concretizeType
loggerFactory
baseClassTypes
state
assy.Name
@@ -1221,7 +1335,8 @@ module internal UnaryMetadataIlOp =
methodGenerics
typeDefn
let alloc, state = IlMachineState.getOrAllocateType baseClassTypes handle state
let alloc, state =
IlMachineState.getOrAllocateType loggerFactory baseClassTypes handle state
let vt =
{
@@ -1234,40 +1349,10 @@ module internal UnaryMetadataIlOp =
IlMachineState.pushToEvalStack (CliType.ValueType vt) thread state
| 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 =
IlMachineState.lookupTypeDefn baseClassTypes state activeAssy h
let state, handle =
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
handleTypeToken typeDefn state
| _ -> failwith $"Unexpected metadata token %O{metadataToken} in LdToken"
state
@@ -1293,6 +1378,7 @@ module internal UnaryMetadataIlOp =
let state, typeHandle =
IlMachineState.concretizeType
loggerFactory
baseClassTypes
state
assy.Name

View File

@@ -2,12 +2,13 @@ namespace WoofWare.PawPrint
open System.Collections.Immutable
open System.Reflection
open System.Reflection.Metadata
open Microsoft.Extensions.Logging
[<RequireQualifiedAccess>]
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module internal UnaryStringTokenIlOp =
let execute
(loggerFactory : ILoggerFactory)
(baseClassTypes : BaseClassTypes<DumpedAssembly>)
(op : UnaryStringTokenIlOp)
(sh : StringToken)
@@ -66,6 +67,7 @@ module internal UnaryStringTokenIlOp =
let state, stringType =
DumpedAssembly.typeInfoToTypeDefn' baseClassTypes state._LoadedAssemblies baseClassTypes.String
|> IlMachineState.concretizeType
loggerFactory
baseClassTypes
state
baseClassTypes.Corelib.Name