mirror of
https://github.com/Smaug123/WoofWare.PawPrint
synced 2025-10-13 09:38:40 +00:00
Compare commits
33 Commits
net10
...
55677a507b
Author | SHA1 | Date | |
---|---|---|---|
|
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 |
@@ -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 ()
|
||||
}
|
||||
@@ -66,11 +71,6 @@ module TestPureCases =
|
||||
ExpectedReturnCode = 0
|
||||
NativeImpls = MockEnv.make ()
|
||||
}
|
||||
{
|
||||
FileName = "UnsafeAs.cs"
|
||||
ExpectedReturnCode = 0
|
||||
NativeImpls = MockEnv.make ()
|
||||
}
|
||||
]
|
||||
|
||||
let cases : EndToEndTestCase list =
|
||||
@@ -80,6 +80,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 +180,6 @@ module TestPureCases =
|
||||
ExpectedReturnCode = 0
|
||||
NativeImpls = MockEnv.make ()
|
||||
}
|
||||
{
|
||||
FileName = "Initobj.cs"
|
||||
ExpectedReturnCode = 0
|
||||
NativeImpls = MockEnv.make ()
|
||||
}
|
||||
]
|
||||
|
||||
let runTest (case : EndToEndTestCase) : unit =
|
||||
|
@@ -440,6 +440,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)
|
||||
@@ -1190,6 +1238,7 @@ module IlMachineState =
|
||||
(baseClassTypes : BaseClassTypes<DumpedAssembly>)
|
||||
(currentThread : ThreadId)
|
||||
(assy : DumpedAssembly)
|
||||
(genericMethodTypeArgs : ImmutableArray<ConcreteTypeHandle>)
|
||||
(m : MemberReferenceHandle)
|
||||
(state : IlMachineState)
|
||||
: IlMachineState *
|
||||
@@ -1328,7 +1377,7 @@ module IlMachineState =
|
||||
state
|
||||
(state.ActiveAssembly(currentThread).Name)
|
||||
concreteExtractedTypeArgs
|
||||
ImmutableArray.Empty
|
||||
genericMethodTypeArgs
|
||||
ty
|
||||
)
|
||||
|
||||
@@ -1345,7 +1394,7 @@ module IlMachineState =
|
||||
state
|
||||
assy.Name
|
||||
concreteExtractedTypeArgs
|
||||
ImmutableArray.Empty
|
||||
genericMethodTypeArgs
|
||||
ty
|
||||
)
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -28,6 +28,23 @@ 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
|
||||
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 +61,7 @@ module internal UnaryMetadataIlOp =
|
||||
baseClassTypes
|
||||
thread
|
||||
(state.ActiveAssembly thread)
|
||||
methodGenerics
|
||||
ref
|
||||
state
|
||||
|
||||
@@ -58,6 +76,7 @@ module internal UnaryMetadataIlOp =
|
||||
baseClassTypes
|
||||
thread
|
||||
(state.ActiveAssembly thread)
|
||||
currentMethod.DeclaringType.Generics
|
||||
h
|
||||
state
|
||||
|
||||
@@ -114,6 +133,23 @@ 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
|
||||
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 +164,7 @@ module internal UnaryMetadataIlOp =
|
||||
baseClassTypes
|
||||
thread
|
||||
(state.ActiveAssembly thread)
|
||||
methodGenerics
|
||||
ref
|
||||
state
|
||||
|
||||
@@ -142,6 +179,7 @@ module internal UnaryMetadataIlOp =
|
||||
baseClassTypes
|
||||
thread
|
||||
(state.ActiveAssembly thread)
|
||||
ImmutableArray.Empty
|
||||
h
|
||||
state
|
||||
|
||||
@@ -203,6 +241,7 @@ module internal UnaryMetadataIlOp =
|
||||
baseClassTypes
|
||||
thread
|
||||
(state.ActiveAssembly thread)
|
||||
ImmutableArray.Empty
|
||||
mr
|
||||
state
|
||||
|
||||
@@ -481,7 +520,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 +544,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 +561,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 +646,7 @@ module internal UnaryMetadataIlOp =
|
||||
baseClassTypes
|
||||
thread
|
||||
(state.ActiveAssembly thread)
|
||||
ImmutableArray.Empty
|
||||
mr
|
||||
state
|
||||
|
||||
@@ -660,7 +706,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 +803,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 +833,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 +855,7 @@ module internal UnaryMetadataIlOp =
|
||||
|> IlMachineState.pushToEvalStack' result thread
|
||||
|> IlMachineState.advanceProgramCounter thread
|
||||
|> Tuple.withRight WhatWeDid.Executed
|
||||
|
||||
| Ldsfld ->
|
||||
let state, field =
|
||||
match metadataToken with
|
||||
@@ -807,7 +870,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 +1053,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 +1117,7 @@ module internal UnaryMetadataIlOp =
|
||||
state
|
||||
|> IlMachineState.advanceProgramCounter thread
|
||||
|> Tuple.withRight WhatWeDid.Executed
|
||||
|
||||
| Ldsflda ->
|
||||
|
||||
// TODO: check whether we should throw FieldAccessException
|
||||
@@ -1142,6 +1214,40 @@ 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
|
||||
baseClassTypes
|
||||
state
|
||||
activeAssy.Name
|
||||
typeGenerics
|
||||
methodGenerics
|
||||
typeDefn
|
||||
|
||||
let alloc, state = IlMachineState.getOrAllocateType 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 ->
|
||||
@@ -1234,40 +1340,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
|
||||
|
Reference in New Issue
Block a user