Math.NET Numerics
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

2446 lines
94 KiB

// (c) Microsoft Corporation. All rights reserved
/// The "unlinked" view of .NET metadata and code. Central to
/// to Abstract IL library
module (* internal *) Microsoft.FSharp.Compiler.AbstractIL.IL
open Internal.Utilities
#light
// ====================================================================
// .NET binaries can be converted to the data structures below by using
// the functions in the "Ilread" module.
//
// Constituent types are listed in ascending order of complexity,
// all the way up to the type "assembly". Types are often specified
// via a concrete representation for the type (e.g. a record), though
// later versions of this toolkit may make these types abstract.
// Types are followed by a collection of abstract functions
// of the form "dest_XYZ" and "ABC_of_XYZ" to
// access information from objects. Sometimes these
// abstract access functions are not complete, i.e. you may have
// to use the concrete representation directly.
//
// The second part of the file (after the definition of all the types)
// specifies a large set of utilities for building objects belonging to
// the types. You will only need to become familiar with these if you
// are transforming code or writing a code-generating compiler.
//
// Several other utilities are also defined in this file:
// 1. A code builder for turning linear sequences of instructions
// augmented with exception tables into the more structured
// format used for code.
//
// 2. The "typ_XYZ", "tspec_XYZ" and "mspec_XYZ" values which
// can be used to reference types in the "mscorlib" assembly.
//
// 3. The "rescope_XYZ" functions which can be used to lift a piece of
// metadata from one assembly and transform it to a piece of metadata
// suitable for use from another assembly. The transformation adjusts
// references in the metadata to take into account the assembly
// where the metadata will now be located.
//
// 4. The "inst_XYZ" utilities to replace type variables
// by types. These are associated with generics.
//
// 5. The "intern_XYZ" tables for reducing the memory used by
// generated constructs.
//
// 6. The "refs_of_XYZ" utilities for finding all the assemblies
// referenced by a module.
//
// 7. A somewhat obscure facility to allow new instructions and types
// to be added to the IL. This is used by ILX.
// ====================================================================
// A note on strings: Strings in this module represent slightly
// different things depending on whether you are accessing the
// library using OCaml or a .NET language:
//
// F# (and any other .NET language):
// The type 'string' in this file repesents a Unicode string.
//
// We often use the type "byte[]" where we want a type that can faithfully
// represent Unicode strings.
// Guids - REVIEW: adjust these to the System.Guid type
type Guid = byte[]
type ILPlatform =
| X86
| AMD64
| IA64
/// Debug info. Values of type "source" can be attached at sequence
/// points and some other locations.
[<Sealed>]
type ILSourceDocument =
static member Create : language: Guid option * vendor: Guid option * documentType: Guid option * file: string -> ILSourceDocument
member Language: Guid option
member Vendor: Guid option
member DocumentType: Guid option
member File: string
[<Sealed>]
type ILSourceMarker =
static member Create : document: ILSourceDocument * line: int * column: int * endLine:int * endColumn: int-> ILSourceMarker
member Document: ILSourceDocument
member Line: int
member Column: int
member EndLine: int
member EndColumn: int
/// Extensibility: ignore these unless you are generating ILX
/// structures directly.
type IlxExtensionType
type IlxExtensionTypeKind
type IlxExtensionInstr
type Locale = string
type PublicKey =
| PublicKey of byte[]
| PublicKeyToken of byte[]
member IsKey: bool
member IsKeyToken: bool
member Key: byte[]
member KeyToken: byte[]
type ILVersionInfo = uint16 * uint16 * uint16 * uint16
[<Sealed>]
type ILAssemblyRef =
static member Create : name: string * hash: byte[] option * publicKey: PublicKey option * retargetable: bool * version: ILVersionInfo option * locale: Locale option -> ILAssemblyRef
static member FromAssembly : System.Reflection.Assembly -> ILAssemblyRef
member Name: string;
/// The fully qualified name of the assembly reference, e.g. mscorlib, Version=1.0.3705 etc.
member QualifiedName: string;
member Hash: byte[] option;
member PublicKey: PublicKey option;
/// CLI says this indicates if the assembly can be retargeted (at runtime) to be from a different publisher.
member Retargetable: bool;
member Version: ILVersionInfo option;
member Locale: Locale option
interface System.IComparable
[<Sealed>]
type ILModuleRef =
static member Create : name: string * hasMetadata: bool * hash: byte[] option -> ILModuleRef
member Name: string;
member HasMetadata: bool;
member Hash: byte[] option;
/// Scope references
///
/// Scope references are the bits of metadata attached to type names
/// that indicate where a type can be found. CIL has three
/// kinds: local, module and assembly references:
/// o Local: the type must reside in the same module as the scope reference
/// o Module: the type must reside in the indicated module in the same
/// assembly as the scope reference
/// o Assembly: The type must reside in the indicated assembly.
/// These have no implicit context. Assembly references can end up
/// binding to the assembly containing the reference, i.e.
/// may be self or mutually referential.
///
/// Assembly reference may also resolve to type in an
/// auxiliary module of an assembly when the assembly
/// has an "exported types" (here called "classes elsewhere") table.
///
/// We represent these references by values embedded within type
/// references. These values are usually "shared" across the data
/// structures for a module, i.e. one such value is created for each
/// assembly or module reference, and this value is reused within each
/// type object.
///
/// Note that as with method references the term structure is not
/// _linked_, i.e. a "ILScopeRef" is still a _reference_ to a scope,
/// not the scope itself. Because the structure is not linked,
/// the Abstract IL toolset does not require
/// strongly connected inputs: you can manipulate an assembly
/// without loading all its dependent assemblies. This is the primary
/// difference between Abstract IL and Reflection, and it can be both
/// a blessing and a curse depending on the kind of manipulation you
/// wish to perform.
///
/// Similarly, you can manipulate individual modules within
/// an assembly without having the whole assembly loaded. (But note that
/// most assemblies are single-module in any case).
///
/// [ILScopeRef]'s _cannot_ be compared for equality in the way that
/// might be expected, in these sense that two ILScopeRef's may
/// resolve to the same assembly/module even though they are not equal.
///
/// Aside: People have suggested normalizing all scope references
/// so that this would be possible, and early versions of this
/// toolkit did this. However, this meant that in order to load
/// each module you had to tell the toolkit which assembly it belonged to.
/// Furthermore, you had to know the exact resolved details of
/// each assembly the module refers to. This is
/// effectively like having a "fully-linked" view of the graph
/// of assemblies, like that provided in the Ilbind module. This is really problematic for compile-time tools,
/// as, for example, the policy for linking at the runtime-machine
/// may actually alter the results of linking. If such compile-time
/// assumptions are to be made then the tool built on top
/// of the toolkit rather than the toolkit itself should
/// make them.
///
/// Scope references, type references, field references and method references
/// can be "bound" to particular assemblies using the functions in "Ilbind".
/// This simulates the resolution/binding process performed by a Common Language
/// Runtime during execution. Various tests and derived operations
/// can then be performed on the results of binding. See the Ilbind module
/// for more details. Many (but not all) analyses should rightly be built on top of
/// Ilbind.
type ILScopeRef =
// ... in M.
| ScopeRef_local
// ... be in the given module of A.
| ScopeRef_module of ILModuleRef
// ... be in some module of the given assembly.
| ScopeRef_assembly of ILAssemblyRef
static member Local: ILScopeRef
static member Module: ILModuleRef -> ILScopeRef
static member Assembly: ILAssemblyRef -> ILScopeRef
member IsLocalRef: bool
member IsModuleRef: bool
member IsAssemblyRef: bool
member ModuleRef: ILModuleRef
member AssemblyRef: ILAssemblyRef
member QualifiedName: string
/// Calling conventions.
///
/// For nearly all purposes you simply want to use CC_default combined
/// with CC_instance or CC_static, i.e.
/// ILCallingConv.Instance == Callconv(CC_instance, CC_default): for an instance method
/// ILCallingConv.Static == Callconv(CC_static, CC_default): for a static method
///
/// CC_instance_explicit is only used by Managed C++, and indicates
/// that the 'this' pointer is actually explicit in the signature.
type ILArgumentConvention =
| CC_default
| CC_cdecl
| CC_stdcall
| CC_thiscall
| CC_fastcall
| CC_vararg
type ILThisConvention =
/// accepts an implicit 'this' pointer
| CC_instance
/// accepts an implicit 'this' pointer
| CC_instance_explicit
/// no 'this' pointer is passed
| CC_static
type ILCallingConv =
| Callconv of ILThisConvention * ILArgumentConvention
member IsInstance : bool
member IsInstanceExplicit : bool
member IsStatic : bool
member ThisConv : ILThisConvention
member BasicConv : ILArgumentConvention
static member Instance : ILCallingConv
static member Static : ILCallingConv
/// Array shapes. For most purposes, including verification, the
/// rank is the only thing that matters.
type ILArrayBound = int32 option
type ILArrayBounds = ILArrayBound * ILArrayBound
type ILArrayShape =
| ILArrayShape of ILArrayBounds list (* lobound/size pairs *)
member Rank : int
static member SingleDimensional: ILArrayShape
/// Bounds for a single dimensional, zero based array
val Rank1ArrayShape: ILArrayShape
type ILBoxity =
| AsObject
| AsValue
/// Type refs, i.e. references to types in some .NET assembly
[<Sealed>]
type ILTypeRef =
/// Create a ILTypeRef
static member Create : scope: ILScopeRef * enclosing: string list * name: string -> ILTypeRef
/// Where is the type, i.e. is it in this module, in another module in this assembly or in another assembly?
member Scope: ILScopeRef
/// The list of enclosing type names for a nested type. If non-nil then the first of these also contains the namespace.
member Enclosing: string list
/// The name of the type. This also contains the namespace if Enclosing is empty
member Name: string
member FullName: string
member QualifiedName: string
interface System.IComparable
/// Type specs and types.
///
/// These are the types that appear syntactically in
/// .NET binaries. They can be resolved to bound types (see ilbind.ml).
///
/// Generic type definitions must be combined with
/// an instantiation to form a type. Throughout this file,
/// a "ref" refers to something that is uninstantiated, and
/// a "spec" to a ref that is combined with the relevant instantiations.
[<Sealed>]
type ILTypeSpec =
static member Create : typeRef:ILTypeRef * instantiation:ILGenericArgs -> ILTypeSpec
/// Which type is being referred to?
member TypeRef: ILTypeRef
/// The type instantiation if the type is generic, otherwise empty
member GenericArgs: ILGenericArgs
member Scope: ILScopeRef
member Enclosing: string list
member Name: string
member FullName: string
and ILType =
/// Used only in return and pointer types.
| Type_void
/// Array types
| Type_array of ILArrayShape * ILType
/// Unboxed types, including builtin types.
| Type_value of ILTypeSpec
/// Reference types. Also may be used for parents of members even if for members in value types.
| Type_boxed of ILTypeSpec
/// Unmanaged pointers. Nb. the type is used by tools and for binding only, not by the verifier.
| Type_ptr of ILType
/// Managed pointers.
| Type_byref of ILType
/// ILCode pointers.
| Type_fptr of ILCallingSignature
/// Reference a generic arg.
| Type_tyvar of uint16
/// Custom modifiers.
| Type_modified of
/// True if modifier is "required"
bool *
/// The class of the custom modifier.
ILTypeRef *
/// The type being modified.
ILType
member TypeSpec : ILTypeSpec
member Boxity : ILBoxity
member TypeRef : ILTypeRef
member IsNominal : bool
member GenericArgs : ILGenericArgs
member IsTyvar : bool
and ILCallingSignature =
{ callsigCallconv: ILCallingConv;
callsigArgs: ILType list;
callsigReturn: ILType }
member CallingConv : ILCallingConv
member ArgTypes: ILType list
member ReturnType: ILType
/// Generic parameters. Actual generic parameters are
/// always types. Formal generic parameter declarations
/// may include the bounds, if any, on the generic parameter.
and ILGenericParameterDefs = ILGenericParameterDef list
and ILGenericArgs = ILType list
and ILGenericVariance =
| NonVariant
| CoVariant
| ContraVariant
and ILGenericParameterDef =
{ gpName: string;
gpConstraints: ILType list;
gpVariance: ILGenericVariance;
gpReferenceTypeConstraint: bool;
gpNotNullableValueTypeConstraint: bool;
gpDefaultConstructorConstraint: bool; }
member Name : string
/// At most one is the parent type, the others are interface types
member Constraints: ILType list
/// Variance of type parameters, only applicable to generic parameters for generic interfaces and delegates
member Variance: ILGenericVariance
/// The type argument must be a reference type
member HasReferenceTypeConstraint: bool
/// The type argument must be a value type, but not Nullable
member HasNotNullableValueTypeConstraint: bool
/// The type argument must have a public nullary constructor
member HasDefaultConstructorConstraint: bool
/// Accessors on types
val is_array_ty: ILType -> bool
val dest_array_ty: ILType -> ILArrayShape * ILType
val tspec_of_typ: ILType -> ILTypeSpec
val boxity_of_typ: ILType -> ILBoxity
val tref_of_typ: ILType -> ILTypeRef
val is_tref_typ: ILType -> bool
val inst_of_typ: ILType -> ILGenericArgs
val is_tyvar_ty: ILType -> bool
/// Formal identities of methods. Method refs refer to methods on
/// named types. In general you should work with ILMethodSpec objects
/// rather than MethodRef objects, because ILMethodSpec objects carry
/// information about how generic methods are instantiated. MethodRef
/// objects are only used at a few places in the Abstract IL syntax
/// and if analyzing or generating IL you will be unlikely to come across
/// these.
[<Sealed>]
type ILMethodRef =
static member Create : enclosingTypeRef: ILTypeRef *
callingConv: ILCallingConv *
name: string *
genericArity: int *
argTypes: ILType list *
returnType: ILType
-> ILMethodRef
member EnclosingTypeRef: ILTypeRef
member CallingConv: ILCallingConv
member Name: string
member GenericArity: int
member ArgCount: int
member ArgTypes: ILType list
member ReturnType: ILType
member CallingSignature: ILCallingSignature
/// Formal identities of fields.
type ILFieldRef =
{ frefParent: ILTypeRef;
frefName: string;
frefType: ILType }
member EnclosingTypeRef: ILTypeRef
member Name: string
member Type: ILType
/// Method specs and field specs
///
/// A ILMethodSpec is everything given at the callsite (apart from
/// whether the call is a tailcall and whether it is passing
/// varargs - see the instruction set below). It is made up of
/// 1) a (possibly generic) ILMethodRef
/// 2) a "usage type" that indicates the how the type
/// containing the declaration is being used (as
/// a value class, a boxed value class, an instantiated
/// generic class or whatever - see below)
/// 3) an instantiation in the case where the method is generic.
///
/// In this unbound form of the metadata, the enclosing type may
/// be Type_boxed even when the member is a member of a value type or
/// enumeration. This is because the binary format of the metadata
/// does not carry enough information in a MemberRefParent to determine
/// from the binary alone whether the enclosing type is a value type or
/// not.
[<Sealed>]
type ILMethodSpec =
static member Create : ILType * ILMethodRef * ILGenericArgs -> ILMethodSpec
member MethodRef: ILMethodRef
member EnclosingType: ILType
member GenericArgs: ILGenericArgs
member CallingConv: ILCallingConv
member GenericArity: int
member Name: string
member FormalArgTypes: ILType list
member FormalReturnType: ILType
val dest_mspec : ILMethodSpec -> ILMethodRef * ILType * ILGenericArgs
/// Field specs. The data given for a ldfld, stfld etc. instruction.
type ILFieldSpec =
{ fspecFieldRef: ILFieldRef;
fspecEnclosingType: ILType }
member FieldRef: ILFieldRef
member EnclosingType: ILType
member EnclosingTypeRef: ILTypeRef
member Name: string
member FormalType: ILType
val actual_typ_of_fspec: ILFieldSpec -> ILType
/// ILCode labels. In structured code each code label
/// refers to a basic block somewhere in the code of the method.
type ILCodeLabel = int
type ILBasicType =
| DT_R
| DT_I1
| DT_U1
| DT_I2
| DT_U2
| DT_I4
| DT_U4
| DT_I8
| DT_U8
| DT_R4
| DT_R8
| DT_I
| DT_U
| DT_REF
type ILTokenSpec =
| Token_type of ILType
| Token_method of ILMethodSpec
| Token_field of ILFieldSpec
type ILConstSpec =
| NUM_I4 of int32
| NUM_I8 of int64
| NUM_R4 of single
| NUM_R8 of double
type Tailcall =
| Tailcall
| Normalcall
type Alignment =
| Aligned
| Unaligned_1
| Unaligned_2
| Unaligned_4
type Volatility =
| Volatile
| Nonvolatile
type ReadonlySpec =
| ReadonlyAddress
| NormalAddress
type varargs = ILType list option
type ILComparisonInstr =
| BI_beq
| BI_bge
| BI_bge_un
| BI_bgt
| BI_bgt_un
| BI_ble
| BI_ble_un
| BI_blt
| BI_blt_un
| BI_bne_un
| BI_brfalse
| BI_brtrue
type ILArithInstr =
| 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
| AI_clt_un
| AI_conv of ILBasicType
| AI_conv_ovf of ILBasicType
| AI_conv_ovf_un of ILBasicType
| AI_mul
| AI_mul_ovf
| AI_mul_ovf_un
| AI_rem
| AI_rem_un
| AI_shl
| AI_shr
| AI_shr_un
| AI_sub
| AI_sub_ovf
| AI_sub_ovf_un
| AI_xor
| AI_or
| AI_neg
| AI_not
| AI_ldnull
| AI_dup
| AI_pop
| AI_ckfinite
| AI_nop
| AI_ldc of ILBasicType * ILConstSpec
/// The instruction set.
///
/// In general we don't categorize instructions, as different
/// instruction groups are relevant for different types of operations.
/// However we do collect the branch and compare instructions together
/// because they all take an address, and the ILArithInstr ones because
/// none of them take any direct arguments.
type ILInstr =
(* Basic *)
| I_arith of ILArithInstr
| I_ldarg of uint16
| I_ldarga of uint16
| I_ldind of Alignment * Volatility * ILBasicType
| I_ldloc of uint16
| I_ldloca of uint16
| I_starg of uint16
| I_stind of Alignment * Volatility * ILBasicType
| I_stloc of uint16
(* Control transfer *)
| I_br of ILCodeLabel
| I_jmp of ILMethodSpec
| I_brcmp of ILComparisonInstr * ILCodeLabel * ILCodeLabel (* second label is fall-through *)
| I_switch of (ILCodeLabel list * ILCodeLabel) (* last label is fallthrough *)
| I_ret
(* Method call *)
| I_call of Tailcall * ILMethodSpec * varargs
| I_callvirt of Tailcall * ILMethodSpec * varargs
| I_callconstraint of Tailcall * ILType * ILMethodSpec * varargs
| I_calli of Tailcall * ILCallingSignature * varargs
| I_ldftn of ILMethodSpec
| I_newobj of ILMethodSpec * varargs
(* Exceptions *)
| I_throw
| I_endfinally
| I_endfilter
| I_leave of ILCodeLabel
(* Object instructions *)
| I_ldsfld of Volatility * ILFieldSpec
| I_ldfld of Alignment * Volatility * ILFieldSpec
| I_ldsflda of ILFieldSpec
| I_ldflda of ILFieldSpec
| I_stsfld of Volatility * ILFieldSpec
| I_stfld of Alignment * Volatility * ILFieldSpec
| I_ldstr of string
| I_isinst of ILType
| I_castclass of ILType
| I_ldtoken of ILTokenSpec
| I_ldvirtftn of ILMethodSpec
(* Value type instructions *)
| I_cpobj of ILType
| I_initobj of ILType
| I_ldobj of Alignment * Volatility * ILType
| I_stobj of Alignment * Volatility * ILType
| I_box of ILType
| I_unbox of ILType
| I_unbox_any of ILType
| I_sizeof of ILType
(* Generalized array instructions. In AbsIL these instructions include *)
(* both the single-dimensional variants (with ILArrayShape == Rank1ArrayShape) *)
(* and calls to the "special" multi-dimensional "methods" such as *)
(* newobj void string[,]::.ctor(int32, int32) *)
(* call string string[,]::Get(int32, int32) *)
(* call string& string[,]::Address(int32, int32) *)
(* call void string[,]::Set(int32, int32,string) *)
(* The IL reader transforms calls of this form to the corresponding *)
(* generalized instruction with the corresponding ILArrayShape *)
(* argument. This is done to simplify the IL and make it more uniform. *)
(* The IL writer then reverses this when emitting the binary. *)
| I_ldelem of ILBasicType
| I_stelem of ILBasicType
| I_ldelema of ReadonlySpec * ILArrayShape * ILType (* ILArrayShape = Rank1ArrayShape for single dimensional arrays *)
| I_ldelem_any of ILArrayShape * ILType (* ILArrayShape = Rank1ArrayShape for single dimensional arrays *)
| I_stelem_any of ILArrayShape * ILType (* ILArrayShape = Rank1ArrayShape for single dimensional arrays *)
| I_newarr of ILArrayShape * ILType (* ILArrayShape = Rank1ArrayShape for single dimensional arrays *)
| I_ldlen
(* "System.TypedReference" related instructions: almost *)
(* no languages produce these, though they do occur in mscorlib.dll *)
(* System.TypedReference represents a pair of a type and a byref-pointer *)
(* to a value of that type. *)
| I_mkrefany of ILType
| I_refanytype
| I_refanyval of ILType
| I_rethrow
(* Debug-specific *)
(* I_seqpoint is a fake instruction to represent a sequence point: *)
(* the next instruction starts the execution of the *)
(* statement covered by the given range - this is a *)
(* dummy instruction and is not emitted *)
| I_break
| I_seqpoint of ILSourceMarker
(* Varargs - C++ only *)
| I_arglist
(* Local aggregates, i.e. stack allocated data (alloca) : C++ only *)
| I_localloc
| I_cpblk of Alignment * Volatility
| I_initblk of Alignment * Volatility
(* FOR EXTENSIONS, e.g. MS-ILX *)
| EI_ilzero of ILType
| EI_ldlen_multi of int32 * int32
| I_other of IlxExtensionInstr
/// Basic Blocks
/// A basic block is a list of instructions ending in an unconditionally
/// branching instruction. A basic block has a label which must be unique
/// within the method it is located in. Only the first instruction of
/// a basic block can be the target of a branch.
///
/// Details: The last instruction is always a control flow instruction,
/// i.e. branch, tailcall, throw etc.
///
/// For example
/// B1: ldarg 1
/// pop
/// ret
///
/// will be one basic block:
/// ILBasicBlock("B1", [| I_ldarg(1); I_arith(AI_pop); I_ret |])
type ILBasicBlock =
{ bblockLabel: ILCodeLabel;
bblockInstrs: ILInstr array }
member Label : ILCodeLabel
member Instructions: ILInstr array
val fallthrough_of_bblock: ILBasicBlock -> ILCodeLabel option
/// These nodes indicate a particular local variable has the given source
/// language name within a GroupBlock. Note this does not effect local
/// variable numbering, which is global over the whole method.
type ILDebugMapping =
{ localNum: int;
localName: string; }
member LocalVarIndex : int
member Name: string
/// ILCode
///
/// The code for a method is made up of a "code" object. Each "code"
/// object gives the contents of the method in a "semi-structured" form, i.e.
/// 1. The structure implicit in the IL exception handling tables
/// has been made explicit
/// 2. No relative offsets are used in the code: all branches and
/// switch targets are made explicit as labels.
/// 3. All "fallthroughs" from one basic block to the next have
/// been made explicit, by adding extra "branch" instructions to
/// the end of basic blocks which simply fallthrough to another basic
/// block.
///
/// You can convert a straight-line sequence of instructions to structured
/// code by using build_code and
/// Most of the interesting code is contained in BasicBlocks. If you're
/// just interested in getting started with the format then begin
/// by simply considering methods which do not contain any branch
/// instructions, or methods which do not contain any exception handling
/// constructs.
///
/// The above format has the great advantage that you can insert and
/// delete new code blocks without needing to fixup relative offsets
/// or exception tables.
///
/// ILBasicBlock(bblock)
/// See above
///
/// GroupBlock(localDebugInfo, blocks)
/// A set of blocks, with interior branching between the blocks. For example
/// B1: ldarg 1
/// br B2
///
/// B2: pop
/// ret
///
/// will be two basic blocks
/// let b1 = ILBasicBlock("B1", [| I_ldarg(1); I_br("B2") |])
/// let b2 = ILBasicBlock("B2", [| I_arith(AI_pop); I_ret |])
/// GroupBlock([], [b1; b2])
///
/// A GroupBlock can include a list of debug info records for locally
/// scoped local variables. These indicate that within the given blocks
/// the given local variables are used for the given Debug info
/// will only be recorded for local variables
/// declared in these nodes, and the local variable will only appear live
/// in the debugger for the instructions covered by this node. So if you
/// omit or erase these nodes then no debug info will be emitted for local
/// variables. If necessary you can have one outer ScopeBlock which specifies
/// the information for all the local variables
///
/// Not all the destination labels used within a group of blocks need
/// be satisfied by that group alone. For example, the interior "try" code
/// of "try"-"catch" construct may be:
/// B1: ldarg 1
/// br B2
///
/// B2: pop
/// leave B3
///
/// Again there will be two basic blocks grouped together:
/// let b1 = ILBasicBlock("B1", [| I_ldarg(1); I_br("B2") |])
/// let b2 = ILBasicBlock("B2", [| I_arith(AI_pop); I_leave("B3") |])
/// GroupBlock([], [b1; b2])
/// Here the code must be embedded in a method where "B3" is a label
/// somewhere in the method.
///
/// RestrictBlock(labels,code)
/// This block hides labels, i.e. the given set of labels represent
/// wiring which is purely internal to the given code block, and may not
/// be used as the target of a branch by any blocks which this block
/// is placed alongside.
///
/// For example, if a method is made up of:
/// B1: ldarg 1
/// br B2
///
/// B2: ret
///
/// then the label "B2" is internal. The overall code will
/// be two basic blocks grouped together, surrounded by a RestrictBlock.
/// The label "B1" is then the only remaining visible entry to the method
/// and execution will begin at that label.
///
/// let b1 = ILBasicBlock("B1", [| I_ldarg(1); I_br("B2") |])
/// let b2 = ILBasicBlock("B2", [| I_arith(AI_pop); I_leave("B3") |])
/// let gb1 = GroupBlock([], [b1; b2])
/// RestrictBlock(["B2"], gb1)
///
/// RestrictBlock is necessary to build well-formed code.
///
/// TryBlock(trycode,seh)
///
/// A try-catch, try-finally or try-fault block.
/// If an exception is raised while executing
/// an instruction in 'trycode' then the exception handler given by
/// 'seh' is executed.
///
/// Well-formedness conditions for code:
///
/// Well-formed code includes nodes which explicitly "hide" interior labels.
/// For example, the code object for a method may have only one entry
/// label which is not hidden, and this label will be the label where
/// execution begins.
///
/// Both filter and catch blocks must have one
/// and only one entry. These entry labels are not visible
/// outside the filter and catch blocks. Filter has no
/// exits (it always uses endfilter), catch may have exits.
/// The "try" block can have multiple entries, i.e. you can branch
/// into a try from outside. They can have multiple exits, each of
/// which will be a "leave".
///
type ILCode =
| ILBasicBlock of ILBasicBlock
| GroupBlock of ILDebugMapping list * ILCode list
| RestrictBlock of ILCodeLabel list * ILCode
| TryBlock of ILCode * ILExceptionBlock
/// The 'seh' specification can have several forms:
///
/// FilterCatchBlock
/// A multi-try-filter-catch block. Execute the
/// filters in order to determine which 'catch' block to catch the
/// exception with. There are two kinds of filters - one for
/// filtering exceptions by type and one by an instruction sequence.
/// Note that filter blocks can't contain any exception blocks.
///
and ILExceptionBlock =
| FaultBlock of ILCode
| FinallyBlock of ILCode
| FilterCatchBlock of (ILFilterBlock * ILCode) list
and ILFilterBlock =
| TypeFilter of ILType
| CodeFilter of ILCode
val labels_of_code: ILCode -> ILCodeLabel list
val unique_entry_of_code: ILCode -> ILCodeLabel
/// Field Init
type ILFieldInit =
| FieldInit_string of string
| FieldInit_bool of bool
| FieldInit_char of uint16
| FieldInit_int8 of sbyte
| FieldInit_int16 of int16
| FieldInit_int32 of int32
| FieldInit_int64 of int64
| FieldInit_uint8 of byte
| FieldInit_uint16 of uint16
| FieldInit_uint32 of uint32
| FieldInit_uint64 of uint64
| FieldInit_single of single
| FieldInit_double of double
| FieldInit_ref
/// Native Types, for marshalling to the native C interface.
/// These are taken directly from the ILASM syntax, and don't really
/// correspond yet to the ECMA Spec (Partition II, 7.4).
type ILNativeType =
| NativeType_empty
| NativeType_custom of Guid * string * string * byte[] (* guid,nativeTypeName,custMarshallerName,cookieString *)
| NativeType_fixed_sysstring of int32
| NativeType_fixed_array of int32
| NativeType_currency
| NativeType_lpstr
| NativeType_lpwstr
| NativeType_lptstr
| NativeType_byvalstr
| NativeType_tbstr
| NativeType_lpstruct
| NativeType_struct
| NativeType_void
| NativeType_bool
| NativeType_int8
| NativeType_int16
| NativeType_int32
| NativeType_int64
| NativeType_float32
| NativeType_float64
| NativeType_unsigned_int8
| NativeType_unsigned_int16
| NativeType_unsigned_int32
| NativeType_unsigned_int64
| NativeType_array of ILNativeType option * (int32 * int32 option) option (* optional idx of parameter giving size plus optional additive i.e. num elems *)
| NativeType_int
| NativeType_unsigned_int
| NativeType_method
| NativeType_as_any
| (* COM interop *) NativeType_bstr
| (* COM interop *) NativeType_iunknown
| (* COM interop *) NativeType_idsipatch
| (* COM interop *) NativeType_interface
| (* COM interop *) NativeType_error
| (* COM interop *) NativeType_safe_array of ILNativeVariantType * string option
| (* COM interop *) NativeType_ansi_bstr
| (* COM interop *) NativeType_variant_bool
and ILNativeVariantType =
| VariantType_empty
| VariantType_null
| VariantType_variant
| VariantType_currency
| VariantType_decimal
| VariantType_date
| VariantType_bstr
| VariantType_lpstr
| VariantType_lpwstr
| VariantType_iunknown
| VariantType_idispatch
| VariantType_safearray
| VariantType_error
| VariantType_hresult
| VariantType_carray
| VariantType_userdefined
| VariantType_record
| VariantType_filetime
| VariantType_blob
| VariantType_stream
| VariantType_storage
| VariantType_streamed_object
| VariantType_stored_object
| VariantType_blob_object
| VariantType_cf
| VariantType_clsid
| VariantType_void
| VariantType_bool
| VariantType_int8
| VariantType_int16
| VariantType_int32
| VariantType_int64
| VariantType_float32
| VariantType_float64
| VariantType_unsigned_int8
| VariantType_unsigned_int16
| VariantType_unsigned_int32
| VariantType_unsigned_int64
| VariantType_ptr
| VariantType_array of ILNativeVariantType
| VariantType_vector of ILNativeVariantType
| VariantType_byref of ILNativeVariantType
| VariantType_int
| VariantType_unsigned_int
/// Local variables
type Local =
{ localType: ILType;
localPinned: bool }
member Type: ILType
member IsPinned: bool
val typ_of_local: Local -> ILType
/// IL method bodies
type ILMethodBody =
{ ilZeroInit: bool;
/// strictly speakin should be a uint16
ilMaxStack: int32;
ilNoInlining: bool;
ilLocals: Local list;
ilCode: ILCode;
ilSource: ILSourceMarker option }
/// Member Access
type ILMemberAccess =
| MemAccess_assembly
| MemAccess_compilercontrolled
| MemAccess_famandassem
| MemAccess_famorassem
| MemAccess_family
| MemAccess_private
| MemAccess_public
type ILAttributeElement =
/// Represents a custom attribute parameter of type 'string'. These may be null, in which case they are encoded in a special
/// way as indicated by Ecma-335 Partition II.
| CustomElem_string of string option
| CustomElem_bool of bool
| CustomElem_char of char
| CustomElem_int8 of sbyte
| CustomElem_int16 of int16
| CustomElem_int32 of int32
| CustomElem_int64 of int64
| CustomElem_uint8 of byte
| CustomElem_uint16 of uint16
| CustomElem_uint32 of uint32
| CustomElem_uint64 of uint64
| CustomElem_float32 of single
| CustomElem_float64 of double
| CustomElem_type of ILType
| CustomElem_tref of ILTypeRef
| CustomElem_array of ILAttributeElement list
/// Named args: values and flags indicating if they are fields or properties
type ILAttributeNamedArg = (string * ILType * bool * ILAttributeElement)
/// Custom attributes. See 'decode_il_attrib_data' for a helper to parse the byte[]
/// to ILAttributeElement's as best as possible.
type ILAttribute =
{ customMethod: ILMethodSpec;
customData: byte[] }
member Data: byte[]
member Method: ILMethodSpec
type ILAttributes
val dest_custom_attrs: ILAttributes -> ILAttribute list
/// Method parameters and return values
type ILParameter =
{ paramName: string option;
paramType: ILType;
paramDefault: ILFieldInit option;
/// Marshalling map for parameters. COM Interop only.
paramMarshal: ILNativeType option;
paramIn: bool;
paramOut: bool;
paramOptional: bool;
paramCustomAttrs: ILAttributes }
member Name: string option
member Type: ILType
member Default: ILFieldInit option
member Marshal: ILNativeType option
member IsIn: bool
member IsOut: bool
member IsOptional: bool
member CustomAttrs: ILAttributes;
val typs_of_params : ILParameter list -> ILType list
/// Method return values
type ILReturnValue =
{ returnMarshal: ILNativeType option;
returnType: ILType;
returnCustomAttrs: ILAttributes }
member Type: ILType
member Marshal: ILNativeType option
member CustomAttrs: ILAttributes
/// Security ILPermissions
///
/// Attached to various structures...
type ILSecurityAction =
| SecAction_request
| SecAction_demand
| SecAction_assert
| SecAction_deny
| SecAction_permitonly
| SecAction_linkcheck
| SecAction_inheritcheck
| SecAction_reqmin
| SecAction_reqopt
| SecAction_reqrefuse
| SecAction_prejitgrant
| SecAction_prejitdeny
| SecAction_noncasdemand
| SecAction_noncaslinkdemand
| SecAction_noncasinheritance
| SecAction_linkdemandchoice
| SecAction_inheritancedemandchoice
| SecAction_demandchoice
type ILPermission =
| PermissionSet of ILSecurityAction * byte[]
/// Abstract type equivalent to ILPermission list - use helpers
/// below to construct/destruct these
type ILPermissions
val dest_security_decls: ILPermissions -> ILPermission list
/// PInvoke attributes.
type PInvokeCallingConvention =
| PInvokeCallConvNone
| PInvokeCallConvCdecl
| PInvokeCallConvStdcall
| PInvokeCallConvThiscall
| PInvokeCallConvFastcall
| PInvokeCallConvWinapi
type PInvokeCharEncoding =
| PInvokeEncodingNone
| PInvokeEncodingAnsi
| PInvokeEncodingUnicode
| PInvokeEncodingAuto
type PInvokeCharBestFit =
| PInvokeBestFitUseAssem
| PInvokeBestFitEnabled
| PInvokeBestFitDisabled
type PInvokeThrowOnUnmappableChar =
| PInvokeThrowOnUnmappableCharUseAssem
| PInvokeThrowOnUnmappableCharEnabled
| PInvokeThrowOnUnmappableCharDisabled
type PInvokeMethod =
{ pinvokeWhere: ILModuleRef;
pinvokeName: string;
pinvokeCallconv: PInvokeCallingConvention;
PInvokeCharEncoding: PInvokeCharEncoding;
pinvokeNoMangle: bool;
pinvokeLastErr: bool;
PInvokeThrowOnUnmappableChar: PInvokeThrowOnUnmappableChar;
PInvokeCharBestFit: PInvokeCharBestFit }
member Where: ILModuleRef
member Name: string
member CallingConv: PInvokeCallingConvention
member CharEncoding: PInvokeCharEncoding
member NoMangle: bool
member LastError: bool
member ThrowOnUnmappableChar: PInvokeThrowOnUnmappableChar
member CharBestFit: PInvokeCharBestFit
/// [OverridesSpec] - refer to a method declaration in a superclass
/// or superinterface. Used for overriding/method impls. Includes
/// a type for the parent for the same reason that a method specs
/// includes the type of the enclosing type, i.e. the type
/// gives the "ILGenericArgs" at which the parent type is being used.
type OverridesSpec =
| OverridesSpec of ILMethodRef * ILType
member MethodRef: ILMethodRef
member EnclosingType: ILType
type ILMethodVirtualInfo =
{ virtFinal: bool;
virtNewslot: bool;
virtStrict: bool; (* mdCheckAccessOnOverride *)
virtAbstract: bool; }
member IsFinal: bool
member IsNewSlot: bool
member IsCheckAccessOnOverride: bool
member IsAbstract: bool
type MethodKind =
| MethodKind_static
| MethodKind_cctor
| MethodKind_ctor
| MethodKind_nonvirtual
| MethodKind_virtual of ILMethodVirtualInfo
type MethodBody =
| MethodBody_il of ILMethodBody
| MethodBody_pinvoke of PInvokeMethod (* platform invoke to native *)
| MethodBody_abstract
| MethodBody_native
type MethodCodeKind =
| MethodCodeKind_il
| MethodCodeKind_native
| MethodCodeKind_runtime
type LazyMethodBody
val dest_mbody : LazyMethodBody -> MethodBody
/// Method definitions.
///
/// There are several different flavours of methods (constructors,
/// abstract, virtual, static, instance, class constructors). There
/// is no perfect factorization of these as the combinations are not
/// independent.
type ILMethodDef =
{ mdName: string;
mdKind: MethodKind;
mdCallconv: ILCallingConv;
mdParams: ILParameter list;
mdReturn: ILReturnValue;
mdAccess: ILMemberAccess;
mdBody: LazyMethodBody;
mdCodeKind: MethodCodeKind;
mdInternalCall: bool;
mdManaged: bool;
mdForwardRef: bool;
mdSecurityDecls: ILPermissions;
/// Note: some methods are marked "HasSecurity" even if there are no permissions attached, e.g. if they use SuppressUnmanagedCodeSecurityAttribute
mdHasSecurity: bool;
mdEntrypoint:bool;
mdReqSecObj: bool;
mdHideBySig: bool;
mdSpecialName: bool;
/// The method is exported to unmanaged code using COM interop.
mdUnmanagedExport: bool;
mdSynchronized: bool;
mdPreserveSig: bool;
/// .NET 2.0 feature: SafeHandle finalizer must be run
mdMustRun: bool;
mdExport: (int32 * string option) option;
mdVtableEntry: (int32 * int32) option;
mdGenericParams: ILGenericParameterDefs;
mdCustomAttrs: ILAttributes; }
member Name: string;
//mdKind: MethodKind;
//Body: LazyMethodBody;
//CodeKind: MethodCodeKind;
member CallingConv: ILCallingConv;
member Parameters: ILParameter list;
member ParameterTypes: ILType list;
member Return: ILReturnValue;
member Access: ILMemberAccess;
member IsInternalCall: bool;
member IsManaged: bool;
member IsForwardRef: bool;
member SecurityDecls: ILPermissions;
/// Note: some methods are marked "HasSecurity" even if there are no permissions attached, e.g. if they use SuppressUnmanagedCodeSecurityAttribute
member HasSecurity: bool;
member IsEntrypoint:bool;
member IsReqSecObj: bool;
member IsHideBySig: bool;
/// The method is exported to unmanaged code using COM interop.
member IsUnmanagedExport: bool;
member IsSynchronized: bool;
member IsPreserveSig: bool;
/// Whidbey feature: SafeHandle finalizer must be run
member IsMustRun: bool;
//member Export: (int32 * string option) option;
//member VtableEntry: (int32 * int32) option;
member GenericParams: ILGenericParameterDefs;
member CustomAttrs: ILAttributes;
member IsIL : bool
member Code : ILCode option
member Locals : Local list
member IsNoInline : bool
member MaxStack : int32
member IsZeroInit : bool
/// .cctor methods. The predicates (IsClassInitializer,IsConstructor,IsStatic,IsNonVirtualInstance,IsVirtual) form a complete, non-overlapping classification of this type
member IsClassInitializer: bool
/// .ctor methods. The predicates (IsClassInitializer,IsConstructor,IsStatic,IsNonVirtualInstance,IsVirtual) form a complete, non-overlapping classification of this type
member IsConstructor: bool
/// static methods. The predicates (IsClassInitializer,IsConstructor,IsStatic,IsNonVirtualInstance,IsVirtual) form a complete, non-overlapping classification of this type
member IsStatic: bool
/// instance methods that are not virtual. The predicates (IsClassInitializer,IsConstructor,IsStatic,IsNonVirtualInstance,IsVirtual) form a complete, non-overlapping classification of this type
member IsNonVirtualInstance: bool
/// instance methods that are virtual or abstract or implement an interface slot. The predicates (IsClassInitializer,IsConstructor,IsStatic,IsNonVirtualInstance,IsVirtual) form a complete, non-overlapping classification of this type
member IsVirtual: bool
member IsFinal: bool
member IsNewSlot: bool
member IsCheckAccessOnOverride : bool
member IsAbstract: bool
val ilmbody_of_mdef: ILMethodDef -> ILMethodBody
val callsig_of_mdef: ILMethodDef -> ILCallingSignature
/// Tables of methods. Logically equivalent to a list of methods but
/// the table is kept in a form optimized for looking up methods by
/// name and arity.
/// abstract type equivalent to [ILMethodDef list]
type ILMethodDefs
val dest_mdefs: ILMethodDefs -> ILMethodDef list
val find_mdefs_by_name: string -> ILMethodDefs -> ILMethodDef list
val find_mdefs_by_arity: string * int -> ILMethodDefs -> ILMethodDef list
/// Field definitions
type ILFieldDef =
{ fdName: string;
fdType: ILType;
fdStatic: bool;
fdAccess: ILMemberAccess;
fdData: byte[] option;
fdInit: ILFieldInit option;
fdOffset: int32 option;
fdSpecialName: bool;
fdMarshal: ILNativeType option;
fdNotSerialized: bool;
fdLiteral: bool ;
fdInitOnly: bool;
fdCustomAttrs: ILAttributes; }
member Name: string;
member Type: ILType;
member IsStatic: bool;
member Access: ILMemberAccess;
member Data: byte[] option;
member LiteralValue: ILFieldInit option;
/// The explicit offset in byte[] when explicit layout is used.
member Offset: int32 option;
member Marshal: ILNativeType option;
member NotSerialized: bool;
member IsLiteral: bool ;
member IsInitOnly: bool;
member CustomAttrs: ILAttributes;
val typ_of_fdef : ILFieldDef -> ILType
val name_of_fdef: ILFieldDef -> string
/// Tables of fields. Logically equivalent to a list of fields but
/// the table is kept in a form optimized for looking up fields by
/// name.
type ILFieldDefs
val dest_fdefs: ILFieldDefs -> ILFieldDef list
val filter_fdefs: (ILFieldDef -> bool) -> ILFieldDefs -> ILFieldDefs
val find_fdefs: string -> ILFieldDefs -> ILFieldDef list
/// Event definitions
type ILEventDef =
{ eventType: ILType option;
eventName: string;
eventRTSpecialName: bool;
eventSpecialName: bool;
eventAddOn: ILMethodRef;
eventRemoveOn: ILMethodRef;
eventFire: ILMethodRef option;
eventOther: ILMethodRef list;
eventCustomAttrs: ILAttributes; }
member Type: ILType option;
member Name: string;
member AddMethod: ILMethodRef;
member RemoveMethod: ILMethodRef;
member FireMethod: ILMethodRef option;
member OtherMethods: ILMethodRef list;
member CustomAttrs: ILAttributes;
/// Table of those events in a type definition.
type ILEventDefs
val dest_edefs: ILEventDefs -> ILEventDef list
val filter_edefs: (ILEventDef -> bool) -> ILEventDefs -> ILEventDefs
val find_edefs: string -> ILEventDefs -> ILEventDef list
/// Property definitions
type ILPropertyDef =
{ propName: string;
propRTSpecialName: bool;
propSpecialName: bool;
propSet: ILMethodRef option;
propGet: ILMethodRef option;
propCallconv: ILThisConvention;
propType: ILType;
propInit: ILFieldInit option;
propArgs: ILType list;
propCustomAttrs: ILAttributes; }
member Name: string;
member SetMethod: ILMethodRef option;
member GetMethod: ILMethodRef option;
member CallingConv: ILThisConvention;
member Type: ILType;
member Init: ILFieldInit option;
member Args: ILType list;
member CustomAttrs: ILAttributes;
/// Table of those properties in a type definition.
type PropertyDefs
val dest_pdefs: PropertyDefs -> ILPropertyDef list
val filter_pdefs: (ILPropertyDef -> bool) -> PropertyDefs -> PropertyDefs
val find_pdefs: string -> PropertyDefs -> ILPropertyDef list
/// Method Impls
///
/// If there is an entry (pms --&gt; ms) in this table, then method [ms]
/// is used to implement method [pms] for the purposes of this class
/// and its subclasses.
type ILMethodImplDef =
{ mimplOverrides: OverridesSpec;
mimplOverrideBy: ILMethodSpec }
type ILMethodImplDefs
val dest_mimpls: ILMethodImplDefs -> ILMethodImplDef list
/// Type Layout information
type ILTypeDefLayout =
| TypeLayout_auto
| TypeLayout_sequential of ILTypeDefLayoutInfo
| TypeLayout_explicit of ILTypeDefLayoutInfo
and ILTypeDefLayoutInfo =
{ typeSize: int32 option;
typePack: uint16 option }
member Size: int32 option
member Pack: uint16 option
/// Type init semantics
type ILTypeDefInitSemantics =
| TypeInit_beforefield
| TypeInit_beforeany
/// Default Unicode encoding for P/Invoke within a type
type ILDefaultPInvokeEncoding =
| TypeEncoding_ansi
| TypeEncoding_autochar
| TypeEncoding_unicode
/// Type Access
type ILTypeDefAccess =
| TypeAccess_public
| TypeAccess_private
| TypeAccess_nested of ILMemberAccess
/// A categorization of type definitions into "kinds"
(*-------------------------------------------------------------------
*
* A note for the nit-picky.... In theory, the "kind" of a type
* definition can only be partially determined prior to binding.
* For example, you cannot really, absolutely tell if a type is
* really, absolutely a value type until you bind the
* super class and test it for type equality against System.ValueType.
* However, this is unbearably annoying, as it means you
* have to load "mscorlib" and perform bind operations
* in order to be able to determine some quite simple
* things. So we approximate by simply looking at the name
* of the superclass when loading.
* ------------------------------------------------------------------ *)
type ILTypeDefKind =
| TypeDef_class
| TypeDef_valuetype
| TypeDef_interface
| TypeDef_enum
| TypeDef_delegate
(* FOR EXTENSIONS, e.g. MS-ILX *)
| TypeDef_other of IlxExtensionTypeKind
(* ------------------------------------------------------------------
* Type Names
*
* The name of a type stored in the tdName field is as follows:
* - For outer types it is, for example, System.String, i.e.
* the namespace followed by the type name.
* - For nested types, it is simply the type name. The namespace
* must be gleaned from the context in which the nested type
* lies.
* ------------------------------------------------------------------ *)
type NamespaceAndTypename = string list * string
val split_namespace: string -> string list
val split_namespace_array: string -> string[]
/// The [split_type_name] utility helps you split a string representing
/// a type name into the leading namespace elements (if any), the
/// names of any nested types and the type name itself. This function
/// memoizes and interns the splitting of the namespace portion of
/// the type name.
val split_type_name: string -> NamespaceAndTypename
val split_type_name_array: string -> string[] * string
/// Type Definitions
///
/// As for methods there are several important constraints not encoded
/// in the type definition below, for example that the super class of
/// an interface type is always None, or that enumerations always
/// have a very specific form.
type ILTypeDef =
{ tdKind: ILTypeDefKind;
tdName: string;
tdGenericParams: ILGenericParameterDefs;
tdAccess: ILTypeDefAccess;
tdAbstract: bool;
tdSealed: bool;
tdSerializable: bool;
tdComInterop: bool; (* Class or interface generated for COM interop *)
tdLayout: ILTypeDefLayout;
tdSpecialName: bool;
tdEncoding: ILDefaultPInvokeEncoding;
tdNested: ILTypeDefs;
tdImplements: ILType list;
tdExtends: ILType option;
tdMethodDefs: ILMethodDefs;
tdSecurityDecls: ILPermissions;
tdHasSecurity: bool; (* Note: some classes are marked "HasSecurity" even if there are no permissions attached, e.g. if they use SuppressUnmanagedCodeSecurityAttribute *)
tdFieldDefs: ILFieldDefs;
tdMethodImpls: ILMethodImplDefs;
tdInitSemantics: ILTypeDefInitSemantics;
tdEvents: ILEventDefs;
tdProperties: PropertyDefs;
tdCustomAttrs: ILAttributes; }
member IsClass: bool;
member IsValueType: bool;
member IsInterface: bool;
member IsEnum: bool;
member IsDelegate: bool;
member Name: string;
member GenericParams: ILGenericParameterDefs;
member Access: ILTypeDefAccess;
member IsAbstract: bool;
member IsSealed: bool;
member IsSerializable: bool;
/// Class or interface generated for COM interop
member IsComInterop: bool;
member Layout: ILTypeDefLayout;
member IsSpecialName: bool;
member Encoding: ILDefaultPInvokeEncoding;
member NestedTypes: ILTypeDefs;
member Implements: ILType list;
member Extends: ILType option;
member SecurityDecls: ILPermissions;
/// Note: some classes are marked "HasSecurity" even if there are no permissions attached, e.g. if they use SuppressUnmanagedCodeSecurityAttribute
member HasSecurity: bool;
member Fields: ILFieldDefs;
member Methods: ILMethodDefs;
member MethodImpls: ILMethodImplDefs;
member Events: ILEventDefs;
member Properties: PropertyDefs;
member InitSemantics: ILTypeDefInitSemantics;
member CustomAttrs: ILAttributes;
/// Tables of named type definitions. The types and table may contain on-demand
/// (lazy) computations, e.g. the actual reading of some aspects
/// of a type definition may be delayed if the reader being used supports
/// this.
///
/// This is an abstract type equivalent to "ILTypeDef list"
and ILTypeDefs
val is_value_or_enum_tdef: ILTypeDef -> bool
/// Find the method definition corresponding to the given property or
/// event operation. These are always in the same class as the property
/// or event. This is useful especially if your code is not using the Ilbind
/// API to bind references.
val resolve_mref: ILTypeDef -> ILMethodRef -> ILMethodDef
val iter_tdefs: (ILTypeDef -> unit) -> ILTypeDefs -> unit
val dest_tdefs: ILTypeDefs -> ILTypeDef list
/// Calls to [find_tdef] will result in any laziness in the overall
/// set of ILTypeDefs being read in in addition
/// to the details for the type found, but the remaining individual
/// type definitions will not be read.
val find_tdef: string -> ILTypeDefs -> ILTypeDef
val dest_lazy_tdefs: ILTypeDefs -> (string list * string * ILAttributes * ILTypeDef Lazy.t) list
val tname_for_toplevel: string
val is_toplevel_tname: string -> bool
val ungenericize_tname: string -> string (* e.g. List`1 --> List *)
/// "Classes Elsewhere" - classes in auxiliary modules.
///
/// Manifests include declarations for all the classes in an
/// assembly, regardless of which module they are in.
///
/// The ".class extern" construct describes so-called exported types --
/// these are public classes defined in the auxiliary modules of this assembly,
/// i.e. modules other than the manifest-carrying module.
///
/// For example, if you have a two-module
/// assembly (A.DLL and B.DLL), and the manifest resides in the A.DLL,
/// then in the manifest all the public classes declared in B.DLL should
/// be defined as exported types, i.e., as ".class extern". The public classes
/// defined in A.DLL should not be defined as ".class extern" -- they are
/// already available in the manifest-carrying module. The union of all
/// public classes defined in the manifest-carrying module and all
/// exported types defined there is the set of all classes exposed by
/// this assembly. Thus, by analysing the metadata of the manifest-carrying
/// module of an assembly, you can identify all the classes exposed by
/// this assembly, and where to find them.
///
/// Nested classes found in external modules should also be located in
/// this table, suitably nested inside another "ILExportedType"
/// definition.
/// these are only found in the "Nested" field of ILExportedType objects
type ILNestedExportedType =
{ nestedExportedTypeName: string;
nestedExportedTypeAccess: ILMemberAccess;
nestedExportedTypeNested: ILNestedExportedTypes;
nestedExportedTypeCustomAttrs: ILAttributes }
and ILNestedExportedTypes
/// these are only found in the ILExportedTypes table in the manifest
type ILExportedType =
{ exportedTypeScope: ILScopeRef;
/// [Namespace.]Name
exportedTypeName: string;
exportedTypeForwarder: bool;
exportedTypeAccess: ILTypeDefAccess;
exportedTypeNested: ILNestedExportedTypes;
exportedTypeCustomAttrs: ILAttributes }
member ScopeRef: ILScopeRef
member IsForwarder: bool
member Name: string
member Access: ILTypeDefAccess
member Nested: ILNestedExportedTypes
member CustomAttrs: ILAttributes
type ILExportedTypes
val dest_nested_exported_types: ILNestedExportedTypes -> ILNestedExportedType list
val dest_exported_types: ILExportedTypes -> ILExportedType list
val find_exported_type: string -> ILExportedTypes -> ILExportedType
type ILResourceAccess =
| Resource_public
| Resource_private
type ILResourceLocation =
| Resource_local of (unit -> byte[]) (* resources may be re-read each time this function is called *)
| Resource_file of ILModuleRef * int32
| Resource_assembly of ILAssemblyRef
/// "Manifest ILResources" are chunks of resource data, being one of:
/// - the data section of the current module (byte[] of resource given directly)
/// - in an external file in this assembly (offset given in the ILResourceLocation field)
/// - as a resources in another assembly of the same name.
type ILResource =
{ resourceName: string;
resourceWhere: ILResourceLocation;
resourceAccess: ILResourceAccess;
resourceCustomAttrs: ILAttributes }
member Name: string
member Location: ILResourceLocation
member Access: ILResourceAccess
member CustomAttrs: ILAttributes
/// Table of resources in a module
type ILResources
val dest_resources: ILResources -> ILResource list
type ILAssemblyLongevity =
| LongevityUnspecified
| LongevityLibrary
| LongevityPlatformAppDomain
| LongevityPlatformProcess
| LongevityPlatformSystem
/// The main module of an assembly is a module plus some manifest information.
type ILAssemblyManifest =
{ manifestName: string;
manifestAuxModuleHashAlgorithm: int32;
manifestSecurityDecls: ILPermissions;
manifestPublicKey: byte[] option;
manifestVersion: ILVersionInfo option;
manifestLocale: Locale option;
manifestCustomAttrs: ILAttributes;
manifestLongevity: ILAssemblyLongevity;
manifestDisableJitOptimizations: bool;
manifestJitTracking: bool;
manifestRetargetable: bool;
manifestExportedTypes: ILExportedTypes;
manifestEntrypointElsewhere: ILModuleRef option;
}
member Name: string;
/// This is ID of the algorithm used for the hashes of auxiliary
/// files in the assembly. These hashes are stored in the
/// ILModuleRef.Hash fields of this assembly. These are not cryptographic
/// hashes: they are simple file hashes. The algorithm is normally
/// 0x00008004 indicating the SHA1 hash algorithm.
member AuxModuleHashAlgorithm: int32;
member SecurityDecls: ILPermissions;
/// This is the public key used to sign this
/// assembly (the signature itself is stored elsewhere: see the
/// binary format, and may not have been written if delay signing
/// is used). (member Name, member PublicKey) forms the full
/// public name of the assembly.
member PublicKey: byte[] option;
member Version: ILVersionInfo option;
member Locale: Locale option;
member CustomAttrs: ILAttributes;
member AssemblyLongevity: ILAssemblyLongevity;
member DisableJitOptimizations: bool;
member JitTracking: bool;
member Retargetable: bool;
/// Records the types impemented by this asssembly in auxiliary
/// modules.
member ExportedTypes: ILExportedTypes;
/// Records whether the entrypoint resides in another module.
member EntrypointElsewhere: ILModuleRef option;
/// One module in the "current" assembly, either a main-module or
/// an auxiliary module. The main module will have a manifest.
///
/// An assembly is built by joining together a "main" module plus
/// several auxiliary modules.
type ILModuleDef =
{ modulManifest: ILAssemblyManifest option;
modulCustomAttrs: ILAttributes;
modulName: string;
modulTypeDefs: ILTypeDefs;
modulSubSystem: int32;
modulDLL: bool;
modulILonly: bool;
modulPlatform: ILPlatform option;
modul32bit: bool;
modul64bit: bool;
modulVirtAlignment: int32;
modulPhysAlignment: int32;
modulImageBase: int32;
modulResources: ILResources;
modulNativeResources: byte[] Lazy.t list; (* e.g. win86 resources, as the exact contents of a .res or .obj file *)
(* modulFixups: fixups; *) }
member Manifest: ILAssemblyManifest option;
member ManifestOfAssembly: ILAssemblyManifest
member CustomAttrs: ILAttributes;
member Name: string;
member TypeDefs: ILTypeDefs;
member SubSystemFlags: int32;
member IsDLL: bool;
member IsILOnly: bool;
member Platform: ILPlatform option;
member Is32Bit: bool;
member Is64Bit: bool;
member VirtualAlignment: int32;
member PhysicalAlignment: int32;
member ImageBase: int32;
member Resources: ILResources;
member NativeResources: byte[] Lazy.t list
val module_is_mainmod: ILModuleDef -> bool
val assname_of_mainmod: ILModuleDef -> string
// ====================================================================
// PART 2
//
// Making metadata. Where no explicit constructor
// is given, you should create the concrete datatype directly,
// e.g. by filling in all appropriate record fields.
// ==================================================================== *)
/// A table of common references to items in mscorlib. Version-neutral references
/// can be generated using ecmaILGlobals. If you have already loaded a particular
/// version of mscorlib you should reference items via an ILGlobals for that particular
/// version of mscorlib built using mk_ILGlobals.
[<StructuralEquality(false); StructuralComparison(false)>]
type ILGlobals =
{ mscorlib_scoref: ILScopeRef;
mscorlibAssemblyName: string;
tref_Object: ILTypeRef
; tspec_Object: ILTypeSpec
; typ_Object: ILType
; tref_String: ILTypeRef
; typ_String: ILType
; typ_StringBuilder: ILType
; typ_AsyncCallback: ILType
; typ_IAsyncResult: ILType
; typ_IComparable: ILType
; tref_Type: ILTypeRef
; typ_Type: ILType
; tref_Missing: ILTypeRef
; typ_Missing: ILType
; typ_Activator: ILType
; typ_Delegate: ILType
; typ_ValueType: ILType
; typ_Enum: ILType
; tspec_TypedReference: ILTypeSpec
; typ_TypedReference: ILType
; typ_MulticastDelegate: ILType
; typ_Array: ILType
; tspec_Int64: ILTypeSpec
; tspec_UInt64: ILTypeSpec
; tspec_Int32: ILTypeSpec
; tspec_UInt32: ILTypeSpec
; tspec_Int16: ILTypeSpec
; tspec_UInt16: ILTypeSpec
; tspec_SByte: ILTypeSpec
; tspec_Byte: ILTypeSpec
; tspec_Single: ILTypeSpec
; tspec_Double: ILTypeSpec
; tspec_IntPtr: ILTypeSpec
; tspec_UIntPtr: ILTypeSpec
; tspec_Char: ILTypeSpec
; tspec_Bool: ILTypeSpec
; typ_int8: ILType
; typ_int16: ILType
; typ_int32: ILType
; typ_int64: ILType
; typ_uint8: ILType
; typ_uint16: ILType
; typ_uint32: ILType
; typ_uint64: ILType
; typ_float32: ILType
; typ_float64: ILType
; typ_bool: ILType
; typ_char: ILType
; typ_IntPtr: ILType
; typ_UIntPtr: ILType
; typ_RuntimeArgumentHandle: ILType
; typ_RuntimeTypeHandle: ILType
; typ_RuntimeMethodHandle: ILType
; typ_RuntimeFieldHandle: ILType
; typ_Byte: ILType
; typ_Int16: ILType
; typ_Int32: ILType
; typ_Int64: ILType
; typ_SByte: ILType
; typ_UInt16: ILType
; typ_UInt32: ILType
; typ_UInt64: ILType
; typ_Single: ILType
; typ_Double: ILType
; typ_Bool: ILType
; typ_Char: ILType
; typ_SerializationInfo: ILType
; typ_StreamingContext: ILType
; tref_SecurityPermissionAttribute : ILTypeRef
; tspec_Exception: ILTypeSpec
; typ_Exception: ILType }
/// Build the table of commonly used references given a ILScopeRef for mscorlib.
val mk_ILGlobals : ILScopeRef -> string option -> ILGlobals
/// When writing a binary the fake "toplevel" type definition (called <Module>)
/// must come first. [dest_tdefs_with_toplevel_first] puts it first, and
/// creates it in the returned list as an empty typedef if it
/// doesn't already exist.
val dest_tdefs_with_toplevel_first: ILGlobals -> ILTypeDefs -> ILTypeDef list
/// Note: not all custom attribute data can be decoded without binding types. In particular
/// enums must be bound in order to discover the size of the underlying integer.
/// The following assumes enums have size int32.
/// It also does not completely decode System.Type attributes
val decode_il_attrib_data:
ILGlobals ->
ILAttribute ->
ILAttributeElement list * (* fixed args *)
ILAttributeNamedArg list (* named args: values and flags indicating if they are fields or properties *)
/// Generate simple references to assemblies and modules
val mk_simple_assref: string -> ILAssemblyRef
val mk_simple_modref: string -> ILModuleRef
val scoref_for_modname: string -> ILScopeRef
val mk_empty_gactuals: ILGenericArgs
val mk_tyvar_ty: uint16 -> ILType
/// Make type refs
val mk_nested_tref: ILScopeRef * string list * string -> ILTypeRef
val mk_tref: ILScopeRef * string -> ILTypeRef
val mk_tref_in_tref: ILTypeRef * string -> ILTypeRef
/// Make type specs
val mk_nongeneric_tspec: ILTypeRef -> ILTypeSpec
val mk_tspec: ILTypeRef * ILGenericArgs -> ILTypeSpec
/// Make types
val mk_typ: ILBoxity -> ILTypeSpec -> ILType
val mk_named_typ: ILBoxity -> ILTypeRef -> ILGenericArgs -> ILType
val mk_boxed_typ: ILTypeRef -> ILGenericArgs -> ILType
val mk_value_typ: ILTypeRef -> ILGenericArgs -> ILType
val mk_nongeneric_boxed_typ: ILTypeRef -> ILType
val mk_nongeneric_value_typ: ILTypeRef -> ILType
val mk_array_ty: ILType * ILArrayShape -> ILType
val mk_sdarray_ty: ILType -> ILType
/// Make method references and specs
val mk_mref: ILTypeRef * ILCallingConv * string * int * ILType list * ILType -> ILMethodRef
val mk_mspec: ILMethodRef * ILBoxity * ILGenericArgs * ILGenericArgs -> ILMethodSpec
val mk_mref_mspec_in_typ: ILMethodRef * ILType * ILGenericArgs -> ILMethodSpec
val mk_mspec_in_typ: ILType * ILCallingConv * string * ILType list * ILType * ILGenericArgs -> ILMethodSpec
/// Construct references to methods on a given type
val mk_nongeneric_mspec_in_typ: ILType * ILCallingConv * string * ILType list * ILType -> ILMethodSpec
/// Construct references to methods given a ILTypeSpec
val mk_mspec_in_tspec: ILTypeSpec * ILBoxity * ILCallingConv * string * ILType list * ILType * ILGenericArgs -> ILMethodSpec
val mk_nongeneric_mspec_in_tspec: ILTypeSpec * ILBoxity * ILCallingConv * string * ILType list * ILType -> ILMethodSpec
/// Construct references to instance methods
val mk_instance_mspec_in_tref: ILTypeRef * ILBoxity * string * ILType list * ILType * ILGenericArgs * ILGenericArgs -> ILMethodSpec
val mk_instance_mspec_in_tspec: ILTypeSpec * ILBoxity * string * ILType list * ILType * ILGenericArgs -> ILMethodSpec
val mk_instance_mspec_in_typ: ILType * string * ILType list * ILType * ILGenericArgs -> ILMethodSpec
val mk_instance_mspec_in_boxed_tspec: ILTypeSpec * string * ILType list * ILType * ILGenericArgs -> ILMethodSpec
val mk_instance_mspec_in_nongeneric_boxed_tref: ILTypeRef * string * ILType list * ILType * ILGenericArgs -> ILMethodSpec
/// Construct references to non-generic methods
val mk_nongeneric_mspec_in_tref: ILTypeRef * ILBoxity * ILCallingConv * string * ILType list * ILType * ILGenericArgs -> ILMethodSpec
val mk_nongeneric_mspec_in_nongeneric_tref: ILTypeRef * ILBoxity * ILCallingConv * string * ILType list * ILType -> ILMethodSpec
/// Construct references to non-generic instance methods
val mk_nongeneric_instance_mspec_in_tref: ILTypeRef * ILBoxity * string * ILType list * ILType * ILGenericArgs -> ILMethodSpec
val mk_nongeneric_instance_mspec_in_tspec: ILTypeSpec * ILBoxity * string * ILType list * ILType -> ILMethodSpec
val mk_nongeneric_instance_mspec_in_typ: ILType * string * ILType list * ILType -> ILMethodSpec
val mk_nongeneric_instance_mspec_in_boxed_tspec: ILTypeSpec * string * ILType list * ILType -> ILMethodSpec
val mk_nongeneric_instance_mspec_in_nongeneric_boxed_tref: ILTypeRef * string * ILType list * ILType -> ILMethodSpec
/// Construct references to static methods
val mk_static_mspec_in_nongeneric_boxed_tref: ILTypeRef * string * ILType list * ILType * ILGenericArgs -> ILMethodSpec
val mk_static_mspec_in_boxed_tspec: ILTypeSpec * string * ILType list * ILType * ILGenericArgs -> ILMethodSpec
val mk_static_mspec_in_typ: ILType * string * ILType list * ILType * ILGenericArgs -> ILMethodSpec
/// Construct references to static, non-generic methods
val mk_static_nongeneric_mspec_in_nongeneric_boxed_tref: ILTypeRef * string * ILType list * ILType -> ILMethodSpec
val mk_static_nongeneric_mspec_in_boxed_tspec: ILTypeSpec * string * ILType list * ILType -> ILMethodSpec
val mk_static_nongeneric_mspec_in_typ: ILType * string * ILType list * ILType -> ILMethodSpec
/// Construct references to toplevel methods in modules. Usually compiler generated.
val mk_toplevel_static_mspec: ILScopeRef -> string * ILType list * ILType * ILGenericArgs -> ILMethodSpec
val mk_toplevel_static_nongeneric_mspec: ILScopeRef -> string * ILType list * ILType -> ILMethodSpec
/// Construct references to constructors
val mk_ctor_mspec: ILTypeRef * ILBoxity * ILType list * ILGenericArgs -> ILMethodSpec
val mk_nongeneric_ctor_mspec: ILTypeRef * ILBoxity * ILType list -> ILMethodSpec
val mk_ctor_mspec_for_boxed_tspec: ILTypeSpec * ILType list -> ILMethodSpec
val mk_ctor_mspec_for_typ: ILType * ILType list -> ILMethodSpec
val mk_ctor_mspec_for_nongeneric_boxed_tref: ILTypeRef * ILType list -> ILMethodSpec
/// Construct references to fields
val mk_fref_in_tref: ILTypeRef * string * ILType -> ILFieldRef
val mk_fspec: ILFieldRef * ILType -> ILFieldSpec
val mk_fspec_in_typ: ILType * string * ILType -> ILFieldSpec
val mk_fspec_in_tspec: ILTypeSpec * ILBoxity * string * ILType -> ILFieldSpec
val mk_fspec_in_boxed_tspec: ILTypeSpec * string * ILType -> ILFieldSpec
val mk_fspec_in_nongeneric_boxed_tref: ILTypeRef * string * ILType -> ILFieldSpec
val mk_callsig: ILCallingConv * ILType list * ILType -> ILCallingSignature
/// Make generalized verions of possibly-generic types,
/// e.g. Given the ILTypeDef for List, return the type "List<T>".
val generalize_tref: ILTypeRef -> ILGenericParameterDef list -> ILTypeSpec
val gparam_of_gactual: ILType -> ILGenericParameterDef
val gparams_of_inst: ILGenericArgs -> ILGenericParameterDefs
val generalize_gparams: ILGenericParameterDefs -> ILGenericArgs
/// Make custom attributes
val mk_custom_attribute_mref:
ILGlobals
-> ILMethodSpec
* ILAttributeElement list (* fixed args: values and implicit types *)
* ILAttributeNamedArg list (* named args: values and flags indicating if they are fields or properties *)
-> ILAttribute
val mk_custom_attribute:
ILGlobals
-> ILTypeRef * ILType list *
ILAttributeElement list (* fixed args: values and implicit types *) *
ILAttributeNamedArg list (* named args: values and flags indicating if they are fields or properties *)
-> ILAttribute
val mk_permission_set : ILGlobals -> ILSecurityAction * (ILTypeRef * (string * ILType * ILAttributeElement) list) list -> ILPermission
/// Making code.
val check_code: ILCode -> ILCode
val generate_code_label: unit -> ILCodeLabel
val string_of_code_label : ILCodeLabel -> string
/// Make some code that is a straight line sequence of instructions.
/// The function will add a "return" if the last instruction is not an exiting instruction
val nonbranching_instrs_to_code: ILInstr list -> ILCode
/// Make some code that is a straight line sequence of instructions, then do
/// some control flow. The first code label is the entry label of the generated code.
val nonbranching_instrs_then: ILCodeLabel -> ILInstr list -> ILInstr -> ILCode
val nonbranching_instrs_then_br: ILCodeLabel -> ILInstr list -> ILCodeLabel -> ILCode
/// Make a basic block. The final instruction must be control flow
val nonbranching_instrs: ILCodeLabel -> ILInstr list -> ILCode
/// Some more primitive helpers
val mk_bblock: ILBasicBlock -> ILCode
val mk_group_block: ILCodeLabel list * ILCode list -> ILCode
/// Helpers for codegen: scopes for allocating new temporary variables.
type tmps
val alloc_tmp: tmps -> Local -> uint16
val new_tmps : int -> tmps
val get_tmps : tmps -> Local list
/// Derived functions for making some common patterns of instructions
val mk_normal_call: ILMethodSpec -> ILInstr
val mk_normal_callvirt: ILMethodSpec -> ILInstr
val mk_normal_callconstraint: ILType * ILMethodSpec -> ILInstr
val mk_normal_newobj: ILMethodSpec -> ILInstr
val mk_nongeneric_call_superclass_constructor: ILType list * ILTypeRef -> ILInstr list
val mk_call_superclass_constructor : ILType list * ILTypeSpec -> ILInstr list
val mk_normal_stfld: ILFieldSpec -> ILInstr
val mk_normal_stsfld: ILFieldSpec -> ILInstr
val mk_normal_ldsfld: ILFieldSpec -> ILInstr
val mk_normal_ldfld: ILFieldSpec -> ILInstr
val mk_normal_ldflda: ILFieldSpec -> ILInstr
val mk_normal_stind: ILBasicType -> ILInstr
val mk_normal_ldind: ILBasicType -> ILInstr
val mk_normal_cpind: ILBasicType -> ILInstr list
val mk_normal_ldobj: ILType -> ILInstr
val mk_normal_stobj: ILType -> ILInstr
val mk_ldc_i32: int32 -> ILInstr
val ldarg_0: ILInstr
val and_tailness: Tailcall -> bool -> Tailcall
/// Derived functions for making return, parameter and local variable
/// objects for use in method definitions.
val mk_param: string option * ILType -> ILParameter
val mk_unnamed_param: ILType -> ILParameter
val mk_named_param: string * ILType -> ILParameter
val mk_return: ILType -> ILReturnValue
val mk_local: ILType -> Local
/// Make a formal generic parameters
val mk_empty_gparams: ILGenericParameterDefs
/// Make method definitions
val mk_ilmbody: initlocals:bool * Local list * int * ILCode * ILSourceMarker option -> ILMethodBody
val mk_impl: bool * Local list * int * ILCode * ILSourceMarker option -> MethodBody
val mk_ctor: ILMemberAccess * ILParameter list * MethodBody -> ILMethodDef
val mk_nongeneric_nothing_ctor: ILSourceMarker option -> ILTypeRef -> ILParameter list -> ILMethodDef
val mk_static_mdef: ILGenericParameterDefs * string * ILMemberAccess * ILParameter list * ILReturnValue * MethodBody -> ILMethodDef
val mk_static_nongeneric_mdef: string * ILMemberAccess * ILParameter list * ILReturnValue * MethodBody -> ILMethodDef
val mk_cctor: MethodBody -> ILMethodDef
val mk_generic_virtual_mdef: string * ILMemberAccess * ILGenericParameterDefs * ILParameter list * ILReturnValue * MethodBody -> ILMethodDef
val mk_generic_instance_mdef: string * ILMemberAccess * ILGenericParameterDefs * ILParameter list * ILReturnValue * MethodBody -> ILMethodDef
val mk_virtual_mdef: string * ILMemberAccess * ILParameter list * ILReturnValue * MethodBody -> ILMethodDef
val mk_instance_mdef: string * ILMemberAccess * ILParameter list * ILReturnValue * MethodBody -> ILMethodDef
/// Make field definitions
val mk_instance_fdef: string * ILType * ILFieldInit option * ILMemberAccess -> ILFieldDef
val mk_static_fdef: string * ILType * ILFieldInit option * byte[] option * ILMemberAccess -> ILFieldDef
/// Make a type definition
val mk_generic_class: string * ILTypeDefAccess * ILGenericParameterDefs * ILType * ILType list * ILMethodDefs * ILFieldDefs * PropertyDefs * ILEventDefs * ILAttributes -> ILTypeDef
val mk_simple_tdef: ILGlobals -> string * ILTypeDefAccess * ILMethodDefs * ILFieldDefs * PropertyDefs * ILEventDefs * ILAttributes -> ILTypeDef
val mk_toplevel_tdef: ILGlobals -> ILMethodDefs * ILFieldDefs -> ILTypeDef
/// Make a type definition for a value type used to point to raw data.
/// These are useful when generating array initialization code
/// according to the
/// ldtoken field valuetype '<PrivateImplementationDetails>'/'$$struct0x6000127-1' '<PrivateImplementationDetails>'::'$$method0x6000127-1'
/// call void System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class System.Array,valuetype System.RuntimeFieldHandle)
/// idiom.
val mk_rawdata_vtdef: ILGlobals -> string * size:int32 * pack:uint16 -> ILTypeDef
/// Injecting code into existing code blocks. A branch will
/// be added from the given instructions to the (unique) entry of
/// the code, and the first instruction will be the new entry
/// of the method. The instructions should be non-branching.
val prepend_instrs_to_code: ILInstr list -> ILCode -> ILCode
val prepend_instrs_to_mdef: ILInstr list -> ILMethodDef -> ILMethodDef
/// Injecting initialization code into a class.
/// Add some code to the end of the .cctor for a type. Create a .cctor
/// if one doesn't exist already.
val prepend_instrs_to_cctor: ILInstr list -> ILSourceMarker option -> ILTypeDef -> ILTypeDef
/// Derived functions for making some simple constructors
val mk_storage_ctor: ILSourceMarker option * ILInstr list * ILTypeSpec * (string * ILType) list * ILMemberAccess -> ILMethodDef
val mk_simple_storage_ctor: ILSourceMarker option * ILTypeSpec option * ILTypeSpec * (string * ILType) list * ILMemberAccess -> ILMethodDef
val mk_simple_storage_ctor_with_param_names: ILSourceMarker option * ILTypeSpec option * ILTypeSpec * (string * string * ILType) list * ILMemberAccess -> ILMethodDef
val mk_delegate_mdefs: ILGlobals -> ILParameter list * ILReturnValue -> ILMethodDef list
/// Given a delegate type definition which lies in a particular scope,
/// make a reference to its constructor
val mk_ctor_mspec_for_delegate: ILGlobals -> ILTypeRef * ILGenericArgs * bool -> ILMethodSpec
/// The toplevel "class" for a module or assembly.
val typ_for_toplevel: ILScopeRef -> ILType
/// Making tables of custom attributes, etc.
val mk_custom_attrs: ILAttribute list -> ILAttributes
val mk_computed_custom_attrs: (unit -> ILAttribute list) -> ILAttributes
val mk_security_decls: ILPermission list -> ILPermissions
val mk_lazy_security_decls: (ILPermission list) Lazy.t -> ILPermissions
val mk_mbody : MethodBody -> LazyMethodBody
val mk_lazy_mbody : MethodBody Lazy.t -> LazyMethodBody
val mk_events: ILEventDef list -> ILEventDefs
val mk_lazy_events: (ILEventDef list) Lazy.t -> ILEventDefs
val mk_properties: ILPropertyDef list -> PropertyDefs
val mk_lazy_properties: (ILPropertyDef list) Lazy.t -> PropertyDefs
val mk_mdefs: ILMethodDef list -> ILMethodDefs
val mk_lazy_mdefs: (ILMethodDef list) Lazy.t -> ILMethodDefs
val add_mdef: ILMethodDef -> ILMethodDefs -> ILMethodDefs
val mk_fdefs: ILFieldDef list -> ILFieldDefs
val mk_lazy_fdefs: (ILFieldDef list) Lazy.t -> ILFieldDefs
val mk_mimpls: ILMethodImplDef list -> ILMethodImplDefs
val mk_lazy_mimpls: (ILMethodImplDef list) Lazy.t -> ILMethodImplDefs
val mk_tdefs: ILTypeDef list -> ILTypeDefs
/// Create table of types which is loaded/computed on-demand, and whose individual
/// elements are also loaded/computed on-demand. Any call to [dest_tdefs] will
/// result in the laziness being forced. Operations can examine the
/// custom attributes and name of each type in order to decide whether
/// to proceed with examining the other details of the type.
///
/// Note that individual type definitions may contain further delays
/// in their method, field and other tables.
val mk_lazy_tdefs: ((string list * string * ILAttributes * ILTypeDef Lazy.t) list) Lazy.t -> ILTypeDefs
val add_tdef: ILTypeDef -> ILTypeDefs -> ILTypeDefs
val mk_nested_exported_types: ILNestedExportedType list -> ILNestedExportedTypes
val mk_lazy_nested_exported_types: (ILNestedExportedType list) Lazy.t -> ILNestedExportedTypes
val mk_exported_types: ILExportedType list -> ILExportedTypes
val mk_lazy_exported_types: (ILExportedType list) Lazy.t -> ILExportedTypes
val mk_resources: ILResource list -> ILResources
val mk_lazy_resources: (ILResource list) Lazy.t -> ILResources
/// Making modules
val mk_simple_mainmod: assemblyName:string -> moduleName:string -> dll:bool -> ILTypeDefs -> int32 option -> Locale option -> int -> ILModuleDef
/// Default values for some of the strange flags in a module.
val default_modulSubSystem: int32
val default_modulVirtAlignment: int32
val default_modulPhysAlignment: int32
val default_modulImageBase: int32
/// Generate references to existing type definitions, method definitions
/// etc. Useful for generating references, e.g. to a class we're processing
/// Also used to reference type definitions that we've generated. [ILScopeRef]
/// is normally ScopeRef_local, unless we've generated the ILTypeDef in
/// an auxiliary module or are generating multiple assemblies at
/// once.
val tref_for_nested_tdef : ILScopeRef -> ILTypeDef list * ILTypeDef -> ILTypeRef
val tspec_for_nested_tdef: ILScopeRef -> ILTypeDef list * ILTypeDef -> ILTypeSpec
val mref_for_mdef : ILScopeRef -> ILTypeDef list * ILTypeDef -> ILMethodDef -> ILMethodRef
val fref_for_fdef : ILScopeRef -> ILTypeDef list * ILTypeDef -> ILFieldDef -> ILFieldRef
val mk_mref_to_mdef: ILTypeRef * ILMethodDef -> ILMethodRef
val mk_fref_to_fdef: ILTypeRef * ILFieldDef -> ILFieldRef
val assref_for_manifest: ILAssemblyManifest -> ILAssemblyRef
val assref_for_mainmod: ILModuleDef -> ILAssemblyRef
val modref_for_modul: ILModuleDef -> ILModuleRef
// --------------------------------------------------------------------
// Rescoping.
//
// Given an object O1 referenced from where1 (e.g. O1 binds to some
// result R when referenced from where1), and given that SR2 resolves to where1 from where2,
// produce a new O2 for use from where2 (e.g. O2 binds to R from where2)
//
// So, ILScopeRef tells you how to reference the original scope from
// the new scope. e.g. if ILScopeRef is:
// [ScopeRef_local] then the object is returned unchanged
// [ScopeRef_module m] then an object is returned
// where all ScopeRef_local references
// become ScopeRef_module m
// [ScopeRef_assembly m] then an object is returned
// where all ScopeRef_local and ScopeRef_module references
// become ScopeRef_assembly m
// --------------------------------------------------------------------
/// Rescoping. The first argument tells the function how to reference the original scope from
/// the new scope.
val rescope_scoref: ILScopeRef -> ILScopeRef -> ILScopeRef
/// Rescoping. The first argument tells the function how to reference the original scope from
/// the new scope.
val rescope_tspec: ILScopeRef -> ILTypeSpec -> ILTypeSpec
/// Rescoping. The first argument tells the function how to reference the original scope from
/// the new scope.
val rescope_typ: ILScopeRef -> ILType -> ILType
/// Rescoping. The first argument tells the function how to reference the original scope from
/// the new scope.
val rescope_mspec: ILScopeRef -> ILMethodSpec -> ILMethodSpec
/// Rescoping. The first argument tells the function how to reference the original scope from
/// the new scope.
val rescope_ospec: ILScopeRef -> OverridesSpec -> OverridesSpec
/// Rescoping. The first argument tells the function how to reference the original scope from
/// the new scope.
val rescope_mref: ILScopeRef -> ILMethodRef -> ILMethodRef
/// Rescoping. The first argument tells the function how to reference the original scope from
/// the new scope.
val rescope_fref: ILScopeRef -> ILFieldRef -> ILFieldRef
/// Rescoping. The first argument tells the function how to reference the original scope from
/// the new scope.
val rescope_fspec: ILScopeRef -> ILFieldSpec -> ILFieldSpec
//-----------------------------------------------------------------------
// The ILCode Builder utility.
//----------------------------------------------------------------------
type ExceptionClause =
| SEH_finally of (ILCodeLabel * ILCodeLabel)
| SEH_fault of (ILCodeLabel * ILCodeLabel)
| SEH_filter_catch of (ILCodeLabel * ILCodeLabel) * (ILCodeLabel * ILCodeLabel)
| SEH_type_catch of ILType * (ILCodeLabel * ILCodeLabel)
type ILExceptionSpec =
{ exnRange: (ILCodeLabel * ILCodeLabel);
exnClauses: ExceptionClause list }
type ILLocalSpec =
{ locRange: (ILCodeLabel * ILCodeLabel);
locInfos: ILDebugMapping list }
/// build_code: Build code from a sequence of instructions.
///
/// e.g. "build_code meth resolver instrs exns locals"
///
/// This makes the basic block structure of code from more primitive
/// information, i.e. an array of instructions.
/// [meth]: for debugging and should give the name of the method.
/// [resolver]: should return the instruction indexes referred to
/// by code-label strings in the instruction stream.
/// [instrs]: the instructions themselves, perhaps with attributes giving
/// debugging information
/// [exns]: the table of exception-handling specifications
/// for the method. These are again given with respect to labels which will
/// be mapped to pc's by [resolver].
/// [locals]: the table of specifications of when local variables are live and
/// should appear in the debug info.
///
/// If the input code is well-formed, the function will returns the
/// chop up the instruction sequence into basic blocks as required for
/// the exception handlers and then return the tree-structured code
/// corresponding to the instruction stream.
/// A new set of code labels will be used throughout the resulting code.
///
/// The input can be badly formed in many ways: exception handlers might
/// overlap, or scopes of local variables may overlap badly with
/// exception handlers.
val build_code:
string ->
(ILCodeLabel -> int) ->
ILInstr array ->
ILExceptionSpec list ->
ILLocalSpec list ->
ILCode
// --------------------------------------------------------------------
// The instantiation utilities.
// --------------------------------------------------------------------
/// Instantiate type variables that occur within types and other items.
val inst_typ_aux: int -> ILGenericArgs -> ILType -> ILType
/// Instantiate type variables that occur within types and other items.
val inst_typ: ILGenericArgs -> ILType -> ILType
/// Instantiate type variables that occur within types and other items.
val inst_inst: ILGenericArgs -> ILGenericArgs -> ILGenericArgs
/// Instantiate type variables that occur within types and other items.
val inst_tspec: ILGenericArgs -> ILTypeSpec -> ILTypeSpec
/// Instantiate type variables that occur within types and other items.
val inst_callsig: ILGenericArgs -> ILCallingSignature -> ILCallingSignature
/// Instantiate type variables that occur within types and other items.
val inst_read: ILGenericArgs -> uint16 -> ILType
/// Instantiate type variables that occur within types and other items.
val inst_add: ILGenericArgs -> ILGenericArgs -> ILGenericArgs
/// Names of some commonly used things in mscorlib...
val mscorlib_module_name: string
/// This is a 'vendor neutral' way of referencing mscorlib.
val ecma_public_token: PublicKey
/// This is a 'vendor neutral' way of referencing mscorlib.
val ecma_mscorlib_scoref: ILScopeRef
/// This is a 'vendor neutral' collection of references to items in mscorlib.
val ecmaILGlobals: ILGlobals
/// Some commonly used methods
val mspec_RuntimeHelpers_InitializeArray: ILGlobals -> ILMethodSpec
val mspec_RunClassConstructor: ILGlobals -> ILMethodSpec
val mspec_StringBuilder_string: ILGlobals -> ILMethodSpec
val mk_RunClassConstructor: ILGlobals -> ILTypeSpec -> ILInstr list
val mk_mscorlib_exn_newobj: ILGlobals -> string -> ILInstr
/// Some commonly used custom attibutes
val mk_DebuggableAttribute: ILGlobals -> bool (* debug tracking *) * bool (* disable JIT optimizations *) -> ILAttribute
val mk_DebuggableAttribute_v2: ILGlobals -> bool (* jitTracking *) * bool (* ignoreSymbolStoreSequencePoints *) * bool (* disable JIT optimizations *) * bool (* enable EnC *) -> ILAttribute
val mk_CompilerGeneratedAttribute : ILGlobals -> ILAttribute
val mk_DebuggerNonUserCodeAttribute : ILGlobals -> ILAttribute
val mk_DebuggerHiddenAttribute : ILGlobals -> ILAttribute
val mk_DebuggerDisplayAttribute : ILGlobals -> string -> ILAttribute
val mk_DebuggerTypeProxyAttribute : ILGlobals -> ILType -> ILAttribute
val mk_DebuggerBrowsableNeverAttribute : ILGlobals -> ILAttribute
val mk_DebuggerBrowsableRootHiddenAttribute: ILGlobals -> ILAttribute
val mk_DebuggerBrowsableCollapsedAttribute : ILGlobals -> ILAttribute
val add_mdef_generated_attrs : ILGlobals -> ILMethodDef -> ILMethodDef
val add_pdef_generated_attrs : ILGlobals -> ILPropertyDef -> ILPropertyDef
val add_fdef_generated_attrs : ILGlobals -> ILFieldDef -> ILFieldDef
val add_pdef_never_attrs : ILGlobals -> ILPropertyDef -> ILPropertyDef
val add_fdef_never_attrs : ILGlobals -> ILFieldDef -> ILFieldDef
/// Discriminating different important built-in types
val typ_is_Object: ILGlobals -> ILType -> bool
val typ_is_String: ILGlobals -> ILType -> bool
val typ_is_SByte: ILGlobals -> ILType -> bool
val typ_is_Byte: ILGlobals -> ILType -> bool
val typ_is_Int16: ILGlobals -> ILType -> bool
val typ_is_UInt16: ILGlobals -> ILType -> bool
val typ_is_Int32: ILGlobals -> ILType -> bool
val typ_is_UInt32: ILGlobals -> ILType -> bool
val typ_is_Int64: ILGlobals -> ILType -> bool
val typ_is_UInt64: ILGlobals -> ILType -> bool
val typ_is_IntPtr: ILGlobals -> ILType -> bool
val typ_is_UIntPtr: ILGlobals -> ILType -> bool
val typ_is_Bool: ILGlobals -> ILType -> bool
val typ_is_Char: ILGlobals -> ILType -> bool
val typ_is_TypedReference: ILGlobals -> ILType -> bool
val typ_is_Double: ILGlobals -> ILType -> bool
val typ_is_Single: ILGlobals -> ILType -> bool
/// Get a public key token from a public key.
val sha1_hash_bytes : byte[] -> byte[] (* SHA1 hash *)
/// Get a version number from a CLR version string, e.g. 1.0.3705.0
val parse_version: string -> ILVersionInfo
val version_to_string: ILVersionInfo -> string
val version_compare: ILVersionInfo -> ILVersionInfo -> int
val version_max: ILVersionInfo -> ILVersionInfo -> ILVersionInfo
val version_min: ILVersionInfo -> ILVersionInfo -> ILVersionInfo
/// Decompose a type definition according to its kind.
type ILEnumInfo =
{ enumValues: (string * ILFieldInit) list;
enumType: ILType }
val typ_of_enum_info: ILEnumInfo -> ILType
val info_for_enum: string * ILFieldDefs -> ILEnumInfo
val memoize_on: ('a -> 'key) -> ('a -> 'b) -> ('a -> 'b)
val memoize: mapping:('a -> 'b) -> ('a -> 'b)
// --------------------------------------------------------------------
// For completeness. These do not occur in metadata but tools that
// care about the existence of properties and events in the metadata
// can benefit from them.
// --------------------------------------------------------------------
[<Sealed>]
type ILEventRef =
static member Create : ILTypeRef * string -> ILEventRef
member EnclosingTypeRef: ILTypeRef
member Name: string
[<Sealed>]
type ILEventSpec =
static member Create : ILEventRef * ILType -> ILEventSpec
member EventRef: ILEventRef
member EnclosingType: ILType
[<Sealed>]
type ILPropertyRef =
static member Create : ILTypeRef * string -> ILPropertyRef
member EnclosingTypeRef: ILTypeRef
member Name: string
[<Sealed>]
type ILPropertySpec =
static member Create : ILPropertyRef * ILType -> ILPropertySpec
member PropertyRef: ILPropertyRef
member EnclosingType: ILType
val tref_of_pref : ILPropertyRef -> ILTypeRef
val tref_of_eref : ILEventRef -> ILTypeRef
val mk_pref : ILTypeRef * string -> ILPropertyRef
val mk_eref : ILTypeRef * string -> ILEventRef
val mk_pspec : ILPropertyRef * ILType -> ILPropertySpec
val mk_espec : ILEventRef * ILType -> ILEventSpec
val name_of_pref : ILPropertyRef -> string
val name_of_eref : ILEventRef -> string
val enclosing_typ_of_pspec : ILPropertySpec -> ILType
val enclosing_typ_of_espec : ILEventSpec -> ILType
val pref_of_pspec : ILPropertySpec -> ILPropertyRef
val eref_of_espec : ILEventSpec -> ILEventRef
val eref_for_edef : ILScopeRef -> ILTypeDef list * ILTypeDef -> ILEventDef -> ILEventRef
val pref_for_pdef : ILScopeRef -> ILTypeDef list * ILTypeDef -> ILPropertyDef -> ILPropertyRef
// --------------------------------------------------------------------
// The referenced-assemblies utility.
val runningOnMono: bool
type ILReferences =
{ refsAssembly: ILAssemblyRef list;
refsModul: ILModuleRef list; }
member AssemblyReferences: ILAssemblyRef list
member ModuleReferences: ILModuleRef list
/// Find the full set of assemblies referenced by a module
val refs_of_module: ILModuleDef -> ILReferences
val empty_refs: ILReferences
// --------------------------------------------------------------------
// The following functions are used to define an extension to the IL. In reality the only extension is ILX
type ILInstrSetExtension<'a> =
{ instrExtDests: ('a -> ILCodeLabel list);
instrExtFallthrough: ('a -> ILCodeLabel option);
instrExtIsTailcall: ('a -> bool);
instrExtRelabel: (ILCodeLabel -> ILCodeLabel) -> 'a -> 'a; }
type ILTypeDefKindExtension<'a> = Type_def_kind_extension
val define_instr_extension: 'a ILInstrSetExtension -> ('a -> IlxExtensionInstr) * (IlxExtensionInstr -> bool) * (IlxExtensionInstr -> 'a)
val define_type_def_kind_extension: 'a ILTypeDefKindExtension -> ('a -> IlxExtensionTypeKind) * (IlxExtensionTypeKind -> bool) * (IlxExtensionTypeKind -> 'a)