mirror of
https://github.com/Smaug123/WoofWare.PawPrint
synced 2025-10-05 14:18:40 +00:00
Uncomment a bit of a test (#64)
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
|
||||
|
@@ -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 =
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user