mirror of
https://github.com/Smaug123/WoofWare.PawPrint
synced 2025-10-12 09:08:39 +00:00
Merge commit '174e415c70843d905a6d40790cbdfdcf0f21cbdb' into generic-edge-cases
This commit is contained in:
@@ -52,6 +52,14 @@ module Parameter =
|
||||
|
||||
result.ToImmutable ()
|
||||
|
||||
type GenericVariance =
|
||||
| Covariant
|
||||
| Contravariant
|
||||
|
||||
type GenericConstraint =
|
||||
| Reference
|
||||
| NonNullableValue
|
||||
|
||||
/// <summary>
|
||||
/// Represents a generic type or method parameter definition.
|
||||
/// Corresponds to GenericParameter in System.Reflection.Metadata.
|
||||
@@ -66,6 +74,10 @@ type GenericParameter =
|
||||
/// For example, in Dictionary<TKey, TValue&rt;, TKey has index 0 and TValue has index 1.
|
||||
/// </summary>
|
||||
SequenceNumber : int
|
||||
|
||||
Variance : GenericVariance option
|
||||
Constraint : GenericConstraint option
|
||||
RequiresParameterlessConstructor : bool
|
||||
}
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
@@ -79,9 +91,31 @@ module GenericParameter =
|
||||
|> Seq.map (fun param ->
|
||||
let param = metadata.GetGenericParameter param
|
||||
|
||||
let requiresParamlessCons =
|
||||
param.Attributes.HasFlag GenericParameterAttributes.DefaultConstructorConstraint
|
||||
|
||||
let constr =
|
||||
if param.Attributes.HasFlag GenericParameterAttributes.NotNullableValueTypeConstraint then
|
||||
Some GenericConstraint.NonNullableValue
|
||||
elif param.Attributes.HasFlag GenericParameterAttributes.ReferenceTypeConstraint then
|
||||
Some GenericConstraint.Reference
|
||||
else
|
||||
None
|
||||
|
||||
let variance =
|
||||
if param.Attributes.HasFlag GenericParameterAttributes.Contravariant then
|
||||
Some GenericVariance.Contravariant
|
||||
elif param.Attributes.HasFlag GenericParameterAttributes.Covariant then
|
||||
Some GenericVariance.Covariant
|
||||
else
|
||||
None
|
||||
|
||||
{
|
||||
Name = metadata.GetString param.Name
|
||||
SequenceNumber = param.Index
|
||||
Variance = variance
|
||||
Constraint = constr
|
||||
RequiresParameterlessConstructor = requiresParamlessCons
|
||||
}
|
||||
)
|
||||
|> ImmutableArray.CreateRange
|
||||
|
@@ -119,7 +119,13 @@ module ConcreteActivePatterns =
|
||||
match handle with
|
||||
| ConcreteTypeHandle.Concrete id ->
|
||||
match concreteTypes.Mapping |> Map.tryFind id with
|
||||
| Some ct when ct.Namespace = "System" && ct.Name = "Void" && ct.Generics.IsEmpty -> Some ()
|
||||
| Some ct when
|
||||
ct.Assembly.Name = "System.Private.CoreLib"
|
||||
&& ct.Namespace = "System"
|
||||
&& ct.Name = "Void"
|
||||
&& ct.Generics.IsEmpty
|
||||
->
|
||||
Some ()
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
@@ -149,6 +155,34 @@ module ConcreteActivePatterns =
|
||||
| None -> None
|
||||
| _ -> None
|
||||
|
||||
let (|ConcreteRuntimeFieldHandle|_|) (concreteTypes : AllConcreteTypes) (handle : ConcreteTypeHandle) =
|
||||
match handle with
|
||||
| ConcreteTypeHandle.Concrete id ->
|
||||
match concreteTypes.Mapping |> Map.tryFind id with
|
||||
| Some ct when
|
||||
ct.Assembly.Name = "System.Private.CoreLib"
|
||||
&& ct.Namespace = "System"
|
||||
&& ct.Name = "RuntimeFieldHandle"
|
||||
&& ct.Generics.IsEmpty
|
||||
->
|
||||
Some ()
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
let (|ConcreteNonGenericArray|_|) (concreteTypes : AllConcreteTypes) (handle : ConcreteTypeHandle) =
|
||||
match handle with
|
||||
| ConcreteTypeHandle.Concrete id ->
|
||||
match concreteTypes.Mapping |> Map.tryFind id with
|
||||
| Some ct when
|
||||
ct.Assembly.Name = "System.Private.CoreLib"
|
||||
&& ct.Namespace = "System"
|
||||
&& ct.Name = "Array"
|
||||
&& ct.Generics.IsEmpty
|
||||
->
|
||||
Some ()
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
let (|ConcreteBool|_|) (concreteTypes : AllConcreteTypes) (handle : ConcreteTypeHandle) : unit option =
|
||||
match handle with
|
||||
| ConcreteTypeHandle.Concrete id ->
|
||||
@@ -542,7 +576,7 @@ module TypeConcretization =
|
||||
let rec concretizeType
|
||||
(ctx : ConcretizationContext<'corelib>)
|
||||
(loadAssembly :
|
||||
AssemblyName -> AssemblyReferenceHandle -> (ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly))
|
||||
AssemblyName -> AssemblyReferenceHandle -> ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly)
|
||||
(assembly : AssemblyName)
|
||||
(typeGenerics : ConcreteTypeHandle ImmutableArray)
|
||||
(methodGenerics : ConcreteTypeHandle ImmutableArray)
|
||||
@@ -890,7 +924,7 @@ module Concretization =
|
||||
let concretizeMethod
|
||||
(ctx : AllConcreteTypes)
|
||||
(loadAssembly :
|
||||
AssemblyName -> AssemblyReferenceHandle -> (ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly))
|
||||
AssemblyName -> AssemblyReferenceHandle -> ImmutableDictionary<string, DumpedAssembly> * DumpedAssembly)
|
||||
(assemblies : ImmutableDictionary<string, DumpedAssembly>)
|
||||
(baseTypes : BaseClassTypes<DumpedAssembly>)
|
||||
(method : WoofWare.PawPrint.MethodInfo<TypeDefn, WoofWare.PawPrint.GenericParameter, TypeDefn>)
|
||||
|
@@ -403,9 +403,9 @@ module IlMachineState =
|
||||
| PrimitiveType.Double -> baseClassTypes.Double
|
||||
| PrimitiveType.String -> baseClassTypes.String
|
||||
| PrimitiveType.TypedReference -> failwith "todo"
|
||||
| PrimitiveType.IntPtr -> failwith "todo"
|
||||
| PrimitiveType.UIntPtr -> failwith "todo"
|
||||
| PrimitiveType.Object -> failwith "todo"
|
||||
| PrimitiveType.IntPtr -> baseClassTypes.IntPtr
|
||||
| PrimitiveType.UIntPtr -> baseClassTypes.UIntPtr
|
||||
| PrimitiveType.Object -> baseClassTypes.Object
|
||||
|> TypeInfo.mapGeneric (fun _ -> failwith "none of these types are generic")
|
||||
|
||||
state, baseClassTypes.Corelib, ty
|
||||
|
@@ -403,7 +403,34 @@ module internal UnaryConstIlOp =
|
||||
else
|
||||
id
|
||||
|> Tuple.withRight WhatWeDid.Executed
|
||||
| Bne_un_s b -> failwith "TODO: Bne_un_s unimplemented"
|
||||
| Bne_un_s b ->
|
||||
// Table III.4
|
||||
let value2, state = IlMachineState.popEvalStack currentThread state
|
||||
let value1, state = IlMachineState.popEvalStack currentThread state
|
||||
|
||||
let isNotEqual =
|
||||
match value1, value2 with
|
||||
| EvalStackValue.Int32 v1, EvalStackValue.Int32 v2 -> v1 <> v2
|
||||
| EvalStackValue.Int32 v1, EvalStackValue.NativeInt v2 -> failwith "TODO"
|
||||
| EvalStackValue.Int32 v1, _ -> failwith $"invalid comparison, {v1} with {value2}"
|
||||
| _, EvalStackValue.Int32 v2 -> failwith $"invalid comparison, {value1} with {v2}"
|
||||
| EvalStackValue.Int64 v1, EvalStackValue.Int64 v2 -> v1 <> v2
|
||||
| EvalStackValue.Int64 v1, _ -> failwith $"invalid comparison, {v1} with {value2}"
|
||||
| _, EvalStackValue.Int64 v2 -> failwith $"invalid comparison, {value1} with {v2}"
|
||||
| EvalStackValue.Float v1, EvalStackValue.Float v2 -> v1 <> v2
|
||||
| _, EvalStackValue.Float v2 -> failwith $"invalid comparison, {value1} with {v2}"
|
||||
| EvalStackValue.Float v1, _ -> failwith $"invalid comparison, {v1} with {value2}"
|
||||
| EvalStackValue.NativeInt v1, EvalStackValue.NativeInt v2 -> v1 <> v2
|
||||
| EvalStackValue.ManagedPointer ptr1, EvalStackValue.ManagedPointer ptr2 -> ptr1 <> ptr2
|
||||
| _, _ -> failwith $"TODO {value1} {value2} (see table III.4)"
|
||||
|
||||
state
|
||||
|> IlMachineState.advanceProgramCounter currentThread
|
||||
|> if isNotEqual then
|
||||
IlMachineState.jumpProgramCounter currentThread (int b)
|
||||
else
|
||||
id
|
||||
|> Tuple.withRight WhatWeDid.Executed
|
||||
| Bge_un_s b ->
|
||||
let value2, state = IlMachineState.popEvalStack currentThread state
|
||||
let value1, state = IlMachineState.popEvalStack currentThread state
|
||||
|
Reference in New Issue
Block a user