Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 26 additions & 19 deletions src/absil/il.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2133,26 +2133,33 @@ and [<Sealed>] ILTypeDefs(f : unit -> ILPreTypeDef[]) =
let ns, n = splitILTypeName nm
dict.Value.[(ns, n)].GetTypeDef()


and [<NoEquality; NoComparison>] ILPreTypeDef =
abstract Namespace: string list
abstract Name: string
abstract GetTypeDef: unit -> ILTypeDef


/// This is a memory-critical class. Very many of these objects get allocated and held to represent the contents of .NET assemblies.
and [<Sealed>] ILPreTypeDef(nameSpace: string list, name: string, metadataIndex: int32, storage: ILTypeDefStored) =
and [<Sealed>] ILPreTypeDefImpl(nameSpace: string list, name: string, metadataIndex: int32, storage: ILTypeDefStored) =
let mutable store : ILTypeDef = Unchecked.defaultof<_>

member __.Namespace = nameSpace
member __.Name = name
member __.MetadataIndex = metadataIndex
interface ILPreTypeDef with
member __.Namespace = nameSpace
member __.Name = name

member x.GetTypeDef() =
match box store with
| null ->
match storage with
| ILTypeDefStored.Given td ->
store <- td
td
| ILTypeDefStored.Computed f ->
LazyInitializer.EnsureInitialized<ILTypeDef>(&store, Func<_>(fun () -> f()))
| ILTypeDefStored.Reader f ->
LazyInitializer.EnsureInitialized<ILTypeDef>(&store, Func<_>(fun () -> f x.MetadataIndex))
| _ -> store
member x.GetTypeDef() =
match box store with
| null ->
match storage with
| ILTypeDefStored.Given td ->
store <- td
td
| ILTypeDefStored.Computed f ->
LazyInitializer.EnsureInitialized<ILTypeDef>(&store, Func<_>(fun () -> f()))
| ILTypeDefStored.Reader f ->
LazyInitializer.EnsureInitialized<ILTypeDef>(&store, Func<_>(fun () -> f metadataIndex))
| _ -> store

and ILTypeDefStored =
| Given of ILTypeDef
Expand Down Expand Up @@ -2491,11 +2498,11 @@ let mkRefForNestedILTypeDef scope (enc: ILTypeDef list, td: ILTypeDef) =

let mkILPreTypeDef (td: ILTypeDef) =
let ns, n = splitILTypeName td.Name
ILPreTypeDef (ns, n, NoMetadataIdx, ILTypeDefStored.Given td)
ILPreTypeDefImpl (ns, n, NoMetadataIdx, ILTypeDefStored.Given td) :> ILPreTypeDef
let mkILPreTypeDefComputed (ns, n, f) =
ILPreTypeDef (ns, n, NoMetadataIdx, ILTypeDefStored.Computed f)
ILPreTypeDefImpl (ns, n, NoMetadataIdx, ILTypeDefStored.Computed f) :> ILPreTypeDef
let mkILPreTypeDefRead (ns, n, idx, f) =
ILPreTypeDef (ns, n, idx, f)
ILPreTypeDefImpl (ns, n, idx, f) :> ILPreTypeDef


let addILTypeDef td (tdefs: ILTypeDefs) = ILTypeDefs (fun () -> [| yield mkILPreTypeDef td; yield! tdefs.AsArrayOfPreTypeDefs |])
Expand Down
14 changes: 9 additions & 5 deletions src/absil/il.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -1322,12 +1322,16 @@ and [<NoComparison; NoEquality>]
/// The information is enough to perform name resolution for the F# compiler, probe attributes
/// for ExtensionAttribute etc. This is key to the on-demand exploration of .NET metadata.
/// This information has to be "Goldilocks" - not too much, not too little, just right.
and [<NoEquality; NoComparison; Sealed>] ILPreTypeDef =
member Namespace: string list
member Name: string
member MetadataIndex: int32
and [<NoEquality; NoComparison>] ILPreTypeDef =
abstract Namespace: string list
abstract Name: string
/// Realise the actual full typedef
member GetTypeDef : unit -> ILTypeDef
abstract GetTypeDef : unit -> ILTypeDef


and [<NoEquality; NoComparison; Sealed>] ILPreTypeDefImpl =
interface ILPreTypeDef


and [<Sealed>] ILTypeDefStored

Expand Down
6 changes: 3 additions & 3 deletions src/fsharp/import.fs
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ and ImportILTypeDefList amap m (cpath: CompilationPath) enc items =
let modty = lazy (ImportILTypeDefList amap m (cpath.NestedCompPath n Namespace) enc tgs)
NewModuleOrNamespace (Some cpath) taccessPublic (mkSynId m n) XmlDoc.Empty [] (MaybeLazy.Lazy modty))
(fun (n, info: Lazy<_>) ->
let (scoref2, _, lazyTypeDef: ILPreTypeDef) = info.Force()
let (scoref2, lazyTypeDef: ILPreTypeDef) = info.Force()
ImportILTypeDef amap m scoref2 cpath enc n (lazyTypeDef.GetTypeDef()))

let kind = match enc with [] -> Namespace | _ -> ModuleOrType
Expand All @@ -489,7 +489,7 @@ and ImportILTypeDefList amap m (cpath: CompilationPath) enc items =
and ImportILTypeDefs amap m scoref cpath enc (tdefs: ILTypeDefs) =
// We be very careful not to force a read of the type defs here
tdefs.AsArrayOfPreTypeDefs
|> Array.map (fun pre -> (pre.Namespace, (pre.Name, notlazy(scoref, pre.MetadataIndex, pre))))
|> Array.map (fun pre -> (pre.Namespace, (pre.Name, notlazy(scoref, pre))))
|> Array.toList
|> ImportILTypeDefList amap m cpath enc

Expand Down Expand Up @@ -519,7 +519,7 @@ let ImportILAssemblyExportedType amap m auxModLoader (scoref: ILScopeRef) (expor
| None ->
error(Error(FSComp.SR.impReferenceToDllRequiredByAssembly(exportedType.ScopeRef.QualifiedName, scoref.QualifiedName, exportedType.Name), m))
| Some preTypeDef ->
scoref, -1, preTypeDef)
scoref, preTypeDef)

[ ImportILTypeDefList amap m (CompPath(scoref, [])) [] [(ns, (n, info))] ]

Expand Down