Fix statics (#24)

This commit is contained in:
Patrick Stevens
2025-05-31 00:52:15 +01:00
committed by GitHub
parent 2ab920a1ba
commit ab40427a15
2 changed files with 54 additions and 15 deletions

View File

@@ -21,10 +21,25 @@ type IlMachineState =
_LoadedAssemblies : ImmutableDictionary<string, DumpedAssembly> _LoadedAssemblies : ImmutableDictionary<string, DumpedAssembly>
/// Tracks initialization state of types across assemblies /// Tracks initialization state of types across assemblies
TypeInitTable : TypeInitTable TypeInitTable : TypeInitTable
Statics : ImmutableDictionary<TypeDefinitionHandle * AssemblyName, CliType> Statics : ImmutableDictionary<TypeDefinitionHandle * AssemblyName, ImmutableDictionary<string, CliType>>
DotnetRuntimeDirs : string ImmutableArray DotnetRuntimeDirs : string ImmutableArray
} }
member this.SetStatic
(ty : TypeDefinitionHandle * AssemblyName)
(field : string)
(value : CliType)
: IlMachineState
=
let statics =
match this.Statics.TryGetValue ty with
| false, _ -> this.Statics.Add (ty, ImmutableDictionary.Create().Add (field, value))
| true, v -> this.Statics.SetItem (ty, v.SetItem (field, value))
{ this with
Statics = statics
}
member this.WithTypeBeginInit (thread : ThreadId) (handle : TypeDefinitionHandle, assy : AssemblyName) = member this.WithTypeBeginInit (thread : ThreadId) (handle : TypeDefinitionHandle, assy : AssemblyName) =
this.Logger.LogDebug ( this.Logger.LogDebug (
"Beginning initialisation of type {TypeName}, handle {TypeDefinitionHandle} from assy {AssemblyHash}", "Beginning initialisation of type {TypeName}, handle {TypeDefinitionHandle} from assy {AssemblyHash}",

View File

@@ -248,9 +248,7 @@ module internal UnaryMetadataIlOp =
EvalStackValue.toCliTypeCoerced (CliType.zeroOf ImmutableArray.Empty field.Signature) popped EvalStackValue.toCliTypeCoerced (CliType.zeroOf ImmutableArray.Empty field.Signature) popped
let state = let state =
{ state with state.SetStatic (field.DeclaringType, activeAssy.Name) field.Name toStore
Statics = state.Statics.SetItem ((field.DeclaringType, activeAssy.Name), toStore)
}
|> IlMachineState.advanceProgramCounter thread |> IlMachineState.advanceProgramCounter thread
state, WhatWeDid.Executed state, WhatWeDid.Executed
@@ -274,7 +272,7 @@ module internal UnaryMetadataIlOp =
let declaring = state.ActiveAssembly(thread).TypeDefs.[field.DeclaringType] let declaring = state.ActiveAssembly(thread).TypeDefs.[field.DeclaringType]
logger.LogInformation ( logger.LogInformation (
"Storing in object field {FieldAssembly}.{FieldDeclaringType}.{FieldName} (type {FieldType})", "Loading object field {FieldAssembly}.{FieldDeclaringType}.{FieldName} (type {FieldType})",
declaring.Assembly.Name, declaring.Assembly.Name,
declaring.Name, declaring.Name,
field.Name, field.Name,
@@ -284,7 +282,7 @@ module internal UnaryMetadataIlOp =
let currentObj, state = IlMachineState.popEvalStack thread state let currentObj, state = IlMachineState.popEvalStack thread state
if field.Attributes.HasFlag FieldAttributes.Static then if field.Attributes.HasFlag FieldAttributes.Static then
let staticField = state.Statics.[field.DeclaringType, assyName] let staticField = state.Statics.[field.DeclaringType, assyName].[field.Name]
let state = state |> IlMachineState.pushToEvalStack staticField thread let state = state |> IlMachineState.pushToEvalStack staticField thread
state, WhatWeDid.Executed state, WhatWeDid.Executed
else else
@@ -317,6 +315,8 @@ module internal UnaryMetadataIlOp =
| Ldflda -> failwith "TODO: Ldflda unimplemented" | Ldflda -> failwith "TODO: Ldflda unimplemented"
| Ldsfld -> | Ldsfld ->
let logger = loggerFactory.CreateLogger "Ldsfld"
let fieldHandle = let fieldHandle =
match metadataToken with match metadataToken with
| MetadataToken.FieldDefinition f -> f | MetadataToken.FieldDefinition f -> f
@@ -329,7 +329,6 @@ module internal UnaryMetadataIlOp =
| true, field -> | true, field ->
do do
let logger = loggerFactory.CreateLogger "Ldsfld"
let declaring = state.ActiveAssembly(thread).TypeDefs.[field.DeclaringType] let declaring = state.ActiveAssembly(thread).TypeDefs.[field.DeclaringType]
logger.LogInformation ( logger.LogInformation (
@@ -350,11 +349,27 @@ module internal UnaryMetadataIlOp =
// TODO: generics // TODO: generics
let newVal = CliType.zeroOf ImmutableArray.Empty field.Signature let newVal = CliType.zeroOf ImmutableArray.Empty field.Signature
newVal, newVal, state.SetStatic (field.DeclaringType, activeAssy.Name) field.Name newVal
{ state with | true, v ->
Statics = state.Statics.SetItem ((field.DeclaringType, activeAssy.Name), newVal) match v.TryGetValue field.Name with
} | true, v -> v, state
| true, v -> v, state | false, _ ->
// TODO: generics
let newVal = CliType.zeroOf ImmutableArray.Empty field.Signature
newVal, state.SetStatic (field.DeclaringType, activeAssy.Name) field.Name newVal
do
let logger = loggerFactory.CreateLogger "Ldsfld"
let declaring = state.ActiveAssembly(thread).TypeDefs.[field.DeclaringType]
logger.LogInformation (
"Loaded from static field {FieldAssembly}.{FieldDeclaringType}.{FieldName} (type {FieldType}), value {LoadedValue}",
declaring.Assembly.Name,
declaring.Name,
field.Name,
field.Signature,
fieldValue
)
let state = let state =
IlMachineState.pushToEvalStack fieldValue thread state IlMachineState.pushToEvalStack fieldValue thread state
@@ -385,9 +400,18 @@ module internal UnaryMetadataIlOp =
if TypeDefn.isManaged field.Signature then if TypeDefn.isManaged field.Signature then
match state.Statics.TryGetValue ((field.DeclaringType, activeAssy.Name)) with match state.Statics.TryGetValue ((field.DeclaringType, activeAssy.Name)) with
| true, v -> | true, v ->
IlMachineState.pushToEvalStack v thread state match v.TryGetValue field.Name with
|> IlMachineState.advanceProgramCounter thread | true, v ->
|> Tuple.withRight WhatWeDid.Executed IlMachineState.pushToEvalStack v thread state
|> IlMachineState.advanceProgramCounter thread
|> Tuple.withRight WhatWeDid.Executed
| false, _ ->
let allocation, state =
state |> (failwith "TODO: Ldsflda static field allocation unimplemented")
state
|> IlMachineState.pushToEvalStack (CliType.ObjectRef (Some allocation)) thread
|> Tuple.withRight WhatWeDid.Executed
| false, _ -> | false, _ ->
let allocation, state = let allocation, state =
state |> (failwith "TODO: Ldsflda static field allocation unimplemented") state |> (failwith "TODO: Ldsflda static field allocation unimplemented")