Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
DedSec256 committed Jun 13, 2024
1 parent f0f27cc commit 029fd16
Show file tree
Hide file tree
Showing 12 changed files with 192 additions and 84 deletions.
36 changes: 22 additions & 14 deletions src/Compiler/AbstractIL/il.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2611,6 +2611,14 @@ let convertInitSemantics (init: ILTypeInit) =
| ILTypeInit.BeforeField -> TypeAttributes.BeforeFieldInit
| ILTypeInit.OnAny -> enum 0

[<Flags>]
type ILTypeDefAdditionalFlags =
| None = 0
| IsKnownToBeAttribute = 1
/// The type can contain extension methods,
/// or this information may not be available at the time the ILTypeDef is created
| CanContainExtensionMethods = 2

[<NoComparison; NoEquality; StructuredFormatDisplay("{DebugText}")>]
type ILTypeDef
(
Expand All @@ -2626,7 +2634,7 @@ type ILTypeDef
methodImpls: ILMethodImplDefs,
events: ILEventDefs,
properties: ILPropertyDefs,
isKnownToBeAttribute: bool,
additionalFlags: ILTypeDefAdditionalFlags,
securityDeclsStored: ILSecurityDeclsStored,
customAttrsStored: ILAttributesStored,
metadataIndex: int32
Expand All @@ -2646,7 +2654,7 @@ type ILTypeDef
methodImpls,
events,
properties,
isKnownToBeAttribute,
additionalFlags,
securityDecls,
customAttrs) =
ILTypeDef(
Expand All @@ -2662,9 +2670,9 @@ type ILTypeDef
methodImpls,
events,
properties,
isKnownToBeAttribute,
additionalFlags,
storeILSecurityDecls securityDecls,
storeILCustomAttrs customAttrs,
customAttrs,
NoMetadataIdx
)

Expand Down Expand Up @@ -2694,12 +2702,12 @@ type ILTypeDef

member _.Properties = properties

member _.IsKnownToBeAttribute = isKnownToBeAttribute

member _.CustomAttrsStored = customAttrsStored

member _.MetadataIndex = metadataIndex

member _.HasAdditionalFlags(flags) = additionalFlags &&& flags = flags

member x.With
(
?name,
Expand All @@ -2714,7 +2722,7 @@ type ILTypeDef
?methodImpls,
?events,
?properties,
?isKnownToBeAttribute,
?newAdditionalFlags,
?customAttrs,
?securityDecls
) =
Expand All @@ -2732,11 +2740,11 @@ type ILTypeDef
methodImpls = defaultArg methodImpls x.MethodImpls,
events = defaultArg events x.Events,
properties = defaultArg properties x.Properties,
isKnownToBeAttribute = defaultArg isKnownToBeAttribute x.IsKnownToBeAttribute,
customAttrs = defaultArg customAttrs x.CustomAttrs
additionalFlags = defaultArg newAdditionalFlags additionalFlags,
customAttrs = defaultArg customAttrs (storeILCustomAttrs x.CustomAttrs)
)

member x.CustomAttrs =
member x.CustomAttrs: ILAttributes =
match customAttrsStored with
| ILAttributesStored.Reader f ->
let res = ILAttributes(f x.MetadataIndex)
Expand Down Expand Up @@ -4220,11 +4228,11 @@ let mkILGenericClass (nm, access, genparams, extends, impl, methods, fields, nes
methods = methods,
fields = fields,
nestedTypes = nestedTypes,
customAttrs = attrs,
customAttrs = storeILCustomAttrs attrs,
methodImpls = emptyILMethodImpls,
properties = props,
events = events,
isKnownToBeAttribute = false,
additionalFlags = ILTypeDefAdditionalFlags.None,
securityDecls = emptyILSecurityDecls
)

Expand All @@ -4244,11 +4252,11 @@ let mkRawDataValueTypeDef (iltyp_ValueType: ILType) (nm, size, pack) =
methods = emptyILMethods,
fields = emptyILFields,
nestedTypes = emptyILTypeDefs,
customAttrs = emptyILCustomAttrs,
customAttrs = emptyILCustomAttrsStored,
methodImpls = emptyILMethodImpls,
properties = emptyILProperties,
events = emptyILEvents,
isKnownToBeAttribute = false,
additionalFlags = ILTypeDefAdditionalFlags.None,
securityDecls = emptyILSecurityDecls
)

Expand Down
21 changes: 15 additions & 6 deletions src/Compiler/AbstractIL/il.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
module rec FSharp.Compiler.AbstractIL.IL

open System
open FSharp.Compiler.IO
open System.Collections.Generic
open System.Reflection
Expand Down Expand Up @@ -1481,6 +1482,12 @@ type ILTypeDefs =
/// Calls to <c>ExistsByName</c> will result in all the ILPreTypeDefs being read.
member internal ExistsByName: string -> bool

[<Flags>]
type ILTypeDefAdditionalFlags =
| None = 0
| IsKnownToBeAttribute = 1
| CanContainExtensionMethods = 2

/// Represents IL Type Definitions.
[<NoComparison; NoEquality>]
type ILTypeDef =
Expand All @@ -1499,7 +1506,7 @@ type ILTypeDef =
methodImpls: ILMethodImplDefs *
events: ILEventDefs *
properties: ILPropertyDefs *
isKnownToBeAttribute: bool *
additionalFlags: ILTypeDefAdditionalFlags *
securityDeclsStored: ILSecurityDeclsStored *
customAttrsStored: ILAttributesStored *
metadataIndex: int32 ->
Expand All @@ -1519,9 +1526,9 @@ type ILTypeDef =
methodImpls: ILMethodImplDefs *
events: ILEventDefs *
properties: ILPropertyDefs *
isKnownToBeAttribute: bool *
additionalFlags: ILTypeDefAdditionalFlags *
securityDecls: ILSecurityDecls *
customAttrs: ILAttributes ->
customAttrs: ILAttributesStored ->
ILTypeDef

member Name: string
Expand Down Expand Up @@ -1555,7 +1562,8 @@ type ILTypeDef =
/// e.g. if they use SuppressUnmanagedCodeSecurityAttribute
member HasSecurity: bool
member Encoding: ILDefaultPInvokeEncoding
member IsKnownToBeAttribute: bool

member HasAdditionalFlags: ILTypeDefAdditionalFlags -> bool

member internal WithAccess: ILTypeDefAccess -> ILTypeDef
member internal WithNestedAccess: ILMemberAccess -> ILTypeDef
Expand Down Expand Up @@ -1584,8 +1592,8 @@ type ILTypeDef =
?methodImpls: ILMethodImplDefs *
?events: ILEventDefs *
?properties: ILPropertyDefs *
?isKnownToBeAttribute: bool *
?customAttrs: ILAttributes *
?newAdditionalFlags: ILTypeDefAdditionalFlags *
?customAttrs: ILAttributesStored *
?securityDecls: ILSecurityDecls ->
ILTypeDef

Expand Down Expand Up @@ -2214,6 +2222,7 @@ val mkILCustomAttrsFromArray: ILAttribute[] -> ILAttributes
val storeILCustomAttrs: ILAttributes -> ILAttributesStored
val internal mkILCustomAttrsReader: (int32 -> ILAttribute[]) -> ILAttributesStored
val emptyILCustomAttrs: ILAttributes
val emptyILCustomAttrsStored: ILAttributesStored

val mkILSecurityDecls: ILSecurityDecl list -> ILSecurityDecls
val emptyILSecurityDecls: ILSecurityDecls
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/AbstractIL/ilmorph.fs
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ let rec tdef_ty2ty_ilmbody2ilmbody_mdefs2mdefs isInKnownSet enc fs (tdef: ILType
methodImpls = mimpls_ty2ty fTyInCtxtR tdef.MethodImpls,
events = edefs_ty2ty fTyInCtxtR tdef.Events,
properties = pdefs_ty2ty fTyInCtxtR tdef.Properties,
customAttrs = cattrs_ty2ty fTyInCtxtR tdef.CustomAttrs
customAttrs = storeILCustomAttrs (cattrs_ty2ty fTyInCtxtR tdef.CustomAttrs)
)

and tdefs_ty2ty_ilmbody2ilmbody_mdefs2mdefs isInKnownSet enc fs tdefs =
Expand Down
92 changes: 76 additions & 16 deletions src/Compiler/AbstractIL/ilread.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2112,9 +2112,64 @@ and typeDefReader ctxtH : ILTypeDefStored =
let layout = typeLayoutOfFlags ctxt mdv flags idx

let hasLayout =
(match layout with
| ILTypeDefLayout.Explicit _ -> true
| _ -> false)
match layout with
| ILTypeDefLayout.Explicit _ -> true
| _ -> false

let containsExtensionMethods =
let mutable containsExtensionMethods = false
let searchedKey = TaggedIndex(hca_TypeDef, idx)

let attributesSearcher =
{ new ISeekReadIndexedRowReader<CustomAttributeRow, CustomAttributeRow, CustomAttributeRow> with
member _.GetRow(i, row) =
seekReadCustomAttributeRow ctxt mdv i &row

member _.GetKey(row) = row
member _.CompareKey(key) = hcaCompare searchedKey key.parentIndex
member _.ConvertRow(row) = row
}

let attrsStartIdx, attrsEndIdx =
seekReadIndexedRowsRange
(ctxt.getNumRows TableNames.CustomAttribute)
(isSorted ctxt TableNames.CustomAttribute)
attributesSearcher

let hasAttributes = attrsStartIdx > 0 && attrsEndIdx >= attrsStartIdx
let mutable attrIdx = attrsStartIdx

while hasAttributes && attrIdx <= attrsEndIdx && not containsExtensionMethods do
let mutable attr = Unchecked.defaultof<_>
attributesSearcher.GetRow(attrIdx, &attr)
let attrCtorIdx = attr.typeIndex.index

let name =
if attr.typeIndex.tag = cat_MethodDef then
let idx = seekMethodDefParent ctxt attrCtorIdx
let _, nameIdx, namespaceIdx, _, _, _ = seekReadTypeDefRow ctxt idx
readBlobHeapAsTypeName ctxt (nameIdx, namespaceIdx)
else
let mrpTag, _, _ = seekReadMemberRefRow ctxt mdv attrCtorIdx

if mrpTag.tag <> mrp_TypeRef then
""
else
let _, nameIdx, namespaceIdx = seekReadTypeRefRow ctxt mdv mrpTag.index
readBlobHeapAsTypeName ctxt (nameIdx, namespaceIdx)

if name = "System.Runtime.CompilerServices.ExtensionAttribute" then
containsExtensionMethods <- true

attrIdx <- attrIdx + 1

containsExtensionMethods

let additionalFlags =
if containsExtensionMethods then
ILTypeDefAdditionalFlags.CanContainExtensionMethods
else
ILTypeDefAdditionalFlags.None

let mdefs = seekReadMethods ctxt numTypars methodsIdx endMethodsIdx
let fdefs = seekReadFields ctxt (numTypars, hasLayout) fieldsIdx endFieldsIdx
Expand All @@ -2138,7 +2193,7 @@ and typeDefReader ctxtH : ILTypeDefStored =
methodImpls = mimpls,
events = events,
properties = props,
isKnownToBeAttribute = false,
additionalFlags = additionalFlags,
customAttrsStored = ctxt.customAttrsReader_TypeDef,
metadataIndex = idx
))
Expand Down Expand Up @@ -2797,22 +2852,27 @@ and seekReadMemberRefAsFieldSpecUncached ctxtH (MemberRefAsFspecIdx(numTypars, i
// method-range and field-range start/finish indexes
and seekReadMethodDefAsMethodData ctxt idx = ctxt.seekReadMethodDefAsMethodData idx

and seekMethodDefParent (ctxt: ILMetadataReader) methodIdx =
seekReadIndexedRow (
ctxt.getNumRows TableNames.TypeDef,
(fun i -> i, seekReadTypeDefRowWithExtents ctxt i),
id,
(fun (_, ((_, _, _, _, _, methodsIdx), (_, endMethodsIdx))) ->
if endMethodsIdx <= methodIdx then
1
elif methodsIdx <= methodIdx && methodIdx < endMethodsIdx then
0
else
-1),
true,
fst
)

and seekReadMethodDefAsMethodDataUncached ctxtH idx =
let (ctxt: ILMetadataReader) = getHole ctxtH
let mdv = ctxt.mdfile.GetView()
// Look for the method def parent.
let tidx =
seekReadIndexedRow (
ctxt.getNumRows TableNames.TypeDef,
(fun i -> i, seekReadTypeDefRowWithExtents ctxt i),
id,
(fun (_, ((_, _, _, _, _, methodsIdx), (_, endMethodsIdx))) ->
if endMethodsIdx <= idx then 1
elif methodsIdx <= idx && idx < endMethodsIdx then 0
else -1),
true,
fst
)
let tidx = seekMethodDefParent ctxt idx
// Create a formal instantiation if needed
let typeGenericArgs = seekReadGenericParams ctxt 0 (tomd_TypeDef, tidx)
let typeGenericArgsCount = typeGenericArgs.Length
Expand Down
5 changes: 3 additions & 2 deletions src/Compiler/AbstractIL/ilwrite.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1159,7 +1159,8 @@ let canGenMethodDef (tdef: ILTypeDef) cenv (mdef: ILMethodDef) =

// We want to generate pretty much everything for attributes, because of serialization scenarios, and the fact that non-visible constructors, properties and fields can still be part of reference assembly.
// Example: NoDynamicInvocationAttribute has an internal constructor, which should be included in the reference assembly.
else if tdef.IsKnownToBeAttribute && mdef.IsSpecialName && (not mdef.IsClassInitializer) then
else if tdef.HasAdditionalFlags(ILTypeDefAdditionalFlags.IsKnownToBeAttribute) &&
mdef.IsSpecialName && (not mdef.IsClassInitializer) then
true
else
match mdef.Access with
Expand All @@ -1179,7 +1180,7 @@ let canGenFieldDef (tdef: ILTypeDef) cenv (fd: ILFieldDef) =
if not cenv.referenceAssemblyOnly then
true
// We want to explicitly generate fields for struct types and attributes, since they can be part of `unmanaged constraint`.
else if tdef.IsStruct || tdef.IsKnownToBeAttribute then
else if tdef.IsStruct || tdef.HasAdditionalFlags(ILTypeDefAdditionalFlags.IsKnownToBeAttribute) then
true
else
match fd.Access with
Expand Down
6 changes: 5 additions & 1 deletion src/Compiler/Checking/NameResolution.fs
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,11 @@ let NextExtensionMethodPriority() = uint64 (newStamp())
/// Checks if the type is used for C# style extension members.
let IsTyconRefUsedForCSharpStyleExtensionMembers g m (tcref: TyconRef) =
// Type must be non-generic and have 'Extension' attribute
isNil(tcref.Typars m) && TyconRefHasAttribute g m g.attrib_ExtensionAttribute tcref
match metadataOfTycon tcref.Deref with
| ILTypeMetadata(TILObjectReprData(_, _, tdef)) ->
tdef.HasAdditionalFlags(ILTypeDefAdditionalFlags.CanContainExtensionMethods)
| _ -> true
&& isNil(tcref.Typars m) && TyconRefHasAttribute g m g.attrib_ExtensionAttribute tcref

/// Checks if the type is used for C# style extension members.
let IsTypeUsedForCSharpStyleExtensionMembers g m ty =
Expand Down
8 changes: 4 additions & 4 deletions src/Compiler/CodeGen/EraseClosures.fs
Original file line number Diff line number Diff line change
Expand Up @@ -578,11 +578,11 @@ let rec convIlxClosureDef cenv encl (td: ILTypeDef) clo =
extends = Some cenv.mkILTyFuncTy,
methods = mkILMethods (ctorMethodDef :: nowApplyMethDef :: nowMethods),
fields = mkILFields (mkILCloFldDefs cenv nowFields @ td.Fields.AsList()),
customAttrs = emptyILCustomAttrs,
customAttrs = emptyILCustomAttrsStored,
methodImpls = emptyILMethodImpls,
properties = emptyILProperties,
events = emptyILEvents,
isKnownToBeAttribute = false,
additionalFlags = ILTypeDefAdditionalFlags.None,
securityDecls = emptyILSecurityDecls
)
.WithSpecialName(false)
Expand Down Expand Up @@ -712,11 +712,11 @@ let rec convIlxClosureDef cenv encl (td: ILTypeDef) clo =
extends = Some nowEnvParentClass,
methods = mkILMethods (ctorMethodDef :: nowApplyMethDef :: nowMethods),
fields = mkILFields (mkILCloFldDefs cenv nowFields @ td.Fields.AsList()),
customAttrs = emptyILCustomAttrs,
customAttrs = emptyILCustomAttrsStored,
methodImpls = emptyILMethodImpls,
properties = emptyILProperties,
events = emptyILEvents,
isKnownToBeAttribute = false,
additionalFlags = ILTypeDefAdditionalFlags.None,
securityDecls = emptyILSecurityDecls
)
.WithHasSecurity(false)
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/CodeGen/EraseUnions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1452,8 +1452,8 @@ let mkClassUnionDef
methodImpls = emptyILMethodImpls,
events = emptyILEvents,
properties = emptyILProperties,
isKnownToBeAttribute = false,
customAttrs = emptyILCustomAttrs
additionalFlags = ILTypeDefAdditionalFlags.None,
customAttrs = emptyILCustomAttrsStored
)
.WithNestedAccess(cud.UnionCasesAccessibility)
.WithAbstract(true)
Expand Down
Loading

0 comments on commit 029fd16

Please sign in to comment.