Skip to content

Commit

Permalink
code
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinRansom committed Nov 20, 2024
1 parent 542e005 commit c64060c
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 18 deletions.
41 changes: 24 additions & 17 deletions src/Compiler/CodeGen/IlxGen.fs
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ let ComputeTypeAccess (tref: ILTypeRef) hidden (accessibility: Accessibility) re

/// Indicates how type parameters are mapped to IL type variables
[<NoEquality; NoComparison>]
type TypeReprEnv(reprs: Map<Stamp, uint16>, count: int, templateReplacement: (TyconRef * ILTypeRef * Typars * TyparInstantiation) option) =
type TypeReprEnv(reprs: Map<Stamp, (uint16 * Typar)>, count: int, templateReplacement: (TyconRef * ILTypeRef * Typars * TyparInstantiation) option) =

static let empty = TypeReprEnv(count = 0, reprs = Map.empty, templateReplacement = None)

Expand All @@ -536,7 +536,7 @@ type TypeReprEnv(reprs: Map<Stamp, uint16>, count: int, templateReplacement: (Ty
/// Lookup a type parameter
member _.Item(tp: Typar, m: range) =
try
reprs[tp.Stamp]
reprs[tp.Stamp] |>fst
with :? KeyNotFoundException ->
errorR (InternalError("Undefined or unsolved type variable: " + showL (typarL tp), m))
// Random value for post-hoc diagnostic analysis on generated tree *
Expand All @@ -546,7 +546,7 @@ type TypeReprEnv(reprs: Map<Stamp, uint16>, count: int, templateReplacement: (Ty
/// then it is ignored, since it doesn't correspond to a .NET type parameter.
member tyenv.AddOne(tp: Typar) =
if IsNonErasedTypar tp then
TypeReprEnv(reprs.Add(tp.Stamp, uint16 count), count + 1, templateReplacement)
TypeReprEnv(reprs.Add(tp.Stamp, (uint16 count, tp)), count + 1, templateReplacement)
else
tyenv

Expand All @@ -573,6 +573,9 @@ type TypeReprEnv(reprs: Map<Stamp, uint16>, count: int, templateReplacement: (Ty
/// Get the environment for generating a reference to items within a type definition
member eenv.ForTyconRef(tcref: TyconRef) = eenv.ForTycon tcref.Deref

/// Get a list of the Typars in this environment
member eenv.AsUserProvidedTypars() = reprs |> Map.toList |> List.map(fun (_, (_, tp)) -> tp) |> List.filter(fun tp -> not tp.IsCompilerGenerated) |> Zset.ofList typarOrder

//--------------------------------------------------------------------------
// Generate type references
//--------------------------------------------------------------------------
Expand Down Expand Up @@ -6892,14 +6895,6 @@ and GenFreevar cenv m eenvouter tyenvinner (fv: Val) =
and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) boxity eenv takenNames expr =
let g = cenv.g

// Choose a base name for the closure
let basename =
let boundv = eenv.letBoundVars |> List.tryFind (fun v -> not v.IsCompilerGenerated)

match boundv with
| Some v -> v.CompiledName cenv.g.CompilerGlobalState
| None -> "clo"

// Get a unique stamp for the closure. This must be stable for things that can be part of a let rec.
let uniq =
match expr with
Expand All @@ -6909,18 +6904,30 @@ and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) boxity eenv takenNames
| _ -> newUnique ()

// Choose a name for the closure
let ilCloTypeRef =
let ilCloTypeRef, initialFreeTyvars =
let boundvar =
eenv.letBoundVars |> List.tryFind (fun v -> not v.IsCompilerGenerated)

let basename =
match boundvar with
| Some v -> v.CompiledName cenv.g.CompilerGlobalState
| None -> "clo"

// FSharp 1.0 bug 3404: System.Reflection doesn't like '.' and '`' in type names
let basenameSafeForUseAsTypename = CleanUpGeneratedTypeName basename

let suffixmark = expr.Range

let cloName =
// Ensure that we have an g.CompilerGlobalState
assert (g.CompilerGlobalState |> Option.isSome)
g.CompilerGlobalState.Value.StableNameGenerator.GetUniqueCompilerGeneratedName(basenameSafeForUseAsTypename, suffixmark, uniq)
g.CompilerGlobalState.Value.StableNameGenerator.GetUniqueCompilerGeneratedName(basenameSafeForUseAsTypename, expr.Range, uniq)

let ilCloTypeRef = NestedTypeRefForCompLoc eenv.cloc cloName
let initialFreeTyvars =
match g.realsig with
| true -> { emptyFreeTyvars with FreeTypars = eenv.tyenv.AsUserProvidedTypars() }
| false -> emptyFreeTyvars

NestedTypeRefForCompLoc eenv.cloc cloName
ilCloTypeRef, initialFreeTyvars

// Collect the free variables of the closure
let cloFreeVarResults =
Expand All @@ -6931,7 +6938,7 @@ and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) boxity eenv takenNames
| None -> opts
| Some(tcref, _, typars, _) -> opts.WithTemplateReplacement(tyconRefEq g tcref, typars)

freeInExpr opts expr
accFreeInExpr opts expr { emptyFreeVars with FreeTyvars = initialFreeTyvars }

// Partition the free variables when some can be accessed from places besides the immediate environment
// Also filter out the current value being bound, if any, as it is available from the "this"
Expand Down
4 changes: 3 additions & 1 deletion src/Compiler/TypedTree/CompilerGlobalState.fs
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,6 @@ let newUnique() = System.Threading.Interlocked.Increment &uniqueCount
/// Unique name generator for stamps attached to to val_specs, tycon_specs etc.
//++GLOBAL MUTABLE STATE (concurrency-safe)
let mutable private stampCount = 0L
let newStamp() = System.Threading.Interlocked.Increment &stampCount
let newStamp() =
let stamp = System.Threading.Interlocked.Increment &stampCount
stamp
3 changes: 3 additions & 0 deletions src/Compiler/TypedTree/TypedTreeOps.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,9 @@ val accFreeInDecisionTree: FreeVarOptions -> DecisionTree -> FreeVars -> FreeVar
/// Get the free variables in a module definition.
val freeInModuleOrNamespace: FreeVarOptions -> ModuleOrNamespaceContents -> FreeVars

/// Get the free variables in an expression with accumulator
val accFreeInExpr: FreeVarOptions -> Expr -> FreeVars -> FreeVars

/// Get the free variables in an expression.
val freeInExpr: FreeVarOptions -> Expr -> FreeVars

Expand Down

0 comments on commit c64060c

Please sign in to comment.