diff --git a/src/Compiler/CodeGen/IlxGen.fs b/src/Compiler/CodeGen/IlxGen.fs index 704c43d4b2df..74f24ac21a2e 100644 --- a/src/Compiler/CodeGen/IlxGen.fs +++ b/src/Compiler/CodeGen/IlxGen.fs @@ -213,16 +213,26 @@ let CountStaticFieldDef = NewCounter "IL field definitions corresponding to valu let CountCallFuncInstructions = NewCounter "callfunc instructions (indirect calls)" +type LazyInitInfoArray = ResizeArray 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 - } +/// 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, lazyInitInfo: LazyInitInfoArray) = + + static member Create() = new IlxGenIntraAssemblyInfo(new ConcurrentDictionary<_, _>(HashIdentity.Structural), new LazyInitInfoArray()) + + member _.AddTypeInitInfo(f: ILFieldSpec -> ILInstr list -> ILInstr list -> unit) = lazyInitInfo.Add(f) + + member _.GetTypeInitInfo() = lazyInitInfo.ToArray() + + member _.GetOrAddStaticFieldInfo(info: ILMethodRef, f: System.Func) = staticFieldInfo.GetOrAdd(info, f) + + member _.WithNewLazyInitInfo() = IlxGenIntraAssemblyInfo(staticFieldInfo, new LazyInitInfoArray()) + /// Helper to make sure we take tailcalls in some situations type FakeUnit = | Fake @@ -315,9 +325,6 @@ type cenv = /// Cache the generation of the "unit" type mutable ilUnitTy: ILType option - /// Other information from the emit of this assembly - intraAssemblyInfo: IlxGenIntraAssemblyInfo - /// Cache methods with SecurityAttribute applied to them, to prevent unnecessary calls to ExistsInEntireHierarchyOfType casApplied: IDictionary @@ -489,23 +496,25 @@ let rec TypeRefForCompLoc cloc = let mkILTyForCompLoc cloc = mkILNonGenericBoxedTy (TypeRefForCompLoc cloc) -let ComputeMemberAccess hidden = +let ComputeMemberAccess hidden (accessibility: Accessibility option) realInternalSignature = if hidden then - ILMemberAccess.Assembly + match accessibility with + | Some access when realInternalSignature -> access.AsILMemberAccess + | _ -> ILMemberAccess.Assembly else ILMemberAccess.Public -// Under --publicasinternal change types from Public to Private (internal for types) -let ComputePublicTypeAccess () = ILTypeDefAccess.Public - -let ComputeTypeAccess (tref: ILTypeRef) hidden = +let ComputeTypeAccess (tref: ILTypeRef) hidden (accessibility: Accessibility) realInternalSignature = match tref.Enclosing with | [] -> if hidden then - ILTypeDefAccess.Private + if realInternalSignature then + accessibility.AsILTypeDefAccess + else + ILTypeDefAccess.Private else - ComputePublicTypeAccess() - | _ -> ILTypeDefAccess.Nested(ComputeMemberAccess hidden) + ILTypeDefAccess.Public + | _ -> ILTypeDefAccess.Nested(ComputeMemberAccess hidden (Some accessibility) realInternalSignature) //-------------------------------------------------------------------------- // TypeReprEnv @@ -813,8 +822,12 @@ and GenTypeArgs cenv m tyenv tyargs = GenTypeArgsAux cenv m tyenv tyargs // Computes the location where the static field for a value lives. // - Literals go in their type/module. // - For interactive code, we always place fields in their type/module with an accurate name -let GenFieldSpecForStaticField (isInteractive, g, ilContainerTy, vspec: Val, nm, m, cloc, ilTy) = - if isInteractive || HasFSharpAttribute g g.attrib_LiteralAttribute vspec.Attribs then +let GenFieldSpecForStaticField (isInteractive, (g: TcGlobals), ilContainerTy: ILType, vspec: Val, nm, m, cloc, ilTy) = + if + g.realInternalSignature + || isInteractive + || HasFSharpAttribute g g.attrib_LiteralAttribute vspec.Attribs + then let fieldName = vspec.CompiledName g.CompilerGlobalState let fieldName = @@ -1193,6 +1206,12 @@ and IlxGenEnv = /// Collection of code-gen functions where each inner array represents codegen (method bodies) functions for a single file delayedFileGenReverse: list<(unit -> unit)[]> + + /// Other information from the emit of this assembly + intraAssemblyInfo: IlxGenIntraAssemblyInfo + + realInternalSignature: bool + } override _.ToString() = "" @@ -1453,7 +1472,7 @@ let ComputeFieldSpecForVal match optIntraAssemblyInfo with | None -> generate () - | Some iai -> iai.StaticFieldInfo.GetOrAdd(ilGetterMethRef, (fun _ -> generate ())) + | Some iai -> iai.GetOrAddStaticFieldInfo(ilGetterMethRef, (fun _ -> generate ())) /// Compute the representation information for an F#-declared value (not a member nor a function). /// Mutable and literal static fields must have stable names and live in the "public" location @@ -1756,21 +1775,11 @@ and AddBindingsForModuleOrNamespaceBinding allocVal cloc x eenv = /// into the stored results for the whole CCU. /// isIncrementalFragment = true --> "typed input" /// isIncrementalFragment = false --> "#load" -let AddIncrementalLocalAssemblyFragmentToIlxGenEnv - ( - cenv: cenv, - isIncrementalFragment, - g, - ccu, - fragName, - intraAssemblyInfo, - eenv, - implFiles - ) = +let AddIncrementalLocalAssemblyFragmentToIlxGenEnv (cenv: cenv, isIncrementalFragment, g, ccu, fragName, eenv, implFiles) = let cloc = CompLocForFragment fragName ccu let allocVal = - ComputeAndAddStorageForLocalValWithValReprInfo(cenv, g, intraAssemblyInfo, true, NoShadowLocal) + ComputeAndAddStorageForLocalValWithValReprInfo(cenv, g, eenv.intraAssemblyInfo, true, NoShadowLocal) (eenv, implFiles) ||> List.fold (fun eenv implFile -> @@ -2250,7 +2259,10 @@ and AssemblyBuilder(cenv: cenv, anonTypeTable: AnonTypeGenerationTable) as mgbuf let vtdef = mkRawDataValueTypeDef g.iltyp_ValueType (name, size, 0us) let vtref = NestedTypeRefForCompLoc cloc vtdef.Name let vtspec = mkILTySpec (vtref, []) - let vtdef = vtdef.WithAccess(ComputeTypeAccess vtref true) + + let vtdef = + vtdef.WithAccess(ComputeTypeAccess vtref true taccessInternal cenv.g.realInternalSignature) + mgbuf.AddTypeDef(vtref, vtdef, false, true, None) vtspec), keyComparer = HashIdentity.Structural @@ -2322,6 +2334,7 @@ and AssemblyBuilder(cenv: cenv, anonTypeTable: AnonTypeGenerationTable) as mgbuf if ilMethodDef.IsEntryPoint then explicitEntryPointInfo <- Some tref + //@@@@@@@@@@@@@@@@@@@@@@ member _.AddExplicitInitToSpecificMethodDef(cond, tref, fspec, sourceOpt, imports, feefee, seqpt) = // 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 @@ -6070,7 +6083,7 @@ and GenStructStateMachine cenv cgbuf eenvouter (res: LoweredStateMachine) sequel ) do // Suppress the "ResumptionDynamicInfo" from generated state machines if templateFld.LogicalName <> "ResumptionDynamicInfo" then - let access = ComputeMemberAccess false + let access = ComputeMemberAccess false None cenv.g.realInternalSignature let fty = GenType cenv m eenvinner.tyenv templateFld.FieldType let fdef = @@ -6091,7 +6104,7 @@ and GenStructStateMachine cenv cgbuf eenvouter (res: LoweredStateMachine) sequel // Fields for captured variables for ilCloFreeVar in ilCloFreeVars do - let access = ComputeMemberAccess false + let access = ComputeMemberAccess false None cenv.g.realInternalSignature let fdef = ILFieldDef( @@ -6136,7 +6149,7 @@ and GenStructStateMachine cenv cgbuf eenvouter (res: LoweredStateMachine) sequel ) .WithSealed(true) .WithSpecialName(true) - .WithAccess(ComputeTypeAccess ilCloTypeRef true) + .WithAccess(ComputeTypeAccess ilCloTypeRef true taccessInternal cenv.g.realInternalSignature) .WithLayout(ILTypeDefLayout.Auto) .WithEncoding(ILDefaultPInvokeEncoding.Auto) .WithInitSemantics(ILTypeInit.BeforeField) @@ -6559,7 +6572,7 @@ and GenClosureTypeDefs .WithSealed(true) .WithSerializable(true) .WithSpecialName(true) - .WithAccess(ComputeTypeAccess tref true) + .WithAccess(ComputeTypeAccess tref true taccessInternal cenv.g.realInternalSignature) .WithLayout(ILTypeDefLayout.Auto) .WithEncoding(ILDefaultPInvokeEncoding.Auto) .WithInitSemantics(ILTypeInit.BeforeField) @@ -8173,7 +8186,7 @@ and ComputeMethodAccessRestrictedBySig eenv vspec = // Compiler generated members for class function 'let' bindings get assembly visibility vspec.IsIncrClassGeneratedMember - ComputeMemberAccess isHidden + ComputeMemberAccess isHidden None eenv.realInternalSignature and GenBindingAfterDebugPoint cenv cgbuf eenv bind isStateVar startMarkOpt = let g = cenv.g @@ -8359,7 +8372,7 @@ and GenBindingAfterDebugPoint cenv cgbuf eenv bind isStateVar startMarkOpt = /// Generate a static field definition... let ilFieldDefs = let access = - ComputeMemberAccess(not hasLiteralAttr || IsHiddenVal eenv.sigToImplRemapInfo vspec) + ComputeMemberAccess (not hasLiteralAttr || IsHiddenVal eenv.sigToImplRemapInfo vspec) None cenv.g.realInternalSignature let ilFieldDef = mkILStaticField (fspec.Name, fty, None, None, access) @@ -9677,16 +9690,15 @@ and AllocValForBind cenv cgbuf (scopeMarks: Mark * Mark) eenv (TBind (v, repr, _ and AllocValReprWithinExpr cenv cgbuf endMark cloc v eenv = let g = cenv.g - + //@@@@@@@@@@@@@@@@@@ // decide whether to use a shadow local or not let useShadowLocal = cenv.options.generateDebugSymbols && not cenv.options.localOptimizationsEnabled && not v.IsCompilerGenerated && not v.IsMutable - && // Don't use shadow locals for things like functions which are not compiled as static values/properties - IsCompiledAsStaticProperty g v + && IsCompiledAsStaticProperty g v let optShadowLocal, eenv = if useShadowLocal then @@ -9696,7 +9708,7 @@ and AllocValReprWithinExpr cenv cgbuf endMark cloc v eenv = else NoShadowLocal, eenv - ComputeAndAddStorageForLocalValWithValReprInfo (cenv, g, cenv.intraAssemblyInfo, cenv.options.isInteractive, optShadowLocal) cloc v eenv + ComputeAndAddStorageForLocalValWithValReprInfo (cenv, g, eenv.intraAssemblyInfo, cenv.options.isInteractive, optShadowLocal) cloc v eenv //-------------------------------------------------------------------------- // Generate stack save/restore and assertions - pulled into letrec by alloc* @@ -9886,7 +9898,19 @@ and CreatePermissionSets cenv eenv (securityAttributes: Attrib list) = //-------------------------------------------------------------------------- /// Generate a static class at the given cloc -and GenTypeDefForCompLoc (cenv, eenv, mgbuf: AssemblyBuilder, cloc, hidden, attribs, initTrigger, eliminateIfEmpty, addAtEnd) = +and GenTypeDefForCompLoc + ( + cenv, + eenv, + mgbuf: AssemblyBuilder, + cloc, + hidden, + accessibility: Accessibility, + attribs, + initTrigger, + eliminateIfEmpty, + addAtEnd + ) = let g = cenv.g let tref = TypeRefForCompLoc cloc @@ -9894,7 +9918,7 @@ and GenTypeDefForCompLoc (cenv, eenv, mgbuf: AssemblyBuilder, cloc, hidden, attr mkILSimpleClass g.ilg (tref.Name, - ComputeTypeAccess tref hidden, + ComputeTypeAccess tref hidden accessibility cenv.g.realInternalSignature, emptyILMethods, emptyILFields, emptyILTypeDefs, @@ -9920,7 +9944,7 @@ and GenTypeDefForCompLoc (cenv, eenv, mgbuf: AssemblyBuilder, cloc, hidden, attr let tdef = tdef.WithSealed(true).WithAbstract(true) mgbuf.AddTypeDef(tref, tdef, eliminateIfEmpty, addAtEnd, None) -and GenImplFileContents cenv cgbuf qname lazyInitInfo eenv mty def = +and GenImplFileContents cenv cgbuf qname eenv mty def = // REVIEW: the scopeMarks are used for any shadow locals we create for the module bindings // We use one scope for all the bindings in the module, which makes them all appear with their "default" values // rather than incrementally as we step through the initializations in the module. This is a little unfortunate @@ -9932,13 +9956,14 @@ and GenImplFileContents cenv cgbuf qname lazyInitInfo eenv mty def = let eenv = AddSignatureRemapInfo "defs" sigToImplRemapInfo eenv // Allocate all the values, including any shadow locals for static fields + //@@@@@@@@@@@@@@@@@@@@ let eenv = AddBindingsForModuleOrNamespaceContents (AllocValReprWithinExpr cenv cgbuf endMark) eenv.cloc eenv def - let _eenvEnd = GenModuleOrNamespaceContents cenv cgbuf qname lazyInitInfo eenv def + let _eenvEnd = GenModuleOrNamespaceContents cenv cgbuf qname eenv def ()) -and GenModuleOrNamespaceContents cenv (cgbuf: CodeGenBuffer) qname lazyInitInfo eenv x = +and GenModuleOrNamespaceContents cenv (cgbuf: CodeGenBuffer) qname eenv x = match x with | TMDefRec (_isRec, opens, tycons, mbinds, m) -> let eenvinner = AddDebugImportsToEnv cenv eenv opens @@ -9947,7 +9972,7 @@ and GenModuleOrNamespaceContents cenv (cgbuf: CodeGenBuffer) qname lazyInitInfo if tc.IsFSharpException then GenExnDef cenv cgbuf.mgbuf eenvinner m tc else - GenTypeDef cenv cgbuf.mgbuf lazyInitInfo eenvinner m tc + GenTypeDef cenv cgbuf.mgbuf eenvinner m tc // Generate chunks of non-nested bindings together to allow recursive fixups. let mutable bindsRemaining = mbinds @@ -9973,7 +9998,7 @@ and GenModuleOrNamespaceContents cenv (cgbuf: CodeGenBuffer) qname lazyInitInfo GenLetRecBindings cenv cgbuf eenv (recBinds, m) bindsRemaining <- otherBinds | (ModuleOrNamespaceBinding.Module _ as mbind) :: rest -> - GenModuleBinding cenv cgbuf qname lazyInitInfo eenvinner m mbind + GenModuleBinding cenv cgbuf qname eenvinner m mbind bindsRemaining <- rest | [] -> failwith "unreachable" @@ -9991,12 +10016,10 @@ and GenModuleOrNamespaceContents cenv (cgbuf: CodeGenBuffer) qname lazyInitInfo GenExpr cenv cgbuf eenv e discard eenv - | TMDefs mdefs -> - (eenv, mdefs) - ||> List.fold (GenModuleOrNamespaceContents cenv cgbuf qname lazyInitInfo) + | TMDefs mdefs -> (eenv, mdefs) ||> List.fold (GenModuleOrNamespaceContents cenv cgbuf qname) // Generate a module binding -and GenModuleBinding cenv (cgbuf: CodeGenBuffer) (qname: QualifiedNameOfFile) lazyInitInfo eenv m x = +and GenModuleBinding cenv (cgbuf: CodeGenBuffer) (qname: QualifiedNameOfFile) eenv m x = match x with | ModuleOrNamespaceBinding.Binding bind -> GenLetRecBindings cenv cgbuf eenv ([ bind ], m) @@ -10033,6 +10056,7 @@ and GenModuleBinding cenv (cgbuf: CodeGenBuffer) (qname: QualifiedNameOfFile) la cgbuf.mgbuf, eenvinner.cloc, hidden, + mspec.Accessibility, mspec.Attribs, staticClassTrigger, false (* atEnd= *) , @@ -10040,8 +10064,7 @@ and GenModuleBinding cenv (cgbuf: CodeGenBuffer) (qname: QualifiedNameOfFile) la ) // Generate the declarations in the module and its initialization code - let _envAtEnd = - GenModuleOrNamespaceContents cenv cgbuf qname lazyInitInfo eenvinner mdef + let _envAtEnd = GenModuleOrNamespaceContents cenv cgbuf qname eenvinner mdef // If the module has a .cctor for some mutable fields, we need to ensure that when // those fields are "touched" the InitClass .cctor is forced. The InitClass .cctor will @@ -10052,13 +10075,7 @@ and GenModuleBinding cenv (cgbuf: CodeGenBuffer) (qname: QualifiedNameOfFile) la |> Seq.isEmpty |> not) then - GenForceWholeFileInitializationAsPartOfCCtor - cenv - cgbuf.mgbuf - lazyInitInfo - (TypeRefForCompLoc eenvinner.cloc) - eenv.imports - mspec.Range + GenForceWholeFileInitializationAsPartOfCCtor cenv cgbuf.mgbuf (TypeRefForCompLoc eenvinner.cloc) eenv mspec.Range /// Generate the namespace fragments in a single file and GenImplFile cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (implFile: CheckedImplFileAfterOptimization) = @@ -10097,20 +10114,15 @@ and GenImplFile cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (implFile: Checke cloc = initClassCompLoc isFinalFile = isFinalFile someTypeInThisAssembly = initClassTy + intraAssemblyInfo = eenv.intraAssemblyInfo.WithNewLazyInitInfo() } // Create the class to hold the initialization code and static fields for this file. // internal static class $ {} // Put it at the end since that gives an approximation of dependency order (to aid FSI.EXE's code generator - see FSharp 1.0 5548) - GenTypeDefForCompLoc(cenv, eenv, mgbuf, initClassCompLoc, useHiddenInitCode, [], initClassTrigger, false, true) - // lazyInitInfo is an accumulator of functions which add the forced initialization of the storage module to - // - mutable fields in public modules - // - static "let" bindings in types - // These functions only get executed/committed if we actually end up producing some code for the .cctor for the storage module. - // The existence of .cctors adds costs to execution, so this is a half-sensible attempt to avoid adding them when possible. - let lazyInitInfo = - ResizeArray ILInstr list -> ILInstr list -> unit>() + //@@@@@@@@ let lazyInitInfo = ResizeArray ILInstr list -> ILInstr list -> unit>() + GenTypeDefForCompLoc(cenv, eenv, mgbuf, initClassCompLoc, useHiddenInitCode, taccessInternal, [], initClassTrigger, false, true) // codegen .cctor/main for outer module let clocCcu = CompLocForCcu cenv.viewCcu @@ -10136,7 +10148,7 @@ and GenImplFile cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (implFile: Checke 0, None, (fun cgbuf eenv -> - GenImplFileContents cenv cgbuf qname lazyInitInfo eenv signature contents + GenImplFileContents cenv cgbuf qname eenv signature contents CG.EmitInstr cgbuf (pop 0) Push0 I_ret), m) @@ -10166,7 +10178,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 - lazyInitInfo.Add(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 @@ -10224,7 +10236,7 @@ and GenImplFile cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (implFile: Checke let initFieldName = CompilerGeneratedName "init" let ilFieldDef = - mkILStaticField (initFieldName, g.ilg.typ_Int32, None, None, ComputeMemberAccess true) + mkILStaticField (initFieldName, g.ilg.typ_Int32, None, None, ComputeMemberAccess true None cenv.g.realInternalSignature) |> g.AddFieldNeverAttributes |> g.AddFieldGeneratedAttributes @@ -10234,7 +10246,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. - 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) @@ -10244,7 +10256,7 @@ and GenImplFile cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (implFile: Checke // We add the module type all over again. Note no shadow locals for static fields needed here since they are only relevant to the main/.cctor let eenvafter = let allocVal = - ComputeAndAddStorageForLocalValWithValReprInfo(cenv, g, cenv.intraAssemblyInfo, cenv.options.isInteractive, NoShadowLocal) + ComputeAndAddStorageForLocalValWithValReprInfo(cenv, g, eenv.intraAssemblyInfo, cenv.options.isInteractive, NoShadowLocal) AddBindingsForLocalModuleOrNamespaceType allocVal clocCcu eenv signature @@ -10256,12 +10268,12 @@ and GenImplFile cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (implFile: Checke cenv.delayedGenMethods.Clear() eenvfinal -and GenForceWholeFileInitializationAsPartOfCCtor cenv (mgbuf: AssemblyBuilder) (lazyInitInfo: ResizeArray<_>) tref imports m = +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 - 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, imports, feefee, seqpt)) + mgbuf.AddExplicitInitToSpecificMethodDef((fun md -> md.Name = ".cctor"), tref, fspec, ilDebugRange, eenv.imports, feefee, seqpt)) /// Generate an Equals method. and GenEqualsOverrideCallingIComparable cenv (tcref: TyconRef, ilThisTy, _ilThatTy) = @@ -10490,7 +10502,7 @@ and GenPrintingMethod cenv eenv methName ilThisTy m = | _ -> () ] -and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = +and GenTypeDef cenv mgbuf eenv m (tycon: Tycon) = let g = cenv.g let tcref = mkLocalTyconRef tycon @@ -10522,7 +10534,9 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = let hidden = IsHiddenTycon eenv.sigToImplRemapInfo tycon let hiddenRepr = hidden || IsHiddenTyconRepr eenv.sigToImplRemapInfo tycon - let access = ComputeTypeAccess tref hidden + + let access = + ComputeTypeAccess tref hidden tycon.Accessibility cenv.g.realInternalSignature // The implicit augmentation doesn't actually create CompareTo(object) or Object.Equals // So we do it here. @@ -10624,7 +10638,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = let tyconRepr = tycon.TypeReprInfo - let reprAccess = ComputeMemberAccess hiddenRepr + let reprAccess = ComputeMemberAccess hiddenRepr None cenv.g.realInternalSignature // DebugDisplayAttribute gets copied to the subtypes generated as part of DU compilation let debugDisplayAttrs, normalAttrs = @@ -10790,7 +10804,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = [ g.CompilerGeneratedAttribute; g.DebuggerBrowsableNeverAttribute ] | _ -> [] // don't hide fields in classes in debug display - let access = ComputeMemberAccess isFieldHidden + let access = ComputeMemberAccess isFieldHidden None cenv.g.realInternalSignature let literalValue = Option.map (GenFieldInit m) fspec.LiteralValue @@ -10860,7 +10874,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = if not useGenuineField then let ilPropName = fspec.LogicalName let ilMethName = "get_" + ilPropName - let access = ComputeMemberAccess isPropHidden + let access = ComputeMemberAccess isPropHidden None cenv.g.realInternalSignature let isStruct = isStructTyconRef tcref let attrs = @@ -10883,7 +10897,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = let ilMethName = "set_" + ilPropName let ilParams = [ mkILParamNamed ("value", ilPropType) ] let ilReturn = mkILReturn ILType.Void - let iLAccess = ComputeMemberAccess isPropHidden + let iLAccess = ComputeMemberAccess isPropHidden None cenv.g.realInternalSignature let ilMethodDef = if isStatic then @@ -11394,7 +11408,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = && tycon.MembersOfFSharpTyconSorted |> List.exists (fun vref -> vref.Deref.IsClassConstructor) then - GenForceWholeFileInitializationAsPartOfCCtor cenv mgbuf lazyInitInfo tref eenv.imports m + GenForceWholeFileInitializationAsPartOfCCtor cenv mgbuf tref eenv m /// Generate the type for an F# exception declaration. and GenExnDef cenv mgbuf eenv m (exnc: Tycon) = @@ -11409,8 +11423,11 @@ and GenExnDef cenv mgbuf eenv m (exnc: Tycon) = let ilThisTy = GenExnType cenv m eenv.tyenv exncref let tref = ilThisTy.TypeRef let isHidden = IsHiddenTycon eenv.sigToImplRemapInfo exnc - let access = ComputeTypeAccess tref isHidden - let reprAccess = ComputeMemberAccess isHidden + + let access = + ComputeTypeAccess tref isHidden exnc.Accessibility cenv.g.realInternalSignature + + let reprAccess = ComputeMemberAccess isHidden None cenv.g.realInternalSignature let fspecs = exnc.TrueInstanceFieldsAsList let ilMethodDefsForProperties, ilFieldDefs, ilPropertyDefs, fieldNamesAndTypes = @@ -11573,14 +11590,13 @@ let CodegenAssembly cenv eenv mgbuf implFiles = 0, None, (fun cgbuf eenv -> - let lazyInitInfo = ResizeArray() let qname = QualifiedNameOfFile(mkSynId range0 "unused") LocalScope "module" cgbuf (fun (_, endMark) -> let eenv = AddBindingsForModuleOrNamespaceContents (AllocValReprWithinExpr cenv cgbuf endMark) eenv.cloc eenv mexpr - let _eenvEnv = GenModuleOrNamespaceContents cenv cgbuf qname lazyInitInfo eenv mexpr + let _eenvEnv = GenModuleOrNamespaceContents cenv cgbuf qname eenv mexpr ())), range0) //printfn "#_emptyTopInstrs = %d" _emptyTopInstrs.Length @@ -11615,6 +11631,8 @@ let GetEmptyIlxGenEnv (g: TcGlobals) ccu = imports = None delayCodeGen = true delayedFileGenReverse = [] + realInternalSignature = g.realInternalSignature + intraAssemblyInfo = IlxGenIntraAssemblyInfo.Create() } type IlxGenResults = @@ -11685,6 +11703,7 @@ let GenerateCode (cenv, anonTypeTable, eenv, CheckedAssemblyAfterOptimization im mgbuf, CompLocForPrivateImplementationDetails eenv.cloc, useHiddenInitCode, + taccessInternal, [], ILTypeInit.BeforeField, true (* atEnd= *) , @@ -11848,11 +11867,6 @@ type IlxAssemblyGenerator(amap: ImportMap, tcGlobals: TcGlobals, tcVal: Constrai let mutable ilxGenEnv = GetEmptyIlxGenEnv tcGlobals ccu let anonTypeTable = AnonTypeGenerationTable() - let intraAssemblyInfo = - { - StaticFieldInfo = ConcurrentDictionary<_, _>(HashIdentity.Structural) - } - let cenv = { g = tcGlobals @@ -11869,7 +11883,6 @@ type IlxAssemblyGenerator(amap: ImportMap, tcGlobals: TcGlobals, tcVal: Constrai namedDebugPointsForInlinedCode = Map.empty amap = amap casApplied = ConcurrentDictionary() - intraAssemblyInfo = intraAssemblyInfo optionsOpt = None optimizeDuringCodeGen = (fun _flag expr -> expr) stackGuard = getEmptyStackGuard () @@ -11884,16 +11897,7 @@ type IlxAssemblyGenerator(amap: ImportMap, tcGlobals: TcGlobals, tcVal: Constrai /// is assumed to be a fragment 'typed' into FSI.EXE, otherwise the input is assumed to be the result of a '#load' member _.AddIncrementalLocalAssemblyFragment(isIncrementalFragment, fragName, typedImplFiles) = ilxGenEnv <- - AddIncrementalLocalAssemblyFragmentToIlxGenEnv( - cenv, - isIncrementalFragment, - tcGlobals, - ccu, - fragName, - intraAssemblyInfo, - ilxGenEnv, - typedImplFiles - ) + AddIncrementalLocalAssemblyFragmentToIlxGenEnv(cenv, isIncrementalFragment, tcGlobals, ccu, fragName, ilxGenEnv, typedImplFiles) /// Generate ILX code for an assembly fragment member _.GenerateCode(codeGenOpts, typedAssembly: CheckedAssemblyAfterOptimization, assemAttribs, moduleAttribs) =