mirror of
https://github.com/Smaug123/WoofWare.PawPrint
synced 2025-10-07 15:08:40 +00:00
Uncomment a bit of a test
This commit is contained in:
@@ -519,6 +519,12 @@ type UnaryMetadataTokenIlOp =
|
||||
| Call
|
||||
| Calli
|
||||
| Callvirt
|
||||
/// Attempts to cast an object passed by reference to the specified class.
|
||||
/// If the class of the object on the top of the stack does not implement the new class
|
||||
/// (assuming the new class is an interface)
|
||||
/// and is not a derived class of the new class then an InvalidCastException is thrown.
|
||||
/// If the object reference is a null reference, castclass succeeds
|
||||
/// and returns the new object as a null reference.
|
||||
| Castclass
|
||||
| Newobj
|
||||
| Newarr
|
||||
|
@@ -46,6 +46,13 @@ type TypeMethodSignature<'Types> =
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module TypeMethodSignature =
|
||||
let sigsEqual<'T> (equal : 'T -> 'T -> bool) (s1 : TypeMethodSignature<'T>) (s2 : TypeMethodSignature<'T>) : bool =
|
||||
s1.GenericParameterCount = s2.GenericParameterCount
|
||||
&& s1.ParameterTypes.Length = s2.ParameterTypes.Length
|
||||
&& equal s1.ReturnType s2.ReturnType
|
||||
&& List.zip s1.ParameterTypes s2.ParameterTypes
|
||||
|> List.forall (fun (x, y) -> equal x y)
|
||||
|
||||
let make<'T> (p : MethodSignature<'T>) : TypeMethodSignature<'T> =
|
||||
{
|
||||
Header = ComparableSignatureHeader.Make p.Header
|
||||
@@ -170,6 +177,30 @@ type TypeDefn =
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module TypeDefn =
|
||||
let rec equals
|
||||
(t1TypeGenerics : TypeDefn ImmutableArray)
|
||||
(t1MethodGenerics : TypeDefn ImmutableArray)
|
||||
(t2TypeGenerics : TypeDefn ImmutableArray)
|
||||
(t2MethodGenerics : TypeDefn ImmutableArray)
|
||||
(t1 : TypeDefn)
|
||||
(t2 : TypeDefn)
|
||||
: bool
|
||||
=
|
||||
match t1, t2 with
|
||||
| TypeDefn.GenericTypeParameter i, j ->
|
||||
equals t1TypeGenerics t1MethodGenerics t2TypeGenerics t2MethodGenerics t1TypeGenerics.[i] j
|
||||
| TypeDefn.GenericMethodParameter i, j ->
|
||||
equals t1TypeGenerics t1MethodGenerics t2TypeGenerics t2MethodGenerics t1MethodGenerics.[i] j
|
||||
| i, TypeDefn.GenericTypeParameter j ->
|
||||
equals t1TypeGenerics t1MethodGenerics t2TypeGenerics t2MethodGenerics i t2TypeGenerics.[j]
|
||||
| i, TypeDefn.GenericMethodParameter j ->
|
||||
equals t1TypeGenerics t1MethodGenerics t2TypeGenerics t2MethodGenerics i t2MethodGenerics.[j]
|
||||
| TypeDefn.PrimitiveType x, TypeDefn.PrimitiveType y -> x = y
|
||||
| TypeDefn.Array (x, shapeX), TypeDefn.Array (y, shapeY) ->
|
||||
shapeX = shapeY
|
||||
&& equals t1TypeGenerics t1MethodGenerics t2TypeGenerics t2TypeGenerics x y
|
||||
| t1, t2 -> failwith $"TODO: {t1} = {t2}"
|
||||
|
||||
let isManaged (typeDefn : TypeDefn) : bool =
|
||||
match typeDefn with
|
||||
| TypeDefn.PrimitiveType primitiveType -> failwith "todo"
|
||||
|
@@ -92,6 +92,8 @@ type TypeInfoCrate =
|
||||
abstract ToString : unit -> string
|
||||
abstract BaseType : BaseTypeInfo option
|
||||
abstract Assembly : AssemblyName
|
||||
abstract Namespace : string
|
||||
abstract Name : string
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module TypeInfoCrate =
|
||||
@@ -108,6 +110,10 @@ module TypeInfoCrate =
|
||||
member this.BaseType = t.BaseType
|
||||
|
||||
member this.Assembly = t.Assembly
|
||||
|
||||
member this.Namespace = t.Namespace
|
||||
|
||||
member this.Name = t.Name
|
||||
}
|
||||
|
||||
type BaseClassTypes<'corelib> =
|
||||
|
@@ -42,7 +42,7 @@ unsafe class LdindTest
|
||||
// failures += TestManagedPointers();
|
||||
|
||||
// Test Ldind.i (native int)
|
||||
// failures += TestLdindI();
|
||||
failures += TestLdindI();
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
@@ -65,7 +65,7 @@ module AbstractMachine =
|
||||
|
||||
let methodPtr =
|
||||
match delegateToRun.Fields.["_methodPtr"] with
|
||||
| CliType.Numeric (CliNumericType.ProvenanceTrackedNativeInt64 mi) -> mi
|
||||
| CliType.Numeric (CliNumericType.NativeInt (NativeIntSource.FunctionPointer mi)) -> mi
|
||||
| d -> failwith $"unexpectedly not a method pointer in delegate invocation: {d}"
|
||||
|
||||
let typeGenerics =
|
||||
|
@@ -36,11 +36,74 @@ type BasicCliType =
|
||||
| NativeInt of int64
|
||||
| NativeFloat of float
|
||||
|
||||
[<NoComparison>]
|
||||
type ManagedPointerSource =
|
||||
| LocalVariable of sourceThread : ThreadId * methodFrame : int * whichVar : uint16
|
||||
| Argument of sourceThread : ThreadId * methodFrame : int * whichVar : uint16
|
||||
| Heap of ManagedHeapAddress
|
||||
| Null
|
||||
|
||||
override this.ToString () =
|
||||
match this with
|
||||
| ManagedPointerSource.Null -> "<null pointer>"
|
||||
| ManagedPointerSource.Heap addr -> $"%O{addr}"
|
||||
| ManagedPointerSource.LocalVariable (source, method, var) ->
|
||||
$"<variable %i{var} in method frame %i{method} of thread %O{source}>"
|
||||
| ManagedPointerSource.Argument (source, method, var) ->
|
||||
$"<argument %i{var} in method frame %i{method} of thread %O{source}>"
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
type UnsignedNativeIntSource =
|
||||
| Verbatim of uint64
|
||||
| FromManagedPointer of ManagedPointerSource
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
type NativeIntSource =
|
||||
| Verbatim of int64
|
||||
| ManagedPointer of ManagedPointerSource
|
||||
| FunctionPointer of MethodInfo<FakeUnit, WoofWare.PawPrint.GenericParameter>
|
||||
| TypeHandlePtr of int64<typeHandle>
|
||||
|
||||
override this.ToString () : string =
|
||||
match this with
|
||||
| NativeIntSource.Verbatim int64 -> $"%i{int64}"
|
||||
| NativeIntSource.ManagedPointer ptr -> $"<managed pointer {ptr}>"
|
||||
| NativeIntSource.FunctionPointer methodDefinition ->
|
||||
$"<pointer to {methodDefinition.Name} in {methodDefinition.DeclaringType.Assembly.Name}>"
|
||||
| NativeIntSource.TypeHandlePtr ptr -> $"<type ID %i{ptr}>"
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module NativeIntSource =
|
||||
let isZero (n : NativeIntSource) : bool =
|
||||
match n with
|
||||
| NativeIntSource.Verbatim i -> i = 0L
|
||||
| NativeIntSource.TypeHandlePtr _ -> false
|
||||
| NativeIntSource.FunctionPointer _ -> failwith "TODO"
|
||||
| NativeIntSource.ManagedPointer src ->
|
||||
match src with
|
||||
| ManagedPointerSource.Null -> true
|
||||
| _ -> false
|
||||
|
||||
let isNonnegative (n : NativeIntSource) : bool =
|
||||
match n with
|
||||
| NativeIntSource.Verbatim i -> i >= 0L
|
||||
| NativeIntSource.FunctionPointer _ -> failwith "TODO"
|
||||
| NativeIntSource.TypeHandlePtr _ -> true
|
||||
| NativeIntSource.ManagedPointer _ -> true
|
||||
|
||||
/// True if a < b.
|
||||
let isLess (a : NativeIntSource) (b : NativeIntSource) : bool =
|
||||
match a, b with
|
||||
| NativeIntSource.Verbatim a, NativeIntSource.Verbatim b -> a < b
|
||||
| _, _ -> failwith "TODO"
|
||||
|
||||
|
||||
/// Defined in III.1.1.1
|
||||
type CliNumericType =
|
||||
| Int32 of int32
|
||||
| Int64 of int64
|
||||
| NativeInt of int64
|
||||
/// The real CLR just represents these as native ints, but we track their provenance.
|
||||
| NativeInt of NativeIntSource
|
||||
| NativeFloat of float
|
||||
| Int8 of int8
|
||||
| Int16 of int16
|
||||
@@ -48,10 +111,6 @@ type CliNumericType =
|
||||
| UInt16 of uint16
|
||||
| Float32 of float32
|
||||
| Float64 of float
|
||||
/// Not a real CLI numeric type! Represents an int64 obtained by taking a NativeInt from the eval stack.
|
||||
| ProvenanceTrackedNativeInt64 of MethodInfo<FakeUnit, WoofWare.PawPrint.GenericParameter>
|
||||
/// Not a real CLI numeric type! An opaque TypeHandle pointer.
|
||||
| TypeHandlePtr of int64<typeHandle>
|
||||
|
||||
type CliValueType =
|
||||
private
|
||||
|
@@ -1,65 +1,5 @@
|
||||
namespace WoofWare.PawPrint
|
||||
|
||||
type ManagedPointerSource =
|
||||
| LocalVariable of sourceThread : ThreadId * methodFrame : int * whichVar : uint16
|
||||
| Argument of sourceThread : ThreadId * methodFrame : int * whichVar : uint16
|
||||
| Heap of ManagedHeapAddress
|
||||
| Null
|
||||
|
||||
override this.ToString () =
|
||||
match this with
|
||||
| ManagedPointerSource.Null -> "<null pointer>"
|
||||
| ManagedPointerSource.Heap addr -> $"%O{addr}"
|
||||
| ManagedPointerSource.LocalVariable (source, method, var) ->
|
||||
$"<variable %i{var} in method frame %i{method} of thread %O{source}>"
|
||||
| ManagedPointerSource.Argument (source, method, var) ->
|
||||
$"<argument %i{var} in method frame %i{method} of thread %O{source}>"
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
type NativeIntSource =
|
||||
| Verbatim of int64
|
||||
| ManagedPointer of ManagedPointerSource
|
||||
| FunctionPointer of MethodInfo<FakeUnit, GenericParameter>
|
||||
| TypeHandlePtr of int64<typeHandle>
|
||||
|
||||
override this.ToString () : string =
|
||||
match this with
|
||||
| NativeIntSource.Verbatim int64 -> $"%i{int64}"
|
||||
| NativeIntSource.ManagedPointer ptr -> $"<managed pointer {ptr}>"
|
||||
| NativeIntSource.FunctionPointer methodDefinition ->
|
||||
$"<pointer to {methodDefinition.Name} in {methodDefinition.DeclaringType.Assembly.Name}>"
|
||||
| NativeIntSource.TypeHandlePtr ptr -> $"<type ID %i{ptr}>"
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module NativeIntSource =
|
||||
let isZero (n : NativeIntSource) : bool =
|
||||
match n with
|
||||
| NativeIntSource.Verbatim i -> i = 0L
|
||||
| NativeIntSource.TypeHandlePtr _ -> false
|
||||
| NativeIntSource.FunctionPointer _ -> failwith "TODO"
|
||||
| NativeIntSource.ManagedPointer src ->
|
||||
match src with
|
||||
| ManagedPointerSource.Null -> true
|
||||
| _ -> false
|
||||
|
||||
let isNonnegative (n : NativeIntSource) : bool =
|
||||
match n with
|
||||
| NativeIntSource.Verbatim i -> i >= 0L
|
||||
| NativeIntSource.FunctionPointer _ -> failwith "TODO"
|
||||
| NativeIntSource.TypeHandlePtr _ -> true
|
||||
| NativeIntSource.ManagedPointer _ -> true
|
||||
|
||||
/// True if a < b.
|
||||
let isLess (a : NativeIntSource) (b : NativeIntSource) : bool =
|
||||
match a, b with
|
||||
| NativeIntSource.Verbatim a, NativeIntSource.Verbatim b -> a < b
|
||||
| _, _ -> failwith "TODO"
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
type UnsignedNativeIntSource =
|
||||
| Verbatim of uint64
|
||||
| FromManagedPointer of ManagedPointerSource
|
||||
|
||||
/// See I.12.3.2.1 for definition
|
||||
type EvalStackValue =
|
||||
| Int32 of int32
|
||||
@@ -164,8 +104,6 @@ module EvalStackValue =
|
||||
| EvalStackValue.Int32 i -> CliType.Numeric (CliNumericType.Int32 i)
|
||||
| EvalStackValue.UserDefinedValueType [ popped ] -> toCliTypeCoerced target popped
|
||||
| i -> failwith $"TODO: %O{i}"
|
||||
| CliNumericType.TypeHandlePtr _
|
||||
| CliNumericType.ProvenanceTrackedNativeInt64 _
|
||||
| CliNumericType.Int64 _ ->
|
||||
match popped with
|
||||
| EvalStackValue.Int64 i -> CliType.Numeric (CliNumericType.Int64 i)
|
||||
@@ -173,11 +111,18 @@ module EvalStackValue =
|
||||
match src with
|
||||
| NativeIntSource.Verbatim i -> CliType.Numeric (CliNumericType.Int64 i)
|
||||
| NativeIntSource.ManagedPointer ptr -> failwith "TODO"
|
||||
| NativeIntSource.FunctionPointer f ->
|
||||
CliType.Numeric (CliNumericType.ProvenanceTrackedNativeInt64 f)
|
||||
| NativeIntSource.TypeHandlePtr f -> CliType.Numeric (CliNumericType.TypeHandlePtr f)
|
||||
| NativeIntSource.FunctionPointer f -> failwith $"TODO: {f}"
|
||||
// CliType.Numeric (CliNumericType.ProvenanceTrackedNativeInt64 f)
|
||||
| NativeIntSource.TypeHandlePtr f -> failwith $"TODO: {f}"
|
||||
// CliType.Numeric (CliNumericType.TypeHandlePtr f)
|
||||
| i -> failwith $"TODO: %O{i}"
|
||||
| CliNumericType.NativeInt int64 -> failwith "todo"
|
||||
| CliNumericType.NativeInt _ ->
|
||||
match popped with
|
||||
| EvalStackValue.NativeInt s -> CliNumericType.NativeInt s
|
||||
| EvalStackValue.ManagedPointer ptrSrc ->
|
||||
CliNumericType.NativeInt (NativeIntSource.ManagedPointer ptrSrc)
|
||||
| _ -> failwith $"TODO: {popped}"
|
||||
|> CliType.Numeric
|
||||
| CliNumericType.NativeFloat f -> failwith "todo"
|
||||
| CliNumericType.Int8 _ ->
|
||||
match popped with
|
||||
@@ -262,7 +207,8 @@ module EvalStackValue =
|
||||
match src with
|
||||
| ManagedPointerSource.Heap src ->
|
||||
CliType.RuntimePointer (CliRuntimePointer.Managed (CliRuntimePointerSource.Heap src))
|
||||
| ManagedPointerSource.Null -> failwith "TODO"
|
||||
| ManagedPointerSource.Null ->
|
||||
CliType.RuntimePointer (CliRuntimePointer.Managed CliRuntimePointerSource.Null)
|
||||
| ManagedPointerSource.LocalVariable (a, b, c) ->
|
||||
CliType.RuntimePointer (
|
||||
CliRuntimePointer.Managed (CliRuntimePointerSource.LocalVariable (a, b, c))
|
||||
@@ -270,7 +216,7 @@ module EvalStackValue =
|
||||
| ManagedPointerSource.Argument (a, b, c) ->
|
||||
CliType.RuntimePointer (CliRuntimePointer.Managed (CliRuntimePointerSource.Argument (a, b, c)))
|
||||
| NativeIntSource.FunctionPointer methodInfo ->
|
||||
CliType.Numeric (CliNumericType.ProvenanceTrackedNativeInt64 methodInfo)
|
||||
CliType.Numeric (CliNumericType.NativeInt (NativeIntSource.FunctionPointer methodInfo))
|
||||
| NativeIntSource.TypeHandlePtr int64 -> failwith "todo"
|
||||
| _ -> failwith $"TODO: %O{popped}"
|
||||
| CliType.Char _ ->
|
||||
@@ -298,7 +244,7 @@ module EvalStackValue =
|
||||
match numeric with
|
||||
| CliNumericType.Int32 i -> EvalStackValue.Int32 i
|
||||
| CliNumericType.Int64 i -> EvalStackValue.Int64 i
|
||||
| CliNumericType.NativeInt i -> failwith "TODO"
|
||||
| CliNumericType.NativeInt i -> EvalStackValue.NativeInt i
|
||||
// Sign-extend types int8 and int16
|
||||
// Zero-extend unsigned int8/unsigned int16
|
||||
| CliNumericType.Int8 b -> int32<int8> b |> EvalStackValue.Int32
|
||||
@@ -308,9 +254,6 @@ module EvalStackValue =
|
||||
| CliNumericType.Float32 f -> EvalStackValue.Float (float<float32> f)
|
||||
| CliNumericType.Float64 f -> EvalStackValue.Float f
|
||||
| CliNumericType.NativeFloat f -> EvalStackValue.Float f
|
||||
| CliNumericType.ProvenanceTrackedNativeInt64 f ->
|
||||
EvalStackValue.NativeInt (NativeIntSource.FunctionPointer f)
|
||||
| CliNumericType.TypeHandlePtr f -> EvalStackValue.NativeInt (NativeIntSource.TypeHandlePtr f)
|
||||
| CliType.ObjectRef i ->
|
||||
match i with
|
||||
| None -> EvalStackValue.ManagedPointer ManagedPointerSource.Null
|
||||
@@ -320,7 +263,7 @@ module EvalStackValue =
|
||||
| CliType.Char (high, low) -> int32 high * 256 + int32 low |> EvalStackValue.Int32
|
||||
| CliType.RuntimePointer ptr ->
|
||||
match ptr with
|
||||
| CliRuntimePointer.Unmanaged _ -> failwith "todo: unmanaged"
|
||||
| CliRuntimePointer.Unmanaged ptrInt -> NativeIntSource.Verbatim ptrInt |> EvalStackValue.NativeInt
|
||||
| CliRuntimePointer.Managed ptr ->
|
||||
match ptr with
|
||||
| CliRuntimePointerSource.LocalVariable (sourceThread, methodFrame, var) ->
|
||||
@@ -330,7 +273,7 @@ module EvalStackValue =
|
||||
ManagedPointerSource.Argument (sourceThread, methodFrame, var)
|
||||
|> EvalStackValue.ManagedPointer
|
||||
| CliRuntimePointerSource.Heap addr -> EvalStackValue.ObjectRef addr
|
||||
| CliRuntimePointerSource.Null -> failwith "TODO"
|
||||
| CliRuntimePointerSource.Null -> EvalStackValue.ManagedPointer ManagedPointerSource.Null
|
||||
| CliType.ValueType fields -> fields |> List.map ofCliType |> EvalStackValue.UserDefinedValueType
|
||||
|
||||
type EvalStack =
|
||||
|
@@ -1211,6 +1211,10 @@ module IlMachineState =
|
||||
resolveTypeFromSpec loggerFactory corelib parent assy typeGenerics methodGenerics state
|
||||
| parent -> failwith $"Unexpected: {parent}"
|
||||
|
||||
let executingMethod = state.ThreadState.[currentThread].MethodState.ExecutingMethod
|
||||
let methodGenerics = executingMethod.Generics
|
||||
let typeGenerics = executingMethod.DeclaringType.Generics
|
||||
|
||||
match mem.Signature with
|
||||
| MemberSignature.Field fieldSig ->
|
||||
let availableFields =
|
||||
@@ -1234,8 +1238,12 @@ module IlMachineState =
|
||||
let availableMethods =
|
||||
targetType.Methods
|
||||
|> List.filter (fun mi -> mi.Name = memberName)
|
||||
// TODO: this needs to resolve the TypeMethodSignature to e.g. remove references to generic parameters
|
||||
|> List.filter (fun mi -> mi.Signature = memberSig)
|
||||
|> List.filter (fun mi ->
|
||||
let pars = mi.Signature.ParameterTypes = memberSig.ParameterTypes
|
||||
let ret = mi.Signature.ReturnType = memberSig.ReturnType
|
||||
pars && ret
|
||||
// TypeMethodSignature.sigsEqual (TypeDefn.equals ) mi.Signature memberSig
|
||||
)
|
||||
|
||||
let method =
|
||||
match availableMethods with
|
||||
|
@@ -47,7 +47,7 @@ module NullaryIlOp =
|
||||
// Helper to get the target CliType for each Ldind variant
|
||||
let private getTargetLdindCliType (targetType : LdindTargetType) : CliType =
|
||||
match targetType with
|
||||
| LdindI -> CliType.Numeric (CliNumericType.NativeInt 0L)
|
||||
| LdindI -> CliType.Numeric (CliNumericType.NativeInt (NativeIntSource.Verbatim 0L))
|
||||
| LdindI1 -> CliType.Numeric (CliNumericType.Int8 0y)
|
||||
| LdindI2 -> CliType.Numeric (CliNumericType.Int16 0s)
|
||||
| LdindI4 -> CliType.Numeric (CliNumericType.Int32 0)
|
||||
@@ -357,15 +357,23 @@ module NullaryIlOp =
|
||||
| EvalStackValue.Float var1, EvalStackValue.Float var2 -> failwith "TODO: float CEQ float"
|
||||
| EvalStackValue.Float _, _ -> failwith $"bad ceq: Float vs {var2}"
|
||||
| EvalStackValue.NativeInt var1, EvalStackValue.NativeInt var2 ->
|
||||
failwith $"TODO (CEQ): nativeint vs nativeint"
|
||||
match var1, var2 with
|
||||
| NativeIntSource.FunctionPointer f1, NativeIntSource.FunctionPointer f2 ->
|
||||
if f1 = f2 then
|
||||
1
|
||||
else
|
||||
failwith $"TODO(CEQ): nativeint vs nativeint, {f1} vs {f2}"
|
||||
| NativeIntSource.TypeHandlePtr f1, NativeIntSource.TypeHandlePtr f2 -> if f1 = f2 then 1 else 0
|
||||
| NativeIntSource.Verbatim f1, NativeIntSource.Verbatim f2 -> if f1 = f2 then 1 else 0
|
||||
| NativeIntSource.ManagedPointer f1, NativeIntSource.ManagedPointer f2 -> if f1 = f2 then 1 else 0
|
||||
| _, _ -> failwith $"TODO (CEQ): nativeint vs nativeint, {var1} vs {var2}"
|
||||
| EvalStackValue.NativeInt var1, EvalStackValue.Int32 var2 -> failwith $"TODO (CEQ): nativeint vs int32"
|
||||
| EvalStackValue.NativeInt var1, EvalStackValue.ManagedPointer var2 ->
|
||||
failwith $"TODO (CEQ): nativeint vs managed pointer"
|
||||
| EvalStackValue.NativeInt _, _ -> failwith $"bad ceq: NativeInt vs {var2}"
|
||||
| EvalStackValue.ObjectRef var1, EvalStackValue.ObjectRef var2 -> if var1 = var2 then 1 else 0
|
||||
| EvalStackValue.ObjectRef _, _ -> failwith $"bad ceq: ObjectRef vs {var2}"
|
||||
| EvalStackValue.ManagedPointer var1, EvalStackValue.ManagedPointer var2 ->
|
||||
failwith $"TODO (CEQ): managed pointers"
|
||||
| EvalStackValue.ManagedPointer var1, EvalStackValue.ManagedPointer var2 -> if var1 = var2 then 1 else 0
|
||||
| EvalStackValue.ManagedPointer var1, EvalStackValue.NativeInt var2 ->
|
||||
failwith $"TODO (CEQ): managed pointer vs nativeint"
|
||||
| EvalStackValue.ManagedPointer _, _ -> failwith $"bad ceq: ManagedPointer vs {var2}"
|
||||
@@ -717,7 +725,7 @@ module NullaryIlOp =
|
||||
| Localloc -> failwith "TODO: Localloc unimplemented"
|
||||
| Stind_I ->
|
||||
let state =
|
||||
stind (CliType.Numeric (CliNumericType.NativeInt 0L)) currentThread state
|
||||
stind (CliType.Numeric (CliNumericType.NativeInt (NativeIntSource.Verbatim 0L))) currentThread state
|
||||
|> IlMachineState.advanceProgramCounter currentThread
|
||||
|
||||
(state, WhatWeDid.Executed) |> ExecutionResult.Stepped
|
||||
|
@@ -45,8 +45,8 @@ module TypeHandleRegistry =
|
||||
// for the GC, I think?
|
||||
"m_keepalive", CliType.ObjectRef None
|
||||
// TODO: this is actually a System.IntPtr https://github.com/dotnet/runtime/blob/ec11903827fc28847d775ba17e0cd1ff56cfbc2e/src/coreclr/nativeaot/Runtime.Base/src/System/Primitives.cs#L339
|
||||
"m_cache", CliType.Numeric (CliNumericType.NativeInt 0L)
|
||||
"m_handle", CliType.Numeric (CliNumericType.TypeHandlePtr handle)
|
||||
"m_cache", CliType.Numeric (CliNumericType.NativeInt (NativeIntSource.Verbatim 0L))
|
||||
"m_handle", CliType.Numeric (CliNumericType.NativeInt (NativeIntSource.TypeHandlePtr handle))
|
||||
// This is the const -1, apparently?!
|
||||
// https://github.com/dotnet/runtime/blob/f0168ee80ba9aca18a7e7140b2bb436defda623c/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs#L2496
|
||||
"GenericParameterCountAny", CliType.Numeric (CliNumericType.Int32 -1)
|
||||
|
@@ -141,7 +141,54 @@ module internal UnaryMetadataIlOp =
|
||||
|> fst
|
||||
|> IlMachineState.callMethodInActiveAssembly loggerFactory baseClassTypes thread true generics method None
|
||||
|
||||
| Castclass -> failwith "TODO: Castclass unimplemented"
|
||||
| Castclass ->
|
||||
let logger = loggerFactory.CreateLogger "Castclass"
|
||||
|
||||
let actualObj, state = IlMachineState.popEvalStack thread state
|
||||
|
||||
let actualObj =
|
||||
match actualObj with
|
||||
| EvalStackValue.ManagedPointer p ->
|
||||
match p with
|
||||
| ManagedPointerSource.Heap a -> a
|
||||
| ManagedPointerSource.Null -> failwith "TODO: push null and succeed"
|
||||
| _ -> failwith $"TODO: {p}"
|
||||
| s -> failwith $"TODO: {s}"
|
||||
|
||||
let targetType : TypeDefn =
|
||||
match metadataToken with
|
||||
| MetadataToken.TypeDefinition td ->
|
||||
let activeAssy = state.ActiveAssembly thread
|
||||
let ty = activeAssy.TypeDefs.[td]
|
||||
|
||||
let baseTy =
|
||||
DumpedAssembly.resolveBaseType
|
||||
baseClassTypes
|
||||
state._LoadedAssemblies
|
||||
activeAssy.Name
|
||||
ty.BaseType
|
||||
|
||||
let sigType =
|
||||
match baseTy with
|
||||
| ResolvedBaseType.Enum
|
||||
| ResolvedBaseType.ValueType -> SignatureTypeKind.ValueType
|
||||
| ResolvedBaseType.Object -> SignatureTypeKind.Class
|
||||
| ResolvedBaseType.Delegate -> failwith "todo"
|
||||
|
||||
TypeDefn.FromDefinition (ComparableTypeDefinitionHandle.Make td, activeAssy.Name.FullName, sigType)
|
||||
| MetadataToken.TypeSpecification handle -> state.ActiveAssembly(thread).TypeSpecs.[handle].Signature
|
||||
| m -> failwith $"unexpected metadata token {m} in Castclass"
|
||||
|
||||
let sourceType = state.ManagedHeap.NonArrayObjects.[actualObj].Type
|
||||
|
||||
logger.LogDebug (
|
||||
"Casting object of type {SourceTypeAssembly}.{SourceTypeNamespace}.{SourceTypeName}",
|
||||
sourceType.Assembly.Name,
|
||||
sourceType.Namespace,
|
||||
sourceType.Name
|
||||
)
|
||||
|
||||
failwith "TODO: Castclass unimplemented"
|
||||
| Newobj ->
|
||||
let logger = loggerFactory.CreateLogger "Newobj"
|
||||
|
||||
@@ -342,6 +389,8 @@ module internal UnaryMetadataIlOp =
|
||||
| Box -> failwith "TODO: Box unimplemented"
|
||||
| Ldelema -> failwith "TODO: Ldelema unimplemented"
|
||||
| Isinst ->
|
||||
let logger = loggerFactory.CreateLogger "Isinst"
|
||||
|
||||
let actualObj, state = IlMachineState.popEvalStack thread state
|
||||
|
||||
let targetType : TypeDefn =
|
||||
|
Reference in New Issue
Block a user