mirror of
https://github.com/Smaug123/WoofWare.PawPrint
synced 2025-10-07 06:58:39 +00:00
Add field pointer handle (#113)
This commit is contained in:
@@ -41,6 +41,7 @@ type ManagedPointerSource =
|
||||
| Argument of sourceThread : ThreadId * methodFrame : int * whichVar : uint16
|
||||
| Heap of ManagedHeapAddress
|
||||
| ArrayIndex of arr : ManagedHeapAddress * index : int
|
||||
| Field of ManagedPointerSource * fieldName : string
|
||||
| Null
|
||||
|
||||
override this.ToString () =
|
||||
@@ -52,6 +53,7 @@ type ManagedPointerSource =
|
||||
| ManagedPointerSource.Argument (source, method, var) ->
|
||||
$"<argument %i{var} in method frame %i{method} of thread %O{source}>"
|
||||
| ManagedPointerSource.ArrayIndex (arr, index) -> $"<index %i{index} of array %O{arr}>"
|
||||
| ManagedPointerSource.Field (source, name) -> $"<field %s{name} of %O{source}>"
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
type UnsignedNativeIntSource =
|
||||
@@ -117,6 +119,7 @@ type CliNumericType =
|
||||
type CliRuntimePointerSource =
|
||||
| LocalVariable of sourceThread : ThreadId * methodFrame : int * whichVar : uint16
|
||||
| Argument of sourceThread : ThreadId * methodFrame : int * whichVar : uint16
|
||||
| Field of source : CliRuntimePointerSource * fieldName : string
|
||||
| Heap of ManagedHeapAddress
|
||||
| ArrayIndex of arr : ManagedHeapAddress * index : int
|
||||
| Null
|
||||
@@ -132,6 +135,10 @@ module CliRuntimePointerSource =
|
||||
| ManagedPointerSource.Heap managedHeapAddress -> CliRuntimePointerSource.Heap managedHeapAddress
|
||||
| ManagedPointerSource.Null -> CliRuntimePointerSource.Null
|
||||
| ManagedPointerSource.ArrayIndex (arr, ind) -> CliRuntimePointerSource.ArrayIndex (arr, ind)
|
||||
| ManagedPointerSource.Field (a, ind) ->
|
||||
let a = ofManagedPointerSource a
|
||||
CliRuntimePointerSource.Field (a, ind)
|
||||
|
||||
|
||||
type CliRuntimePointer =
|
||||
| Unmanaged of int64
|
||||
|
@@ -319,6 +319,9 @@ module EvalStackValue =
|
||||
|> EvalStackValue.ManagedPointer
|
||||
| CliRuntimePointerSource.Heap addr -> EvalStackValue.ObjectRef addr
|
||||
| CliRuntimePointerSource.Null -> EvalStackValue.ManagedPointer ManagedPointerSource.Null
|
||||
| CliRuntimePointerSource.Field (source, fieldName) ->
|
||||
ManagedPointerSource.Field (failwith "TODO", fieldName)
|
||||
|> EvalStackValue.ManagedPointer
|
||||
| CliType.ValueType fields ->
|
||||
// TODO: this is a bit dubious; we're being a bit sloppy with possibly-overlapping fields here
|
||||
fields.Fields
|
||||
|
@@ -169,6 +169,7 @@ module EvalStackValueComparisons =
|
||||
match src with
|
||||
| ManagedPointerSource.Heap src -> src = var1
|
||||
| ManagedPointerSource.Null -> false
|
||||
| ManagedPointerSource.Field _
|
||||
| ManagedPointerSource.LocalVariable _
|
||||
| ManagedPointerSource.Argument _ -> false
|
||||
| ManagedPointerSource.ArrayIndex (arr, index) -> failwith "todo"
|
||||
|
@@ -88,6 +88,7 @@ module System_Threading_Monitor =
|
||||
failwith "not really expecting to *edit* an argument..."
|
||||
| ManagedPointerSource.Heap addr -> failwith "todo: managed heap"
|
||||
| ManagedPointerSource.ArrayIndex _ -> failwith "todo: array index"
|
||||
| ManagedPointerSource.Field (managedPointerSource, fieldName) -> failwith "todo"
|
||||
|
||||
(state, WhatWeDid.Executed) |> ExecutionResult.Stepped
|
||||
|
||||
|
@@ -1602,6 +1602,12 @@ module IlMachineState =
|
||||
state.ThreadState.[sourceThread].MethodStates.[methodFrame].Arguments.[int<uint16> whichVar]
|
||||
| ManagedPointerSource.Heap addr -> failwith "todo"
|
||||
| ManagedPointerSource.ArrayIndex (arr, index) -> getArrayValue arr index state
|
||||
| ManagedPointerSource.Field (addr, name) ->
|
||||
let obj = dereferencePointer state addr
|
||||
|
||||
match obj with
|
||||
| CliType.ValueType vt -> vt |> CliValueType.DereferenceField name
|
||||
| v -> failwith $"could not find field {name} on object {v}"
|
||||
|
||||
let lookupTypeDefn
|
||||
(baseClassTypes : BaseClassTypes<DumpedAssembly>)
|
||||
|
@@ -62,6 +62,7 @@ module IlMachineStateExecution =
|
||||
state, o.ConcreteType
|
||||
| ManagedPointerSource.ArrayIndex (arr, index) -> failwith "todo"
|
||||
| ManagedPointerSource.Null -> failwith "todo"
|
||||
| ManagedPointerSource.Field (managedPointerSource, fieldName) -> failwith "todo"
|
||||
| EvalStackValue.ObjectRef addr ->
|
||||
let o = ManagedHeap.get addr state.ManagedHeap
|
||||
state, o.ConcreteType
|
||||
|
@@ -112,6 +112,7 @@ module Intrinsics =
|
||||
CliRuntimePointer.Managed (CliRuntimePointerSource.Heap managedHeapAddress)
|
||||
| ManagedPointerSource.Null -> failwith "todo"
|
||||
| ManagedPointerSource.ArrayIndex _ -> failwith "TODO"
|
||||
| ManagedPointerSource.Field _ -> failwith "TODO"
|
||||
| x -> failwith $"TODO: Unsafe.AsPointer(%O{x})"
|
||||
|
||||
IlMachineState.pushToEvalStack (CliType.RuntimePointer toPush) currentThread state
|
||||
|
@@ -37,19 +37,6 @@ module NullaryIlOp =
|
||||
| LdindR4 -> CliType.Numeric (CliNumericType.Float32 0.0f)
|
||||
| LdindR8 -> CliType.Numeric (CliNumericType.Float64 0.0)
|
||||
|
||||
/// Retrieve a value from a pointer
|
||||
let private loadFromPointerSource (state : IlMachineState) (src : ManagedPointerSource) : CliType =
|
||||
match src with
|
||||
| ManagedPointerSource.Null -> failwith "unexpected null pointer in Ldind operation"
|
||||
| ManagedPointerSource.Argument (sourceThread, methodFrame, whichVar) ->
|
||||
state.ThreadState.[sourceThread].MethodStates.[methodFrame].Arguments.[int<uint16> whichVar]
|
||||
| ManagedPointerSource.LocalVariable (sourceThread, methodFrame, whichVar) ->
|
||||
state.ThreadState.[sourceThread].MethodStates.[methodFrame].LocalVariables.[int<uint16> whichVar]
|
||||
| ManagedPointerSource.Heap managedHeapAddress -> failwith "TODO: Heap pointer dereferencing not implemented"
|
||||
| ManagedPointerSource.ArrayIndex (arr, index) ->
|
||||
let arr = state.ManagedHeap.Arrays.[arr]
|
||||
arr.Elements.[index]
|
||||
|
||||
// Unified Ldind implementation
|
||||
let private executeLdind
|
||||
(targetType : LdindTargetType)
|
||||
@@ -61,7 +48,7 @@ module NullaryIlOp =
|
||||
|
||||
let loadedValue =
|
||||
match popped with
|
||||
| EvalStackValue.ManagedPointer src -> loadFromPointerSource state src
|
||||
| EvalStackValue.ManagedPointer src -> IlMachineState.dereferencePointer state src
|
||||
| EvalStackValue.NativeInt nativeIntSource ->
|
||||
failwith $"TODO: Native int pointer dereferencing not implemented for {targetType}"
|
||||
| EvalStackValue.ObjectRef managedHeapAddress ->
|
||||
@@ -125,6 +112,7 @@ module NullaryIlOp =
|
||||
}
|
||||
| ManagedPointerSource.Heap managedHeapAddress -> failwith "todo"
|
||||
| ManagedPointerSource.ArrayIndex _ -> failwith "todo"
|
||||
| ManagedPointerSource.Field (managedPointerSource, fieldName) -> failwith "todo"
|
||||
| EvalStackValue.ObjectRef managedHeapAddress -> failwith "todo"
|
||||
|
||||
let internal ldElem
|
||||
@@ -892,16 +880,7 @@ module NullaryIlOp =
|
||||
|
||||
let referenced =
|
||||
match addr with
|
||||
| EvalStackValue.ManagedPointer src ->
|
||||
match src with
|
||||
| ManagedPointerSource.Null -> failwith "TODO: throw NRE"
|
||||
| ManagedPointerSource.LocalVariable (sourceThread, methodFrame, whichVar) ->
|
||||
state.ThreadState.[sourceThread].MethodStates.[methodFrame].LocalVariables
|
||||
.[int<uint16> whichVar]
|
||||
| ManagedPointerSource.Argument (sourceThread, methodFrame, whichVar) ->
|
||||
state.ThreadState.[sourceThread].MethodStates.[methodFrame].Arguments.[int<uint16> whichVar]
|
||||
| ManagedPointerSource.Heap managedHeapAddress -> failwith "todo"
|
||||
| ManagedPointerSource.ArrayIndex _ -> failwith "todo"
|
||||
| EvalStackValue.ManagedPointer src -> IlMachineState.dereferencePointer state src
|
||||
| a -> failwith $"TODO: {a}"
|
||||
|
||||
let state =
|
||||
@@ -929,6 +908,7 @@ module NullaryIlOp =
|
||||
arr
|
||||
(EvalStackValue.toCliTypeCoerced (CliType.ObjectRef None) value)
|
||||
index
|
||||
| ManagedPointerSource.Field _ -> failwith "TODO"
|
||||
| addr -> failwith $"TODO: {addr}"
|
||||
|
||||
let state = state |> IlMachineState.advanceProgramCounter currentThread
|
||||
|
@@ -601,6 +601,8 @@ module internal UnaryMetadataIlOp =
|
||||
|> CliType.withFieldSet field.Name valueToStore
|
||||
|
||||
state |> IlMachineState.setArrayValue arr newValue index
|
||||
| EvalStackValue.ManagedPointer (ManagedPointerSource.Field (managedPointerSource, fieldName)) ->
|
||||
failwith "todo"
|
||||
| EvalStackValue.UserDefinedValueType _ -> failwith "todo"
|
||||
|
||||
state
|
||||
@@ -768,6 +770,8 @@ module internal UnaryMetadataIlOp =
|
||||
IlMachineState.pushToEvalStack currentValue thread state
|
||||
| EvalStackValue.ManagedPointer ManagedPointerSource.Null ->
|
||||
failwith "TODO: raise NullReferenceException"
|
||||
| EvalStackValue.ManagedPointer (ManagedPointerSource.Field _) ->
|
||||
failwith "TODO: get a field on a field ptr"
|
||||
| EvalStackValue.UserDefinedValueType vt ->
|
||||
let result = vt |> EvalStackValueUserType.DereferenceField field.Name
|
||||
IlMachineState.pushToEvalStack' result thread state
|
||||
|
Reference in New Issue
Block a user