"Fossies" - the Fresh Open Source Software Archive

Member "fsharp-4.5/src/absil/il.fs" (5 Sep 2018, 165681 Bytes) of package /linux/misc/mono-sources/fsharp/fsharp-4.5.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) F# source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "il.fs": 4.1.33_vs_4.5.

    1 // Copyright (c) Microsoft Corporation.  All Rights Reserved.  See License.txt in the project root for license information.
    2 
    3 module Microsoft.FSharp.Compiler.AbstractIL.IL 
    4 
    5 #nowarn "49"
    6 #nowarn "343" // The type 'ILAssemblyRef' implements 'System.IComparable' explicitly but provides no corresponding override for 'Object.Equals'.
    7 #nowarn "346" // The struct, record or union type 'IlxExtensionType' has an explicit implementation of 'Object.Equals'. ...
    8 
    9 
   10 open System
   11 open System.Diagnostics
   12 open System.IO
   13 open System.Collections
   14 open System.Collections.Generic
   15 open System.Collections.Concurrent
   16 open System.Runtime.CompilerServices
   17 open System.Reflection
   18 
   19 open Microsoft.FSharp.Compiler.AbstractIL
   20 open Microsoft.FSharp.Compiler.AbstractIL.Diagnostics
   21 open Microsoft.FSharp.Compiler.AbstractIL.Internal
   22 open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library
   23 
   24 open Internal.Utilities
   25  
   26 let logging = false 
   27 
   28 let runningOnMono = 
   29 #if ENABLE_MONO_SUPPORT
   30 // Officially supported way to detect if we are running on Mono.
   31 // See http://www.mono-project.com/FAQ:_Technical
   32 // "How can I detect if am running in Mono?" section
   33     try
   34         System.Type.GetType("Mono.Runtime") <> null
   35     with e-> 
   36         // Must be robust in the case that someone else has installed a handler into System.AppDomain.OnTypeResolveEvent
   37         // that is not reliable.
   38         // This is related to bug 5506--the issue is actually a bug in VSTypeResolutionService.EnsurePopulated which is  
   39         // called by OnTypeResolveEvent. The function throws a NullReferenceException. I'm working with that team to get 
   40         // their issue fixed but we need to be robust here anyway.
   41         false  
   42 #else
   43     false
   44 #endif
   45 
   46 let _ = if logging then dprintn "* warning: Il.logging is on"
   47 
   48 let int_order = LanguagePrimitives.FastGenericComparer<int>
   49 
   50 let notlazy v = Lazy<_>.CreateFromValue v
   51 
   52 /// A little ugly, but the idea is that if a data structure does not 
   53 /// contain lazy values then we don't add laziness.  So if the thing to map  
   54 /// is already evaluated then immediately apply the function.  
   55 let lazyMap f (x:Lazy<_>) =  
   56       if x.IsValueCreated then notlazy (f (x.Force())) else lazy (f (x.Force()))
   57 
   58 [<RequireQualifiedAccess>]
   59 type PrimaryAssembly = 
   60     | Mscorlib
   61     | System_Runtime   
   62     | NetStandard   
   63 
   64     member this.Name = 
   65         match this with
   66         | Mscorlib -> "mscorlib"
   67         | System_Runtime -> "System.Runtime"
   68         | NetStandard -> "netstandard"
   69     static member IsSomePrimaryAssembly n = 
   70       n = PrimaryAssembly.Mscorlib.Name 
   71       || n = PrimaryAssembly.System_Runtime.Name  
   72       || n = PrimaryAssembly.NetStandard.Name  
   73 
   74 // -------------------------------------------------------------------- 
   75 // Utilities: type names
   76 // -------------------------------------------------------------------- 
   77 
   78 let splitNameAt (nm:string) idx = 
   79     if idx < 0 then failwith "splitNameAt: idx < 0"
   80     let last = nm.Length - 1 
   81     if idx > last then failwith "splitNameAt: idx > last"
   82     (nm.Substring(0, idx)),
   83     (if idx < last then nm.Substring (idx+1, last - idx) else "")
   84 
   85 let rec splitNamespaceAux (nm:string) = 
   86     match nm.IndexOf '.' with 
   87     | -1 -> [nm]
   88     | idx -> 
   89         let s1, s2 = splitNameAt nm idx 
   90         s1::splitNamespaceAux s2 
   91 
   92 /// Global State. All namespace splits ever seen
   93 // ++GLOBAL MUTABLE STATE (concurrency-safe)
   94 let memoizeNamespaceTable = new ConcurrentDictionary<string, string list>()
   95 
   96 //  ++GLOBAL MUTABLE STATE (concurrency-safe)
   97 let memoizeNamespaceRightTable = new ConcurrentDictionary<string, string option * string>()
   98 
   99 
  100 let splitNamespace nm =
  101     memoizeNamespaceTable.GetOrAdd(nm, splitNamespaceAux)
  102 
  103 let splitNamespaceMemoized nm = splitNamespace nm
  104 
  105 // ++GLOBAL MUTABLE STATE (concurrency-safe)
  106 let memoizeNamespaceArrayTable = 
  107     Concurrent.ConcurrentDictionary<string, string[]>()
  108 
  109 let splitNamespaceToArray nm =
  110     memoizeNamespaceArrayTable.GetOrAdd(nm, fun nm -> 
  111         let x = Array.ofList (splitNamespace nm)
  112         x)
  113 
  114 let splitILTypeName (nm:string) = 
  115     match nm.LastIndexOf '.' with
  116     | -1 -> [], nm
  117     | idx -> 
  118         let s1, s2 = splitNameAt nm idx
  119         splitNamespace s1, s2
  120 
  121 let emptyStringArray = ([| |] : string[])
  122 
  123 // Duplicate of comment in import.fs:
  124 //   The type names that flow to the point include the "mangled" type names used for static parameters for provided types.
  125 //   For example,
  126 //       Foo.Bar,"1.0"
  127 //   This is because the ImportSystemType code goes via Abstract IL type references. Ultimately this probably isn't 
  128 //   the best way to do things.
  129 let splitILTypeNameWithPossibleStaticArguments (nm:string) = 
  130     let nm, suffix = 
  131         match nm.IndexOf ',' with
  132         | -1 -> nm, None
  133         | idx -> let s1, s2 = splitNameAt nm idx in s1, Some s2
  134 
  135     let nsp, nm = 
  136         match nm.LastIndexOf '.' with
  137         | -1 -> emptyStringArray, nm
  138         | idx -> 
  139             let s1, s2 = splitNameAt nm idx
  140             splitNamespaceToArray s1, s2
  141     nsp, (match suffix with None -> nm | Some s -> nm + "," + s)
  142 
  143 (*
  144 splitILTypeNameWithPossibleStaticArguments "Foo" = ([| |], "Foo")
  145 splitILTypeNameWithPossibleStaticArguments "Foo.Bar" = ([| "Foo" |], "Bar")
  146 splitILTypeNameWithPossibleStaticArguments "Foo.Bar,3" = ([| "Foo" |], "Bar, 3")
  147 splitILTypeNameWithPossibleStaticArguments "Foo.Bar," = ([| "Foo" |], "Bar,")
  148 splitILTypeNameWithPossibleStaticArguments "Foo.Bar,\"1.0\"" = ([| "Foo" |], "Bar,\"1.0\"")
  149 splitILTypeNameWithPossibleStaticArguments "Foo.Bar.Bar,\"1.0\"" = ([| "Foo"; "Bar" |], "Bar,\"1.0\"")
  150 *)
  151 
  152 let unsplitTypeName (ns, n) = 
  153     match ns with 
  154     | [] -> String.concat "." ns + "." + n 
  155     | _ -> n 
  156 
  157 let splitTypeNameRightAux nm = 
  158     if String.contains nm '.' then 
  159       let idx = String.rindex nm '.'
  160       let s1, s2 = splitNameAt nm idx
  161       Some s1, s2 
  162     else None, nm
  163 
  164 let splitTypeNameRight nm =
  165     memoizeNamespaceRightTable.GetOrAdd(nm, splitTypeNameRightAux)
  166 
  167 // -------------------------------------------------------------------- 
  168 // Ordered lists with a lookup table
  169 // --------------------------------------------------------------------
  170 
  171 /// This is used to store event, property and field maps.
  172 type LazyOrderedMultiMap<'Key, 'Data when 'Key : equality>(keyf : 'Data -> 'Key, lazyItems : Lazy<'Data list>) = 
  173 
  174     let quickMap= 
  175         lazyItems |> lazyMap (fun entries -> 
  176             let t = new Dictionary<_, _>(entries.Length, HashIdentity.Structural)
  177             do entries |> List.iter (fun y ->
  178                 let key = keyf y
  179                 let v =
  180                     match t.TryGetValue(key) with
  181                     | true, v -> v
  182                     | _ -> []
  183                 t.[key] <- y :: v) 
  184             t)
  185 
  186     member self.Entries() = lazyItems.Force()
  187 
  188     member self.Add(y) = new LazyOrderedMultiMap<'Key, 'Data>(keyf, lazyItems |> lazyMap (fun x -> y :: x))
  189     
  190     member self.Filter(f) = new LazyOrderedMultiMap<'Key, 'Data>(keyf, lazyItems |> lazyMap (List.filter f))
  191 
  192     member self.Item
  193         with get(x) =
  194             match quickMap.Force().TryGetValue(x) with
  195             | true, v -> v
  196             | _ -> []
  197 
  198 
  199 //---------------------------------------------------------------------
  200 // SHA1 hash-signing algorithm.  Used to get the public key token from
  201 // the public key.
  202 //---------------------------------------------------------------------
  203 
  204 
  205 let b0 n =  (n &&& 0xFF)
  206 let b1 n =  ((n >>> 8) &&& 0xFF)
  207 let b2 n =  ((n >>> 16) &&& 0xFF)
  208 let b3 n =  ((n >>> 24) &&& 0xFF)
  209 
  210 
  211 module SHA1 = 
  212 
  213     let inline (>>>&)  (x:int) (y:int)  = int32 (uint32 x >>> y)
  214 
  215     let f(t, b, c, d) = 
  216         if t < 20 then (b &&& c) ||| ((~~~b) &&& d)
  217         elif t < 40 then b ^^^ c ^^^ d
  218         elif t < 60 then (b &&& c) ||| (b &&& d) ||| (c &&& d)
  219         else b ^^^ c ^^^ d
  220 
  221     let [<Literal>] k0to19 = 0x5A827999
  222     let [<Literal>] k20to39 = 0x6ED9EBA1
  223     let [<Literal>] k40to59 = 0x8F1BBCDC
  224     let [<Literal>] k60to79 = 0xCA62C1D6
  225 
  226     let k t = 
  227         if t < 20 then k0to19 
  228         elif t < 40 then k20to39 
  229         elif t < 60 then k40to59 
  230         else k60to79 
  231 
  232 
  233     type SHAStream = 
  234         { stream: byte[]
  235           mutable pos: int
  236           mutable eof:  bool }
  237 
  238     let rotLeft32 x n =  (x <<< n) ||| (x >>>& (32-n))
  239 
  240     
  241     // padding and length (in bits!) recorded at end 
  242     let shaAfterEof sha  = 
  243         let n = sha.pos
  244         let len = sha.stream.Length
  245         if n = len then 0x80
  246         else 
  247           let padded_len = (((len + 9 + 63) / 64) * 64) - 8
  248           if n < padded_len - 8  then 0x0  
  249           elif (n &&& 63) = 56 then int32 ((int64 len * int64 8) >>> 56) &&& 0xff
  250           elif (n &&& 63) = 57 then int32 ((int64 len * int64 8) >>> 48) &&& 0xff
  251           elif (n &&& 63) = 58 then int32 ((int64 len * int64 8) >>> 40) &&& 0xff
  252           elif (n &&& 63) = 59 then int32 ((int64 len * int64 8) >>> 32) &&& 0xff
  253           elif (n &&& 63) = 60 then int32 ((int64 len * int64 8) >>> 24) &&& 0xff
  254           elif (n &&& 63) = 61 then int32 ((int64 len * int64 8) >>> 16) &&& 0xff
  255           elif (n &&& 63) = 62 then int32 ((int64 len * int64 8) >>> 8) &&& 0xff
  256           elif (n &&& 63) = 63 then (sha.eof <- true; int32 (int64 len * int64 8) &&& 0xff)
  257           else 0x0
  258 
  259     let shaRead8 sha = 
  260         let s = sha.stream 
  261         let b = if sha.pos >= s.Length then shaAfterEof sha else int32 s.[sha.pos]
  262         sha.pos <- sha.pos + 1
  263         b
  264         
  265     let shaRead32 sha  = 
  266         let b0 = shaRead8 sha
  267         let b1 = shaRead8 sha
  268         let b2 = shaRead8 sha
  269         let b3 = shaRead8 sha
  270         let res = (b0 <<< 24) ||| (b1 <<< 16) ||| (b2 <<< 8) ||| b3
  271         res
  272 
  273     let sha1Hash sha = 
  274         let mutable h0 = 0x67452301
  275         let mutable h1 = 0xEFCDAB89
  276         let mutable h2 = 0x98BADCFE
  277         let mutable h3 = 0x10325476
  278         let mutable h4 = 0xC3D2E1F0
  279         let mutable a = 0
  280         let mutable b = 0
  281         let mutable c = 0
  282         let mutable d = 0
  283         let mutable e = 0
  284         let w = Array.create 80 0x00
  285         while (not sha.eof) do
  286             for i = 0 to 15 do
  287                 w.[i] <- shaRead32 sha
  288             for t = 16 to 79 do
  289                 w.[t] <- rotLeft32 (w.[t-3] ^^^ w.[t-8] ^^^ w.[t-14] ^^^ w.[t-16]) 1
  290             a <- h0 
  291             b <- h1
  292             c <- h2
  293             d <- h3
  294             e <- h4
  295             for t = 0 to 79 do
  296                 let temp = (rotLeft32 a 5) + f(t, b, c, d) + e + w.[t] + k(t)
  297                 e <- d
  298                 d <- c
  299                 c <- rotLeft32 b 30
  300                 b <- a
  301                 a <- temp
  302             h0 <- h0 + a
  303             h1 <- h1 + b
  304             h2 <- h2 + c
  305             h3 <- h3 + d
  306             h4 <- h4 + e
  307         h0, h1, h2, h3, h4
  308 
  309     let sha1HashBytes s = 
  310         let (_h0, _h1, _h2, h3, h4) = sha1Hash { stream = s; pos = 0; eof = false }   // the result of the SHA algorithm is stored in registers 3 and 4
  311         Array.map byte [|  b0 h4; b1 h4; b2 h4; b3 h4; b0 h3; b1 h3; b2 h3; b3 h3; |]
  312 
  313 
  314 let sha1HashBytes s = SHA1.sha1HashBytes s
  315 
  316 // --------------------------------------------------------------------
  317 // 
  318 // -------------------------------------------------------------------- 
  319 
  320 type ILVersionInfo = uint16 * uint16 * uint16 * uint16
  321 
  322 type Locale = string
  323 
  324 [<StructuralEquality; StructuralComparison>]
  325 type PublicKey =
  326 
  327     | PublicKey of byte[]
  328 
  329     | PublicKeyToken of byte[]
  330 
  331     member x.IsKey=match x with PublicKey _ -> true | _ -> false
  332 
  333     member x.IsKeyToken=match x with PublicKeyToken _ -> true | _ -> false
  334 
  335     member x.Key=match x with PublicKey b -> b | _ -> invalidOp "not a key"
  336 
  337     member x.KeyToken=match x with PublicKeyToken b -> b | _ -> invalidOp"not a key token"
  338 
  339     member x.ToToken() = 
  340         match x with 
  341         | PublicKey bytes -> SHA1.sha1HashBytes bytes
  342         | PublicKeyToken token -> token
  343 
  344     static member KeyAsToken(k) = PublicKeyToken(PublicKey(k).ToToken())
  345 
  346 [<StructuralEquality; StructuralComparison>]
  347 type AssemblyRefData =
  348     { assemRefName: string
  349       assemRefHash: byte[] option
  350       assemRefPublicKeyInfo: PublicKey option
  351       assemRefRetargetable: bool
  352       assemRefVersion: ILVersionInfo option
  353       assemRefLocale: Locale option }
  354 
  355 /// Global state: table of all assembly references keyed by AssemblyRefData.
  356 let AssemblyRefUniqueStampGenerator = new UniqueStampGenerator<AssemblyRefData>()
  357 
  358 let isMscorlib data =
  359     data.assemRefName = "mscorlib"
  360 
  361 [<Sealed>]
  362 type ILAssemblyRef(data)  =
  363     let uniqueStamp = AssemblyRefUniqueStampGenerator.Encode(data)
  364 
  365     member x.Name=data.assemRefName
  366 
  367     member x.Hash=data.assemRefHash
  368 
  369     member x.PublicKey=data.assemRefPublicKeyInfo
  370 
  371     member x.Retargetable=data.assemRefRetargetable  
  372 
  373     member x.Version=data.assemRefVersion
  374 
  375     member x.Locale=data.assemRefLocale
  376 
  377     member x.UniqueStamp=uniqueStamp
  378 
  379     override x.GetHashCode() = uniqueStamp
  380 
  381     override x.Equals(yobj) = ((yobj :?> ILAssemblyRef).UniqueStamp = uniqueStamp)
  382 
  383     interface System.IComparable with
  384         override x.CompareTo(yobj) = compare (yobj :?> ILAssemblyRef).UniqueStamp uniqueStamp
  385 
  386     static member Create(name, hash, publicKey, retargetable, version, locale) =
  387         ILAssemblyRef
  388             { assemRefName=name
  389               assemRefHash=hash
  390               assemRefPublicKeyInfo=publicKey
  391               assemRefRetargetable=retargetable
  392               assemRefVersion=version
  393               assemRefLocale=locale }
  394 
  395     static member FromAssemblyName (aname:System.Reflection.AssemblyName) =
  396 
  397         let locale = None
  398 
  399         let publicKey = 
  400            match aname.GetPublicKey()  with 
  401            | null | [| |] -> 
  402                match aname.GetPublicKeyToken()  with 
  403                | null | [| |] -> None
  404                | bytes -> Some (PublicKeyToken bytes)
  405            | bytes -> 
  406                Some (PublicKey bytes)
  407         
  408         let version = 
  409            match aname.Version with 
  410            | null -> None
  411            | v -> Some (uint16 v.Major, uint16 v.Minor, uint16 v.Build, uint16 v.Revision)
  412            
  413         let retargetable = aname.Flags = System.Reflection.AssemblyNameFlags.Retargetable
  414 
  415         ILAssemblyRef.Create(aname.Name, None, publicKey, retargetable, version, locale)
  416  
  417     member aref.QualifiedName = 
  418         let b = new System.Text.StringBuilder(100)
  419         let add (s:string) = (b.Append(s) |> ignore)
  420         let addC (s:char) = (b.Append(s) |> ignore)
  421         add(aref.Name)
  422         match aref.Version with 
  423         | None -> ()
  424         | Some (a, b, c, d) -> 
  425             add ", Version="
  426             add (string (int a))
  427             add "."
  428             add (string (int b))
  429             add "."
  430             add (string (int c))
  431             add "."
  432             add (string (int d))
  433             add ", Culture="
  434             match aref.Locale with 
  435             | None -> add "neutral"
  436             | Some b -> add b
  437             add ", PublicKeyToken="
  438             match aref.PublicKey with 
  439             | None -> add "null"
  440             | Some pki -> 
  441                   let pkt = pki.ToToken()
  442                   let convDigit(digit) = 
  443                       let digitc = 
  444                           if digit < 10 
  445                           then  System.Convert.ToInt32 '0' + digit 
  446                           else System.Convert.ToInt32 'a' + (digit - 10) 
  447                       System.Convert.ToChar(digitc)
  448                   for i = 0 to pkt.Length-1 do
  449                       let v = pkt.[i]
  450                       addC (convDigit(System.Convert.ToInt32(v)/16))
  451                       addC (convDigit(System.Convert.ToInt32(v)%16))
  452             // retargetable can be true only for system assemblies that definitely have Version
  453             if aref.Retargetable then
  454                 add ", Retargetable=Yes" 
  455         b.ToString()
  456 
  457 
  458 [<StructuralEquality; StructuralComparison>]
  459 type ILModuleRef = 
  460     { name: string
  461       hasMetadata: bool 
  462       hash: byte[] option }
  463 
  464     static member Create(name, hasMetadata, hash) = 
  465         { name=name
  466           hasMetadata= hasMetadata
  467           hash=hash }
  468     
  469     member x.Name=x.name
  470 
  471     member x.HasMetadata=x.hasMetadata
  472 
  473     member x.Hash=x.hash 
  474 
  475 [<StructuralEquality; StructuralComparison>]
  476 [<RequireQualifiedAccess>]
  477 type ILScopeRef = 
  478     | Local
  479     | Module of ILModuleRef 
  480     | Assembly of ILAssemblyRef
  481 
  482     member x.IsLocalRef   = match x with ILScopeRef.Local      -> true | _ -> false
  483 
  484     member x.IsModuleRef  = match x with ILScopeRef.Module _   -> true | _ -> false
  485 
  486     member x.IsAssemblyRef= match x with ILScopeRef.Assembly _ -> true | _ -> false
  487 
  488     member x.ModuleRef    = match x with ILScopeRef.Module x   -> x | _ -> failwith "not a module reference"
  489 
  490     member x.AssemblyRef  = match x with ILScopeRef.Assembly x -> x | _ -> failwith "not an assembly reference"
  491 
  492     member x.QualifiedName = 
  493         match x with 
  494         | ILScopeRef.Local -> ""
  495         | ILScopeRef.Module mref -> "module "+mref.Name
  496         | ILScopeRef.Assembly aref -> aref.QualifiedName
  497 
  498 type ILArrayBound = int32 option 
  499 
  500 type ILArrayBounds = ILArrayBound * ILArrayBound
  501 
  502 [<StructuralEquality; StructuralComparison>]
  503 type ILArrayShape = 
  504 
  505     | ILArrayShape of ILArrayBounds list (* lobound/size pairs *)
  506 
  507     member x.Rank = (let (ILArrayShape l) = x in l.Length)
  508 
  509     static member SingleDimensional = ILArrayShapeStatics.SingleDimensional
  510 
  511     static member FromRank n = if n = 1 then ILArrayShape.SingleDimensional else ILArrayShape(List.replicate n (Some 0, None))
  512 
  513 
  514 and ILArrayShapeStatics() = 
  515 
  516     static let singleDimensional = ILArrayShape [(Some 0, None)]    
  517 
  518     static member SingleDimensional = singleDimensional
  519 
  520 /// Calling conventions. These are used in method pointer types.
  521 [<StructuralEquality; StructuralComparison; RequireQualifiedAccess>]
  522 type ILArgConvention = 
  523     | Default
  524     | CDecl 
  525     | StdCall 
  526     | ThisCall 
  527     | FastCall 
  528     | VarArg
  529       
  530 [<StructuralEquality; StructuralComparison; RequireQualifiedAccess>]
  531 type ILThisConvention =
  532     | Instance
  533     | InstanceExplicit
  534     | Static
  535 
  536 [<StructuralEquality; StructuralComparison>]
  537 type ILCallingConv =
  538 
  539     | Callconv of ILThisConvention * ILArgConvention
  540 
  541     member x.ThisConv           = let (Callconv(a, _b)) = x in a
  542 
  543     member x.BasicConv          = let (Callconv(_a, b)) = x in b
  544 
  545     member x.IsInstance         = match x.ThisConv with ILThisConvention.Instance -> true | _ -> false
  546 
  547     member x.IsInstanceExplicit = match x.ThisConv with ILThisConvention.InstanceExplicit -> true | _ -> false
  548 
  549     member x.IsStatic           = match x.ThisConv with ILThisConvention.Static -> true | _ -> false
  550 
  551     static member Instance = ILCallingConvStatics.Instance
  552 
  553     static member Static = ILCallingConvStatics.Static
  554 
  555 /// Static storage to amortize the allocation of <c>ILCallingConv.Instance</c> and <c>ILCallingConv.Static</c>.
  556 and ILCallingConvStatics() = 
  557 
  558     static let instanceCallConv = Callconv(ILThisConvention.Instance, ILArgConvention.Default)
  559 
  560     static let staticCallConv =  Callconv(ILThisConvention.Static, ILArgConvention.Default)
  561 
  562     static member Instance = instanceCallConv
  563 
  564     static member Static = staticCallConv
  565 
  566 type ILBoxity = 
  567     | AsObject 
  568     | AsValue
  569 
  570 // IL type references have a pre-computed hash code to enable quick lookup tables during binary generation.
  571 [<CustomEquality; CustomComparison; StructuredFormatDisplay("{DebugText}")>]
  572 type ILTypeRef = 
  573     { trefScope: ILScopeRef
  574       trefEnclosing: string list
  575       trefName: string
  576       hashCode : int 
  577       mutable asBoxedType: ILType }
  578       
  579     static member Create(scope, enclosing, name) = 
  580         let hashCode = hash scope * 17 ^^^ (hash enclosing * 101 <<< 1) ^^^ (hash name * 47 <<< 2)
  581         { trefScope=scope
  582           trefEnclosing=enclosing
  583           trefName=name
  584           hashCode=hashCode
  585           asBoxedType = Unchecked.defaultof<_> }
  586           
  587     member x.Scope = x.trefScope
  588 
  589     member x.Enclosing = x.trefEnclosing
  590 
  591     member x.Name = x.trefName
  592 
  593     member x.ApproxId = x.hashCode
  594 
  595     member x.AsBoxedType (tspec:ILTypeSpec) = 
  596         if isNil tspec.tspecInst then
  597             let v = x.asBoxedType
  598             match box v with 
  599             | null -> 
  600                let r = ILType.Boxed tspec
  601                x.asBoxedType <- r
  602                r
  603             | _ -> v
  604         else 
  605             ILType.Boxed tspec
  606 
  607     override x.GetHashCode() = x.hashCode
  608 
  609     override x.Equals(yobj) = 
  610          let y = (yobj :?> ILTypeRef) 
  611          (x.ApproxId = y.ApproxId) && 
  612          (x.Scope = y.Scope) && 
  613          (x.Name = y.Name) && 
  614          (x.Enclosing = y.Enclosing)
  615 
  616     interface System.IComparable with
  617 
  618         override x.CompareTo(yobj) = 
  619             let y = (yobj :?> ILTypeRef) 
  620             let c = compare x.ApproxId y.ApproxId
  621             if c <> 0 then c else
  622             let c = compare x.Scope y.Scope
  623             if c <> 0 then c else
  624             let c = compare x.Name y.Name 
  625             if c <> 0 then c else
  626             compare x.Enclosing y.Enclosing
  627         
  628     member tref.FullName = String.concat "." (tref.Enclosing @ [tref.Name])
  629         
  630     member tref.BasicQualifiedName =
  631         (String.concat "+" (tref.Enclosing @ [ tref.Name ] )).Replace(",", @"\,")
  632 
  633     member tref.AddQualifiedNameExtension(basic) = 
  634         let sco = tref.Scope.QualifiedName
  635         if sco = "" then basic else String.concat ", " [basic;sco]
  636 
  637     member tref.QualifiedName = 
  638         tref.AddQualifiedNameExtension(tref.BasicQualifiedName)
  639 
  640     /// For debugging
  641     [<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
  642     member x.DebugText = x.ToString()
  643 
  644     /// For debugging
  645     override x.ToString() = x.FullName
  646 
  647         
  648 and [<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
  649     ILTypeSpec = 
  650     { tspecTypeRef: ILTypeRef
  651       /// The type instantiation if the type is generic.
  652       tspecInst: ILGenericArgs }    
  653 
  654     member x.TypeRef=x.tspecTypeRef
  655 
  656     member x.Scope=x.TypeRef.Scope
  657 
  658     member x.Enclosing=x.TypeRef.Enclosing
  659 
  660     member x.Name=x.TypeRef.Name
  661 
  662     member x.GenericArgs=x.tspecInst
  663 
  664     static member Create(tref, inst) = { tspecTypeRef =tref; tspecInst=inst }
  665 
  666     member x.BasicQualifiedName = 
  667         let tc = x.TypeRef.BasicQualifiedName
  668         if isNil x.GenericArgs then
  669             tc
  670         else 
  671             tc + "[" + String.concat "," (x.GenericArgs |> List.map (fun arg -> "[" + arg.QualifiedName + "]")) + "]"
  672 
  673     member x.AddQualifiedNameExtension(basic) = 
  674         x.TypeRef.AddQualifiedNameExtension(basic)
  675 
  676     member x.FullName=x.TypeRef.FullName
  677 
  678     /// For debugging
  679     [<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
  680     member x.DebugText = x.ToString()
  681 
  682     override x.ToString() = x.TypeRef.ToString() + if isNil x.GenericArgs then "" else "<...>"
  683 
  684 and [<RequireQualifiedAccess; StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
  685     ILType =
  686     | Void                   
  687     | Array    of ILArrayShape * ILType 
  688     | Value    of ILTypeSpec      
  689     | Boxed    of ILTypeSpec      
  690     | Ptr      of ILType             
  691     | Byref    of ILType           
  692     | FunctionPointer     of ILCallingSignature 
  693     | TypeVar    of uint16              
  694     | Modified of bool * ILTypeRef * ILType
  695 
  696     member x.BasicQualifiedName = 
  697         match x with 
  698         | ILType.TypeVar n -> "!" + string n
  699         | ILType.Modified(_, _ty1, ty2) -> ty2.BasicQualifiedName
  700         | ILType.Array (ILArrayShape(s), ty) -> ty.BasicQualifiedName + "[" + System.String(',', s.Length-1) + "]"
  701         | ILType.Value tr | ILType.Boxed tr -> tr.BasicQualifiedName
  702         | ILType.Void -> "void"
  703         | ILType.Ptr _ty -> failwith "unexpected pointer type"
  704         | ILType.Byref _ty -> failwith "unexpected byref type"
  705         | ILType.FunctionPointer _mref -> failwith "unexpected function pointer type"
  706 
  707     member x.AddQualifiedNameExtension(basic) = 
  708         match x with 
  709         | ILType.TypeVar _n -> basic
  710         | ILType.Modified(_, _ty1, ty2) -> ty2.AddQualifiedNameExtension(basic)
  711         | ILType.Array (ILArrayShape(_s), ty) -> ty.AddQualifiedNameExtension(basic)
  712         | ILType.Value tr | ILType.Boxed tr -> tr.AddQualifiedNameExtension(basic)
  713         | ILType.Void -> failwith "void"
  714         | ILType.Ptr _ty -> failwith "unexpected pointer type"
  715         | ILType.Byref _ty -> failwith "unexpected byref type"
  716         | ILType.FunctionPointer _mref -> failwith "unexpected function pointer type"
  717         
  718     member x.QualifiedName = 
  719         x.AddQualifiedNameExtension(x.BasicQualifiedName)
  720 
  721     member x.TypeSpec =
  722         match x with 
  723         | ILType.Boxed tr | ILType.Value tr -> tr
  724         | _ -> invalidOp "not a nominal type"
  725 
  726     member x.Boxity =
  727         match x with 
  728         | ILType.Boxed _ -> AsObject
  729         | ILType.Value _ -> AsValue
  730         | _ -> invalidOp "not a nominal type"
  731 
  732     member x.TypeRef = 
  733         match x with 
  734         | ILType.Boxed tspec | ILType.Value tspec -> tspec.TypeRef
  735         | _ -> invalidOp "not a nominal type"
  736 
  737     member x.IsNominal = 
  738         match x with 
  739         | ILType.Boxed _ | ILType.Value _ -> true
  740         | _ -> false
  741 
  742     member x.GenericArgs =
  743         match x with 
  744         | ILType.Boxed tspec | ILType.Value tspec -> tspec.GenericArgs
  745         | _ -> []
  746 
  747     member x.IsTyvar =
  748         match x with 
  749         | ILType.TypeVar _ -> true | _ -> false
  750 
  751     /// For debugging
  752     [<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
  753     member x.DebugText = x.ToString()
  754 
  755     override x.ToString() = x.QualifiedName
  756 
  757 and [<StructuralEquality; StructuralComparison>]
  758     ILCallingSignature = 
  759     { CallingConv: ILCallingConv
  760       ArgTypes: ILTypes
  761       ReturnType: ILType }
  762 
  763 and ILGenericArgs = list<ILType>
  764 
  765 and ILTypes = list<ILType>
  766 
  767 let mkILCallSig (cc, args, ret) = { ArgTypes=args; CallingConv=cc; ReturnType=ret}
  768 
  769 let mkILBoxedType (tspec:ILTypeSpec) = tspec.TypeRef.AsBoxedType tspec
  770 
  771 [<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
  772 type ILMethodRef =
  773     { mrefParent: ILTypeRef
  774       mrefCallconv: ILCallingConv
  775       mrefGenericArity: int
  776       mrefName: string
  777       mrefArgs: ILTypes
  778       mrefReturn: ILType }
  779 
  780     member x.DeclaringTypeRef = x.mrefParent
  781 
  782     member x.CallingConv = x.mrefCallconv
  783 
  784     member x.Name = x.mrefName
  785 
  786     member x.GenericArity = x.mrefGenericArity
  787 
  788     member x.ArgCount = List.length x.mrefArgs
  789 
  790     member x.ArgTypes = x.mrefArgs
  791 
  792     member x.ReturnType = x.mrefReturn
  793 
  794     member x.CallingSignature = mkILCallSig (x.CallingConv, x.ArgTypes, x.ReturnType)
  795 
  796     static member Create(a, b, c, d, e, f) = 
  797         { mrefParent= a;mrefCallconv=b;mrefName=c;mrefGenericArity=d; mrefArgs=e;mrefReturn=f }
  798 
  799     /// For debugging
  800     [<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
  801     member x.DebugText = x.ToString()
  802 
  803     override x.ToString() = x.DeclaringTypeRef.ToString() + "::" + x.Name + "(...)"
  804 
  805 
  806 [<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
  807 type ILFieldRef = 
  808     { DeclaringTypeRef: ILTypeRef
  809       Name: string
  810       Type: ILType }
  811 
  812     /// For debugging
  813     [<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
  814     member x.DebugText = x.ToString()
  815 
  816     override x.ToString() = x.DeclaringTypeRef.ToString() + "::" + x.Name
  817 
  818 [<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
  819 type ILMethodSpec = 
  820     { mspecMethodRef: ILMethodRef
  821 
  822       mspecDeclaringType: ILType          
  823 
  824       mspecMethodInst: ILGenericArgs }     
  825 
  826     static member Create(a, b, c) = { mspecDeclaringType=a; mspecMethodRef=b; mspecMethodInst=c }
  827 
  828     member x.MethodRef = x.mspecMethodRef
  829 
  830     member x.DeclaringType=x.mspecDeclaringType
  831 
  832     member x.GenericArgs=x.mspecMethodInst
  833 
  834     member x.Name=x.MethodRef.Name
  835 
  836     member x.CallingConv=x.MethodRef.CallingConv
  837 
  838     member x.GenericArity = x.MethodRef.GenericArity
  839 
  840     member x.FormalArgTypes = x.MethodRef.ArgTypes
  841 
  842     member x.FormalReturnType = x.MethodRef.ReturnType
  843 
  844     /// For debugging
  845     [<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
  846     member x.DebugText = x.ToString()
  847 
  848     override x.ToString() = x.MethodRef.ToString() + "(...)"
  849 
  850 [<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
  851 type ILFieldSpec =
  852     { FieldRef: ILFieldRef
  853       DeclaringType: ILType }         
  854 
  855     member x.FormalType       = x.FieldRef.Type
  856 
  857     member x.Name             = x.FieldRef.Name
  858 
  859     member x.DeclaringTypeRef = x.FieldRef.DeclaringTypeRef
  860 
  861     /// For debugging
  862     [<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
  863     member x.DebugText = x.ToString()
  864 
  865     override x.ToString() = x.FieldRef.ToString()
  866 
  867 // --------------------------------------------------------------------
  868 // Debug info.                                                     
  869 // -------------------------------------------------------------------- 
  870 
  871 type ILGuid =  byte[]
  872 
  873 type ILPlatform = 
  874     | X86
  875     | AMD64
  876     | IA64
  877 
  878 type ILSourceDocument = 
  879     { sourceLanguage: ILGuid option
  880       sourceVendor: ILGuid option
  881       sourceDocType: ILGuid option
  882       sourceFile: string }
  883 
  884     static member Create(language, vendor, docType, file) =
  885         { sourceLanguage=language
  886           sourceVendor=vendor
  887           sourceDocType=docType
  888           sourceFile=file }
  889 
  890     member x.Language=x.sourceLanguage
  891 
  892     member x.Vendor=x.sourceVendor
  893 
  894     member x.DocumentType=x.sourceDocType
  895 
  896     member x.File=x.sourceFile
  897 
  898 [<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
  899 type ILSourceMarker =
  900     { sourceDocument: ILSourceDocument
  901       sourceLine: int
  902       sourceColumn: int
  903       sourceEndLine: int
  904       sourceEndColumn: int }
  905 
  906     static member Create(document, line, column, endLine, endColumn) = 
  907         { sourceDocument=document
  908           sourceLine=line
  909           sourceColumn=column
  910           sourceEndLine=endLine
  911           sourceEndColumn=endColumn }
  912 
  913     member x.Document=x.sourceDocument
  914 
  915     member x.Line=x.sourceLine
  916 
  917     member x.Column=x.sourceColumn
  918 
  919     member x.EndLine=x.sourceEndLine
  920 
  921     member x.EndColumn=x.sourceEndColumn
  922 
  923     /// For debugging
  924     [<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
  925     member x.DebugText = x.ToString()
  926 
  927     override x.ToString() = sprintf "(%d, %d)-(%d, %d)" x.Line x.Column x.EndLine x.EndColumn
  928 
  929 type ILAttribElem =  
  930   | String of string  option
  931   | Bool of bool
  932   | Char of char
  933   | SByte of int8
  934   | Int16 of int16
  935   | Int32 of int32
  936   | Int64 of int64
  937   | Byte of uint8
  938   | UInt16 of uint16
  939   | UInt32 of uint32
  940   | UInt64 of uint64
  941   | Single of single
  942   | Double of double
  943   | Null 
  944   | Type of ILType option
  945   | TypeRef of ILTypeRef option
  946   | Array of ILType * ILAttribElem list
  947 
  948 type ILAttributeNamedArg =  (string * ILType * bool * ILAttribElem)
  949 
  950 [<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
  951 type ILAttribute = 
  952     { Method: ILMethodSpec
  953       Data: byte[] 
  954       Elements: ILAttribElem list }
  955 
  956     /// For debugging
  957     [<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
  958     member x.DebugText = x.ToString()
  959 
  960     override x.ToString() = x.Method.ToString() + "(...)"
  961 
  962 [<NoEquality; NoComparison; Struct>]
  963 type ILAttributes(array : ILAttribute[]) =
  964 
  965     member x.AsArray = array
  966 
  967     member x.AsList = x.AsArray |> Array.toList
  968 
  969 [<NoEquality; NoComparison>]
  970 type ILAttributesStored =
  971 
  972     /// Computed by ilread.fs based on metadata index
  973     | Reader of (int32 -> ILAttribute[])
  974 
  975     /// Already computed
  976     | Given of ILAttributes
  977 
  978     member x.GetCustomAttrs metadataIndex = 
  979        match x with
  980        | Reader f -> ILAttributes(f metadataIndex)
  981        | Given attrs -> attrs
  982 
  983 let emptyILCustomAttrs = ILAttributes [| |]
  984 
  985 let mkILCustomAttrsFromArray (attrs: ILAttribute[]) = if attrs.Length = 0 then emptyILCustomAttrs else ILAttributes attrs
  986 
  987 let mkILCustomAttrs l = match l with [] -> emptyILCustomAttrs | _ -> mkILCustomAttrsFromArray (List.toArray l)
  988 
  989 let emptyILCustomAttrsStored = ILAttributesStored.Given emptyILCustomAttrs
  990 
  991 let storeILCustomAttrs (attrs: ILAttributes)  = if attrs.AsArray.Length = 0 then emptyILCustomAttrsStored else ILAttributesStored.Given attrs
  992 
  993 let mkILCustomAttrsReader f = ILAttributesStored.Reader f
  994 
  995 type ILCodeLabel = int
  996 
  997 // --------------------------------------------------------------------
  998 // Instruction set.                                                     
  999 // -------------------------------------------------------------------- 
 1000 
 1001 type ILBasicType =
 1002   | DT_R
 1003   | DT_I1
 1004   | DT_U1
 1005   | DT_I2
 1006   | DT_U2
 1007   | DT_I4
 1008   | DT_U4
 1009   | DT_I8
 1010   | DT_U8
 1011   | DT_R4
 1012   | DT_R8
 1013   | DT_I
 1014   | DT_U
 1015   | DT_REF
 1016 
 1017 [<StructuralEquality; StructuralComparison; RequireQualifiedAccess>]
 1018 type ILToken = 
 1019   | ILType of ILType 
 1020   | ILMethod of ILMethodSpec 
 1021   | ILField of ILFieldSpec
 1022 
 1023 [<StructuralEquality; StructuralComparison; RequireQualifiedAccess>]
 1024 type ILConst = 
 1025   | I4 of int32
 1026   | I8 of int64
 1027   | R4 of single
 1028   | R8 of double
 1029 
 1030 type ILTailcall = 
 1031   | Tailcall
 1032   | Normalcall
 1033 
 1034 type ILAlignment =  
 1035   | Aligned
 1036   | Unaligned1
 1037   | Unaligned2
 1038   | Unaligned4
 1039 
 1040 type ILVolatility =  
 1041   | Volatile
 1042   | Nonvolatile
 1043 
 1044 type ILReadonly =  
 1045   | ReadonlyAddress
 1046   | NormalAddress
 1047 
 1048 type ILVarArgs = ILTypes option
 1049 
 1050 [<StructuralEquality; StructuralComparison>]
 1051 type ILComparisonInstr = 
 1052   | BI_beq        
 1053   | BI_bge        
 1054   | BI_bge_un     
 1055   | BI_bgt        
 1056   | BI_bgt_un        
 1057   | BI_ble        
 1058   | BI_ble_un        
 1059   | BI_blt        
 1060   | BI_blt_un 
 1061   | BI_bne_un 
 1062   | BI_brfalse 
 1063   | BI_brtrue 
 1064 
 1065 
 1066 [<StructuralEquality; NoComparison>]
 1067 type ILInstr = 
 1068     | AI_add    
 1069     | AI_add_ovf
 1070     | AI_add_ovf_un
 1071     | AI_and    
 1072     | AI_div   
 1073     | AI_div_un
 1074     | AI_ceq      
 1075     | AI_cgt      
 1076     | AI_cgt_un   
 1077     | AI_clt     
 1078     | AI_clt_un  
 1079     | AI_conv      of ILBasicType
 1080     | AI_conv_ovf  of ILBasicType
 1081     | AI_conv_ovf_un  of ILBasicType
 1082     | AI_mul       
 1083     | AI_mul_ovf   
 1084     | AI_mul_ovf_un
 1085     | AI_rem       
 1086     | AI_rem_un       
 1087     | AI_shl       
 1088     | AI_shr       
 1089     | AI_shr_un
 1090     | AI_sub       
 1091     | AI_sub_ovf   
 1092     | AI_sub_ovf_un   
 1093     | AI_xor       
 1094     | AI_or        
 1095     | AI_neg       
 1096     | AI_not       
 1097     | AI_ldnull    
 1098     | AI_dup       
 1099     | AI_pop
 1100     | AI_ckfinite 
 1101     | AI_nop
 1102     | AI_ldc of ILBasicType * ILConst 
 1103     | I_ldarg     of uint16
 1104     | I_ldarga    of uint16
 1105     | I_ldind     of ILAlignment * ILVolatility * ILBasicType
 1106     | I_ldloc     of uint16
 1107     | I_ldloca    of uint16
 1108     | I_starg     of uint16
 1109     | I_stind     of  ILAlignment * ILVolatility * ILBasicType
 1110     | I_stloc     of uint16
 1111 
 1112     | I_br    of  ILCodeLabel
 1113     | I_jmp   of ILMethodSpec
 1114     | I_brcmp of ILComparisonInstr * ILCodeLabel 
 1115     | I_switch    of ILCodeLabel list  
 1116     | I_ret 
 1117 
 1118     | I_call     of ILTailcall * ILMethodSpec * ILVarArgs
 1119     | I_callvirt of ILTailcall * ILMethodSpec * ILVarArgs
 1120     | I_callconstraint of ILTailcall * ILType * ILMethodSpec * ILVarArgs
 1121     | I_calli    of ILTailcall * ILCallingSignature * ILVarArgs
 1122     | I_ldftn    of ILMethodSpec
 1123     | I_newobj  of ILMethodSpec  * ILVarArgs
 1124   
 1125     | I_throw
 1126     | I_endfinally
 1127     | I_endfilter
 1128     | I_leave     of  ILCodeLabel
 1129     | I_rethrow
 1130 
 1131     | I_ldsfld      of ILVolatility * ILFieldSpec
 1132     | I_ldfld       of ILAlignment * ILVolatility * ILFieldSpec
 1133     | I_ldsflda     of ILFieldSpec
 1134     | I_ldflda      of ILFieldSpec 
 1135     | I_stsfld      of ILVolatility  *  ILFieldSpec
 1136     | I_stfld       of ILAlignment * ILVolatility * ILFieldSpec
 1137     | I_ldstr       of string
 1138     | I_isinst      of ILType
 1139     | I_castclass   of ILType
 1140     | I_ldtoken     of ILToken
 1141     | I_ldvirtftn   of ILMethodSpec
 1142 
 1143     | I_cpobj       of ILType
 1144     | I_initobj     of ILType
 1145     | I_ldobj       of ILAlignment * ILVolatility * ILType
 1146     | I_stobj       of ILAlignment * ILVolatility * ILType
 1147     | I_box         of ILType
 1148     | I_unbox       of ILType
 1149     | I_unbox_any   of ILType
 1150     | I_sizeof      of ILType
 1151 
 1152     | I_ldelem      of ILBasicType
 1153     | I_stelem      of ILBasicType
 1154     | I_ldelema     of ILReadonly * bool * ILArrayShape * ILType
 1155     | I_ldelem_any  of ILArrayShape * ILType
 1156     | I_stelem_any  of ILArrayShape * ILType
 1157     | I_newarr      of ILArrayShape * ILType 
 1158     | I_ldlen
 1159 
 1160     | I_mkrefany    of ILType
 1161     | I_refanytype  
 1162     | I_refanyval   of ILType
 1163 
 1164     | I_break 
 1165     | I_seqpoint of ILSourceMarker
 1166 
 1167     | I_arglist  
 1168 
 1169     | I_localloc
 1170     | I_cpblk of ILAlignment * ILVolatility
 1171     | I_initblk of ILAlignment  * ILVolatility
 1172 
 1173     (* FOR EXTENSIONS, e.g. MS-ILX *)  
 1174     | EI_ilzero of ILType
 1175     | EI_ldlen_multi      of int32 * int32
 1176 
 1177 
 1178 [<RequireQualifiedAccess>]
 1179 type ILExceptionClause = 
 1180     | Finally of (ILCodeLabel * ILCodeLabel)
 1181     | Fault  of (ILCodeLabel * ILCodeLabel)
 1182     | FilterCatch of (ILCodeLabel * ILCodeLabel) * (ILCodeLabel * ILCodeLabel)
 1183     | TypeCatch of ILType * (ILCodeLabel * ILCodeLabel)
 1184 
 1185 [<RequireQualifiedAccess; NoEquality; NoComparison>]
 1186 type ILExceptionSpec = 
 1187     { Range: (ILCodeLabel * ILCodeLabel)
 1188       Clause: ILExceptionClause }
 1189 
 1190 /// Indicates that a particular local variable has a particular source 
 1191 /// language name within a given set of ranges. This does not effect local 
 1192 /// variable numbering, which is global over the whole method. 
 1193 [<RequireQualifiedAccess; NoEquality; NoComparison>]
 1194 type ILLocalDebugMapping =
 1195     { LocalIndex: int
 1196       LocalName: string }
 1197 
 1198 [<RequireQualifiedAccess; NoEquality; NoComparison>]
 1199 type ILLocalDebugInfo = 
 1200     { Range: (ILCodeLabel * ILCodeLabel)
 1201       DebugMappings: ILLocalDebugMapping list }
 1202 
 1203 [<RequireQualifiedAccess; NoEquality; NoComparison>]
 1204 type ILCode = 
 1205     { Labels: Dictionary<ILCodeLabel, int> 
 1206       Instrs:ILInstr[] 
 1207       Exceptions: ILExceptionSpec list 
 1208       Locals: ILLocalDebugInfo list }
 1209 
 1210 [<RequireQualifiedAccess; NoComparison; NoEquality>]
 1211 type ILLocal = 
 1212     { Type: ILType
 1213       IsPinned: bool
 1214       DebugInfo: (string * int * int) option }
 1215       
 1216 type ILLocals = list<ILLocal>
 1217 
 1218 [<RequireQualifiedAccess; NoEquality; NoComparison>]
 1219 type ILMethodBody = 
 1220     { IsZeroInit: bool
 1221       MaxStack: int32
 1222       NoInlining: bool
 1223       AggressiveInlining: bool
 1224       Locals: ILLocals
 1225       Code:  ILCode
 1226       SourceMarker: ILSourceMarker option }
 1227 
 1228 [<RequireQualifiedAccess>]
 1229 type ILMemberAccess = 
 1230     | Assembly
 1231     | CompilerControlled
 1232     | FamilyAndAssembly
 1233     | FamilyOrAssembly
 1234     | Family
 1235     | Private 
 1236     | Public 
 1237 
 1238 [<RequireQualifiedAccess; StructuralEquality; StructuralComparison>]
 1239 type ILFieldInit = 
 1240     | String of string
 1241     | Bool of bool
 1242     | Char of uint16
 1243     | Int8 of int8
 1244     | Int16 of int16
 1245     | Int32 of int32
 1246     | Int64 of int64
 1247     | UInt8 of uint8
 1248     | UInt16 of uint16
 1249     | UInt32 of uint32
 1250     | UInt64 of uint64
 1251     | Single of single
 1252     | Double of double
 1253     | Null
 1254   
 1255 // -------------------------------------------------------------------- 
 1256 // Native Types, for marshalling to the native C interface.
 1257 // These are taken directly from the ILASM syntax, and don't really
 1258 // correspond yet to the ECMA Spec (Partition II, 7.4).  
 1259 // -------------------------------------------------------------------- 
 1260 
 1261 [<RequireQualifiedAccess; StructuralEquality; StructuralComparison>]
 1262 type ILNativeType = 
 1263     | Empty
 1264     | Custom of ILGuid * string * string * byte[] (* guid, nativeTypeName, custMarshallerName, cookieString *)
 1265     | FixedSysString of int32
 1266     | FixedArray of int32
 1267     | Currency
 1268     | LPSTR
 1269     | LPWSTR
 1270     | LPTSTR
 1271     | LPUTF8STR
 1272     | ByValStr
 1273     | TBSTR
 1274     | LPSTRUCT
 1275     | Struct
 1276     | Void
 1277     | Bool
 1278     | Int8
 1279     | Int16
 1280     | Int32
 1281     | Int64
 1282     | Single
 1283     | Double
 1284     | Byte
 1285     | UInt16
 1286     | UInt32
 1287     | UInt64
 1288     | Array of ILNativeType option * (int32 * int32 option) option (* optional idx of parameter giving size plus optional additive i.e. num elems *)
 1289     | Int
 1290     | UInt
 1291     | Method
 1292     | AsAny
 1293     | BSTR
 1294     | IUnknown
 1295     | IDispatch
 1296     | Interface
 1297     | Error               
 1298     | SafeArray of ILNativeVariant * string option 
 1299     | ANSIBSTR
 1300     | VariantBool
 1301 
 1302 and 
 1303   [<RequireQualifiedAccess; StructuralEquality; StructuralComparison>]
 1304   ILNativeVariant = 
 1305     | Empty
 1306     | Null
 1307     | Variant
 1308     | Currency
 1309     | Decimal               
 1310     | Date               
 1311     | BSTR               
 1312     | LPSTR               
 1313     | LPWSTR               
 1314     | IUnknown               
 1315     | IDispatch               
 1316     | SafeArray               
 1317     | Error               
 1318     | HRESULT               
 1319     | CArray               
 1320     | UserDefined               
 1321     | Record               
 1322     | FileTime
 1323     | Blob               
 1324     | Stream               
 1325     | Storage               
 1326     | StreamedObject               
 1327     | StoredObject               
 1328     | BlobObject               
 1329     | CF                
 1330     | CLSID
 1331     | Void 
 1332     | Bool
 1333     | Int8
 1334     | Int16                
 1335     | Int32                
 1336     | Int64                
 1337     | Single                
 1338     | Double                
 1339     | UInt8                
 1340     | UInt16                
 1341     | UInt32                
 1342     | UInt64                
 1343     | PTR                
 1344     | Array of ILNativeVariant                
 1345     | Vector of ILNativeVariant                
 1346     | Byref of ILNativeVariant                
 1347     | Int                
 1348     | UInt                
 1349 
 1350 [<RequireQualifiedAccess; StructuralEquality; StructuralComparison>]
 1351 type ILSecurityAction = 
 1352     | Request 
 1353     | Demand
 1354     | Assert
 1355     | Deny
 1356     | PermitOnly
 1357     | LinkCheck 
 1358     | InheritCheck
 1359     | ReqMin
 1360     | ReqOpt
 1361     | ReqRefuse
 1362     | PreJitGrant
 1363     | PreJitDeny
 1364     | NonCasDemand
 1365     | NonCasLinkDemand
 1366     | NonCasInheritance
 1367     | LinkDemandChoice
 1368     | InheritanceDemandChoice
 1369     | DemandChoice
 1370 
 1371 [<RequireQualifiedAccess; StructuralEquality; StructuralComparison>]
 1372 type ILSecurityDecl = 
 1373     | ILSecurityDecl of ILSecurityAction * byte[]
 1374 
 1375 [<NoEquality; NoComparison; Struct>]
 1376 type ILSecurityDecls(array : ILSecurityDecl[]) =
 1377     member x.AsArray = array
 1378     member x.AsList = x.AsArray |> Array.toList
 1379 
 1380 [<NoEquality; NoComparison>]
 1381 type ILSecurityDeclsStored =
 1382 
 1383     /// Computed by ilread.fs based on metadata index
 1384     | Reader of (int32 -> ILSecurityDecl[])
 1385 
 1386     /// Already computed
 1387     | Given of ILSecurityDecls
 1388 
 1389     member x.GetSecurityDecls metadataIndex = 
 1390        match x with
 1391        | Reader f -> ILSecurityDecls(f metadataIndex)
 1392        | Given attrs -> attrs
 1393 
 1394 let emptyILSecurityDecls = ILSecurityDecls [| |]
 1395 
 1396 let emptyILSecurityDeclsStored = ILSecurityDeclsStored.Given emptyILSecurityDecls
 1397 
 1398 let mkILSecurityDecls l = match l with [] -> emptyILSecurityDecls | _ -> ILSecurityDecls (Array.ofList l)
 1399 
 1400 let storeILSecurityDecls (x: ILSecurityDecls) = if x.AsArray.Length = 0 then emptyILSecurityDeclsStored else ILSecurityDeclsStored.Given x
 1401 
 1402 let mkILSecurityDeclsReader f = ILSecurityDeclsStored.Reader f
 1403 
 1404 [<RequireQualifiedAccess>]
 1405 type PInvokeCharBestFit  = 
 1406     | UseAssembly
 1407     | Enabled
 1408     | Disabled
 1409 
 1410 [<RequireQualifiedAccess>]
 1411 type PInvokeThrowOnUnmappableChar =
 1412     | UseAssembly
 1413     | Enabled
 1414     | Disabled
 1415 
 1416 [<RequireQualifiedAccess>]
 1417 type PInvokeCallingConvention =
 1418     | None
 1419     | Cdecl
 1420     | Stdcall
 1421     | Thiscall
 1422     | Fastcall
 1423     | WinApi
 1424 
 1425 [<RequireQualifiedAccess>]
 1426 type PInvokeCharEncoding =
 1427     | None
 1428     | Ansi
 1429     | Unicode
 1430     | Auto
 1431 
 1432 [<RequireQualifiedAccess; NoComparison; NoEquality>]
 1433 type PInvokeMethod =
 1434     { Where: ILModuleRef
 1435       Name: string
 1436       CallingConv: PInvokeCallingConvention
 1437       CharEncoding: PInvokeCharEncoding
 1438       NoMangle: bool
 1439       LastError: bool
 1440       ThrowOnUnmappableChar: PInvokeThrowOnUnmappableChar
 1441       CharBestFit: PInvokeCharBestFit }
 1442 
 1443 [<RequireQualifiedAccess; NoEquality; NoComparison>]
 1444 type ILParameter =
 1445     { Name: string option
 1446       Type: ILType
 1447       Default: ILFieldInit option
 1448       Marshal: ILNativeType option
 1449       IsIn: bool
 1450       IsOut: bool
 1451       IsOptional: bool
 1452       CustomAttrsStored: ILAttributesStored
 1453       MetadataIndex: int32  }
 1454 
 1455     member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex
 1456 
 1457 type ILParameters = list<ILParameter>
 1458 
 1459 [<RequireQualifiedAccess; NoEquality; NoComparison>]
 1460 type ILReturn = 
 1461     { Marshal: ILNativeType option
 1462       Type: ILType
 1463       CustomAttrsStored: ILAttributesStored
 1464       MetadataIndex: int32  }
 1465 
 1466     member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex
 1467 
 1468     member x.WithCustomAttrs(customAttrs) = { x with CustomAttrsStored = storeILCustomAttrs customAttrs }
 1469 
 1470 type ILOverridesSpec = 
 1471     | OverridesSpec of ILMethodRef * ILType
 1472 
 1473     member x.MethodRef = let (OverridesSpec(mr, _ty)) = x in mr
 1474 
 1475     member x.DeclaringType = let (OverridesSpec(_mr, ty)) = x in ty
 1476 
 1477 type ILMethodVirtualInfo = 
 1478     { IsFinal: bool
 1479       IsNewSlot: bool 
 1480       IsCheckAccessOnOverride: bool
 1481       IsAbstract: bool }
 1482 
 1483 type MethodKind =
 1484     | Static 
 1485     | Cctor 
 1486     | Ctor 
 1487     | NonVirtual 
 1488     | Virtual of ILMethodVirtualInfo
 1489 
 1490 [<RequireQualifiedAccess>]
 1491 type MethodBody =
 1492     | IL of ILMethodBody
 1493     | PInvoke of PInvokeMethod       (* platform invoke to native  *)
 1494     | Abstract
 1495     | Native
 1496     | NotAvailable
 1497 
 1498 type ILLazyMethodBody = 
 1499     | ILLazyMethodBody of Lazy<MethodBody >
 1500 
 1501     member x.Contents = let (ILLazyMethodBody mb) = x in mb.Force()
 1502 
 1503 [<RequireQualifiedAccess>]
 1504 type MethodCodeKind =
 1505     | IL
 1506     | Native
 1507     | Runtime
 1508 
 1509 let mkMethBodyAux mb = ILLazyMethodBody (notlazy mb)
 1510 
 1511 let mkMethBodyLazyAux mb = ILLazyMethodBody mb
 1512 
 1513 let typesOfILParams (ps:ILParameters) : ILTypes = ps |> List.map (fun p -> p.Type)
 1514 
 1515 [<StructuralEquality; StructuralComparison>]
 1516 type ILGenericVariance =
 1517     | NonVariant
 1518     | CoVariant
 1519     | ContraVariant
 1520 
 1521 [<NoEquality; NoComparison; StructuredFormatDisplay("{DebugText}")>]
 1522 type ILGenericParameterDef =
 1523     { Name: string
 1524       Constraints: ILTypes
 1525       Variance: ILGenericVariance 
 1526       HasReferenceTypeConstraint: bool
 1527       HasNotNullableValueTypeConstraint: bool
 1528       HasDefaultConstructorConstraint: bool 
 1529       CustomAttrsStored : ILAttributesStored
 1530       MetadataIndex: int32 }
 1531 
 1532     member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex
 1533 
 1534     /// For debugging
 1535     [<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
 1536     member x.DebugText = x.ToString()
 1537 
 1538     override x.ToString() = x.Name 
 1539 
 1540 type ILGenericParameterDefs = ILGenericParameterDef list
 1541 
 1542 let memberAccessOfFlags flags =
 1543     let f = (flags &&& 0x00000007)
 1544     if f = 0x00000001 then  ILMemberAccess.Private 
 1545     elif f = 0x00000006 then  ILMemberAccess.Public 
 1546     elif f = 0x00000004 then  ILMemberAccess.Family 
 1547     elif f = 0x00000002 then  ILMemberAccess.FamilyAndAssembly 
 1548     elif f = 0x00000005 then  ILMemberAccess.FamilyOrAssembly 
 1549     elif f = 0x00000003 then  ILMemberAccess.Assembly 
 1550     else ILMemberAccess.CompilerControlled
 1551 
 1552 let convertMemberAccess (ilMemberAccess:ILMemberAccess) =
 1553     match ilMemberAccess with
 1554     | ILMemberAccess.Public              -> MethodAttributes.Public
 1555     | ILMemberAccess.Private             -> MethodAttributes.Private
 1556     | ILMemberAccess.Assembly            -> MethodAttributes.Assembly
 1557     | ILMemberAccess.FamilyAndAssembly   -> MethodAttributes.FamANDAssem
 1558     | ILMemberAccess.CompilerControlled   -> MethodAttributes.PrivateScope
 1559     | ILMemberAccess.FamilyOrAssembly    -> MethodAttributes.FamORAssem
 1560     | ILMemberAccess.Family              -> MethodAttributes.Family
 1561 
 1562 let inline conditionalAdd condition flagToAdd source = if condition then source ||| flagToAdd else source &&& ~~~flagToAdd
 1563 
 1564 let NoMetadataIdx = -1
 1565 
 1566 [<NoComparison; NoEquality>]
 1567 type ILMethodDef (name: string, attributes: MethodAttributes, implAttributes: MethodImplAttributes, callingConv: ILCallingConv,
 1568                   parameters: ILParameters, ret: ILReturn, body: ILLazyMethodBody, isEntryPoint:bool, genericParams: ILGenericParameterDefs,
 1569                   securityDeclsStored: ILSecurityDeclsStored, customAttrsStored: ILAttributesStored, metadataIndex: int32) =
 1570 
 1571     new (name, attributes, implAttributes, callingConv, parameters, ret, body, isEntryPoint, genericParams, securityDecls, customAttrs) = 
 1572        ILMethodDef(name, attributes, implAttributes, callingConv, parameters, ret, body, isEntryPoint, genericParams,
 1573                    storeILSecurityDecls securityDecls, storeILCustomAttrs customAttrs, NoMetadataIdx)
 1574     
 1575     // The captured data - remember the object will be as large as the data captured by these members
 1576     member __.Name = name
 1577 
 1578     member __.Attributes = attributes
 1579 
 1580     member __.ImplAttributes = implAttributes
 1581 
 1582     member __.CallingConv = callingConv
 1583 
 1584     member __.Parameters = parameters
 1585 
 1586     member __.Return = ret
 1587 
 1588     member __.Body = body
 1589 
 1590     member __.SecurityDeclsStored = securityDeclsStored
 1591 
 1592     member __.IsEntryPoint = isEntryPoint
 1593 
 1594     member __.GenericParams = genericParams
 1595 
 1596     member __.CustomAttrsStored = customAttrsStored
 1597 
 1598     member __.MetadataIndex = metadataIndex
 1599 
 1600     member x.With (?name: string, ?attributes: MethodAttributes, ?implAttributes: MethodImplAttributes, ?callingConv: ILCallingConv, ?parameters: ILParameters, ?ret: ILReturn, ?body: ILLazyMethodBody, ?securityDecls: ILSecurityDecls, ?isEntryPoint:bool, ?genericParams: ILGenericParameterDefs, ?customAttrs: ILAttributes) =
 1601         ILMethodDef (name = defaultArg name x.Name,
 1602                      attributes = defaultArg attributes x.Attributes,
 1603                      implAttributes = defaultArg implAttributes x.ImplAttributes,
 1604                      callingConv = defaultArg callingConv x.CallingConv,
 1605                      parameters = defaultArg parameters x.Parameters,
 1606                      ret = defaultArg ret x.Return,
 1607                      body = defaultArg body x.Body,
 1608                      securityDecls = (match securityDecls with None -> x.SecurityDecls | Some attrs -> attrs),
 1609                      isEntryPoint = defaultArg isEntryPoint x.IsEntryPoint,
 1610                      genericParams = defaultArg genericParams x.GenericParams,
 1611                      customAttrs=(match customAttrs with None -> x.CustomAttrs | Some attrs -> attrs))
 1612 
 1613     member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs metadataIndex
 1614 
 1615     member x.SecurityDecls = x.SecurityDeclsStored.GetSecurityDecls x.MetadataIndex
 1616 
 1617     member x.ParameterTypes = typesOfILParams x.Parameters
 1618 
 1619     member md.Code = 
 1620           match md.Body.Contents with 
 1621           | MethodBody.IL il-> Some il.Code
 1622           | _ -> None
 1623 
 1624     member x.IsIL = match x.Body.Contents with | MethodBody.IL _ -> true | _ -> false
 1625 
 1626     member x.Locals = match x.Body.Contents with | MethodBody.IL il -> il.Locals | _ -> []
 1627 
 1628     member x.MethodBody = match x.Body.Contents with MethodBody.IL il -> il | _ -> failwith "not IL"
 1629 
 1630     member x.SourceMarker = x.MethodBody.SourceMarker
 1631 
 1632     member x.MaxStack     = x.MethodBody.MaxStack  
 1633 
 1634     member x.IsZeroInit   = x.MethodBody.IsZeroInit
 1635 
 1636     member md.CallingSignature =  mkILCallSig (md.CallingConv, md.ParameterTypes, md.Return.Type)
 1637 
 1638     member x.IsClassInitializer   = x.Name = ".cctor"
 1639     member x.IsConstructor        = x.Name = ".ctor"
 1640 
 1641     member x.Access                 = memberAccessOfFlags (int x.Attributes)
 1642     member x.IsStatic               = x.Attributes &&& MethodAttributes.Static <> enum 0
 1643     member x.IsNonVirtualInstance   = not x.IsStatic && not x.IsVirtual
 1644     member x.IsVirtual              = x.Attributes &&& MethodAttributes.Virtual <> enum 0
 1645     member x.IsFinal                = x.Attributes &&& MethodAttributes.Final <> enum 0
 1646     member x.IsNewSlot              = x.Attributes &&& MethodAttributes.NewSlot <> enum 0
 1647     member x.IsCheckAccessOnOverride= x.Attributes &&& MethodAttributes.CheckAccessOnOverride <> enum 0
 1648     member x.IsAbstract             = x.Attributes &&& MethodAttributes.Abstract <> enum 0
 1649     member x.IsHideBySig            = x.Attributes &&& MethodAttributes.HideBySig <> enum 0
 1650     member x.IsSpecialName          = x.Attributes &&& MethodAttributes.SpecialName <> enum 0
 1651     member x.IsUnmanagedExport      = x.Attributes &&& MethodAttributes.UnmanagedExport <> enum 0
 1652     member x.IsReqSecObj            = x.Attributes &&& MethodAttributes.RequireSecObject <> enum 0
 1653     member x.HasSecurity            = x.Attributes &&& MethodAttributes.HasSecurity <> enum 0
 1654 
 1655     member x.IsManaged         = x.ImplAttributes &&& MethodImplAttributes.Managed <> enum 0
 1656     member x.IsForwardRef      = x.ImplAttributes &&& MethodImplAttributes.ForwardRef <> enum 0
 1657     member x.IsInternalCall    = x.ImplAttributes &&& MethodImplAttributes.InternalCall <> enum 0
 1658     member x.IsPreserveSig     = x.ImplAttributes &&& MethodImplAttributes.PreserveSig <> enum 0
 1659     member x.IsSynchronized    = x.ImplAttributes &&& MethodImplAttributes.Synchronized <> enum 0
 1660     member x.IsNoInline        = x.ImplAttributes &&& MethodImplAttributes.NoInlining <> enum 0
 1661     member x.IsAggressiveInline= x.ImplAttributes &&& MethodImplAttributes.AggressiveInlining <> enum 0
 1662     member x.IsMustRun         = x.ImplAttributes &&& MethodImplAttributes.NoOptimization <> enum 0
 1663 
 1664     member x.WithSpecialName = x.With(attributes = (x.Attributes ||| MethodAttributes.SpecialName))
 1665     member x.WithHideBySig() = 
 1666         x.With(attributes = (
 1667                 if x.IsVirtual then x.Attributes &&& ~~~MethodAttributes.CheckAccessOnOverride ||| MethodAttributes.HideBySig
 1668                 else failwith "WithHideBySig"))
 1669     member x.WithHideBySig(condition) = x.With(attributes = (x.Attributes |> conditionalAdd condition MethodAttributes.HideBySig))
 1670     member x.WithFinal(condition) = x.With(attributes = (x.Attributes |> conditionalAdd condition MethodAttributes.Final))
 1671     member x.WithAbstract(condition) = x.With(attributes = (x.Attributes |> conditionalAdd condition MethodAttributes.Abstract))
 1672     member x.WithAccess(access) = x.With(attributes = (x.Attributes &&& ~~~MethodAttributes.MemberAccessMask ||| convertMemberAccess access))
 1673     member x.WithNewSlot = x.With(attributes = (x.Attributes ||| MethodAttributes.NewSlot))
 1674     member x.WithSecurity(condition) = x.With(attributes = (x.Attributes |> conditionalAdd condition MethodAttributes.HasSecurity))
 1675     member x.WithPInvoke(condition) = x.With(attributes = (x.Attributes |> conditionalAdd condition MethodAttributes.PinvokeImpl))
 1676     member x.WithPreserveSig(condition) = x.With(implAttributes = (x.ImplAttributes |> conditionalAdd condition MethodImplAttributes.PreserveSig))
 1677     member x.WithSynchronized(condition) = x.With(implAttributes = (x.ImplAttributes |> conditionalAdd condition MethodImplAttributes.Synchronized))
 1678     member x.WithNoInlining(condition) = x.With(implAttributes = (x.ImplAttributes |> conditionalAdd condition MethodImplAttributes.NoInlining))
 1679     member x.WithAggressiveInlining(condition) = x.With(implAttributes = (x.ImplAttributes |> conditionalAdd condition MethodImplAttributes.AggressiveInlining))
 1680     member x.WithRuntime(condition) = x.With(implAttributes = (x.ImplAttributes |> conditionalAdd condition MethodImplAttributes.Runtime))
 1681 
 1682 /// Index table by name and arity. 
 1683 type MethodDefMap = Map<string, ILMethodDef list>
 1684 
 1685 [<Sealed>]
 1686 type ILMethodDefs(f : (unit -> ILMethodDef[])) = 
 1687 
 1688     let mutable array = InlineDelayInit<_>(f)
 1689     let mutable dict = InlineDelayInit<_>(fun () -> 
 1690             let arr = array.Value
 1691             let t = Dictionary<_, _>()
 1692             for i = arr.Length - 1 downto 0 do 
 1693                 let y = arr.[i]
 1694                 let key = y.Name
 1695                 match t.TryGetValue(key) with
 1696                 | true, m -> t.[key] <- y :: m
 1697                 | _ -> t.[key] <- [y]
 1698             t)
 1699 
 1700     interface IEnumerable with 
 1701         member x.GetEnumerator() = ((x :> IEnumerable<ILMethodDef>).GetEnumerator() :> IEnumerator)
 1702 
 1703     interface IEnumerable<ILMethodDef> with 
 1704         member x.GetEnumerator() = (array.Value :> IEnumerable<ILMethodDef>).GetEnumerator()
 1705 
 1706     member x.AsArray = array.Value
 1707 
 1708     member x.AsList = array.Value|> Array.toList
 1709 
 1710     member x.FindByName(nm) =
 1711         match dict.Value.TryGetValue(nm) with
 1712         | true, m -> m
 1713         | _ -> []
 1714 
 1715     member x.FindByNameAndArity (nm, arity) = x.FindByName nm |> List.filter (fun x -> List.length x.Parameters = arity)
 1716 
 1717 [<NoComparison; NoEquality; StructuredFormatDisplay("{DebugText}")>]
 1718 type ILEventDef(eventType: ILType option, name: string, attributes: EventAttributes, addMethod: ILMethodRef, removeMethod: ILMethodRef, fireMethod: ILMethodRef option, otherMethods: ILMethodRef list, customAttrsStored: ILAttributesStored, metadataIndex: int32) =
 1719 
 1720     new (eventType, name, attributes, addMethod, removeMethod, fireMethod, otherMethods, customAttrs) =
 1721         ILEventDef(eventType, name, attributes, addMethod, removeMethod, fireMethod, otherMethods, storeILCustomAttrs customAttrs, NoMetadataIdx)
 1722 
 1723     member __.EventType = eventType
 1724     member __.Name = name
 1725     member __.Attributes = attributes
 1726     member __.AddMethod = addMethod
 1727     member __.RemoveMethod = removeMethod
 1728     member __.FireMethod = fireMethod
 1729     member __.OtherMethods = otherMethods
 1730     member __.CustomAttrsStored = customAttrsStored
 1731     member __.MetadataIndex = metadataIndex
 1732     member x.CustomAttrs = customAttrsStored.GetCustomAttrs x.MetadataIndex
 1733 
 1734     member x.With(?eventType, ?name, ?attributes, ?addMethod, ?removeMethod, ?fireMethod, ?otherMethods, ?customAttrs) = 
 1735         ILEventDef(eventType= defaultArg eventType x.EventType,
 1736                    name= defaultArg name x.Name,
 1737                    attributes= defaultArg attributes x.Attributes,
 1738                    addMethod=defaultArg addMethod x.AddMethod,
 1739                    removeMethod=defaultArg removeMethod x.RemoveMethod,
 1740                    fireMethod= defaultArg fireMethod x.FireMethod,
 1741                    otherMethods= defaultArg otherMethods x.OtherMethods,
 1742                    customAttrs=(match customAttrs with None -> x.CustomAttrs | Some attrs -> attrs))
 1743 
 1744     member x.IsSpecialName = (x.Attributes &&& EventAttributes.SpecialName) <> enum<_>(0)
 1745     member x.IsRTSpecialName = (x.Attributes &&& EventAttributes.RTSpecialName) <> enum<_>(0)
 1746 
 1747     /// For debugging
 1748     [<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
 1749     member x.DebugText = x.ToString()
 1750 
 1751     override x.ToString() = "event " + x.Name
 1752 
 1753 [<NoEquality; NoComparison>]
 1754 type ILEventDefs = 
 1755     | ILEvents of LazyOrderedMultiMap<string, ILEventDef>
 1756 
 1757     member x.AsList = let (ILEvents t) = x in t.Entries()
 1758 
 1759     member x.LookupByName s = let (ILEvents t) = x in t.[s]
 1760 
 1761 [<NoComparison; NoEquality; StructuredFormatDisplay("{DebugText}")>]
 1762 type ILPropertyDef(name: string, attributes: PropertyAttributes, setMethod: ILMethodRef option, getMethod: ILMethodRef option, callingConv: ILThisConvention, propertyType: ILType, init: ILFieldInit option, args: ILTypes, customAttrsStored: ILAttributesStored, metadataIndex: int32) =
 1763 
 1764     new (name, attributes, setMethod, getMethod, callingConv, propertyType, init, args, customAttrs) =
 1765        ILPropertyDef(name, attributes, setMethod, getMethod, callingConv, propertyType, init, args, storeILCustomAttrs customAttrs, NoMetadataIdx)
 1766 
 1767     member x.Name = name
 1768     member x.Attributes = attributes
 1769     member x.GetMethod = getMethod
 1770     member x.SetMethod = setMethod
 1771     member x.CallingConv = callingConv
 1772     member x.PropertyType = propertyType
 1773     member x.Init = init
 1774     member x.Args = args
 1775     member x.CustomAttrsStored = customAttrsStored
 1776     member x.CustomAttrs = customAttrsStored.GetCustomAttrs x.MetadataIndex
 1777     member x.MetadataIndex = metadataIndex
 1778 
 1779     member x.With(?name, ?attributes, ?setMethod, ?getMethod, ?callingConv, ?propertyType, ?init, ?args, ?customAttrs) = 
 1780       ILPropertyDef(name=defaultArg name x.Name,
 1781                     attributes=defaultArg attributes x.Attributes,
 1782                     setMethod=defaultArg setMethod x.SetMethod,
 1783                     getMethod=defaultArg getMethod x.GetMethod,
 1784                     callingConv=defaultArg callingConv x.CallingConv,
 1785                     propertyType=defaultArg propertyType x.PropertyType,
 1786                     init=defaultArg init x.Init,
 1787                     args=defaultArg args x.Args,
 1788                     customAttrs=(match customAttrs with None -> x.CustomAttrs | Some attrs -> attrs))
 1789 
 1790 
 1791     member x.IsSpecialName = (x.Attributes &&& PropertyAttributes.SpecialName) <> enum<_>(0)
 1792     member x.IsRTSpecialName = (x.Attributes &&& PropertyAttributes.RTSpecialName) <> enum<_>(0)
 1793 
 1794     /// For debugging
 1795     [<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
 1796     member x.DebugText = x.ToString()
 1797 
 1798     override x.ToString() = "property " + x.Name
 1799     
 1800 // Index table by name.
 1801 [<NoEquality; NoComparison>]
 1802 type ILPropertyDefs = 
 1803     | ILProperties of LazyOrderedMultiMap<string, ILPropertyDef>
 1804     member x.AsList = let (ILProperties t) = x in t.Entries()
 1805     member x.LookupByName s = let (ILProperties t) = x in t.[s]
 1806 
 1807 let convertFieldAccess (ilMemberAccess:ILMemberAccess) =
 1808     match ilMemberAccess with
 1809     | ILMemberAccess.Assembly            -> FieldAttributes.Assembly
 1810     | ILMemberAccess.CompilerControlled   -> enum<FieldAttributes>(0)
 1811     | ILMemberAccess.FamilyAndAssembly   -> FieldAttributes.FamANDAssem
 1812     | ILMemberAccess.FamilyOrAssembly    -> FieldAttributes.FamORAssem
 1813     | ILMemberAccess.Family              -> FieldAttributes.Family
 1814     | ILMemberAccess.Private             -> FieldAttributes.Private
 1815     | ILMemberAccess.Public              -> FieldAttributes.Public
 1816 
 1817 [<NoComparison; NoEquality>]
 1818 type ILFieldDef(name: string, fieldType: ILType, attributes: FieldAttributes, data: byte[] option, literalValue: ILFieldInit option, offset:  int32 option, marshal: ILNativeType option, customAttrsStored: ILAttributesStored, metadataIndex: int32) = 
 1819 
 1820     new (name, fieldType, attributes, data, literalValue, offset, marshal, customAttrs) = 
 1821         ILFieldDef(name, fieldType, attributes, data, literalValue, offset, marshal, storeILCustomAttrs customAttrs, NoMetadataIdx)
 1822     member __.Name=name
 1823     member __.FieldType = fieldType
 1824     member __.Attributes=attributes
 1825     member __.Data=data
 1826     member __.LiteralValue=literalValue
 1827     member __.Offset=offset
 1828     member __.Marshal=marshal
 1829     member x.CustomAttrsStored = customAttrsStored
 1830     member x.CustomAttrs = customAttrsStored.GetCustomAttrs x.MetadataIndex
 1831     member x.MetadataIndex = metadataIndex
 1832 
 1833     member x.With(?name: string, ?fieldType: ILType, ?attributes: FieldAttributes, ?data: byte[] option, ?literalValue: ILFieldInit option, ?offset:  int32 option, ?marshal: ILNativeType option, ?customAttrs: ILAttributes) = 
 1834         ILFieldDef(name=defaultArg name x.Name,
 1835                    fieldType=defaultArg fieldType x.FieldType,
 1836                    attributes=defaultArg attributes x.Attributes,
 1837                    data=defaultArg data x.Data,
 1838                    literalValue=defaultArg literalValue x.LiteralValue,
 1839                    offset=defaultArg offset x.Offset,
 1840                    marshal=defaultArg marshal x.Marshal,
 1841                    customAttrs=defaultArg customAttrs x.CustomAttrs)
 1842     member x.IsStatic = x.Attributes &&& FieldAttributes.Static <> enum 0
 1843     member x.IsSpecialName = x.Attributes &&& FieldAttributes.SpecialName <> enum 0
 1844     member x.IsLiteral = x.Attributes &&& FieldAttributes.Literal <> enum 0
 1845     member x.NotSerialized = x.Attributes &&& FieldAttributes.NotSerialized <> enum 0
 1846     member x.IsInitOnly = x.Attributes &&& FieldAttributes.InitOnly <> enum 0
 1847     member x.Access = memberAccessOfFlags (int x.Attributes)
 1848     member x.WithAccess(access) = x.With(attributes = (x.Attributes &&& ~~~FieldAttributes.FieldAccessMask ||| convertFieldAccess access))
 1849     member x.WithInitOnly(condition) = x.With(attributes = (x.Attributes |> conditionalAdd condition FieldAttributes.InitOnly))
 1850     member x.WithStatic(condition) = x.With(attributes = (x.Attributes |> conditionalAdd condition FieldAttributes.Static))
 1851     member x.WithSpecialName(condition) = x.With(attributes = (x.Attributes |> conditionalAdd condition (FieldAttributes.SpecialName ||| FieldAttributes.RTSpecialName)))
 1852     member x.WithNotSerialized(condition) = x.With(attributes = (x.Attributes |> conditionalAdd condition FieldAttributes.NotSerialized))
 1853     member x.WithLiteralDefaultValue(literal) = x.With(literalValue = literal, attributes = (x.Attributes |> conditionalAdd literal.IsSome (FieldAttributes.Literal ||| FieldAttributes.HasDefault)))
 1854     member x.WithFieldMarshal(marshal) = x.With(marshal = marshal, attributes = (x.Attributes |> conditionalAdd marshal.IsSome FieldAttributes.HasFieldMarshal))
 1855 
 1856 
 1857 // Index table by name.  Keep a canonical list to make sure field order is not disturbed for binary manipulation.
 1858 type ILFieldDefs = 
 1859     | ILFields of LazyOrderedMultiMap<string, ILFieldDef>
 1860 
 1861     member x.AsList = let (ILFields t) = x in t.Entries()
 1862 
 1863     member x.LookupByName s = let (ILFields t) = x in t.[s]
 1864 
 1865 type ILMethodImplDef =
 1866     { Overrides: ILOverridesSpec
 1867       OverrideBy: ILMethodSpec }
 1868 
 1869 // Index table by name and arity. 
 1870 type ILMethodImplDefs = 
 1871     | ILMethodImpls of Lazy<MethodImplsMap>
 1872 
 1873     member x.AsList = let (ILMethodImpls ltab) = x in Map.foldBack (fun _x y r -> y@r) (ltab.Force()) []
 1874 
 1875 and MethodImplsMap = Map<string * int, ILMethodImplDef list>
 1876 
 1877 [<RequireQualifiedAccess>]
 1878 type ILTypeDefLayout =
 1879     | Auto
 1880     | Sequential of ILTypeDefLayoutInfo
 1881     | Explicit of ILTypeDefLayoutInfo (* REVIEW: add field info here *)
 1882 
 1883 and ILTypeDefLayoutInfo =
 1884     { Size: int32 option;
 1885       Pack: uint16 option } 
 1886 
 1887 [<RequireQualifiedAccess>]
 1888 type ILTypeInit =
 1889     | BeforeField
 1890     | OnAny
 1891 
 1892 [<RequireQualifiedAccess>]
 1893 type ILDefaultPInvokeEncoding =
 1894     | Ansi
 1895     | Auto
 1896     | Unicode
 1897 
 1898 type ILTypeDefAccess =
 1899     | Public 
 1900     | Private
 1901     | Nested of ILMemberAccess 
 1902 
 1903 let typeAccessOfFlags flags =
 1904     let f = (flags &&& 0x00000007)
 1905     if f = 0x00000001 then ILTypeDefAccess.Public 
 1906     elif f = 0x00000002 then ILTypeDefAccess.Nested ILMemberAccess.Public 
 1907     elif f = 0x00000003 then ILTypeDefAccess.Nested ILMemberAccess.Private 
 1908     elif f = 0x00000004 then ILTypeDefAccess.Nested ILMemberAccess.Family 
 1909     elif f = 0x00000006 then ILTypeDefAccess.Nested ILMemberAccess.FamilyAndAssembly 
 1910     elif f = 0x00000007 then ILTypeDefAccess.Nested ILMemberAccess.FamilyOrAssembly 
 1911     elif f = 0x00000005 then ILTypeDefAccess.Nested ILMemberAccess.Assembly 
 1912     else ILTypeDefAccess.Private
 1913 
 1914 let typeEncodingOfFlags flags = 
 1915     let f = (flags &&& 0x00030000)
 1916     if f = 0x00020000 then ILDefaultPInvokeEncoding.Auto 
 1917     elif f = 0x00010000 then ILDefaultPInvokeEncoding.Unicode 
 1918     else ILDefaultPInvokeEncoding.Ansi
 1919 
 1920 [<RequireQualifiedAccess>]
 1921 type ILTypeDefKind =
 1922     | Class
 1923     | ValueType
 1924     | Interface
 1925     | Enum 
 1926     | Delegate
 1927 
 1928 let typeKindOfFlags nm _mdefs _fdefs (super:ILType option) flags =
 1929     if (flags &&& 0x00000020) <> 0x0 then ILTypeDefKind.Interface 
 1930     else 
 1931          let isEnum, isDelegate, isMulticastDelegate, isValueType = 
 1932             match super with 
 1933             | None -> false , false, false, false
 1934             | Some ty -> 
 1935                 ty.TypeSpec.Name = "System.Enum",
 1936                 ty.TypeSpec.Name = "System.Delegate",
 1937                 ty.TypeSpec.Name = "System.MulticastDelegate",
 1938                 ty.TypeSpec.Name = "System.ValueType" && nm <> "System.Enum"
 1939          let selfIsMulticastDelegate = nm = "System.MulticastDelegate"
 1940          if isEnum then ILTypeDefKind.Enum 
 1941          elif  (isDelegate && not selfIsMulticastDelegate) || isMulticastDelegate then ILTypeDefKind.Delegate
 1942          elif isValueType then ILTypeDefKind.ValueType 
 1943          else ILTypeDefKind.Class 
 1944 
 1945 let convertTypeAccessFlags access = 
 1946     match access with 
 1947     | ILTypeDefAccess.Public -> TypeAttributes.Public
 1948     | ILTypeDefAccess.Private  -> TypeAttributes.NotPublic
 1949     | ILTypeDefAccess.Nested ILMemberAccess.Public -> TypeAttributes.NestedPublic
 1950     | ILTypeDefAccess.Nested ILMemberAccess.Private  -> TypeAttributes.NestedPrivate
 1951     | ILTypeDefAccess.Nested ILMemberAccess.Family  -> TypeAttributes.NestedFamily
 1952     | ILTypeDefAccess.Nested ILMemberAccess.CompilerControlled -> TypeAttributes.NestedPrivate
 1953     | ILTypeDefAccess.Nested ILMemberAccess.FamilyAndAssembly -> TypeAttributes.NestedFamANDAssem
 1954     | ILTypeDefAccess.Nested ILMemberAccess.FamilyOrAssembly -> TypeAttributes.NestedFamORAssem
 1955     | ILTypeDefAccess.Nested ILMemberAccess.Assembly -> TypeAttributes.NestedAssembly
 1956 
 1957 let convertTypeKind kind =
 1958     match kind with
 1959     | ILTypeDefKind.Class -> TypeAttributes.Class
 1960     | ILTypeDefKind.ValueType -> TypeAttributes.Class
 1961     | ILTypeDefKind.Interface -> TypeAttributes.Abstract ||| TypeAttributes.Interface
 1962     | ILTypeDefKind.Enum -> TypeAttributes.Class
 1963     | ILTypeDefKind.Delegate -> TypeAttributes.Class
 1964 
 1965 let convertLayout layout =
 1966     match layout with
 1967     | ILTypeDefLayout.Auto -> TypeAttributes.AutoLayout
 1968     | ILTypeDefLayout.Sequential _ -> TypeAttributes.SequentialLayout
 1969     | ILTypeDefLayout.Explicit _ -> TypeAttributes.ExplicitLayout
 1970 
 1971 let convertEncoding encoding =
 1972     match encoding with
 1973     | ILDefaultPInvokeEncoding.Auto -> TypeAttributes.AutoClass
 1974     | ILDefaultPInvokeEncoding.Ansi -> TypeAttributes.AnsiClass
 1975     | ILDefaultPInvokeEncoding.Unicode -> TypeAttributes.UnicodeClass
 1976 
 1977 let convertToNestedTypeAccess (ilMemberAccess:ILMemberAccess) =
 1978     match ilMemberAccess with
 1979     | ILMemberAccess.Assembly            -> TypeAttributes.NestedAssembly
 1980     | ILMemberAccess.CompilerControlled   -> failwith "Method access compiler controlled."
 1981     | ILMemberAccess.FamilyAndAssembly   -> TypeAttributes.NestedFamANDAssem
 1982     | ILMemberAccess.FamilyOrAssembly    -> TypeAttributes.NestedFamORAssem
 1983     | ILMemberAccess.Family              -> TypeAttributes.NestedFamily
 1984     | ILMemberAccess.Private             -> TypeAttributes.NestedPrivate
 1985     | ILMemberAccess.Public              -> TypeAttributes.NestedPublic
 1986     
 1987 let convertInitSemantics (init:ILTypeInit) =
 1988     match init with 
 1989     | ILTypeInit.BeforeField -> TypeAttributes.BeforeFieldInit
 1990     | ILTypeInit.OnAny -> enum 0
 1991 
 1992 [<NoComparison; NoEquality>]
 1993 type ILTypeDef(name: string, attributes: TypeAttributes, layout: ILTypeDefLayout, implements: ILTypes, genericParams: ILGenericParameterDefs,
 1994                extends: ILType option, methods: ILMethodDefs, nestedTypes: ILTypeDefs, fields: ILFieldDefs, methodImpls: ILMethodImplDefs,
 1995                events: ILEventDefs, properties: ILPropertyDefs, securityDeclsStored: ILSecurityDeclsStored, customAttrsStored: ILAttributesStored, metadataIndex: int32) =  
 1996 
 1997     let mutable customAttrsStored = customAttrsStored
 1998 
 1999     new (name, attributes, layout, implements, genericParams, extends, methods, nestedTypes, fields, methodImpls, events, properties, securityDecls, customAttrs) =  
 2000        ILTypeDef (name, attributes, layout, implements, genericParams, extends, methods, nestedTypes, fields, methodImpls, events, properties, storeILSecurityDecls securityDecls, storeILCustomAttrs customAttrs, NoMetadataIdx)
 2001 
 2002     member __.Name = name
 2003     member __.Attributes = attributes
 2004     member __.GenericParams = genericParams
 2005     member __.Layout = layout
 2006     member __.NestedTypes = nestedTypes
 2007     member __.Implements = implements
 2008     member __.Extends = extends
 2009     member __.Methods = methods
 2010     member __.SecurityDeclsStored = securityDeclsStored
 2011     member __.Fields = fields
 2012     member __.MethodImpls = methodImpls
 2013     member __.Events = events
 2014     member __.Properties = properties
 2015     member __.CustomAttrsStored = customAttrsStored
 2016     member __.MetadataIndex = metadataIndex
 2017 
 2018     member x.With(?name, ?attributes, ?layout, ?implements, ?genericParams, ?extends, ?methods, ?nestedTypes, ?fields, ?methodImpls, ?events, ?properties, ?customAttrs, ?securityDecls) = 
 2019         ILTypeDef(name=defaultArg name x.Name,
 2020                   attributes=defaultArg attributes x.Attributes,
 2021                   layout=defaultArg layout x.Layout,
 2022                   genericParams = defaultArg genericParams x.GenericParams,
 2023                   nestedTypes = defaultArg nestedTypes x.NestedTypes,
 2024                   implements = defaultArg implements x.Implements,
 2025                   extends = defaultArg extends x.Extends,
 2026                   methods = defaultArg methods x.Methods,
 2027                   securityDecls = defaultArg securityDecls x.SecurityDecls,
 2028                   fields = defaultArg fields x.Fields,
 2029                   methodImpls = defaultArg methodImpls x.MethodImpls,
 2030                   events = defaultArg events x.Events,
 2031                   properties = defaultArg properties x.Properties,
 2032                   customAttrs = defaultArg customAttrs x.CustomAttrs)
 2033 
 2034     member x.CustomAttrs = 
 2035         match customAttrsStored with 
 2036         | ILAttributesStored.Reader f ->
 2037             let res = ILAttributes(f x.MetadataIndex)
 2038             customAttrsStored <- ILAttributesStored.Given res
 2039             res 
 2040         | ILAttributesStored.Given res -> 
 2041             res
 2042 
 2043     member x.SecurityDecls = x.SecurityDeclsStored.GetSecurityDecls x.MetadataIndex
 2044 
 2045     member x.IsClass =     (typeKindOfFlags x.Name x.Methods x.Fields x.Extends (int x.Attributes)) = ILTypeDefKind.Class
 2046     member x.IsStruct =    (typeKindOfFlags x.Name x.Methods x.Fields x.Extends (int x.Attributes)) = ILTypeDefKind.ValueType
 2047     member x.IsInterface = (typeKindOfFlags x.Name x.Methods x.Fields x.Extends (int x.Attributes)) = ILTypeDefKind.Interface
 2048     member x.IsEnum =      (typeKindOfFlags x.Name x.Methods x.Fields x.Extends (int x.Attributes)) = ILTypeDefKind.Enum
 2049     member x.IsDelegate =  (typeKindOfFlags x.Name x.Methods x.Fields x.Extends (int x.Attributes)) = ILTypeDefKind.Delegate
 2050     member x.Access = typeAccessOfFlags (int x.Attributes)  
 2051     member x.IsAbstract = x.Attributes &&& TypeAttributes.Abstract <> enum 0
 2052     member x.IsSealed = x.Attributes &&& TypeAttributes.Sealed <> enum 0
 2053     member x.IsSerializable = x.Attributes &&& TypeAttributes.Serializable <> enum 0
 2054     member x.IsComInterop = x.Attributes &&& TypeAttributes.Import <> enum 0 (* Class or interface generated for COM interop *) 
 2055     member x.IsSpecialName = x.Attributes &&& TypeAttributes.SpecialName <> enum 0
 2056     member x.HasSecurity = x.Attributes &&& TypeAttributes.HasSecurity <> enum 0
 2057     member x.Encoding = typeEncodingOfFlags (int x.Attributes)
 2058     member x.IsStructOrEnum = x.IsStruct || x.IsEnum
 2059     member x.WithAccess(access) = x.With(attributes=(x.Attributes &&& ~~~TypeAttributes.VisibilityMask ||| convertTypeAccessFlags access))
 2060     member x.WithNestedAccess(access) = x.With(attributes=(x.Attributes &&& ~~~TypeAttributes.VisibilityMask ||| convertToNestedTypeAccess access))
 2061     member x.WithSealed(condition) = x.With(attributes=(x.Attributes |> conditionalAdd condition TypeAttributes.Sealed))
 2062     member x.WithSerializable(condition) = x.With(attributes=(x.Attributes |> conditionalAdd condition TypeAttributes.Serializable))
 2063     member x.WithAbstract(condition) = x.With(attributes=(x.Attributes |> conditionalAdd condition TypeAttributes.Abstract))
 2064     member x.WithImport(condition) = x.With(attributes=(x.Attributes |> conditionalAdd condition TypeAttributes.Import))
 2065     member x.WithHasSecurity(condition) = x.With(attributes=(x.Attributes |> conditionalAdd condition TypeAttributes.HasSecurity))
 2066     member x.WithLayout(layout) = x.With(attributes=(x.Attributes ||| convertLayout layout), layout = layout)
 2067     member x.WithKind(kind) = x.With(attributes=(x.Attributes ||| convertTypeKind kind), extends = match kind with ILTypeDefKind.Interface -> None | _ -> x.Extends)
 2068     member x.WithEncoding(encoding) = x.With(attributes=(x.Attributes &&& ~~~TypeAttributes.StringFormatMask ||| convertEncoding encoding))
 2069     member x.WithSpecialName(condition) = x.With(attributes=(x.Attributes |> conditionalAdd condition TypeAttributes.SpecialName))
 2070     member x.WithInitSemantics(init) = x.With(attributes=(x.Attributes ||| convertInitSemantics init))
 2071 
 2072 and [<Sealed>] ILTypeDefs(f : unit -> ILPreTypeDef[]) =
 2073 
 2074     let mutable array = InlineDelayInit<_>(f)
 2075 
 2076     let mutable dict = InlineDelayInit<_>(fun () -> 
 2077         let arr = array.Value
 2078         let t = Dictionary<_, _>(HashIdentity.Structural)
 2079         for pre in arr do 
 2080             let key = pre.Namespace, pre.Name
 2081             t.[key] <- pre
 2082         t)
 2083 
 2084     member x.AsArray = [| for pre in array.Value -> pre.GetTypeDef() |]
 2085 
 2086     member x.AsList = [ for pre in array.Value -> pre.GetTypeDef() ]
 2087 
 2088     interface IEnumerable with 
 2089         member x.GetEnumerator() = ((x :> IEnumerable<ILTypeDef>).GetEnumerator() :> IEnumerator)
 2090 
 2091     interface IEnumerable<ILTypeDef> with 
 2092         member x.GetEnumerator() = 
 2093             (seq { for pre in array.Value -> pre.GetTypeDef() }).GetEnumerator()
 2094     
 2095     member x.AsArrayOfPreTypeDefs = array.Value
 2096 
 2097     member x.FindByName nm  = 
 2098         let ns, n = splitILTypeName nm
 2099         dict.Value.[(ns, n)].GetTypeDef()
 2100 
 2101 /// This is a memory-critical class. Very many of these objects get allocated and held to represent the contents of .NET assemblies.
 2102 and [<Sealed>] ILPreTypeDef(nameSpace: string list, name: string, metadataIndex: int32, storage: ILTypeDefStored) = 
 2103     let mutable store : ILTypeDef = Unchecked.defaultof<_>
 2104 
 2105     member __.Namespace = nameSpace
 2106     member __.Name = name
 2107     member __.MetadataIndex = metadataIndex
 2108 
 2109     member x.GetTypeDef() = 
 2110         match box store with 
 2111         | null -> 
 2112             match storage with 
 2113             | ILTypeDefStored.Given td -> 
 2114                 store <- td
 2115                 td
 2116             | ILTypeDefStored.Computed f -> 
 2117                 System.Threading.LazyInitializer.EnsureInitialized<ILTypeDef>(&store, System.Func<_>(fun () -> f()))
 2118             | ILTypeDefStored.Reader f -> 
 2119                 System.Threading.LazyInitializer.EnsureInitialized<ILTypeDef>(&store, System.Func<_>(fun () -> f x.MetadataIndex))
 2120         | _ -> store
 2121       
 2122 and ILTypeDefStored = 
 2123     | Given of ILTypeDef
 2124     | Reader of (int32 -> ILTypeDef)
 2125     | Computed of (unit -> ILTypeDef)
 2126 
 2127 let mkILTypeDefReader f = ILTypeDefStored.Reader f
 2128 
 2129 type ILNestedExportedType =
 2130     { Name: string
 2131       Access: ILMemberAccess
 2132       Nested: ILNestedExportedTypes
 2133       CustomAttrsStored: ILAttributesStored 
 2134       MetadataIndex: int32 } 
 2135 
 2136     member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex
 2137 
 2138 and ILNestedExportedTypes = 
 2139     | ILNestedExportedTypes of Lazy<Map<string, ILNestedExportedType>>
 2140 
 2141     member x.AsList = let (ILNestedExportedTypes ltab) = x in Map.foldBack (fun _x y r -> y::r) (ltab.Force()) []
 2142 
 2143 and [<NoComparison; NoEquality>]
 2144     ILExportedTypeOrForwarder =
 2145     { ScopeRef: ILScopeRef
 2146       Name: string
 2147       Attributes: TypeAttributes
 2148       Nested: ILNestedExportedTypes
 2149       CustomAttrsStored: ILAttributesStored 
 2150       MetadataIndex: int32 } 
 2151 
 2152     member x.Access = typeAccessOfFlags (int x.Attributes)  
 2153 
 2154     member x.IsForwarder = x.Attributes &&& enum<TypeAttributes>(0x00200000) <> enum 0
 2155 
 2156     member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex
 2157 
 2158 and ILExportedTypesAndForwarders = 
 2159     | ILExportedTypesAndForwarders of Lazy<Map<string, ILExportedTypeOrForwarder>>
 2160 
 2161     member x.AsList = let (ILExportedTypesAndForwarders ltab) = x in Map.foldBack (fun _x y r -> y::r) (ltab.Force()) []
 2162 
 2163 [<RequireQualifiedAccess>]
 2164 type ILResourceAccess = 
 2165     | Public 
 2166     | Private 
 2167 
 2168 [<RequireQualifiedAccess>]
 2169 type ILResourceLocation =
 2170     | LocalIn of string * int * int
 2171     | LocalOut of byte[]
 2172     | File of ILModuleRef * int32
 2173     | Assembly of ILAssemblyRef
 2174 
 2175 type ILResource =
 2176     { Name: string
 2177       Location: ILResourceLocation
 2178       Access: ILResourceAccess
 2179       CustomAttrsStored: ILAttributesStored 
 2180       MetadataIndex: int32 }
 2181 
 2182     /// Read the bytes from a resource local to an assembly
 2183     member r.GetBytes() = 
 2184         match r.Location with
 2185         | ILResourceLocation.LocalIn (file, start, len) -> 
 2186             File.ReadBinaryChunk(file, start, len)
 2187         | ILResourceLocation.LocalOut bytes -> bytes
 2188         | _ -> failwith "GetBytes"
 2189 
 2190     member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex
 2191 
 2192 type ILResources = 
 2193     | ILResources of ILResource list
 2194 
 2195     member x.AsList = let (ILResources ltab) = x in ltab
 2196 
 2197 // -------------------------------------------------------------------- 
 2198 // One module in the "current" assembly
 2199 // -------------------------------------------------------------------- 
 2200 
 2201 [<RequireQualifiedAccess>]
 2202 type ILAssemblyLongevity =
 2203     | Unspecified
 2204     | Library
 2205     | PlatformAppDomain
 2206     | PlatformProcess
 2207     | PlatformSystem
 2208 
 2209 
 2210 type ILAssemblyManifest = 
 2211     { Name: string
 2212       AuxModuleHashAlgorithm: int32
 2213       SecurityDeclsStored: ILSecurityDeclsStored
 2214       PublicKey: byte[] option
 2215       Version: ILVersionInfo option
 2216       Locale: Locale option
 2217       CustomAttrsStored: ILAttributesStored
 2218 
 2219       AssemblyLongevity: ILAssemblyLongevity 
 2220       DisableJitOptimizations: bool
 2221       JitTracking: bool
 2222       IgnoreSymbolStoreSequencePoints: bool
 2223       Retargetable: bool
 2224 
 2225       /// Records the types implemented by other modules. 
 2226       ExportedTypes: ILExportedTypesAndForwarders
 2227 
 2228       /// Records whether the entrypoint resides in another module. 
 2229       EntrypointElsewhere: ILModuleRef option 
 2230       MetadataIndex: int32
 2231     } 
 2232 
 2233     member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex
 2234 
 2235     member x.SecurityDecls = x.SecurityDeclsStored.GetSecurityDecls x.MetadataIndex
 2236 
 2237 [<RequireQualifiedAccess>]
 2238 type ILNativeResource = 
 2239     | In of fileName: string * linkedResourceBase: int * linkedResourceStart: int * linkedResourceLength: int
 2240     | Out of unlinkedResource: byte[]
 2241 
 2242 type ILModuleDef = 
 2243     { Manifest: ILAssemblyManifest option
 2244       Name: string
 2245       TypeDefs: ILTypeDefs
 2246       SubsystemVersion : int * int
 2247       UseHighEntropyVA : bool
 2248       SubSystemFlags: int32
 2249       IsDLL: bool
 2250       IsILOnly: bool
 2251       Platform: ILPlatform option
 2252       StackReserveSize: int32 option
 2253       Is32Bit: bool
 2254       Is32BitPreferred: bool
 2255       Is64Bit: bool
 2256       VirtualAlignment: int32
 2257       PhysicalAlignment: int32
 2258       ImageBase: int32
 2259       MetadataVersion: string
 2260       Resources: ILResources
 2261       /// e.g. win32 resources
 2262       NativeResources: ILNativeResource list 
 2263       CustomAttrsStored: ILAttributesStored
 2264       MetadataIndex: int32
 2265     }
 2266     member x.ManifestOfAssembly = 
 2267         match x.Manifest with 
 2268         | Some m -> m
 2269         | None -> failwith "no manifest.  It is possible you are using an auxiliary module of an assembly in a context where the main module of an assembly is expected.  Typically the main module of an assembly must be specified first within a list of the modules in an assembly."
 2270 
 2271     member m.HasManifest = 
 2272         match m.Manifest with None -> false | _ -> true
 2273 
 2274     member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex
 2275 
 2276 // -------------------------------------------------------------------- 
 2277 // Add fields and types to tables, with decent error messages
 2278 // when clashes occur...
 2279 // -------------------------------------------------------------------- 
 2280 
 2281 let mkILEmptyGenericParams = ([]: ILGenericParameterDefs)
 2282 
 2283 let emptyILGenericArgsList = ([]: ILType list)
 2284 
 2285 // --------------------------------------------------------------------
 2286 // Make ILTypeRefs etc.
 2287 // -------------------------------------------------------------------- 
 2288 
 2289 
 2290 let mkILNestedTyRef (scope, l, nm) =  ILTypeRef.Create(scope, l, nm)
 2291 
 2292 let mkILTyRef (scope, nm) =  mkILNestedTyRef (scope, [], nm)
 2293 
 2294 type ILGenericArgsList = ILType list
 2295 
 2296 let mkILTySpec (tref, inst) =  ILTypeSpec.Create(tref, inst)
 2297 
 2298 let mkILNonGenericTySpec tref =  mkILTySpec (tref, [])
 2299 
 2300 let mkILTyRefInTyRef (tref:ILTypeRef, nm) = 
 2301     mkILNestedTyRef (tref.Scope, tref.Enclosing@[tref.Name], nm)
 2302 
 2303 let mkILTy boxed tspec = 
 2304     match boxed with AsObject -> mkILBoxedType tspec | _ -> ILType.Value tspec
 2305 
 2306 let mkILNamedTy vc tref tinst = mkILTy vc (ILTypeSpec.Create(tref, tinst))
 2307 
 2308 let mkILValueTy tref tinst = mkILNamedTy AsValue tref tinst
 2309 
 2310 let mkILBoxedTy tref tinst = mkILNamedTy AsObject tref tinst
 2311 
 2312 let mkILNonGenericValueTy tref = mkILNamedTy AsValue tref []
 2313 
 2314 let mkILNonGenericBoxedTy tref = mkILNamedTy AsObject tref []
 2315 
 2316 let mkSimpleAssRef n = 
 2317   ILAssemblyRef.Create(n, None, None, false, None, None)
 2318 
 2319 let mkSimpleModRef n = 
 2320     ILModuleRef.Create(n, true, None)
 2321 
 2322 // --------------------------------------------------------------------
 2323 // The toplevel class of a module is called "<Module>"
 2324 // -------------------------------------------------------------------- 
 2325 
 2326 let typeNameForGlobalFunctions = "<Module>"
 2327 
 2328 let mkILTypeForGlobalFunctions scoref = mkILBoxedType (mkILNonGenericTySpec (ILTypeRef.Create(scoref, [], typeNameForGlobalFunctions)))
 2329 
 2330 let isTypeNameForGlobalFunctions d = (d = typeNameForGlobalFunctions)
 2331 
 2332 let mkILMethRef (tref, callconv, nm, gparams, args, rty) =
 2333     { mrefParent=tref 
 2334       mrefCallconv=callconv
 2335       mrefGenericArity=gparams
 2336       mrefName=nm
 2337       mrefArgs=args
 2338       mrefReturn=rty}
 2339 
 2340 let mkILMethSpecForMethRefInTy (mref, ty, minst) = 
 2341     { mspecMethodRef=mref
 2342       mspecDeclaringType=ty
 2343       mspecMethodInst=minst }
 2344 
 2345 let mkILMethSpec (mref, vc, tinst, minst) = mkILMethSpecForMethRefInTy (mref, mkILNamedTy vc mref.DeclaringTypeRef tinst, minst)
 2346 
 2347 let mkILMethSpecInTypeRef (tref, vc, cc, nm, args, rty, tinst, minst) =
 2348     mkILMethSpec (mkILMethRef ( tref, cc, nm, List.length minst, args, rty), vc, tinst, minst)
 2349 
 2350 let mkILMethSpecInTy (ty:ILType, cc, nm, args, rty, minst:ILGenericArgs) =
 2351     mkILMethSpecForMethRefInTy (mkILMethRef (ty.TypeRef, cc, nm, minst.Length, args, rty), ty, minst)
 2352 
 2353 let mkILNonGenericMethSpecInTy (ty, cc, nm, args, rty) = 
 2354     mkILMethSpecInTy (ty, cc, nm, args, rty, [])
 2355 
 2356 let mkILInstanceMethSpecInTy (ty:ILType, nm, args, rty, minst) =
 2357     mkILMethSpecInTy (ty, ILCallingConv.Instance, nm, args, rty, minst)
 2358 
 2359 let mkILNonGenericInstanceMethSpecInTy (ty:ILType, nm, args, rty) =
 2360     mkILInstanceMethSpecInTy (ty, nm, args, rty, [])
 2361 
 2362 let mkILStaticMethSpecInTy (ty, nm, args, rty, minst) =
 2363     mkILMethSpecInTy (ty, ILCallingConv.Static, nm, args, rty, minst)
 2364 
 2365 let mkILNonGenericStaticMethSpecInTy (ty, nm, args, rty) =
 2366     mkILStaticMethSpecInTy (ty, nm, args, rty, [])
 2367 
 2368 let mkILCtorMethSpec (tref, args, cinst) = 
 2369     mkILMethSpecInTypeRef(tref, AsObject, ILCallingConv.Instance, ".ctor", args, ILType.Void, cinst, [])
 2370 
 2371 let mkILCtorMethSpecForTy (ty, args) = 
 2372   mkILMethSpecInTy(ty, ILCallingConv.Instance, ".ctor", args, ILType.Void, [])
 2373 
 2374 let mkILNonGenericCtorMethSpec (tref, args) = 
 2375   mkILCtorMethSpec (tref, args, [])
 2376 
 2377 // --------------------------------------------------------------------
 2378 // Make references to fields
 2379 // -------------------------------------------------------------------- 
 2380 
 2381 let mkILFieldRef(tref, nm, ty) = { DeclaringTypeRef=tref; Name=nm; Type=ty}
 2382 
 2383 let mkILFieldSpec (tref, ty) = { FieldRef= tref; DeclaringType=ty }
 2384 
 2385 let mkILFieldSpecInTy (ty:ILType, nm, fty) = 
 2386     mkILFieldSpec (mkILFieldRef (ty.TypeRef, nm, fty), ty)
 2387     
 2388 
 2389 let andTailness x y = 
 2390   match x with Tailcall when y -> Tailcall | _ -> Normalcall
 2391 
 2392 // -------------------------------------------------------------------- 
 2393 // Basic operations on code.
 2394 // -------------------------------------------------------------------- 
 2395 
 2396 let formatCodeLabel (x:int) = "L"+string x
 2397 
 2398 //  ++GLOBAL MUTABLE STATE (concurrency safe)
 2399 let codeLabelCount = ref 0
 2400 let generateCodeLabel() = System.Threading.Interlocked.Increment(codeLabelCount)
 2401 
 2402 let instrIsRet i = 
 2403     match i with 
 2404     | I_ret ->  true
 2405     | _ -> false
 2406 
 2407 let nonBranchingInstrsToCode instrs : ILCode = 
 2408     let instrs = Array.ofList instrs
 2409     let instrs = 
 2410         if instrs.Length <> 0 && instrIsRet (Array.last instrs) then instrs
 2411         else Array.append instrs  [| I_ret |]
 2412 
 2413     { Labels = Dictionary()
 2414       Instrs = instrs
 2415       Exceptions = []
 2416       Locals = [] }
 2417 
 2418 
 2419 // -------------------------------------------------------------------- 
 2420 // 
 2421 // -------------------------------------------------------------------- 
 2422 
 2423 let mkILTyvarTy tv = ILType.TypeVar tv
 2424 
 2425 let mkILSimpleTypar nm =
 2426    { Name=nm
 2427      Constraints = []
 2428      Variance=NonVariant
 2429      HasReferenceTypeConstraint=false
 2430      HasNotNullableValueTypeConstraint=false
 2431      HasDefaultConstructorConstraint=false
 2432      CustomAttrsStored = storeILCustomAttrs emptyILCustomAttrs
 2433      MetadataIndex = NoMetadataIdx }
 2434 
 2435 let gparam_of_gactual (_ga:ILType) = mkILSimpleTypar "T"
 2436 
 2437 let mkILFormalTypars (x: ILGenericArgsList) = List.map gparam_of_gactual x
 2438 
 2439 let mkILFormalGenericArgs numtypars (gparams:ILGenericParameterDefs)  =
 2440     List.mapi (fun n _gf -> mkILTyvarTy (uint16 (numtypars + n))) gparams
 2441  
 2442 let mkILFormalBoxedTy tref gparams = mkILBoxedTy tref (mkILFormalGenericArgs 0 gparams)
 2443 
 2444 let mkILFormalNamedTy bx tref gparams = mkILNamedTy bx tref (mkILFormalGenericArgs 0 gparams)
 2445 
 2446 // -------------------------------------------------------------------- 
 2447 // Operations on class etc. defs.
 2448 // -------------------------------------------------------------------- 
 2449 
 2450 let mkRefForNestedILTypeDef scope (enc:ILTypeDef list, td:ILTypeDef)  = 
 2451     mkILNestedTyRef(scope, (enc |> List.map (fun etd -> etd.Name)), td.Name)
 2452 
 2453 // -------------------------------------------------------------------- 
 2454 // Operations on type tables.
 2455 // -------------------------------------------------------------------- 
 2456 
 2457 let mkILPreTypeDef (td:ILTypeDef) = 
 2458     let ns, n = splitILTypeName td.Name
 2459     ILPreTypeDef(ns, n, NoMetadataIdx, ILTypeDefStored.Given td)
 2460 let mkILPreTypeDefComputed (ns, n, f) =
 2461     ILPreTypeDef(ns, n, NoMetadataIdx, ILTypeDefStored.Computed f)
 2462 let mkILPreTypeDefRead (ns, n, idx, f) =
 2463     ILPreTypeDef(ns, n, idx, f)
 2464 
 2465 
 2466 let addILTypeDef td (tdefs: ILTypeDefs) = ILTypeDefs (fun () -> [| yield mkILPreTypeDef td; yield! tdefs.AsArrayOfPreTypeDefs |])
 2467 let mkILTypeDefsFromArray (l: ILTypeDef[]) =  ILTypeDefs (fun () -> Array.map mkILPreTypeDef l)
 2468 let mkILTypeDefs l =  mkILTypeDefsFromArray (Array.ofList l)
 2469 let mkILTypeDefsComputed f = ILTypeDefs f
 2470 let emptyILTypeDefs = mkILTypeDefsFromArray [| |]
 2471 
 2472 // -------------------------------------------------------------------- 
 2473 // Operations on method tables.
 2474 // -------------------------------------------------------------------- 
 2475 
 2476 let mkILMethodsFromArray xs =  ILMethodDefs (fun () -> xs)
 2477 let mkILMethods xs =  xs |> Array.ofList |> mkILMethodsFromArray
 2478 let mkILMethodsComputed f =  ILMethodDefs f
 2479 let emptyILMethods = mkILMethodsFromArray [| |]
 2480 
 2481 let filterILMethodDefs f (mdefs: ILMethodDefs) = 
 2482     ILMethodDefs (fun () -> mdefs.AsArray |> Array.filter f)
 2483 
 2484 // -------------------------------------------------------------------- 
 2485 // Operations and defaults for modules, assemblies etc.
 2486 // -------------------------------------------------------------------- 
 2487 
 2488 let defaultSubSystem = 3 (* this is what comes out of ILDASM on 30/04/2001 *)
 2489 let defaultPhysAlignment = 512 (* this is what comes out of ILDASM on 30/04/2001 *)
 2490 let defaultVirtAlignment = 0x2000 (* this is what comes out of ILDASM on 30/04/2001 *)
 2491 let defaultImageBase = 0x034f0000 (* this is what comes out of ILDASM on 30/04/2001 *)
 2492 
 2493 // -------------------------------------------------------------------- 
 2494 // Array types
 2495 // -------------------------------------------------------------------- 
 2496 
 2497 let mkILArrTy (ty, shape) = ILType.Array(shape, ty)
 2498 let mkILArr1DTy ty = mkILArrTy (ty, ILArrayShape.SingleDimensional)
 2499 let isILArrTy ty = match ty with ILType.Array _ -> true| _ -> false
 2500 let destILArrTy ty = match ty with ILType.Array(shape, ty) -> (shape, ty) | _ -> failwith "destILArrTy"
 2501 
 2502 // -------------------------------------------------------------------- 
 2503 // Sigs of special types built-in
 2504 // -------------------------------------------------------------------- 
 2505 
 2506 [<Literal>]
 2507 let tname_Object = "System.Object"
 2508 [<Literal>]
 2509 let tname_String = "System.String"
 2510 [<Literal>]
 2511 let tname_Array = "System.Array"
 2512 [<Literal>]
 2513 let tname_Type = "System.Type"
 2514 [<Literal>]
 2515 let tname_Int64 = "System.Int64"
 2516 [<Literal>]
 2517 let tname_UInt64 = "System.UInt64"
 2518 [<Literal>]
 2519 let tname_Int32 = "System.Int32"
 2520 [<Literal>]
 2521 let tname_UInt32 = "System.UInt32"
 2522 [<Literal>]
 2523 let tname_Int16 = "System.Int16"
 2524 [<Literal>]
 2525 let tname_UInt16 = "System.UInt16"
 2526 [<Literal>]
 2527 let tname_SByte = "System.SByte"
 2528 [<Literal>]
 2529 let tname_Byte = "System.Byte"
 2530 [<Literal>]
 2531 let tname_Single = "System.Single"
 2532 [<Literal>]
 2533 let tname_Double = "System.Double"
 2534 [<Literal>]
 2535 let tname_Bool = "System.Boolean"
 2536 [<Literal>]
 2537 let tname_Char = "System.Char"
 2538 [<Literal>]
 2539 let tname_IntPtr = "System.IntPtr"
 2540 [<Literal>]
 2541 let tname_UIntPtr = "System.UIntPtr"
 2542 
 2543 [<NoEquality; NoComparison; StructuredFormatDisplay("{DebugText}")>]
 2544 // This data structure needs an entirely delayed implementation
 2545 type ILGlobals(primaryScopeRef) = 
 2546     
 2547     let m_mkSysILTypeRef nm = mkILTyRef(primaryScopeRef, nm)
 2548 
 2549     let m_typ_Object = mkILBoxedType (mkILNonGenericTySpec (m_mkSysILTypeRef tname_Object))
 2550     let m_typ_String = mkILBoxedType (mkILNonGenericTySpec (m_mkSysILTypeRef tname_String))
 2551     let m_typ_Array = mkILBoxedType (mkILNonGenericTySpec (m_mkSysILTypeRef tname_Array))
 2552     let m_typ_Type = mkILBoxedType (mkILNonGenericTySpec (m_mkSysILTypeRef tname_Type))
 2553     let m_typ_SByte = ILType.Value (mkILNonGenericTySpec (m_mkSysILTypeRef tname_SByte))
 2554     let m_typ_Int16 = ILType.Value (mkILNonGenericTySpec (m_mkSysILTypeRef tname_Int16))
 2555     let m_typ_Int32 = ILType.Value (mkILNonGenericTySpec (m_mkSysILTypeRef tname_Int32))
 2556     let m_typ_Int64 = ILType.Value (mkILNonGenericTySpec (m_mkSysILTypeRef tname_Int64))
 2557     let m_typ_Byte = ILType.Value (mkILNonGenericTySpec (m_mkSysILTypeRef tname_Byte))
 2558     let m_typ_UInt16 = ILType.Value (mkILNonGenericTySpec (m_mkSysILTypeRef tname_UInt16))
 2559     let m_typ_UInt32 = ILType.Value (mkILNonGenericTySpec (m_mkSysILTypeRef tname_UInt32))
 2560     let m_typ_UInt64 = ILType.Value (mkILNonGenericTySpec (m_mkSysILTypeRef tname_UInt64))
 2561     let m_typ_Single = ILType.Value (mkILNonGenericTySpec (m_mkSysILTypeRef tname_Single))
 2562     let m_typ_Double = ILType.Value (mkILNonGenericTySpec (m_mkSysILTypeRef tname_Double))
 2563     let m_typ_Bool = ILType.Value (mkILNonGenericTySpec (m_mkSysILTypeRef tname_Bool))
 2564     let m_typ_Char = ILType.Value (mkILNonGenericTySpec (m_mkSysILTypeRef tname_Char))
 2565     let m_typ_IntPtr = ILType.Value (mkILNonGenericTySpec (m_mkSysILTypeRef tname_IntPtr))
 2566     let m_typ_UIntPtr = ILType.Value (mkILNonGenericTySpec (m_mkSysILTypeRef tname_UIntPtr))
 2567 
 2568     member x.primaryAssemblyScopeRef    = m_typ_Object.TypeRef.Scope
 2569     member x.primaryAssemblyName        = m_typ_Object.TypeRef.Scope.AssemblyRef.Name
 2570     member x.typ_Object                 = m_typ_Object
 2571     member x.typ_String                 = m_typ_String
 2572     member x.typ_Array                  = m_typ_Array
 2573     member x.typ_Type                   = m_typ_Type
 2574     member x.typ_IntPtr                 = m_typ_IntPtr                    
 2575     member x.typ_UIntPtr                = m_typ_UIntPtr
 2576     member x.typ_Byte                   = m_typ_Byte                 
 2577     member x.typ_Int16                  = m_typ_Int16
 2578     member x.typ_Int32                  = m_typ_Int32
 2579     member x.typ_Int64                  = m_typ_Int64
 2580     member x.typ_SByte                  = m_typ_SByte
 2581     member x.typ_UInt16                 = m_typ_UInt16
 2582     member x.typ_UInt32                 = m_typ_UInt32
 2583     member x.typ_UInt64                 = m_typ_UInt64
 2584     member x.typ_Single                 = m_typ_Single
 2585     member x.typ_Double                 = m_typ_Double
 2586     member x.typ_Bool                   = m_typ_Bool
 2587     member x.typ_Char                   = m_typ_Char
 2588 
 2589     /// For debugging
 2590     [<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
 2591     member x.DebugText = x.ToString()
 2592 
 2593     override x.ToString() = "<ILGlobals>"
 2594 
 2595 let mkILGlobals primaryScopeRef = ILGlobals primaryScopeRef
 2596 
 2597 let mkNormalCall mspec = I_call (Normalcall, mspec, None)
 2598 let mkNormalCallvirt mspec = I_callvirt (Normalcall, mspec, None)
 2599 let mkNormalCallconstraint (ty, mspec) = I_callconstraint (Normalcall, ty, mspec, None)
 2600 let mkNormalNewobj mspec =  I_newobj (mspec, None)
 2601 
 2602 /// Comment on common object cache sizes:
 2603 /// mkLdArg - I can't imagine any IL method we generate needing more than this
 2604 /// mkLdLoc - I tried 256, and there were LdLoc allocations left, so I upped it o 512. I didn't check again.
 2605 /// mkStLoc - it should be the same as LdLoc  (where there's a LdLoc there must be a StLoc)
 2606 /// mkLdcInt32 - just a guess
 2607 
 2608 let ldargs = [| for i in 0 .. 128 -> I_ldarg (uint16 i) |]
 2609 let mkLdarg i = if 0us < i && i < uint16 ldargs.Length then ldargs.[int i] else I_ldarg i
 2610 let mkLdarg0 = mkLdarg 0us
 2611 
 2612 let ldlocs = [| for i in 0 .. 512 -> I_ldloc (uint16 i) |]
 2613 let mkLdloc i = if 0us < i && i < uint16 ldlocs.Length then ldlocs.[int i] else I_ldloc i
 2614 
 2615 let stlocs = [| for i in 0 .. 512 -> I_stloc (uint16 i) |]
 2616 let mkStloc i = if 0us < i && i < uint16 stlocs.Length then stlocs.[int i] else I_stloc i
 2617 
 2618 let ldi32s = [| for i in 0 .. 256 -> AI_ldc (DT_I4, ILConst.I4 i) |]
 2619 let mkLdcInt32 i = if 0 < i && i < ldi32s.Length then ldi32s.[i] else AI_ldc (DT_I4, ILConst.I4 i)
 2620 
 2621 let tname_CompilerGeneratedAttribute = "System.Runtime.CompilerServices.CompilerGeneratedAttribute"
 2622 let tname_DebuggableAttribute = "System.Diagnostics.DebuggableAttribute"
 2623 
 2624 
 2625 
 2626         
 2627 (* NOTE: ecma_ prefix refers to the standard "mscorlib" *)
 2628 let ecmaPublicKey = PublicKeyToken (Bytes.ofInt32Array [|0xde; 0xad; 0xbe; 0xef; 0xca; 0xfe; 0xfa; 0xce |]) 
 2629    
 2630 let isILBoxedTy = function ILType.Boxed _ -> true | _ -> false
 2631 let isILValueTy = function ILType.Value _ -> true | _ -> false
 2632 
 2633 
 2634 let isPrimaryAssemblyTySpec (tspec:ILTypeSpec) n = 
 2635   let tref = tspec.TypeRef
 2636   let scoref = tref.Scope
 2637   (tref.Name = n) &&
 2638   match scoref with
 2639   | ILScopeRef.Assembly n -> PrimaryAssembly.IsSomePrimaryAssembly n.Name
 2640   | ILScopeRef.Module _ -> false
 2641   | ILScopeRef.Local -> true
 2642 
 2643 let isILBoxedPrimaryAssemblyTy (ty:ILType) n = 
 2644   isILBoxedTy ty && isPrimaryAssemblyTySpec ty.TypeSpec n
 2645 
 2646 let isILValuePrimaryAssemblyTy (ty:ILType) n = 
 2647   isILValueTy ty && isPrimaryAssemblyTySpec ty.TypeSpec n
 2648       
 2649 let isILObjectTy            ty = isILBoxedPrimaryAssemblyTy ty tname_Object
 2650 let isILStringTy            ty = isILBoxedPrimaryAssemblyTy ty tname_String
 2651 let isILTypedReferenceTy    ty = isILValuePrimaryAssemblyTy ty "System.TypedReference"
 2652 let isILSByteTy        ty = isILValuePrimaryAssemblyTy ty tname_SByte
 2653 let isILByteTy         ty = isILValuePrimaryAssemblyTy ty tname_Byte
 2654 let isILInt16Ty        ty = isILValuePrimaryAssemblyTy ty tname_Int16
 2655 let isILUInt16Ty       ty = isILValuePrimaryAssemblyTy ty tname_UInt16
 2656 let isILInt32Ty        ty = isILValuePrimaryAssemblyTy ty tname_Int32
 2657 let isILUInt32Ty       ty = isILValuePrimaryAssemblyTy ty tname_UInt32
 2658 let isILInt64Ty        ty = isILValuePrimaryAssemblyTy ty tname_Int64
 2659 let isILUInt64Ty       ty = isILValuePrimaryAssemblyTy ty tname_UInt64
 2660 let isILIntPtrTy       ty = isILValuePrimaryAssemblyTy ty tname_IntPtr
 2661 let isILUIntPtrTy      ty = isILValuePrimaryAssemblyTy ty tname_UIntPtr
 2662 let isILBoolTy         ty = isILValuePrimaryAssemblyTy ty tname_Bool
 2663 let isILCharTy         ty = isILValuePrimaryAssemblyTy ty tname_Char
 2664 let isILSingleTy       ty = isILValuePrimaryAssemblyTy ty tname_Single
 2665 let isILDoubleTy       ty = isILValuePrimaryAssemblyTy ty tname_Double
 2666 
 2667 // -------------------------------------------------------------------- 
 2668 // Rescoping
 2669 // -------------------------------------------------------------------- 
 2670 
 2671 let rescopeILScopeRef scoref scoref1 = 
 2672     match scoref, scoref1 with 
 2673     | _, ILScopeRef.Local -> scoref 
 2674     | ILScopeRef.Local, _ -> scoref1
 2675     | _, ILScopeRef.Module _ -> scoref
 2676     | ILScopeRef.Module _, _ -> scoref1
 2677     | _ -> scoref1
 2678 
 2679 let rescopeILTypeRef scoref (tref1:ILTypeRef) = 
 2680     let scoref1 = tref1.Scope 
 2681     let scoref2 = rescopeILScopeRef scoref scoref1
 2682     if scoref1 === scoref2 then tref1
 2683     else ILTypeRef.Create(scoref2, tref1.Enclosing, tref1.Name)
 2684 
 2685 // ORIGINAL IMPLEMENTATION (too many allocations
 2686 //         { tspecTypeRef=rescopeILTypeRef scoref tref;
 2687 //           tspecInst=rescopeILTypes scoref tinst } 
 2688 let rec rescopeILTypeSpec scoref (tspec1:ILTypeSpec) = 
 2689     let tref1 = tspec1.TypeRef
 2690     let tinst1 = tspec1.GenericArgs
 2691     let tref2 = rescopeILTypeRef scoref tref1
 2692 
 2693     // avoid reallocation in the common case 
 2694     if tref1 === tref2 then 
 2695         if isNil tinst1 then tspec1 else
 2696         let tinst2 = rescopeILTypes scoref tinst1
 2697         if tinst1 === tinst2 then tspec1 else 
 2698         ILTypeSpec.Create (tref2, tinst2)
 2699     else
 2700         let tinst2 = rescopeILTypes scoref tinst1
 2701         ILTypeSpec.Create (tref2, tinst2)
 2702 
 2703 and rescopeILType scoref ty = 
 2704     match ty with 
 2705     | ILType.Ptr t -> ILType.Ptr (rescopeILType scoref t)
 2706     | ILType.FunctionPointer t -> ILType.FunctionPointer (rescopeILCallSig scoref t)
 2707     | ILType.Byref t -> ILType.Byref (rescopeILType scoref t)
 2708     | ILType.Boxed cr1 -> 
 2709         let cr2 = rescopeILTypeSpec scoref cr1
 2710         if cr1 === cr2 then ty else 
 2711         mkILBoxedType cr2
 2712     | ILType.Array (s, ety1) -> 
 2713         let ety2 = rescopeILType scoref ety1
 2714         if ety1 === ety2 then ty else 
 2715         ILType.Array (s, ety2)
 2716     | ILType.Value cr1 -> 
 2717         let cr2 = rescopeILTypeSpec scoref cr1 
 2718         if cr1 === cr2 then ty else 
 2719         ILType.Value cr2
 2720     | ILType.Modified(b, tref, ty) -> ILType.Modified(b, rescopeILTypeRef scoref tref, rescopeILType scoref ty)
 2721     | x -> x
 2722 
 2723 and rescopeILTypes scoref i = 
 2724     if isNil i then i
 2725     else List.mapq (rescopeILType scoref) i
 2726 
 2727 and rescopeILCallSig scoref  csig = 
 2728     mkILCallSig (csig.CallingConv, rescopeILTypes scoref csig.ArgTypes, rescopeILType scoref csig.ReturnType)
 2729 
 2730 let rescopeILMethodRef scoref (x:ILMethodRef) =
 2731     { mrefParent = rescopeILTypeRef scoref x.DeclaringTypeRef
 2732       mrefCallconv = x.mrefCallconv
 2733       mrefGenericArity=x.mrefGenericArity
 2734       mrefName=x.mrefName
 2735       mrefArgs = rescopeILTypes scoref x.mrefArgs
 2736       mrefReturn= rescopeILType scoref x.mrefReturn }
 2737 
 2738 let rescopeILFieldRef scoref x = 
 2739     { DeclaringTypeRef = rescopeILTypeRef scoref x.DeclaringTypeRef
 2740       Name= x.Name
 2741       Type= rescopeILType scoref x.Type }
 2742 
 2743 // -------------------------------------------------------------------- 
 2744 // Instantiate polymorphism in types
 2745 // -------------------------------------------------------------------- 
 2746 
 2747 let rec instILTypeSpecAux numFree inst (tspec:ILTypeSpec) = 
 2748     ILTypeSpec.Create(tspec.TypeRef, instILGenericArgsAux numFree inst tspec.GenericArgs) 
 2749   
 2750 and instILTypeAux numFree (inst:ILGenericArgs) ty = 
 2751     match ty with 
 2752     | ILType.Ptr t       -> ILType.Ptr (instILTypeAux numFree inst t)
 2753     | ILType.FunctionPointer t      -> ILType.FunctionPointer (instILCallSigAux numFree inst t)
 2754     | ILType.Array (a, t) -> ILType.Array (a, instILTypeAux numFree inst t)
 2755     | ILType.Byref t     -> ILType.Byref (instILTypeAux numFree inst t)
 2756     | ILType.Boxed cr    -> mkILBoxedType (instILTypeSpecAux numFree inst cr)
 2757     | ILType.Value cr    -> ILType.Value (instILTypeSpecAux numFree inst cr)
 2758     | ILType.TypeVar  v -> 
 2759         let v = int v
 2760         let top = inst.Length
 2761         if v < numFree then ty else
 2762         if v - numFree >= top then 
 2763             ILType.TypeVar (uint16 (v - top)) 
 2764         else 
 2765             List.item (v - numFree) inst
 2766     | x -> x
 2767     
 2768 and instILGenericArgsAux numFree inst i = List.map (instILTypeAux numFree inst) i
 2769 
 2770 and instILCallSigAux numFree inst  csig = 
 2771   mkILCallSig  (csig.CallingConv, List.map (instILTypeAux numFree inst) csig.ArgTypes, instILTypeAux numFree inst csig.ReturnType)
 2772 
 2773 let instILType     i t = instILTypeAux 0 i t
 2774 
 2775 // --------------------------------------------------------------------
 2776 // MS-IL: Parameters, Return types and Locals
 2777 // -------------------------------------------------------------------- 
 2778 
 2779 let mkILParam (name, ty) : ILParameter =
 2780     { Name=name
 2781       Default=None
 2782       Marshal=None
 2783       IsIn=false
 2784       IsOut=false
 2785       IsOptional=false
 2786       Type=ty
 2787       CustomAttrsStored=storeILCustomAttrs emptyILCustomAttrs
 2788       MetadataIndex = NoMetadataIdx  }
 2789 let mkILParamNamed (s, ty) = mkILParam (Some s, ty)
 2790 let mkILParamAnon ty = mkILParam (None, ty)
 2791 
 2792 let mkILReturn ty : ILReturn = 
 2793     { Marshal=None
 2794       Type=ty
 2795       CustomAttrsStored=storeILCustomAttrs emptyILCustomAttrs
 2796       MetadataIndex = NoMetadataIdx }
 2797 
 2798 let mkILLocal ty dbgInfo : ILLocal = 
 2799     { IsPinned=false
 2800       Type=ty
 2801       DebugInfo=dbgInfo }
 2802 
 2803 type ILFieldSpec with
 2804   member fr.ActualType = 
 2805       let env = fr.DeclaringType.GenericArgs
 2806       instILType env fr.FormalType
 2807 
 2808 // -------------------------------------------------------------------- 
 2809 // Make a method mbody
 2810 // -------------------------------------------------------------------- 
 2811 
 2812 let mkILMethodBody (zeroinit, locals, maxstack, code, tag) : ILMethodBody = 
 2813   { IsZeroInit=zeroinit
 2814     MaxStack=maxstack
 2815     NoInlining=false
 2816     AggressiveInlining=false
 2817     Locals= locals 
 2818     Code= code
 2819     SourceMarker=tag }
 2820 
 2821 let mkMethodBody (zeroinit, locals, maxstack, code, tag) = MethodBody.IL (mkILMethodBody (zeroinit, locals, maxstack, code, tag))
 2822 
 2823 // -------------------------------------------------------------------- 
 2824 // Make a constructor
 2825 // -------------------------------------------------------------------- 
 2826 
 2827 let mkILVoidReturn = mkILReturn ILType.Void
 2828 
 2829 let methBodyNotAvailable = mkMethBodyAux MethodBody.NotAvailable
 2830 let methBodyAbstract = mkMethBodyAux MethodBody.Abstract
 2831 let methBodyNative = mkMethBodyAux MethodBody.Native
 2832 
 2833 let mkILCtor (access, args, impl) = 
 2834     ILMethodDef(name=".ctor",
 2835                 attributes=(convertMemberAccess access ||| MethodAttributes.SpecialName ||| MethodAttributes.RTSpecialName),
 2836                 implAttributes=MethodImplAttributes.Managed,
 2837                 callingConv=ILCallingConv.Instance,
 2838                 parameters = args,
 2839                 ret= mkILVoidReturn,
 2840                 body= mkMethBodyAux impl,
 2841                 securityDecls=emptyILSecurityDecls,
 2842                 isEntryPoint=false,
 2843                 genericParams=mkILEmptyGenericParams,
 2844                 customAttrs = emptyILCustomAttrs)
 2845 
 2846 // -------------------------------------------------------------------- 
 2847 // Do-nothing ctor, just pass on to monomorphic superclass
 2848 // -------------------------------------------------------------------- 
 2849 
 2850 let mkCallBaseConstructor (ty, args: ILType list) =
 2851     [ mkLdarg0 ] @
 2852     List.mapi (fun i _ -> mkLdarg (uint16 (i+1))) args @
 2853     [ mkNormalCall (mkILCtorMethSpecForTy (ty, [])) ]
 2854 
 2855 let mkNormalStfld fspec = I_stfld (Aligned, Nonvolatile, fspec)
 2856 let mkNormalStsfld fspec = I_stsfld (Nonvolatile, fspec)
 2857 let mkNormalLdsfld fspec = I_ldsfld (Nonvolatile, fspec)
 2858 let mkNormalLdfld fspec = I_ldfld (Aligned, Nonvolatile, fspec)
 2859 let mkNormalLdflda fspec = I_ldflda fspec
 2860 let mkNormalLdobj dt = I_ldobj(Aligned, Nonvolatile, dt)
 2861 let mkNormalStobj dt = I_stobj(Aligned, Nonvolatile, dt)
 2862 
 2863 let mkILNonGenericEmptyCtor tag superTy = 
 2864     let ctor = mkCallBaseConstructor (superTy, [])
 2865     mkILCtor(ILMemberAccess.Public, [], mkMethodBody(false, [], 8, nonBranchingInstrsToCode ctor, tag))
 2866 
 2867 // -------------------------------------------------------------------- 
 2868 // Make a static, top level monomophic method - very useful for
 2869 // creating helper ILMethodDefs for internal use.
 2870 // -------------------------------------------------------------------- 
 2871 
 2872 let mkILStaticMethod (genparams, nm, access, args, ret, impl) = 
 2873     ILMethodDef(genericParams=genparams,
 2874                 name=nm,
 2875                 attributes=(convertMemberAccess access ||| MethodAttributes.Static),
 2876                 implAttributes=MethodImplAttributes.Managed,
 2877                 callingConv = ILCallingConv.Static,
 2878                 parameters = args,
 2879                 ret= ret,
 2880                 securityDecls=emptyILSecurityDecls,
 2881                 isEntryPoint=false,
 2882                 customAttrs = emptyILCustomAttrs,
 2883                 body= mkMethBodyAux impl)
 2884 
 2885 let mkILNonGenericStaticMethod (nm, access, args, ret, impl) = 
 2886     mkILStaticMethod (mkILEmptyGenericParams, nm, access, args, ret, impl)
 2887 
 2888 let mkILClassCtor impl = 
 2889     ILMethodDef(name=".cctor",
 2890                 attributes=(MethodAttributes.Private ||| MethodAttributes.Static ||| MethodAttributes.SpecialName ||| MethodAttributes.RTSpecialName),
 2891                 implAttributes=MethodImplAttributes.Managed,
 2892                 callingConv=ILCallingConv.Static,
 2893                 genericParams=mkILEmptyGenericParams,
 2894                 parameters = [],
 2895                 ret=mkILVoidReturn,
 2896                 isEntryPoint=false,
 2897                 securityDecls=emptyILSecurityDecls,
 2898                 customAttrs=emptyILCustomAttrs,
 2899                 body= mkMethBodyAux impl)
 2900 
 2901 // -------------------------------------------------------------------- 
 2902 // Make a virtual method, where the overriding is simply the default
 2903 // (i.e. overrides by name/signature)
 2904 // -------------------------------------------------------------------- 
 2905 
 2906 let mk_ospec (ty:ILType, callconv, nm, genparams, formal_args, formal_ret) =
 2907   OverridesSpec (mkILMethRef (ty.TypeRef, callconv, nm, genparams, formal_args, formal_ret), ty)
 2908 
 2909 let mkILGenericVirtualMethod (nm, access, genparams, actual_args, actual_ret, impl) = 
 2910     ILMethodDef(name=nm,
 2911                 attributes= 
 2912                   (convertMemberAccess access |||
 2913                    MethodAttributes.CheckAccessOnOverride ||| 
 2914                    (match impl with MethodBody.Abstract -> MethodAttributes.Abstract ||| MethodAttributes.Virtual | _ -> MethodAttributes.Virtual)),
 2915                 implAttributes=MethodImplAttributes.Managed,
 2916                 genericParams=genparams,
 2917                 callingConv=ILCallingConv.Instance,
 2918                 parameters=actual_args,
 2919                 ret=actual_ret,
 2920                 isEntryPoint=false,
 2921                 securityDecls=emptyILSecurityDecls,
 2922                 customAttrs = emptyILCustomAttrs,
 2923                 body= mkMethBodyAux impl)
 2924     
 2925 let mkILNonGenericVirtualMethod (nm, access, args, ret, impl) =  
 2926     mkILGenericVirtualMethod (nm, access, mkILEmptyGenericParams, args, ret, impl)
 2927 
 2928 let mkILGenericNonVirtualMethod (nm, access, genparams, actual_args, actual_ret, impl) = 
 2929     ILMethodDef(name=nm,
 2930                 attributes=(convertMemberAccess access ||| MethodAttributes.HideBySig),
 2931                 implAttributes=MethodImplAttributes.Managed,
 2932                 genericParams=genparams,
 2933                 callingConv=ILCallingConv.Instance,
 2934                 parameters=actual_args,
 2935                 ret=actual_ret,
 2936                 isEntryPoint=false,
 2937                 securityDecls=emptyILSecurityDecls,
 2938                 customAttrs = emptyILCustomAttrs,
 2939                 body= mkMethBodyAux impl)
 2940     
 2941 let mkILNonGenericInstanceMethod (nm, access, args, ret, impl) =  
 2942   mkILGenericNonVirtualMethod (nm, access, mkILEmptyGenericParams, args, ret, impl)
 2943 
 2944 
 2945 // -------------------------------------------------------------------- 
 2946 // Add some code to the end of the .cctor for a type.  Create a .cctor
 2947 // if one doesn't exist already.
 2948 // -------------------------------------------------------------------- 
 2949 
 2950 let ilmbody_code2code f (il: ILMethodBody)  =
 2951   {il with Code = f il.Code}
 2952 
 2953 let mdef_code2code f (md: ILMethodDef)  =
 2954     let il = 
 2955         match md.Body.Contents with 
 2956         | MethodBody.IL il-> il 
 2957         | _ -> failwith "mdef_code2code - method not IL"
 2958     let b = MethodBody.IL (ilmbody_code2code f il)
 2959     md.With(body= mkMethBodyAux b)
 2960 
 2961 let prependInstrsToCode (instrs: ILInstr list) (c2: ILCode) = 
 2962     let instrs = Array.ofList instrs
 2963     let n = instrs.Length
 2964     match c2.Instrs.[0] with 
 2965     // If there is a sequence point as the first instruction then keep it at the front
 2966     | I_seqpoint _ as i0 ->
 2967         let labels = 
 2968             let dict = Dictionary.newWithSize c2.Labels.Count
 2969             for kvp in c2.Labels do dict.Add(kvp.Key, if kvp.Value = 0 then 0 else kvp.Value + n)
 2970             dict
 2971         { c2 with Labels = labels
 2972                   Instrs = Array.concat [| [|i0|] ; instrs ; c2.Instrs.[1..] |] }
 2973     | _ ->
 2974         let labels =
 2975             let dict = Dictionary.newWithSize c2.Labels.Count
 2976             for kvp in c2.Labels do dict.Add(kvp.Key, kvp.Value + n)
 2977             dict
 2978         { c2 with Labels = labels
 2979                   Instrs = Array.append instrs c2.Instrs }
 2980 
 2981 let prependInstrsToMethod new_code md  = 
 2982     mdef_code2code (prependInstrsToCode new_code) md
 2983 
 2984 // Creates cctor if needed 
 2985 let cdef_cctorCode2CodeOrCreate tag f (cd: ILTypeDef) = 
 2986     let mdefs = cd.Methods
 2987     let cctor = 
 2988         match mdefs.FindByName ".cctor" with 
 2989         | [mdef] -> mdef
 2990         | [] -> mkILClassCtor (mkMethodBody (false, [], 1, nonBranchingInstrsToCode [ ], tag))
 2991         | _ -> failwith "bad method table: more than one .cctor found"
 2992         
 2993     let methods = ILMethodDefs (fun () -> [| yield f cctor; for md in mdefs do if md.Name <> ".cctor" then yield md |])
 2994     cd.With(methods = methods)
 2995 
 2996 
 2997 let code_of_mdef (md:ILMethodDef) = 
 2998     match md.Code with 
 2999     | Some x -> x
 3000     | None -> failwith "code_of_mdef: not IL" 
 3001 
 3002 let mkRefToILMethod (tref, md: ILMethodDef) =
 3003     mkILMethRef (tref, md.CallingConv, md.Name, md.GenericParams.Length, md.ParameterTypes, md.Return.Type)
 3004 
 3005 let mkRefToILField (tref, fdef:ILFieldDef) =   mkILFieldRef (tref, fdef.Name, fdef.FieldType)
 3006 
 3007 let mkRefForILMethod scope (tdefs, tdef) mdef = mkRefToILMethod (mkRefForNestedILTypeDef scope (tdefs, tdef), mdef)
 3008 let mkRefForILField scope (tdefs, tdef) (fdef:ILFieldDef) = mkILFieldRef (mkRefForNestedILTypeDef scope (tdefs, tdef), fdef.Name, fdef.FieldType)
 3009 
 3010 
 3011 (* Creates cctor if needed *)
 3012 let prependInstrsToClassCtor instrs tag cd = 
 3013     cdef_cctorCode2CodeOrCreate tag (prependInstrsToMethod instrs) cd
 3014     
 3015 
 3016 let mkILField (isStatic, nm, ty, (init:ILFieldInit option), (at: byte [] option), access, isLiteral) =
 3017      ILFieldDef(name=nm,
 3018                 fieldType=ty,
 3019                 attributes=
 3020                     (convertFieldAccess access |||
 3021                      (if isStatic then FieldAttributes.Static else enum 0) ||| 
 3022                      (if isLiteral then FieldAttributes.Literal else enum 0) |||
 3023                      (if init.IsSome then FieldAttributes.HasDefault else enum 0) |||
 3024                      (if at.IsSome then FieldAttributes.HasFieldRVA else enum 0)),
 3025                 literalValue = init,
 3026                 data=at,
 3027                 offset=None,
 3028                 marshal=None,
 3029                 customAttrs=emptyILCustomAttrs)
 3030 
 3031 let mkILInstanceField (nm, ty, init, access) = mkILField (false, nm, ty, init, None, access, false)
 3032 let mkILStaticField (nm, ty, init, at, access) = mkILField (true, nm, ty, init, at, access, false)
 3033 let mkILLiteralField (nm, ty, init, at, access) = mkILField (true, nm, ty, Some init, at, access, true)
 3034 
 3035 // -------------------------------------------------------------------- 
 3036 // Scopes for allocating new temporary variables.
 3037 // -------------------------------------------------------------------- 
 3038 
 3039 type ILLocalsAllocator(numPrealloc:int) = 
 3040     let newLocals = ResizeArray<ILLocal>()
 3041     member tmps.AllocLocal loc = 
 3042         let locn = uint16(numPrealloc + newLocals.Count)
 3043         newLocals.Add loc
 3044         locn
 3045 
 3046     member tmps.Close() = ResizeArray.toList newLocals
 3047 
 3048 
 3049 let mkILFieldsLazy l =  ILFields (LazyOrderedMultiMap((fun (f:ILFieldDef) -> f.Name), l))
 3050 let mkILFields l =  mkILFieldsLazy (notlazy l)
 3051 let emptyILFields = mkILFields []
 3052 
 3053 let mkILEventsLazy l =  ILEvents (LazyOrderedMultiMap((fun (e: ILEventDef) -> e.Name), l))
 3054 let mkILEvents l =  mkILEventsLazy (notlazy l)
 3055 let emptyILEvents =  mkILEvents []
 3056 
 3057 let mkILPropertiesLazy l =  ILProperties (LazyOrderedMultiMap((fun (p: ILPropertyDef) -> p.Name), l) )
 3058 let mkILProperties l =  mkILPropertiesLazy (notlazy l)
 3059 let emptyILProperties =  mkILProperties []
 3060 
 3061 let addExportedTypeToTable (y: ILExportedTypeOrForwarder) tab = Map.add y.Name y tab
 3062 let mkILExportedTypes l =  ILExportedTypesAndForwarders (notlazy (List.foldBack addExportedTypeToTable l Map.empty))
 3063 let mkILExportedTypesLazy (l:Lazy<_>) =   ILExportedTypesAndForwarders (lazy (List.foldBack addExportedTypeToTable (l.Force()) Map.empty))
 3064 
 3065 let addNestedExportedTypeToTable (y: ILNestedExportedType) tab =
 3066     Map.add y.Name y tab
 3067 
 3068 let mkTypeForwarder scopeRef name nested customAttrs access =
 3069     { ScopeRef=scopeRef
 3070       Name=name
 3071       Attributes=enum<TypeAttributes>(0x00200000) ||| convertTypeAccessFlags access
 3072       Nested=nested
 3073       CustomAttrsStored=storeILCustomAttrs customAttrs
 3074       MetadataIndex = NoMetadataIdx }
 3075 
 3076 let mkILNestedExportedTypes l =  
 3077     ILNestedExportedTypes (notlazy (List.foldBack addNestedExportedTypeToTable l Map.empty))
 3078 
 3079 let mkILNestedExportedTypesLazy (l:Lazy<_>) =  
 3080     ILNestedExportedTypes (lazy (List.foldBack addNestedExportedTypeToTable (l.Force()) Map.empty))
 3081 
 3082 let mkILResources l =  ILResources l
 3083 
 3084 let addMethodImplToTable y tab =
 3085     let key = (y.Overrides.MethodRef.Name, y.Overrides.MethodRef.ArgTypes.Length)
 3086     let prev = Map.tryFindMulti key tab
 3087     Map.add key (y::prev) tab
 3088 
 3089 let mkILMethodImpls l =  ILMethodImpls (notlazy (List.foldBack addMethodImplToTable l Map.empty))
 3090 let mkILMethodImplsLazy l =  ILMethodImpls (lazy (List.foldBack addMethodImplToTable (Lazy.force l) Map.empty))
 3091 let emptyILMethodImpls =  mkILMethodImpls []
 3092 
 3093 
 3094 // -------------------------------------------------------------------- 
 3095 // Make a constructor that simply takes its arguments and stuffs
 3096 // them in fields.  preblock is how to call the superclass constructor....
 3097 // -------------------------------------------------------------------- 
 3098 
 3099 let mkILStorageCtorWithParamNames(tag, preblock, ty, extraParams, flds, access) = 
 3100     mkILCtor(access,
 3101             (flds |> List.map (fun (pnm, _, ty) -> mkILParamNamed (pnm, ty))) @ extraParams,
 3102             mkMethodBody
 3103               (false, [], 2,
 3104                nonBranchingInstrsToCode
 3105                  begin 
 3106                    (match tag with Some x -> [I_seqpoint x] | None -> []) @ 
 3107                    preblock @
 3108                    List.concat (List.mapi (fun n (_pnm, nm, fieldTy) -> 
 3109                      [ mkLdarg0
 3110                        mkLdarg (uint16 (n+1))
 3111                        mkNormalStfld (mkILFieldSpecInTy (ty, nm, fieldTy))
 3112                      ])  flds)
 3113                  end, tag))
 3114     
 3115 let mkILSimpleStorageCtorWithParamNames(tag, baseTySpec, ty, extraParams, flds, access) = 
 3116     let preblock = 
 3117       match baseTySpec with 
 3118         None -> []
 3119       | Some tspec -> 
 3120           ([ mkLdarg0 
 3121              mkNormalCall (mkILCtorMethSpecForTy (mkILBoxedType tspec, [])) ])
 3122     mkILStorageCtorWithParamNames(tag, preblock, ty, extraParams, flds, access)
 3123 
 3124 let addParamNames flds = 
 3125     flds |> List.map (fun (nm, ty) -> (nm, nm, ty))
 3126 
 3127 let mkILSimpleStorageCtor(tag, baseTySpec, ty, extraParams, flds, access) = 
 3128     mkILSimpleStorageCtorWithParamNames(tag, baseTySpec, ty, extraParams, addParamNames flds, access)
 3129 
 3130 let mkILStorageCtor(tag, preblock, ty, flds, access) = mkILStorageCtorWithParamNames(tag, preblock, ty, [], addParamNames flds, access)
 3131 
 3132 
 3133 let mkILGenericClass (nm, access, genparams, extends, impl, methods, fields, nestedTypes, props, events, attrs, init) =
 3134     ILTypeDef(name=nm,
 3135               attributes=(convertTypeAccessFlags access ||| TypeAttributes.AutoLayout ||| TypeAttributes.Class ||| (match init with | ILTypeInit.BeforeField -> TypeAttributes.BeforeFieldInit | _ -> enum 0) ||| TypeAttributes.AnsiClass),
 3136               genericParams= genparams,
 3137               implements = impl,
 3138               layout=ILTypeDefLayout.Auto,
 3139               extends = Some extends,
 3140               methods= methods ,
 3141               fields= fields,
 3142               nestedTypes=nestedTypes,
 3143               customAttrs=attrs,
 3144               methodImpls=emptyILMethodImpls,
 3145               properties=props,
 3146               events=events,
 3147               securityDecls=emptyILSecurityDecls)
 3148     
 3149 let mkRawDataValueTypeDef (iltyp_ValueType: ILType) (nm, size, pack) =
 3150     ILTypeDef(name = nm,
 3151               genericParams= [],
 3152               attributes = (TypeAttributes.NotPublic ||| TypeAttributes.Sealed ||| TypeAttributes.ExplicitLayout ||| TypeAttributes.BeforeFieldInit ||| TypeAttributes.AnsiClass),
 3153               implements = [],
 3154               extends = Some iltyp_ValueType,
 3155               layout=ILTypeDefLayout.Explicit { Size=Some size; Pack=Some pack },
 3156               methods= emptyILMethods,
 3157               fields= emptyILFields,
 3158               nestedTypes=emptyILTypeDefs,
 3159               customAttrs=emptyILCustomAttrs,
 3160               methodImpls=emptyILMethodImpls,
 3161               properties=emptyILProperties,
 3162               events=emptyILEvents,
 3163               securityDecls=emptyILSecurityDecls)
 3164 
 3165 
 3166 let mkILSimpleClass (ilg: ILGlobals) (nm, access, methods, fields, nestedTypes, props, events, attrs, init) =
 3167   mkILGenericClass (nm, access, mkILEmptyGenericParams, ilg.typ_Object, [], methods, fields, nestedTypes, props, events, attrs, init)
 3168 
 3169 let mkILTypeDefForGlobalFunctions ilg (methods, fields) = mkILSimpleClass ilg (typeNameForGlobalFunctions, ILTypeDefAccess.Public, methods, fields, emptyILTypeDefs, emptyILProperties, emptyILEvents, emptyILCustomAttrs, ILTypeInit.BeforeField)
 3170 
 3171 let destTypeDefsWithGlobalFunctionsFirst ilg (tdefs: ILTypeDefs) = 
 3172   let l = tdefs.AsList
 3173   let top, nontop = l |> List.partition (fun td -> td.Name = typeNameForGlobalFunctions)
 3174   let top2 = if isNil top then [ mkILTypeDefForGlobalFunctions ilg (emptyILMethods, emptyILFields) ] else top
 3175   top2@nontop
 3176 
 3177 let mkILSimpleModule assname modname dll subsystemVersion useHighEntropyVA tdefs hashalg locale flags exportedTypes metadataVersion = 
 3178     let manifest = 
 3179         { Name=assname
 3180           AuxModuleHashAlgorithm= match hashalg with | Some(alg) -> alg | _ -> 0x8004 // SHA1
 3181           SecurityDeclsStored=emptyILSecurityDeclsStored
 3182           PublicKey= None
 3183           Version= None
 3184           Locale=locale
 3185           CustomAttrsStored=storeILCustomAttrs emptyILCustomAttrs
 3186           AssemblyLongevity=ILAssemblyLongevity.Unspecified
 3187           DisableJitOptimizations = 0 <> (flags &&& 0x4000)
 3188           JitTracking = (0 <> (flags &&& 0x8000)) // always turn these on
 3189           IgnoreSymbolStoreSequencePoints = (0 <> (flags &&& 0x2000))
 3190           Retargetable = (0 <> (flags &&& 0x100))
 3191           ExportedTypes=exportedTypes
 3192           EntrypointElsewhere=None 
 3193           MetadataIndex = NoMetadataIdx }
 3194     { Manifest= Some manifest
 3195       CustomAttrsStored=storeILCustomAttrs emptyILCustomAttrs
 3196       Name=modname
 3197       NativeResources=[]
 3198       TypeDefs=tdefs
 3199       SubsystemVersion = subsystemVersion
 3200       UseHighEntropyVA = useHighEntropyVA
 3201       SubSystemFlags=defaultSubSystem
 3202       IsDLL=dll
 3203       IsILOnly=true
 3204       Platform=None
 3205       StackReserveSize=None
 3206       Is32Bit=false
 3207       Is32BitPreferred=false
 3208       Is64Bit=false
 3209       PhysicalAlignment=defaultPhysAlignment
 3210       VirtualAlignment=defaultVirtAlignment
 3211       ImageBase=defaultImageBase
 3212       MetadataVersion=metadataVersion
 3213       Resources=mkILResources []
 3214       MetadataIndex = NoMetadataIdx 
 3215     }
 3216 
 3217 
 3218 //-----------------------------------------------------------------------
 3219 // [instructions_to_code] makes the basic block structure of code from
 3220 // a primitive array of instructions.  We
 3221 // do this be iterating over the instructions, pushing new basic blocks 
 3222 // everytime we encounter an address that has been recorded
 3223 // [bbstartToCodeLabelMap].
 3224 //-----------------------------------------------------------------------
 3225 
 3226             
 3227 // REVIEW: this function shows up on performance traces. If we eliminated the last ILX->IL rewrites from the
 3228 // F# compiler we could get rid of this structured code representation from Abstract IL altogether and 
 3229 // never convert F# code into this form.
 3230 let buildILCode (_methName:string) lab2pc instrs tryspecs localspecs : ILCode =
 3231     { Labels = lab2pc
 3232       Instrs = instrs
 3233       Exceptions = tryspecs
 3234       Locals = localspecs }
 3235 
 3236 
 3237 // -------------------------------------------------------------------- 
 3238 // Detecting Delegates
 3239 // -------------------------------------------------------------------- 
 3240 
 3241 let mkILDelegateMethods (access) (ilg: ILGlobals) (iltyp_AsyncCallback, iltyp_IAsyncResult) (parms, rtv:ILReturn) = 
 3242     let rty = rtv.Type
 3243     let one nm args ret =
 3244         let mdef = mkILNonGenericVirtualMethod (nm, access, args, mkILReturn ret, MethodBody.Abstract)
 3245         mdef.WithAbstract(false).WithHideBySig(true).WithRuntime(true)
 3246     let ctor = mkILCtor(access, [ mkILParamNamed("object", ilg.typ_Object); mkILParamNamed("method", ilg.typ_IntPtr) ], MethodBody.Abstract)
 3247     let ctor = ctor.WithRuntime(true).WithHideBySig(true)
 3248     [ ctor
 3249       one "Invoke" parms rty
 3250       one "BeginInvoke" (parms @ [mkILParamNamed("callback", iltyp_AsyncCallback); mkILParamNamed("objects", ilg.typ_Object) ] ) iltyp_IAsyncResult
 3251       one "EndInvoke" [mkILParamNamed("result", iltyp_IAsyncResult)] rty ]
 3252     
 3253 
 3254 let mkCtorMethSpecForDelegate (ilg: ILGlobals) (ty:ILType, useUIntPtr) =
 3255     let scoref = ty.TypeRef.Scope 
 3256     mkILInstanceMethSpecInTy (ty, ".ctor", [rescopeILType scoref ilg.typ_Object; rescopeILType scoref (if useUIntPtr then ilg.typ_UIntPtr else ilg.typ_IntPtr)], ILType.Void, emptyILGenericArgsList)
 3257 
 3258 type ILEnumInfo =
 3259     { enumValues: (string * ILFieldInit) list  
 3260       enumType: ILType }
 3261 
 3262 let getTyOfILEnumInfo info = info.enumType
 3263 
 3264 let computeILEnumInfo (mdName, mdFields: ILFieldDefs) = 
 3265     match (List.partition (fun (fd:ILFieldDef) -> fd.IsStatic) mdFields.AsList) with 
 3266     | staticFields, [vfd] -> 
 3267         { enumType = vfd.FieldType 
 3268           enumValues = staticFields |> List.map (fun fd -> (fd.Name, match fd.LiteralValue with Some i -> i | None -> failwith ("info_of_enum_tdef: badly formed enum "+mdName+": static field does not have an default value")))  }
 3269     | _, [] -> failwith ("info_of_enum_tdef: badly formed enum "+mdName+": no non-static field found")
 3270     | _, _ -> failwith ("info_of_enum_tdef: badly formed enum "+mdName+": more than one non-static field found")
 3271 
 3272  
 3273 
 3274 //---------------------------------------------------------------------
 3275 // Primitives to help read signatures.  These do not use the file cursor, but
 3276 // pass around an int index
 3277 //---------------------------------------------------------------------
 3278 
 3279 let sigptr_get_byte bytes sigptr = 
 3280     Bytes.get bytes sigptr, sigptr + 1
 3281 
 3282 let sigptr_get_bool bytes sigptr = 
 3283     let b0, sigptr = sigptr_get_byte bytes sigptr
 3284     (b0 = 0x01) , sigptr
 3285 
 3286 let sigptr_get_u8 bytes sigptr = 
 3287     let b0, sigptr = sigptr_get_byte bytes sigptr
 3288     byte b0, sigptr
 3289 
 3290 let sigptr_get_i8 bytes sigptr = 
 3291     let i, sigptr = sigptr_get_u8 bytes sigptr
 3292     sbyte i, sigptr
 3293 
 3294 let sigptr_get_u16 bytes sigptr = 
 3295     let b0, sigptr = sigptr_get_byte bytes sigptr
 3296     let b1, sigptr = sigptr_get_byte bytes sigptr
 3297     uint16 (b0 ||| (b1 <<< 8)), sigptr
 3298 
 3299 let sigptr_get_i16 bytes sigptr = 
 3300     let u, sigptr = sigptr_get_u16 bytes sigptr
 3301     int16 u, sigptr
 3302 
 3303 let sigptr_get_i32 bytes sigptr = 
 3304     let b0, sigptr = sigptr_get_byte bytes sigptr
 3305     let b1, sigptr = sigptr_get_byte bytes sigptr
 3306     let b2, sigptr = sigptr_get_byte bytes sigptr
 3307     let b3, sigptr = sigptr_get_byte bytes sigptr
 3308     b0 ||| (b1 <<< 8) ||| (b2 <<< 16) ||| (b3 <<< 24), sigptr
 3309 
 3310 let sigptr_get_u32 bytes sigptr = 
 3311     let u, sigptr = sigptr_get_i32 bytes sigptr
 3312     uint32 u, sigptr
 3313 
 3314 let sigptr_get_i64 bytes sigptr = 
 3315     let b0, sigptr = sigptr_get_byte bytes sigptr
 3316     let b1, sigptr = sigptr_get_byte bytes sigptr
 3317     let b2, sigptr = sigptr_get_byte bytes sigptr
 3318     let b3, sigptr = sigptr_get_byte bytes sigptr
 3319     let b4, sigptr = sigptr_get_byte bytes sigptr
 3320     let b5, sigptr = sigptr_get_byte bytes sigptr
 3321     let b6, sigptr = sigptr_get_byte bytes sigptr
 3322     let b7, sigptr = sigptr_get_byte bytes sigptr
 3323     int64 b0 ||| (int64 b1 <<< 8) ||| (int64 b2 <<< 16) ||| (int64 b3 <<< 24) |||
 3324     (int64 b4 <<< 32) ||| (int64 b5 <<< 40) ||| (int64 b6 <<< 48) ||| (int64 b7 <<< 56),
 3325     sigptr
 3326 
 3327 let sigptr_get_u64 bytes sigptr = 
 3328     let u, sigptr = sigptr_get_i64 bytes sigptr
 3329     uint64 u, sigptr
 3330 
 3331 let float32_of_bits (x:int32) = System.BitConverter.ToSingle(System.BitConverter.GetBytes(x), 0)
 3332 let float_of_bits (x:int64) = System.BitConverter.Int64BitsToDouble(x)
 3333 
 3334 let sigptr_get_ieee32 bytes sigptr = 
 3335     let u, sigptr = sigptr_get_i32 bytes sigptr
 3336     float32_of_bits u, sigptr
 3337 
 3338 let sigptr_get_ieee64 bytes sigptr = 
 3339     let u, sigptr = sigptr_get_i64 bytes sigptr
 3340     float_of_bits u, sigptr
 3341 
 3342 let sigptr_get_intarray n (bytes:byte[]) sigptr = 
 3343     let res = Bytes.zeroCreate n
 3344     for i = 0 to n - 1 do 
 3345         res.[i] <- bytes.[sigptr + i]
 3346     res, sigptr + n
 3347 
 3348 let sigptr_get_string n bytes sigptr = 
 3349     let intarray, sigptr = sigptr_get_intarray n bytes sigptr
 3350     System.Text.Encoding.UTF8.GetString(intarray , 0, intarray.Length), sigptr
 3351    
 3352 let sigptr_get_z_i32 bytes sigptr = 
 3353     let b0, sigptr = sigptr_get_byte bytes sigptr
 3354     if b0 <= 0x7F then b0, sigptr
 3355     elif b0 <= 0xbf then 
 3356         let b0 = b0 &&& 0x7f
 3357         let b1, sigptr = sigptr_get_byte bytes sigptr
 3358         (b0 <<< 8) ||| b1, sigptr
 3359     else 
 3360         let b0 = b0 &&& 0x3f
 3361         let b1, sigptr = sigptr_get_byte bytes sigptr
 3362         let b2, sigptr = sigptr_get_byte bytes sigptr
 3363         let b3, sigptr = sigptr_get_byte bytes sigptr
 3364         (b0 <<< 24) ||| (b1 <<< 16) ||| (b2 <<< 8) ||| b3, sigptr
 3365 
 3366 let sigptr_get_serstring  bytes sigptr = 
 3367     let len, sigptr = sigptr_get_z_i32 bytes sigptr 
 3368     sigptr_get_string ( len) bytes sigptr 
 3369   
 3370 let sigptr_get_serstring_possibly_null  bytes sigptr = 
 3371     let b0, new_sigptr = sigptr_get_byte bytes sigptr  
 3372     if b0 = 0xFF then // null case
 3373         None, new_sigptr
 3374     else  // throw away  new_sigptr, getting length & text advance
 3375         let len, sigptr = sigptr_get_z_i32 bytes sigptr 
 3376         let s, sigptr = sigptr_get_string len bytes sigptr
 3377         Some(s), sigptr
 3378   
 3379 //---------------------------------------------------------------------
 3380 // Get the public key token from the public key.
 3381 //---------------------------------------------------------------------
 3382 
 3383 let mkRefToILAssembly (m: ILAssemblyManifest) = 
 3384     ILAssemblyRef.Create(m.Name, None, (match m.PublicKey with Some k -> Some (PublicKey.KeyAsToken(k)) | None -> None), m.Retargetable, m.Version, m.Locale)
 3385 
 3386 let z_unsigned_int_size n = 
 3387     if n <= 0x7F then 1
 3388     elif n <= 0x3FFF then 2
 3389     else 3
 3390 
 3391 let z_unsigned_int n = 
 3392     if n >= 0 &&  n <= 0x7F then [| byte n |] 
 3393     elif n >= 0x80 && n <= 0x3FFF then [| byte (0x80 ||| (n >>>& 8)); byte (n &&& 0xFF) |] 
 3394     else [| byte (0xc0 ||| (n >>>& 24))
 3395             byte ((n >>>& 16) &&& 0xFF) 
 3396             byte ((n >>>& 8) &&& 0xFF) 
 3397             byte (n &&& 0xFF) |]
 3398 
 3399 let string_as_utf8_bytes (s:string) = System.Text.Encoding.UTF8.GetBytes s
 3400 
 3401 (* Little-endian encoding of int64 *)
 3402 let dw7 n = byte ((n >>> 56) &&& 0xFFL)
 3403 let dw6 n = byte ((n >>> 48) &&& 0xFFL)
 3404 let dw5 n = byte ((n >>> 40) &&& 0xFFL)
 3405 let dw4 n = byte ((n >>> 32) &&& 0xFFL)
 3406 let dw3 n = byte ((n >>> 24) &&& 0xFFL)
 3407 let dw2 n = byte ((n >>> 16) &&& 0xFFL)
 3408 let dw1 n = byte ((n >>> 8)  &&& 0xFFL)
 3409 let dw0 n = byte (n          &&& 0xFFL)
 3410 
 3411 let u8AsBytes (i:byte) = [| i |]
 3412 let u16AsBytes x =  let n = (int x) in [| byte (b0 n); byte (b1 n) |]
 3413 let i32AsBytes i = [| byte (b0 i); byte (b1 i); byte (b2 i); byte (b3 i) |]
 3414 let i64AsBytes i = [| dw0 i; dw1 i; dw2 i; dw3 i; dw4 i; dw5 i; dw6 i; dw7 i |]
 3415 
 3416 let i8AsBytes (i:sbyte) = u8AsBytes (byte i)
 3417 let i16AsBytes (i:int16) = u16AsBytes (uint16 i)
 3418 let u32AsBytes (i:uint32) = i32AsBytes (int32 i)
 3419 let u64AsBytes (i:uint64) = i64AsBytes (int64 i)
 3420 
 3421 let bits_of_float32 (x:float32) = System.BitConverter.ToInt32(System.BitConverter.GetBytes(x), 0)
 3422 let bits_of_float (x:float) = System.BitConverter.DoubleToInt64Bits(x)
 3423 
 3424 let ieee32AsBytes i = i32AsBytes (bits_of_float32 i)
 3425 let ieee64AsBytes i = i64AsBytes (bits_of_float i)
 3426 
 3427 let et_END = 0x00uy
 3428 let et_VOID = 0x01uy
 3429 let et_BOOLEAN = 0x02uy
 3430 let et_CHAR = 0x03uy
 3431 let et_I1 = 0x04uy
 3432 let et_U1 = 0x05uy
 3433 let et_I2 = 0x06uy
 3434 let et_U2 = 0x07uy
 3435 let et_I4 = 0x08uy
 3436 let et_U4 = 0x09uy
 3437 let et_I8 = 0x0Auy
 3438 let et_U8 = 0x0Buy
 3439 let et_R4 = 0x0Cuy
 3440 let et_R8 = 0x0Duy
 3441 let et_STRING = 0x0Euy
 3442 let et_PTR = 0x0Fuy
 3443 let et_BYREF = 0x10uy
 3444 let et_VALUETYPE      = 0x11uy
 3445 let et_CLASS          = 0x12uy
 3446 let et_VAR            = 0x13uy
 3447 let et_ARRAY          = 0x14uy
 3448 let et_WITH           = 0x15uy
 3449 let et_TYPEDBYREF     = 0x16uy
 3450 let et_I              = 0x18uy
 3451 let et_U              = 0x19uy
 3452 let et_FNPTR          = 0x1Buy
 3453 let et_OBJECT         = 0x1Cuy
 3454 let et_SZARRAY        = 0x1Duy
 3455 let et_MVAR           = 0x1Euy
 3456 let et_CMOD_REQD      = 0x1Fuy
 3457 let et_CMOD_OPT       = 0x20uy
 3458 
 3459 let formatILVersion ((a, b, c, d):ILVersionInfo) = sprintf "%d.%d.%d.%d" (int a) (int b) (int c) (int d)
 3460 
 3461 let encodeCustomAttrString s = 
 3462     let arr = string_as_utf8_bytes s
 3463     Array.concat [ z_unsigned_int arr.Length; arr ]      
 3464 
 3465 let rec encodeCustomAttrElemType x = 
 3466     match x with
 3467     | ILType.Value tspec when tspec.Name = tname_SByte ->  [| et_I1 |]
 3468     | ILType.Value tspec when tspec.Name = tname_Byte ->  [| et_U1 |]
 3469     | ILType.Value tspec when tspec.Name = tname_Int16 ->  [| et_I2 |]
 3470     | ILType.Value tspec when tspec.Name = tname_UInt16 ->  [| et_U2 |]
 3471     | ILType.Value tspec when tspec.Name = tname_Int32 ->  [| et_I4 |]
 3472     | ILType.Value tspec when tspec.Name = tname_UInt32 ->  [| et_U4 |]
 3473     | ILType.Value tspec when tspec.Name = tname_Int64 ->  [| et_I8 |]
 3474     | ILType.Value tspec when tspec.Name = tname_UInt64 ->  [| et_U8 |]
 3475     | ILType.Value tspec when tspec.Name = tname_Double ->  [| et_R8 |]
 3476     | ILType.Value tspec when tspec.Name = tname_Single ->  [| et_R4 |]
 3477     | ILType.Value tspec when tspec.Name = tname_Char ->  [| et_CHAR |]
 3478     | ILType.Value tspec when tspec.Name = tname_Bool ->  [| et_BOOLEAN |]
 3479     | ILType.Boxed tspec when tspec.Name = tname_String ->  [| et_STRING |]
 3480     | ILType.Boxed tspec when tspec.Name = tname_Object ->  [| 0x51uy |] 
 3481     | ILType.Boxed tspec when tspec.Name = tname_Type ->  [| 0x50uy |]
 3482     | ILType.Value tspec ->  Array.append [| 0x55uy |] (encodeCustomAttrString tspec.TypeRef.QualifiedName)
 3483     | ILType.Array (shape, elemType) when shape = ILArrayShape.SingleDimensional -> 
 3484           Array.append [| et_SZARRAY |] (encodeCustomAttrElemType elemType)
 3485     | _ ->  failwith "encodeCustomAttrElemType: unrecognized custom element type"
 3486 
 3487 /// Given a custom attribute element, work out the type of the .NET argument for that element.
 3488 let rec encodeCustomAttrElemTypeForObject x = 
 3489     match x with
 3490     | ILAttribElem.String _  -> [| et_STRING |]
 3491     | ILAttribElem.Bool _    -> [| et_BOOLEAN |]
 3492     | ILAttribElem.Char _    -> [| et_CHAR |]
 3493     | ILAttribElem.SByte _   -> [| et_I1 |]
 3494     | ILAttribElem.Int16 _   -> [| et_I2 |]
 3495     | ILAttribElem.Int32 _   -> [| et_I4 |]
 3496     | ILAttribElem.Int64 _   -> [| et_I8 |]
 3497     | ILAttribElem.Byte _    -> [| et_U1 |]
 3498     | ILAttribElem.UInt16 _  -> [| et_U2 |]
 3499     | ILAttribElem.UInt32 _  -> [| et_U4 |]
 3500     | ILAttribElem.UInt64 _  -> [| et_U8 |]
 3501     | ILAttribElem.Type _    -> [| 0x50uy |]
 3502     | ILAttribElem.TypeRef _ -> [| 0x50uy |]
 3503     | ILAttribElem.Null _    -> [| et_STRING  |]// yes, the 0xe prefix is used when passing a "null" to a property or argument of type "object" here
 3504     | ILAttribElem.Single _  -> [| et_R4 |]
 3505     | ILAttribElem.Double _  -> [| et_R8 |]
 3506     | ILAttribElem.Array (elemTy, _) -> [| yield et_SZARRAY; yield! encodeCustomAttrElemType elemTy |]
 3507 
 3508 
 3509 let rec decodeCustomAttrElemType (ilg: ILGlobals) bytes sigptr x = 
 3510     match x with
 3511     | x when x =  et_I1 -> ilg.typ_SByte, sigptr
 3512     | x when x = et_U1 -> ilg.typ_Byte, sigptr
 3513     | x when x =  et_I2 -> ilg.typ_Int16, sigptr
 3514     | x when x =  et_U2 -> ilg.typ_UInt16, sigptr
 3515     | x when x =  et_I4 -> ilg.typ_Int32, sigptr
 3516     | x when x =  et_U4 -> ilg.typ_UInt32, sigptr
 3517     | x when x =  et_I8 -> ilg.typ_Int64, sigptr
 3518     | x when x =  et_U8 -> ilg.typ_UInt64, sigptr
 3519     | x when x =  et_R8 -> ilg.typ_Double, sigptr
 3520     | x when x =  et_R4 -> ilg.typ_Single, sigptr
 3521     | x when x = et_CHAR -> ilg.typ_Char, sigptr
 3522     | x when x =  et_BOOLEAN -> ilg.typ_Bool, sigptr
 3523     | x when x =  et_STRING -> ilg.typ_String, sigptr
 3524     | x when x =  et_OBJECT -> ilg.typ_Object, sigptr
 3525     | x when x =  et_SZARRAY -> 
 3526          let et, sigptr = sigptr_get_u8 bytes sigptr 
 3527          let elemTy, sigptr = decodeCustomAttrElemType ilg bytes sigptr et
 3528          mkILArr1DTy elemTy, sigptr
 3529     | x when x = 0x50uy -> ilg.typ_Type, sigptr
 3530     | _ ->  failwithf "decodeCustomAttrElemType ilg: unrecognized custom element type: %A" x
 3531 
 3532 
 3533 /// Given a custom attribute element, encode it to a binary representation according to the rules in Ecma 335 Partition II.
 3534 let rec encodeCustomAttrPrimValue ilg c = 
 3535     match c with 
 3536     | ILAttribElem.Bool b -> [| (if b then 0x01uy else 0x00uy) |]
 3537     | ILAttribElem.String None
 3538     | ILAttribElem.Type None
 3539     | ILAttribElem.TypeRef None
 3540     | ILAttribElem.Null -> [| 0xFFuy |]
 3541     | ILAttribElem.String (Some s) -> encodeCustomAttrString s
 3542     | ILAttribElem.Char x ->  u16AsBytes (uint16 x)
 3543     | ILAttribElem.SByte x -> i8AsBytes x
 3544     | ILAttribElem.Int16 x -> i16AsBytes x
 3545     | ILAttribElem.Int32 x -> i32AsBytes x
 3546     | ILAttribElem.Int64 x -> i64AsBytes x
 3547     | ILAttribElem.Byte x -> u8AsBytes x
 3548     | ILAttribElem.UInt16 x -> u16AsBytes x
 3549     | ILAttribElem.UInt32 x -> u32AsBytes x
 3550     | ILAttribElem.UInt64 x -> u64AsBytes x
 3551     | ILAttribElem.Single x -> ieee32AsBytes x
 3552     | ILAttribElem.Double x -> ieee64AsBytes x
 3553     | ILAttribElem.Type (Some ty) -> encodeCustomAttrString ty.QualifiedName
 3554     | ILAttribElem.TypeRef (Some tref) -> encodeCustomAttrString tref.QualifiedName
 3555     | ILAttribElem.Array (_, elems) ->  
 3556          [| yield! i32AsBytes elems.Length; for elem in elems do yield! encodeCustomAttrPrimValue ilg elem |]
 3557 
 3558 and encodeCustomAttrValue ilg ty c = 
 3559     match ty, c with 
 3560     | ILType.Boxed tspec, _ when tspec.Name = tname_Object ->  
 3561        [| yield! encodeCustomAttrElemTypeForObject c; yield! encodeCustomAttrPrimValue ilg c |]
 3562     | ILType.Array (shape, _), ILAttribElem.Null when shape = ILArrayShape.SingleDimensional ->  
 3563        [| yield! i32AsBytes 0xFFFFFFFF |]
 3564     | ILType.Array (shape, elemType), ILAttribElem.Array (_, elems) when shape = ILArrayShape.SingleDimensional ->  
 3565        [| yield! i32AsBytes elems.Length; for elem in elems do yield! encodeCustomAttrValue ilg elemType elem |]
 3566     | _ -> 
 3567        encodeCustomAttrPrimValue ilg c
 3568 
 3569 let encodeCustomAttrNamedArg ilg (nm, ty, prop, elem) = 
 3570    [| yield (if prop then 0x54uy else 0x53uy) 
 3571       yield! encodeCustomAttrElemType ty
 3572       yield! encodeCustomAttrString nm
 3573       yield! encodeCustomAttrValue ilg ty elem |]
 3574 
 3575 let mkILCustomAttribMethRef (ilg: ILGlobals) (mspec:ILMethodSpec, fixedArgs: list<_>, namedArgs: list<_>) = 
 3576     let argtys = mspec.MethodRef.ArgTypes
 3577     let args = 
 3578       [| yield! [| 0x01uy; 0x00uy; |]
 3579          for (argty, fixedArg) in Seq.zip argtys fixedArgs do
 3580             yield! encodeCustomAttrValue ilg argty fixedArg
 3581          yield! u16AsBytes (uint16 namedArgs.Length) 
 3582          for namedArg in namedArgs do 
 3583              yield! encodeCustomAttrNamedArg ilg namedArg |]
 3584     { Method = mspec
 3585       Data = args
 3586       Elements = fixedArgs @ (namedArgs |> List.map(fun (_, _, _, e) -> e)) }
 3587 
 3588 let mkILCustomAttribute ilg (tref, argtys, argvs, propvs) = 
 3589     mkILCustomAttribMethRef ilg (mkILNonGenericCtorMethSpec (tref, argtys), argvs, propvs)
 3590 
 3591 let MscorlibScopeRef = ILScopeRef.Assembly (ILAssemblyRef.Create("mscorlib", None, Some ecmaPublicKey, true, None, None))
 3592 let EcmaMscorlibILGlobals = mkILGlobals MscorlibScopeRef
 3593 
 3594 
 3595 // ILSecurityDecl is a 'blob' having the following format:
 3596 // - A byte containing a period (.).
 3597 // - A compressed int32 containing the number of attributes encoded in the blob.
 3598 // - An array of attributes each containing the following:
 3599 // - A String, which is the fully-qualified type name of the attribute. (Strings are encoded
 3600 //      as a compressed int to indicate the size followed by an array of UTF8 characters.)
 3601 // - A set of properties, encoded as the named arguments to a custom attribute would be (as
 3602 //      in ยง23.3, beginning with NumNamed).
 3603 let mkPermissionSet (ilg: ILGlobals) (action, attributes: list<(ILTypeRef * (string * ILType * ILAttribElem) list)>) = 
 3604     let bytes = 
 3605         [| yield (byte '.')
 3606            yield! z_unsigned_int attributes.Length
 3607            for (tref:ILTypeRef, props) in attributes do 
 3608               yield! encodeCustomAttrString tref.QualifiedName
 3609               let bytes = 
 3610                   [| yield! z_unsigned_int props.Length
 3611                      for (nm, ty, value) in props do 
 3612                          yield! encodeCustomAttrNamedArg ilg (nm, ty, true, value)|]
 3613               yield! z_unsigned_int bytes.Length
 3614               yield! bytes |]
 3615               
 3616     ILSecurityDecl.ILSecurityDecl(action, bytes)
 3617 
 3618 
 3619 // Parse an IL type signature argument within a custom attribute blob
 3620 type ILTypeSigParser(tstring : string) =
 3621 
 3622     let mutable startPos = 0
 3623     let mutable currentPos = 0
 3624 
 3625     let reset() = startPos <- 0 ; currentPos <- 0
 3626     let nil = '\r' // cannot appear in a type sig
 3627 
 3628     // take a look at the next value, but don't advance
 3629     let peek() = if currentPos < (tstring.Length-1) then tstring.[currentPos+1] else nil
 3630     let peekN(skip) = if currentPos < (tstring.Length - skip) then tstring.[currentPos+skip] else nil
 3631     // take a look at the current value, but don't advance
 3632     let here() = if currentPos < tstring.Length then tstring.[currentPos] else nil
 3633     // move on to the next character
 3634     let step() = currentPos <- currentPos+1
 3635     // ignore the current lexeme
 3636     let skip() = startPos <- currentPos
 3637     // ignore the current lexeme, advance
 3638     let drop() = skip() ; step() ; skip()
 3639     // return the current lexeme, advance
 3640     let take() = 
 3641         let s = if currentPos < tstring.Length then tstring.[startPos..currentPos] else ""
 3642         drop()
 3643         s
 3644 
 3645     // The format we accept is
 3646     // "<type name>{`<arity>[<type>, +]}{<array rank>}{<scope>}"  E.g.,
 3647     //
 3648     // System.Collections.Generic.Dictionary
 3649     //     `2[
 3650     //         [System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],
 3651     //         dev.virtualearth.net.webservices.v1.search.CategorySpecificPropertySet],
 3652     // mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
 3653     //
 3654     // Note that 
 3655     //   Since we're only reading valid IL, we assume that the signature is properly formed
 3656     //   For type parameters, if the type is non-local, it will be wrapped in brackets ([])
 3657     //   Still needs testing with jagged arrays and byref parameters
 3658     member private x.ParseType() =
 3659 
 3660         // Does the type name start with a leading '['?  If so, ignore it
 3661         // (if the specialization type is in another module, it will be wrapped in bracket)
 3662         if here() = '[' then drop()
 3663     
 3664         // 1. Iterate over beginning of type, grabbing the type name and determining if it's generic or an array
 3665         let typeName = 
 3666             while (peek() <> '`') && (peek() <> '[') && (peek() <> ']') && (peek() <> ',') && (peek() <> nil) do step()
 3667             take()
 3668     
 3669         // 2. Classify the type
 3670 
 3671         // Is the type generic?
 3672         let typeName, specializations = 
 3673             if here() = '`' then
 3674                 drop() // step to the number
 3675                 // fetch the arity
 3676                 let arity = 
 3677                     while (int(here()) >= (int('0'))) && (int(here()) <= ((int('9')))) && (int(peek()) >= (int('0'))) && (int(peek()) <= ((int('9')))) do step()
 3678                     System.Int32.Parse(take())
 3679                 // skip the '['
 3680                 drop()
 3681                 // get the specializations
 3682                 typeName+"`"+(arity.ToString()), Some(([for _i in 0..arity-1 do yield x.ParseType()]))
 3683             else
 3684                 typeName, None
 3685 
 3686         // Is the type an array?
 3687         let rank = 
 3688             if here() = '[' then
 3689                 let mutable rank = 0
 3690 
 3691                 while here() <> ']' do
 3692                     rank <- rank + 1
 3693                     step()
 3694                 drop()
 3695 
 3696                 Some(ILArrayShape(List.replicate rank (Some 0, None)))
 3697             else
 3698                 None
 3699 
 3700         // Is there a scope?
 3701         let scope = 
 3702             if (here() = ',' || here() = ' ') && (peek() <> '[' && peekN(2) <> '[') then
 3703                 let grabScopeComponent() =
 3704                     if here() = ',' then drop() // ditch the ','
 3705                     if here() = ' ' then drop() // ditch the ' '
 3706 
 3707                     while (peek() <> ',' && peek() <> ']' && peek() <> nil) do step()
 3708                     take()
 3709 
 3710                 let scope =
 3711                     [ yield grabScopeComponent() // assembly
 3712                       yield grabScopeComponent() // version
 3713                       yield grabScopeComponent() // culture
 3714                       yield grabScopeComponent() // public key token
 3715                     ] |> String.concat ","
 3716                 ILScopeRef.Assembly(ILAssemblyRef.FromAssemblyName(System.Reflection.AssemblyName(scope)))        
 3717             else
 3718                 ILScopeRef.Local
 3719 
 3720         // strip any extraneous trailing brackets or commas
 3721         if (here() = ']')  then drop()
 3722         if (here() = ',') then drop()
 3723 
 3724         // build the IL type
 3725         let tref = mkILTyRef(scope, typeName)
 3726         let genericArgs = 
 3727             match specializations with
 3728             | None -> []
 3729             | Some(genericArgs) -> genericArgs
 3730         let tspec = ILTypeSpec.Create(tref, genericArgs)
 3731         let ilty = 
 3732             match tspec.Name with
 3733             | "System.SByte"
 3734             | "System.Byte"
 3735             | "System.Int16"
 3736             | "System.UInt16"
 3737             | "System.Int32"
 3738             | "System.UInt32"
 3739             | "System.Int64"
 3740             | "System.UInt64"
 3741             | "System.Char"
 3742             | "System.Double"
 3743             | "System.Single"
 3744             | "System.Boolean" -> ILType.Value(tspec)
 3745             | _ -> ILType.Boxed(tspec)
 3746 
 3747         // if it's an array, wrap it - otherwise, just return the IL type
 3748         match rank with
 3749         | Some(r) -> ILType.Array(r, ilty)
 3750         | _ -> ilty
 3751     
 3752     member x.ParseTypeSpec() =
 3753         reset()
 3754         let ilty = x.ParseType()
 3755         ILAttribElem.Type(Some(ilty))
 3756 
 3757 let decodeILAttribData (ilg: ILGlobals) (ca: ILAttribute) = 
 3758     let bytes = ca.Data
 3759     let sigptr = 0
 3760     let bb0, sigptr = sigptr_get_byte bytes sigptr
 3761     let bb1, sigptr = sigptr_get_byte bytes sigptr
 3762     if not (bb0 = 0x01 && bb1 = 0x00) then failwith "decodeILAttribData: invalid data"
 3763 
 3764     let rec parseVal argty sigptr = 
 3765       match argty with 
 3766       | ILType.Value tspec when tspec.Name = "System.SByte" ->  
 3767           let n, sigptr = sigptr_get_i8 bytes sigptr
 3768           ILAttribElem.SByte n, sigptr
 3769       | ILType.Value tspec when tspec.Name = "System.Byte" ->  
 3770           let n, sigptr = sigptr_get_u8 bytes sigptr
 3771           ILAttribElem.Byte n, sigptr
 3772       | ILType.Value tspec when tspec.Name = "System.Int16" ->  
 3773           let n, sigptr = sigptr_get_i16 bytes sigptr
 3774           ILAttribElem.Int16 n, sigptr
 3775       | ILType.Value tspec when tspec.Name = "System.UInt16" ->  
 3776           let n, sigptr = sigptr_get_u16 bytes sigptr
 3777           ILAttribElem.UInt16 n, sigptr
 3778       | ILType.Value tspec when tspec.Name = "System.Int32" ->  
 3779           let n, sigptr = sigptr_get_i32 bytes sigptr
 3780           ILAttribElem.Int32 n, sigptr
 3781       | ILType.Value tspec when tspec.Name = "System.UInt32" ->  
 3782           let n, sigptr = sigptr_get_u32 bytes sigptr
 3783           ILAttribElem.UInt32 n, sigptr
 3784       | ILType.Value tspec when tspec.Name = "System.Int64" ->  
 3785           let n, sigptr = sigptr_get_i64 bytes sigptr
 3786           ILAttribElem.Int64 n, sigptr
 3787       | ILType.Value tspec when tspec.Name = "System.UInt64" ->  
 3788           let n, sigptr = sigptr_get_u64 bytes sigptr
 3789           ILAttribElem.UInt64 n, sigptr
 3790       | ILType.Value tspec when tspec.Name = "System.Double" ->  
 3791           let n, sigptr = sigptr_get_ieee64 bytes sigptr
 3792           ILAttribElem.Double n, sigptr
 3793       | ILType.Value tspec when tspec.Name = "System.Single" ->  
 3794           let n, sigptr = sigptr_get_ieee32 bytes sigptr
 3795           ILAttribElem.Single n, sigptr
 3796       | ILType.Value tspec when tspec.Name = "System.Char" ->  
 3797           let n, sigptr = sigptr_get_u16 bytes sigptr
 3798           ILAttribElem.Char (char (int32 n)), sigptr
 3799       | ILType.Value tspec when tspec.Name = "System.Boolean" ->  
 3800           let n, sigptr = sigptr_get_byte bytes sigptr
 3801           ILAttribElem.Bool (not (n = 0)), sigptr
 3802       | ILType.Boxed tspec when tspec.Name = "System.String" ->  
 3803           let n, sigptr = sigptr_get_serstring_possibly_null bytes sigptr
 3804           ILAttribElem.String n, sigptr
 3805       | ILType.Boxed tspec when tspec.Name = "System.Type" ->  
 3806           let nOpt, sigptr = sigptr_get_serstring_possibly_null bytes sigptr
 3807           match nOpt with
 3808           | None -> ILAttribElem.TypeRef(None), sigptr
 3809           | Some n -> 
 3810             try
 3811                 let parser = ILTypeSigParser(n)
 3812                 parser.ParseTypeSpec(), sigptr
 3813             with e ->
 3814                 failwith (sprintf "decodeILAttribData: error parsing type in custom attribute blob: %s" e.Message)
 3815       | ILType.Boxed tspec when tspec.Name = "System.Object" ->  
 3816           let et, sigptr = sigptr_get_u8 bytes sigptr
 3817           if et = 0xFFuy then 
 3818               ILAttribElem.Null, sigptr
 3819           else
 3820               let ty, sigptr = decodeCustomAttrElemType ilg bytes sigptr et 
 3821               parseVal ty sigptr 
 3822       | ILType.Array(shape, elemTy) when shape = ILArrayShape.SingleDimensional ->  
 3823           let n, sigptr = sigptr_get_i32 bytes sigptr
 3824           if n = 0xFFFFFFFF then ILAttribElem.Null, sigptr else
 3825           let rec parseElems acc n sigptr = 
 3826             if n = 0 then List.rev acc, sigptr else
 3827             let v, sigptr = parseVal elemTy sigptr
 3828             parseElems (v ::acc) (n-1) sigptr
 3829           let elems, sigptr = parseElems [] n sigptr 
 3830           ILAttribElem.Array(elemTy, elems), sigptr
 3831       | ILType.Value _ ->  (* assume it is an enumeration *)
 3832           let n, sigptr = sigptr_get_i32 bytes sigptr
 3833           ILAttribElem.Int32 n, sigptr
 3834       | _ ->  failwith "decodeILAttribData: attribute data involves an enum or System.Type value"
 3835     let rec parseFixed argtys sigptr = 
 3836       match argtys with 
 3837         [] -> [], sigptr
 3838       | h::t -> 
 3839           let nh, sigptr = parseVal h sigptr
 3840           let nt, sigptr = parseFixed t sigptr
 3841           nh ::nt, sigptr
 3842     let fixedArgs, sigptr = parseFixed ca.Method.FormalArgTypes sigptr
 3843     let nnamed, sigptr = sigptr_get_u16 bytes sigptr
 3844     let rec parseNamed acc n sigptr = 
 3845       if n = 0 then List.rev acc else
 3846       let isPropByte, sigptr = sigptr_get_u8 bytes sigptr
 3847       let isProp = (int isPropByte = 0x54)
 3848       let et, sigptr = sigptr_get_u8 bytes sigptr
 3849       // We have a named value 
 3850       let ty, sigptr = 
 3851         if ( (* 0x50 = (int et) || *) 0x55 = (int et)) then
 3852             let qualified_tname, sigptr = sigptr_get_serstring bytes sigptr
 3853             let unqualified_tname, rest = 
 3854                 let pieces = qualified_tname.Split(',')
 3855                 if pieces.Length > 1 then 
 3856                     pieces.[0], Some (String.concat "," pieces.[1..])
 3857                 else 
 3858                     pieces.[0], None
 3859             let scoref = 
 3860                 match rest with 
 3861                 | Some aname -> ILScopeRef.Assembly(ILAssemblyRef.FromAssemblyName(System.Reflection.AssemblyName(aname)))        
 3862                 | None -> ilg.primaryAssemblyScopeRef
 3863 
 3864             let tref = mkILTyRef (scoref, unqualified_tname)
 3865             let tspec = mkILNonGenericTySpec tref
 3866             ILType.Value(tspec), sigptr            
 3867         else
 3868             decodeCustomAttrElemType ilg bytes sigptr et
 3869       let nm, sigptr = sigptr_get_serstring bytes sigptr
 3870       let v, sigptr = parseVal ty sigptr
 3871       parseNamed ((nm, ty, isProp, v) :: acc) (n-1) sigptr
 3872     let named = parseNamed [] (int nnamed) sigptr
 3873     fixedArgs, named     
 3874 
 3875 
 3876 // -------------------------------------------------------------------- 
 3877 // Functions to collect up all the references in a full module or
 3878 // assembly manifest.  The process also allocates
 3879 // a unique name to each unique internal assembly reference.
 3880 // -------------------------------------------------------------------- 
 3881 
 3882 type ILReferences = 
 3883     { AssemblyReferences: ILAssemblyRef list 
 3884       ModuleReferences: ILModuleRef list }
 3885 
 3886 type ILReferencesAccumulator = 
 3887     { refsA: HashSet<ILAssemblyRef> 
 3888       refsM: HashSet<ILModuleRef> }
 3889 
 3890 let emptyILRefs = 
 3891   { AssemblyReferences=[]
 3892     ModuleReferences = [] }
 3893 
 3894 (* Now find references. *)
 3895 let refs_of_assref (s:ILReferencesAccumulator) x = s.refsA.Add x |> ignore
 3896 let refs_of_modref (s:ILReferencesAccumulator) x = s.refsM.Add x |> ignore
 3897     
 3898 let refs_of_scoref s x = 
 3899     match x with 
 3900     | ILScopeRef.Local -> () 
 3901     | ILScopeRef.Assembly assref -> refs_of_assref s assref
 3902     | ILScopeRef.Module modref -> refs_of_modref s modref  
 3903 
 3904 let refs_of_tref s (x:ILTypeRef) = refs_of_scoref s x.Scope
 3905   
 3906 let rec refs_of_typ s x = 
 3907     match x with
 3908     | ILType.Void |  ILType.TypeVar _ -> ()
 3909     | ILType.Modified(_, ty1, ty2) -> refs_of_tref s ty1; refs_of_typ s ty2
 3910     | ILType.Array (_, ty)
 3911     | ILType.Ptr ty | ILType.Byref ty -> refs_of_typ s ty 
 3912     | ILType.Value tr | ILType.Boxed tr -> refs_of_tspec s tr
 3913     | ILType.FunctionPointer mref -> refs_of_callsig s mref 
 3914 
 3915 and refs_of_inst s i = refs_of_tys s i
 3916 and refs_of_tspec s (x:ILTypeSpec) = refs_of_tref s x.TypeRef;  refs_of_inst s x.GenericArgs
 3917 and refs_of_callsig s csig  = refs_of_tys s csig.ArgTypes; refs_of_typ s csig.ReturnType
 3918 and refs_of_genparam s x = refs_of_tys s x.Constraints
 3919 and refs_of_genparams s b = List.iter (refs_of_genparam s) b
 3920     
 3921 and refs_of_dloc s ts = refs_of_tref s ts
 3922    
 3923 and refs_of_mref s (x:ILMethodRef) = 
 3924     refs_of_dloc s x.DeclaringTypeRef
 3925     refs_of_tys s x.mrefArgs
 3926     refs_of_typ s x.mrefReturn
 3927     
 3928 and refs_of_fref s x = refs_of_tref s x.DeclaringTypeRef; refs_of_typ s x.Type
 3929 and refs_of_ospec s (OverridesSpec(mref, ty)) = refs_of_mref s mref; refs_of_typ s ty 
 3930 and refs_of_mspec s (x: ILMethodSpec) = 
 3931     refs_of_mref s x.MethodRef
 3932     refs_of_typ s x.DeclaringType
 3933     refs_of_inst s x.GenericArgs
 3934 
 3935 and refs_of_fspec s x =
 3936     refs_of_fref s x.FieldRef
 3937     refs_of_typ s x.DeclaringType
 3938 
 3939 and refs_of_tys s l = List.iter (refs_of_typ s) l
 3940   
 3941 and refs_of_token s x = 
 3942     match x with
 3943     | ILToken.ILType ty -> refs_of_typ s ty
 3944     | ILToken.ILMethod mr -> refs_of_mspec s mr
 3945     | ILToken.ILField fr -> refs_of_fspec s fr
 3946 
 3947 and refs_of_custom_attr s x = refs_of_mspec s x.Method
 3948     
 3949 and refs_of_custom_attrs s (cas : ILAttributes) = List.iter (refs_of_custom_attr s) cas.AsList
 3950 and refs_of_varargs s tyso = Option.iter (refs_of_tys s) tyso 
 3951 and refs_of_instr s x = 
 3952     match x with
 3953     | I_call (_, mr, varargs) | I_newobj (mr, varargs) | I_callvirt (_, mr, varargs) ->
 3954         refs_of_mspec s mr
 3955         refs_of_varargs s varargs
 3956     | I_callconstraint (_, tr, mr, varargs) -> 
 3957         refs_of_typ s tr
 3958         refs_of_mspec s mr
 3959         refs_of_varargs s varargs
 3960     | I_calli (_, callsig, varargs) ->  
 3961         refs_of_callsig s callsig;  refs_of_varargs s varargs 
 3962     | I_jmp mr | I_ldftn mr | I_ldvirtftn mr -> 
 3963         refs_of_mspec s mr
 3964     | I_ldsfld (_, fr) | I_ldfld (_, _, fr) | I_ldsflda fr | I_ldflda fr | I_stsfld (_, fr) | I_stfld (_, _, fr) -> 
 3965         refs_of_fspec s fr
 3966     | I_isinst ty | I_castclass ty | I_cpobj ty | I_initobj ty | I_ldobj (_, _, ty) 
 3967     | I_stobj (_, _, ty) | I_box ty |I_unbox ty | I_unbox_any ty | I_sizeof ty
 3968     | I_ldelem_any (_, ty) | I_ldelema (_, _, _, ty) |I_stelem_any (_, ty) | I_newarr (_, ty)
 3969     | I_mkrefany ty | I_refanyval ty 
 3970     | EI_ilzero ty ->   refs_of_typ s ty 
 3971     | I_ldtoken token -> refs_of_token s token 
 3972     | I_stelem _|I_ldelem _|I_ldstr _|I_switch _|I_stloc _|I_stind _
 3973     | I_starg _|I_ldloca _|I_ldloc _|I_ldind _
 3974     | I_ldarga _|I_ldarg _|I_leave _|I_br _
 3975     | I_brcmp _|I_rethrow|I_refanytype|I_ldlen|I_throw|I_initblk _ |I_cpblk _ 
 3976     | I_localloc|I_ret |I_endfilter|I_endfinally|I_arglist
 3977     | I_break
 3978     | AI_add    | AI_add_ovf | AI_add_ovf_un | AI_and    | AI_div    | AI_div_un | AI_ceq      | AI_cgt      | AI_cgt_un   | AI_clt     
 3979     | AI_clt_un  | AI_conv      _ | AI_conv_ovf  _ | AI_conv_ovf_un  _ | AI_mul       | AI_mul_ovf    | AI_mul_ovf_un | AI_rem       | AI_rem_un       
 3980     | AI_shl       | AI_shr       | AI_shr_un | AI_sub       | AI_sub_ovf   | AI_sub_ovf_un   | AI_xor       | AI_or        | AI_neg       | AI_not       
 3981     | AI_ldnull    | AI_dup       | AI_pop | AI_ckfinite | AI_nop | AI_ldc       _
 3982     | I_seqpoint _ | EI_ldlen_multi _ ->  ()
 3983       
 3984   
 3985 and refs_of_il_code s (c: ILCode)  = 
 3986     c.Instrs |> Array.iter (refs_of_instr s) 
 3987     c.Exceptions |> List.iter (fun e -> e.Clause |> (function 
 3988         | ILExceptionClause.TypeCatch (ilty, _) -> refs_of_typ s ilty
 3989         | _ -> ()))
 3990 
 3991 and refs_of_ilmbody s (il: ILMethodBody) = 
 3992     List.iter (refs_of_local s) il.Locals
 3993     refs_of_il_code s il.Code 
 3994     
 3995 and refs_of_local s loc = refs_of_typ s loc.Type
 3996     
 3997 and refs_of_mbody s x = 
 3998     match x with 
 3999     | MethodBody.IL il -> refs_of_ilmbody s il
 4000     | MethodBody.PInvoke (attr) -> refs_of_modref s attr.Where
 4001     | _ -> ()
 4002 
 4003 and refs_of_mdef s (md: ILMethodDef) = 
 4004     List.iter (refs_of_param s) md.Parameters
 4005     refs_of_return s md.Return
 4006     refs_of_mbody s  md.Body.Contents
 4007     refs_of_custom_attrs s  md.CustomAttrs
 4008     refs_of_genparams s  md.GenericParams
 4009     
 4010 and refs_of_param s p = refs_of_typ s p.Type 
 4011 and refs_of_return s (rt:ILReturn) = refs_of_typ s rt.Type
 4012 and refs_of_mdefs s x =  Seq.iter (refs_of_mdef s) x
 4013     
 4014 and refs_of_event_def s (ed: ILEventDef) = 
 4015     Option.iter (refs_of_typ s)  ed.EventType
 4016     refs_of_mref s ed.AddMethod
 4017     refs_of_mref s ed.RemoveMethod
 4018     Option.iter (refs_of_mref s) ed.FireMethod
 4019     List.iter (refs_of_mref s) ed.OtherMethods
 4020     refs_of_custom_attrs s ed.CustomAttrs
 4021     
 4022 and refs_of_events s (x: ILEventDefs) =  List.iter (refs_of_event_def s) x.AsList
 4023     
 4024 and refs_of_property_def s (pd: ILPropertyDef) = 
 4025     Option.iter (refs_of_mref s)  pd.SetMethod
 4026     Option.iter (refs_of_mref s)  pd.GetMethod
 4027     refs_of_typ s pd.PropertyType
 4028     refs_of_tys s pd.Args
 4029     refs_of_custom_attrs s pd.CustomAttrs
 4030     
 4031 and refs_of_properties s (x: ILPropertyDefs) = List.iter (refs_of_property_def s) x.AsList
 4032     
 4033 and refs_of_fdef s (fd: ILFieldDef) = 
 4034     refs_of_typ  s fd.FieldType
 4035     refs_of_custom_attrs  s fd.CustomAttrs
 4036 
 4037 and refs_of_fields s fields = List.iter (refs_of_fdef s) fields
 4038     
 4039 and refs_of_method_impls s mimpls =  List.iter (refs_of_method_impl s) mimpls
 4040     
 4041 and refs_of_method_impl s m = 
 4042     refs_of_ospec s m.Overrides
 4043     refs_of_mspec s m.OverrideBy
 4044 
 4045 and refs_of_tdef_kind _s _k =  ()
 4046   
 4047 and refs_of_tdef s (td : ILTypeDef)  =  
 4048     refs_of_types s td.NestedTypes
 4049     refs_of_genparams s  td.GenericParams
 4050     refs_of_tys  s td.Implements
 4051     Option.iter (refs_of_typ s) td.Extends
 4052     refs_of_mdefs        s td.Methods
 4053     refs_of_fields       s td.Fields.AsList
 4054     refs_of_method_impls s td.MethodImpls.AsList
 4055     refs_of_events       s td.Events
 4056     refs_of_tdef_kind    s td
 4057     refs_of_custom_attrs s td.CustomAttrs
 4058     refs_of_properties   s td.Properties
 4059 
 4060 and refs_of_string _s _ = ()
 4061 and refs_of_types s (types: ILTypeDefs) = Seq.iter  (refs_of_tdef s) types
 4062     
 4063 and refs_of_exported_type s (c: ILExportedTypeOrForwarder) = 
 4064     refs_of_custom_attrs s c.CustomAttrs
 4065     
 4066 and refs_of_exported_types s (tab: ILExportedTypesAndForwarders) = List.iter (refs_of_exported_type s) tab.AsList
 4067     
 4068 and refs_of_resource_where s x = 
 4069     match x with 
 4070     | ILResourceLocation.LocalIn _ -> ()
 4071     | ILResourceLocation.LocalOut _ -> ()
 4072     | ILResourceLocation.File (mref, _) -> refs_of_modref s mref
 4073     | ILResourceLocation.Assembly aref -> refs_of_assref s aref
 4074 
 4075 and refs_of_resource s x = 
 4076     refs_of_resource_where s x.Location
 4077     refs_of_custom_attrs s x.CustomAttrs
 4078     
 4079 and refs_of_resources s (tab: ILResources) = List.iter (refs_of_resource s) tab.AsList
 4080     
 4081 and refs_of_modul s m = 
 4082     refs_of_types s m.TypeDefs
 4083     refs_of_resources s m.Resources
 4084     Option.iter (refs_of_manifest s) m.Manifest
 4085     
 4086 and refs_of_manifest s (m: ILAssemblyManifest) = 
 4087     refs_of_custom_attrs s m.CustomAttrs
 4088     refs_of_exported_types s m.ExportedTypes
 4089 
 4090 let computeILRefs modul = 
 4091     let s = 
 4092       { refsA = HashSet<_>(HashIdentity.Structural) 
 4093         refsM = HashSet<_>(HashIdentity.Structural) }
 4094 
 4095     refs_of_modul s modul
 4096     { AssemblyReferences = Seq.fold (fun acc x -> x::acc) [] s.refsA
 4097       ModuleReferences =  Seq.fold (fun acc x -> x::acc) [] s.refsM }
 4098 
 4099 let tspan = System.TimeSpan(System.DateTime.UtcNow.Ticks - System.DateTime(2000, 1, 1).Ticks)
 4100 
 4101 let parseILVersion (vstr : string) = 
 4102     // matches "v1.2.3.4" or "1.2.3.4". Note, if numbers are missing, returns -1 (not 0).
 4103     let mutable vstr = vstr.TrimStart [|'v'|] 
 4104     // if the version string contains wildcards, replace them
 4105     let versionComponents = vstr.Split([|'.'|])
 4106     
 4107     // account for wildcards
 4108     if versionComponents.Length > 2 then
 4109       let defaultBuild = (uint16)tspan.Days % System.UInt16