Skip to content

Commit

Permalink
derecord
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinRansom committed Jul 20, 2023
1 parent 9744a9c commit 1c07e1e
Showing 1 changed file with 16 additions and 27 deletions.
43 changes: 16 additions & 27 deletions src/Compiler/CodeGen/IlxGen.fs
Original file line number Diff line number Diff line change
Expand Up @@ -216,34 +216,23 @@ let CountCallFuncInstructions = NewCounter "callfunc instructions (indirect call
type LazyInitInfoArray = ResizeArray<ILFieldSpec -> ILInstr list -> ILInstr list -> unit>

/// Non-local information related to internals of code generation within an assembly
type IlxGenIntraAssemblyInfo =
{
/// A table recording the generated name of the static backing fields for each mutable top level value where
/// we may need to take the address of that value, e.g. static mutable module-bound values which are structs. These are
/// only accessible intra-assembly. Across assemblies, taking the address of static mutable module-bound values is not permitted.
/// The key to the table is the method ref for the property getter for the value, which is a stable name for the Val's
/// that come from both the signature and the implementation.
StaticFieldInfo: ConcurrentDictionary<ILMethodRef, ILFieldSpec>

/// list of .cctor for nested modules initialization etc.
LazyInitInfo: LazyInitInfoArray
}
/// A table recording the generated name of the static backing fields for each mutable top level value where
/// we may need to take the address of that value, e.g. static mutable module-bound values which are structs. These are
/// only accessible intra-assembly. Across assemblies, taking the address of static mutable module-bound values is not permitted.
/// The key to the table is the method ref for the property getter for the value, which is a stable name for the Val's
/// that come from both the signature and the implementation.
type IlxGenIntraAssemblyInfo (staticFieldInfo: ConcurrentDictionary<ILMethodRef, ILFieldSpec>, lazyInitInfo: LazyInitInfoArray) =

static member Create() =
{
StaticFieldInfo = ConcurrentDictionary<_, _>(HashIdentity.Structural)
LazyInitInfo = new LazyInitInfoArray()
}
static member Create() = new IlxGenIntraAssemblyInfo(new ConcurrentDictionary<_, _>(HashIdentity.Structural), new LazyInitInfoArray())

member this.GetOrAddStaticFieldInfo(info: ILMethodRef, f: System.Func<ILMethodRef, ILFieldSpec>) =
this.StaticFieldInfo.GetOrAdd(info, f)
member _.AddTypeInitInfo(f: ILFieldSpec -> ILInstr list -> ILInstr list -> unit) = lazyInitInfo.Add(f)

member this.AddLazyInitInfo(f: ILFieldSpec -> ILInstr list -> ILInstr list -> unit) = this.LazyInitInfo.Add(f)
member _.GetTypeInitInfo() = lazyInitInfo.ToArray()

member _.GetOrAddStaticFieldInfo(info: ILMethodRef, f: System.Func<ILMethodRef, ILFieldSpec>) = staticFieldInfo.GetOrAdd(info, f)

member _.WithNewLazyInitInfo() = IlxGenIntraAssemblyInfo(staticFieldInfo, new LazyInitInfoArray())

member this.WithNewLazyInitInfo() =
{ this with
LazyInitInfo = new LazyInitInfoArray()
}

/// Helper to make sure we take tailcalls in some situations
type FakeUnit = | Fake
Expand Down Expand Up @@ -10193,7 +10182,7 @@ and GenImplFile cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (implFile: Checke
// Final file, explicit entry point: place the code in a .cctor, and add code to main that forces the .cctor (if topCode has initialization effect).
| Some tref ->
if doesSomething then
eenv.intraAssemblyInfo.AddLazyInitInfo(fun fspec feefee seqpt ->
eenv.intraAssemblyInfo.AddTypeInitInfo(fun fspec feefee seqpt ->
// This adds the explicit init of the .cctor to the explicit entry point main method
let ilDebugRange = GenPossibleILDebugRange cenv m

Expand Down Expand Up @@ -10261,7 +10250,7 @@ and GenImplFile cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (implFile: Checke

// Run the imperative (yuck!) actions that force the generation
// of references to the cctor for nested modules etc.
eenv.intraAssemblyInfo.LazyInitInfo |> Seq.iter (fun f -> f fspec feefee seqpt)
eenv.intraAssemblyInfo.GetTypeInitInfo() |> Seq.iter (fun f -> f fspec feefee seqpt)

if isScript && not isFinalFile then
mgbuf.AddScriptInitFieldSpec(fspec, m)
Expand All @@ -10286,7 +10275,7 @@ and GenImplFile cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (implFile: Checke
and GenForceWholeFileInitializationAsPartOfCCtor cenv (mgbuf: AssemblyBuilder) tref eenv m =
// Authoring a .cctor with effects forces the cctor for the 'initialization' module by doing a dummy store & load of a field
// Doing both a store and load keeps FxCop happier because it thinks the field is useful
eenv.intraAssemblyInfo.LazyInitInfo.Add(fun fspec feefee seqpt ->
eenv.intraAssemblyInfo.AddTypeInitInfo(fun fspec feefee seqpt ->
let ilDebugRange = GenPossibleILDebugRange cenv m
mgbuf.AddExplicitInitToSpecificMethodDef((fun md -> md.Name = ".cctor"), tref, fspec, ilDebugRange, eenv.imports, feefee, seqpt))

Expand Down

0 comments on commit 1c07e1e

Please sign in to comment.