Použité formátování | Obecné syntaktické elementy | Sémantika obecných elementů | Křížová reference direktiv | Blokové direktivy | Řádkové direktivy | Uživatelské atributy | Instrukce | Vysvětlivky a odkazy
Použité formátování | Obecné syntaktické elementy | Sémantika obecných elementů | Křížová reference direktiv | Blokové direktivy | Řádkové direktivy | Uživatelské atributy | Instrukce | CLI+CTS vs. CLS | Vysvětlivky a odkazy
kódReference v kódu*.*, +, ?, (, ), [, ], ., \:
*a* odpovídá '', 'aa', 'aaa', ...+a+ odpovídá 'a', 'aa', 'aaa', ...?a? odpovídá 'a', ''{n}na{3} odpovídá 'aaa'{m,n}m÷na{1,3} odpovídá 'a', 'aa', 'aaa'{}{|}{a|b|c} odpovídá 'a', 'b', 'c', 'ab', 'ac', 'bc', 'ba', 'ca', 'cb', 'abc', 'cba', 'acb', 'cab', 'bac', 'bca'{, } a , nejsou speciální znaky a pokud se v regulárním výrazu nevyskytnou v některé z výše uvedených podob, jsou chápány jako obyčejný text.()(ab)+ odpovídá 'ab', 'abab', ...[]- a nenachází neescapovaná |. Uvnitř specifikátoru skupiny se za speciální znak považuje jen -, ], | a ^.[A-Zů] odpovídá 'A', 'B', 'C', ..., 'ů'[A-Z]+ odpovídá 'A', 'B', 'AB', 'GAG', 'HUIGG', ...[ následuje ^. Nemusí obsahovat neescapovanou -. Uvnitř specifikátoru skupiny se za speciální znak považuje jen -, ] a ^.[^c-dk] neodpovídá 'c', 'd', 'k'-, nezačíná ^ a nachází se za ním jeden z kvantifikátorů *, +, ?, {}[a]* odpovídá '', 'a', 'aa', ...^ a nachází se v něm neescapované |. Pozor funkce | v hranatých závorkách je lehce jiná než mimo ně (nebo v kulatých). V hranatých závorkách se chová jako by po obou jeho stranách byly mezery i když tam nejsou.[aaa|bbb] je totéž jako (aaa | bbb), což je totéž jako ((aaa)|(bbb)) a také je to totéž jako [aaa | bbb]. Odpovídá to 'aaa', 'bbb'[a] '', 'a'\* odpovídá '*'. odpovídá 'a', '_', 'σ', ...ahoj|čau odpovídá 'ahojau', 'ahočau'ahoj | čau odpovídá 'ahoj', 'čau'| uzavřeno v hranatých závorkách, chová se vždy jako by po obou jeho stranách byly mezery.[ahoj|čau] je totéž jako ahoj | čau a dpovídá 'ahoj', 'čau'Použité formátování | Obecné syntaktické elementy | Sémantika obecných elementů | Křížová reference direktiv | Blokové direktivy | Řádkové direktivy | Uživatelské atributy | Instrukce | CLI+CTS vs. CLS | Vysvětlivky a odkazy
Následující přehled popisuje syntaktické elementy používaných v zápisu CLI kódu.
([+|-][0-9]+)|(0x[0-9A-Fa-f]+)[+|-]([0-9]+\.[0-9]+)|([0-9]+(E|e)[0-9]+)|([0-9]+\.[0-9]+(E|e)[+|-]][0-9]+)RealNumber | float32 (Int32) | \(Bytes\)RealNumber | float64 (Int64) | \(Bytes\)NaN, Inf resp. -Inf[A-Za-z_$@`?][A-Za-z_$@`?0-9]*ID | SQSTRINGId[\.Id]*[0-9A-Za-z]{2}HexByte [HexByte]*[+|-|class|valuetype|.ctor]* [\([Type [, Type]*\)] Id\[[\.module] DottedName\] | TypeReference | Type.class System.GC napsat System.GC(\[\.module DottedName\] | \[DottedName\]) DottedName [/ DottedName]*!Int32 | !!Int32 | bool | char | class TypeReference | float32 | float64 | int8 | int16 | int32 | int64 | method CallConv Type \* \(Param [, Param]*\) | native int | native unsigned int | object | string | Type& | Type\* | Type<Type [,Type]* [,]*> | Type \[[(\.\.\. | Int32 | Int32 \.\.\. | Int32 \.\.\. Int32) [, (\.\.\. | Int32 | Int32 \.\.\. | Int32 \.\.\. Int32)]*]\] | Type modopt \(TypeReference\) | Type modreq \(TypeReference\) | Type pinned | typedref | valuetype TypeReference | unsigned int8 | unsigned int16 | unsigned int32 | unsigned int64 | void\[\] | bool | float32 | float64 | [unsigned] int | [unsigned] int8 | [unsigned] int16 | [unsigned] int32 | [unsigned] int64 | lpstr | lpwstr | method | NativeType \[\] | NativeType \[Int32\] | NativeType \[\+Int32\] | NativeType \[Int32 \+ Int32\]
| (as any | byvalstr | custom \(QSTRING,QSTRING\) | fixed array [Int32] | fixed sysstring [Int32] | lpstruct | lptstr | struct)*
[instance [explicit]] (default | unmanaged cdecl | unmanaged fastcall | unmanaged stdcall | unmanaged thiscall | vararg)((\[in\])|(\[opt\])|(\[out\]))* Type [marshal \([NativeType\)][Id]Použité formátování | Obecné syntaktické elementy | Sémantika obecných elementů | Křížová reference direktiv | Blokové direktivy | Řádkové direktivy | Uživatelské atributy | Instrukce | CLI+CTS vs. CLS | Vysvětlivky a odkazy
Type | TypeReference | TypeSpec | GenPar | CallConv | Param | NativeType
Komplexní reference na typ
!Int32!!Int32charcharfloat32float64int8int16int32int64objectstringunsigned int8unsigned int16unsigned int32unsigned int64native intnative unsigned intclass TypeReferencemethod CallConv Type \* \(Param [, Param]*\)Type&typedref. Managovaný pointer je oznámen garbage collectoru.Type\*Type <Type [,Type]* [,]*>ByRef), typy jejichž pole ukazují na CIL evaluation stack (jako System.RuntimeArgumentHandle), void. Částečná instanciace není povolena.Type \[[(\.\.\. | Int32 | Int32 \.\.\. | Int32 \.\.\. Int32) [, (\.\.\. | Int32 | Int32 \.\.\. | Int32 \.\.\. Int32)]*]\]Type \[\]newarr, ldelem, stelem nebo ldelema. Vektory jsou podtypy třídy System.Array.Type \[Bound [,Bound]*\]Bound (hranic), což může být:
System.Array.Type modopt \(TypeReference\)Type modreq \(TypeReference\)Type pinnedpinned, VES nesmí přesunout objekt na který je proměnná referencí.pinned.typedrefSystem.TypedReference) vytvořená pomocí mkrefany. Používáno instrukcemi refanytype a refanyval.valuetype TypeReferencevoidvoid*.Reference na uživatelem definovaný typ
[ResolutionScope] DotedName [/ DottedName]*
ResolutionScope (ResolutionScope)\[\.module FileName\]FileName (DottedName)\[AssemblyRefName\]AssemblyRefName (DottedName).assembly extern {}DottedName / DottedNameZjednodušená reference na typ. Umožňuje na jednom místě použít Type, TypeReference a syntaktickou zkratku \[[\.module] DottedName\]. Např místo class System.GC lze použít System.GC.
Specifikace generického parametru
(\+ | - | class | valuetype | \.ctor)* [\([Type [, Type]*]\)] Id
+IA<+T>, je možné provést přiřazení proměnné typu IA`1<A> do proměnné typu IA`<B> za předpokladu, že je možné provést přiřazení proměnné typu A do proměnné typu B.
Například následující pseudokód by byl možný:
Interface IA<+T>;
IA`1<System.String> var1;
IA`1<System.Object> var2;
var1 := var2;
interface IEnumerator<+T> {
T Current { get; }
bool MoveNext();
}
interface IEnumerable<+T> {
IEnumerator<T> GetEnumerator();
}
Kovariantní generický parametr se může objevit jen v pozici "consumer", "writer" nebo "setter".
-IB<-T> je možné přiřazení IB`1<B> := IB`1<A>, pokud je možné přiřazení A := B.
Interface IB<-T>;
IB`1<System.String> var1;
IB`1<System.Object> var2;
var2 := var1;
interface IComparer<-T> {
bool Compare(T x, T y);
}
interface IKeyComparer<-T> : IComparer<T> {
bool Equals(T x, T y);
int GetHashCode(T obj);
}
Kontravariantní generický parametr se může objevit jen v pozici "producer", "reader" a "getter".
+ a - nemohou být použity současně. Pokud není použit ani jeden z nich, jedná se o nevariantní generický parametr. Na použití
nevariantních generických parametrů se nevztahují žádná omezení.classvaluetypeSystem.Nullable<T>class a valuetype se nesmí
kombinovat.\.ctor+, -, class, valuetype a .ctor se smí vyskytnout jen jednou.Type (Type)Id (Id)Způsob volání metody
[instance [explicit]][default | unmanaged cdecl | unmanaged fastcall | unmanaged stdcall | unmanaged thiscall | vararg]
instanceexplicitdefaultvararg.unmanaged cdeclunmanaged stdcallunmanaged fastcallunmanaged thiscallvarargExistují ještě další volací konvence, které nejsou platformě nezávislé a nejsou ve standardu zmíněny. Jedná se 4 používané konvence, které nejsou platformě nezávislé, 4 rezervované pro budoucí použití a 2 pro nestandardní experimentální použití.
Parametr metody
[\[in\] | \[opt\] | \[out\]]* Type [marshal \([NativeType]\)] [Id]
Id (Id)inoutin a out mohou být použity jen pro ukazatelové typy (managované i nemanagované). Pokud není specifikován ani jeden předpokládá se in.opt.param.in, out a opt nejsou součástí signatury metody.Type (Type)NativeType (NativeType)
\[\] | bool | float32 | float64 | [unsigned] int | [unsigned] int8 | [unsigned] int16 | [unsigned] int32 | [unsigned] int64 | lpstr | lpwstr | method | NativeType\[\] | NativeType\[Int32\] | NativeType\[\+Int32\] | NativeType\[Int32\+Int32\]
| (as any | byvalstr | custom \(QSTRING,QSTRING\) | fixed array [*
Int32] | fixed sysstring [Int32] | lpstruct | lpstr | struct)
Jedná se o nativní typy platformy na které .NET běží. V popisu je v závorce uvedena hodnota výčtu UnmanagedType.
\[\] (LPArray)bool (Bool)false a cokoliv jiného truefloat32 (R4)float64 (R8)[unsigned] int (Sys[U]Int)[Ne]znaménkový integer tak velký, aby se do něj vešel ukazatel (pointer) aktuální platformy.[unsigned] int[8|16|32|64] ((U|I)(1|2|4|8))[Ne]znaménkový integer příslušné velikostilpstr (LPStr)lpwstr (LPWStr)method (FunctionPtr)NativeType\[\] (LPArray)NativeType\[Int32\] (LPArray)NativeType\[\+Int32\] (LPArray)PreserveSig na 1, počítají se parametry od 1 (1-based index).*NativeType\[Int32\+Int32\] (LPArray)PreserveSig na 1, počítají se parametry od 1 (1-based index).*as any (AsAny)*byvalstr (VBByrefStr)*custom \(QSTRING,QSTRING\) (CustomMarshaler)*Reflection.Emit k určení assembly a/nebo modulu). Druhý je řetězec poslaný marshaleru za běhu za účelem identifikace způsobu marshalingu.fixed array [Int32] (ByValArray)*fixed sysstring [Int32] (ByValTStr)*lpstruct (LPStruct)*lpstr (LPTStr)*struct (Struct)*Použité formátování | Obecné syntaktické elementy | Sémantika obecných elementů | Křížová reference direktiv | Blokové direktivy | Řádkové direktivy | Uživatelské atributy | Instrukce | CLI+CTS vs. CLS | Vysvětlivky a odkazy
Použité formátování | Obecné syntaktické elementy | Sémantika obecných elementů | Křížová reference direktiv | Blokové direktivy | Řádkové direktivy | Uživatelské atributy | Instrukce | CLI+CTS vs. CLS | Vysvětlivky a odkazy
.assembly {} |
.assembly extern {} |
.class {} |
.class extern {} |
.data {} |
.event {} |
.method {} |
.mresource {} |
.property {} |
{}
.assembly {}
Viz též:
.assembly extern {} |
.assembly extern |
.module
.custom, .hash alghoritm, .culture, .publickey, .ver, .permissionset, .permission
.culture, použijte .locale.*\.assembly Name {}
Name (DottedName).assembly extern {}
Viz též:
.assembly extern | .class extern {} | .class extern | | .module extern.assembly {}
.hash, .custom, .culture, .publickeytoken, .publickey, .ver
\.assembly extern Name [as Alias] {}
Name (DottedName).assembly)Alias (DottedName).class {}
Viz též:
.class extern {}
.class.class, .custom, .data, .event, .field, .method, .override, .pack, .param type, .property, .size, .line, .permissionset, .permission\.class Attrs Name [<GenericSpec>] [extends ExtendedType [implements ImplementedTypes]] {}
Attrs (bílým znakem oddělený seznam ClassAttr)abstractMustInherit) třída nemůže být instanciována. Pokud obsahuje abstraktní metody musí být abstraktní.sealedNotInheritable)abstract a sealed by měla mít jen statické členy (podobné jako standardní modul ve VB)ansiautocharunicodeansi, autochar a unicode definují marshaling stringů z/do nemanagovaného kódu. Nesmí být kombinovány. Výchozí hodnota je ansi.autoexplicitsequentialauto, explicit a sequential
definují řazení instančních proměnných třídy v paměti. Nesmějí být kombinovány. Výchozí je auto.interfacenested assemblyFriend)nested famandassemnested assembly a nested familly (VB: nedostupné)nested familyProtected)nested famorassemnested assembly a nested familly (VB: Protected Friend)nested privatePrivate)nested publicPublic)privatepublicnested..., private a public definují viditelnost třídy. Může být použít jen jeden z nich.
Pro třídy definované v jiných třídách je nutno použít modifikátory nested..., pro třídy definované na úrovni assembly (top-level) je potřeba použít private nebo public.
Výchozí viditelností pro top-level třídy je public, pro vnořené nested private.
beforefieldinitrtspecialnamertspecialname, musí být použit i specialname.serializablespecialnameimport*Name (Id)GenericSpecs (čárkou oddělený seznam GenPar)ExtendedType (TypeSpec)System.ObjectImplementedTypes (čárkou oddělený seznam TypeSpec)Definováním vlastních tříd jsou definovány nové typy. Nové typy lze také definovat jako instance generických typů, pole, vektory či ukazatele. Tato subkapitola se zabývá typy deklarovanými pomocí direktivy .class {}.
System.Object, nebo od některého z jejích potomků, kromě potomků speciálního typu (viz dále).
Nevztahují se na ně žádná dodatečná omezení.interface. Interface může být implementován jak referenčním tak hodnotovým typem. Pro implementaci interfacu musí třída implementovat veškeré jrho abstraktní metody nebo dědit od metody, která je implementuje.
Výjimkou je abstraktní třída, která nemusí tyto metody (všechny) implementovat,
protože od ní nelze vytvořit instanci. Metody pak musí být implementovány ve třídě, která od této abstraktní třídy dědí.implements direktivy .class {}). Pokut třída implementuje nějaký interface, který vyžaduje implementaci jiného interfacu, stačí, když třída explicitně deklaruje, že implementuje specifičtější z obou interfaců (ten, který dědí).MethodImpl - direktiva .overridesealed (nelze od něj dědit) a jeho rodičovskou třídou musí být System.ValueType nebo System.Enum.null a nemůže být porovnána s null. Na hodnotové typy se nepohlíží jako na podtypy jiných typů, takže na ně nelze použít instrukci isinst (lze ji použít na boxovanou podobu).this managovaný ukazatel na aktuální instanci (zatímco u referenčních typů obdrží přímo hodnotu referenčního typu - tedy referenci).System.Enum.auto.
Výčtový typ musí mít přesně jednu instanční proměnnou, jejíž typ určuje podtyp výčtu.
Ostatní proměnné musí být statické literály, které nejsou inicializovány instrukcí initobj. Tyto proměnné jsou typu sebe sama a jejich hodnota je uložena v metadatech
pomocí FieldInit (viz .field).
sealed typ, který přímo nebo nepřímo dědí od System.Delegate (delegáti dědí od System.MulticastDelegate*)runtime a managed a nemají specifikováno tělo - to poskytne VES automaticky.
Další metody, které mohou být na delegáty volány jsou zděděny od bázové třídy.
.ctorSystem.Object a System.IntPtr). Do prvního se předá instance třídy deklarující metodu a do druhého ukazatel na metodu.InvokeBeginInvokeInvoke. Návratovou hodnotou metody je System.IAsyncResult a za parametry stejnými jako u Invoke následují ještě parametry typu System.AsyncCallback a System.Object.EndInvokeInvoke. Obsahuje ty z parametrů metody Invoke, které jsou typu managovaný pointer (ve stejném pořadí). Za nimi ještě parametr typu System.IAsyncResult.runtime). Pak ale assembly nebude přenosná.
.class extern {}
Viz též:
.assembly extern {} | .assembly extern | .class extern | .module extern | .class
.file, .class extern, .custom\.class extern (public | nested public) Name {}
Name (DottedName)public | nested public.event {}
Viz též:
.property {} | .method {}
.class.addon, .custom, .fire, .other, .removeon, .line\.event [specialname] [rtspecialname] [Type] Name
specialnamertspecialnameType (TypeSpec)Name (Id).method {}
Viz též:
.property {} | .event{} | .field
.class.custom, .data, .emitbyte, .entrypoint, .locals, .maxstack, .override, .override method, .param, .param type, .line, Instrukce, Label, .permission, .permissionset, {}, .try\.method MethAttr* [CallingConvention] ReturnType [marshal \([ReturnMarshaling]\)] Name [<GenPar [, GenPar]*>] \([Parameter [, Parameter]*]\) ImplAttr* {}\.method MethAttr* [CallingConvention] [\[in\] | \[opt\] | \[out\]]* ReturnType [marshal \([ReturnMarshaling]\)] Name [<GenPar [, GenPar]*>] \([Parameter [, Parameter]*]\) ImplAttr* {}*
MethAttr (MethAttr)abstractMustOverride)newslotShadows, nespecifikováno - Overrides)finalNotOverridable). Musí být virtuální.hidebysigShadows, ale Shadows ve VB zastiňuje i členy jiného typu než metoda (proměnné, události, typy, ...); viz také newslot). staticShared)virtualOverridable)strictassemblyFriend)famandassemfamily a assembly operátorem and (VB: žádný ekvivalent).familyProtected).famorassemfamily a assembly operátorem OR (VB: Protected Friend).privatePrivate).publicPublic).compilercontrolledpinvokeimpl \(QSTRING [as QSTRING] PinvAttr*\)rtspecialname.ctor.cctorspecialnameunmanagedexp*reqsecobj*privatescope*compilercontrolled. Použijte místo něj privatescope.static s kterýmkoliv z final, newslot, virtualabstract s kterýmkoliv z final, pinvokeimplcompilercontrolled s kterýmkoliv z final, rtspecialname, specialname, virtualassembly, compilercontrolled, famandassem, family, famorassem, private, public)CallingConvention (CallConv)ReturnType (Type)void.ReturnMarshaling (NativeType)Name (MethodName)\.cctor | \.ctor | DottedName
.cctorrtspecialname..ctorrtspecialname.GenParParameter (Param)ImplAttr (ImplAttr)cilnativeruntimecil, native, runtime může být uveden.managedunmanagedmanaged a unmanaged není možno kombinovat.forwardrefinternalcallinternalclass umožňuje nejnízkoúrovňovějším částem BCL zabalit nemanagovaný kód, který je vestavěn do CLI.*noinliningsynchronizedpreservesig*HRESULT s návratovou hodnotou jako parametrem\[in\] | \[opt\] | \[out\][CallingConvention] a ReturnType uvést [ParamAttr]*. Neuvádí ale k čemu je to dobré. Význam jednotlivých modifikátorů při použití na parametr metody je vysvětlen u Param..mresource {}
Viz též:
.data
.assembly extern, .custom, .file\.mresource [private|public] Name {}
privatepublicName (DottedName).property {}
Viz též:
.method {} | .event{}
.class.custom, .get, .other, .set, .line\.property [specialname] [rtspecialname] CallingConvention Type Name \([Param [,Param]*]\)
specialnamertspecialnameCallingConvention (CallConv)Type (Type)Param (Param){}
Viz též:
try | catch | fault | filter | finally
.method, {}.custom, .data, .emitbyte, .entrypoint, .locals, .maxstack, .override, .override method, .param, .param type, .line, Instrukce, Label, .permission, .permissionset, {}, .try{}Použité formátování | Obecné syntaktické elementy | Sémantika obecných elementů | Křížová reference direktiv | Blokové direktivy | Řádkové direktivy | Uživatelské atributy | Instrukce | CLI+CTS vs. CLS | Vysvětlivky a odkazy
.addon |
.assembly extern |
catch |
.class extern |
.corflags |
.culture |
.custom |
.data |
.emitbyte |
.entrypoint |
.export⁺ |
fault |
.field |
.file |
.file alignment* |
filter |
finally |
.fire |
.get |
handler |
.hash |
.hash alghoritm |
.imagebase* |
.language* |
.line (#line) |
.locale* |
.locals |
.maxstack |
.module |
.module extern |
.namespace* |
.other |
.override |
.override method |
.pack |
.param |
.param type |
.permission |
.permissionset |
.publickey |
.publickeytoken |
.removeon |
.set |
.size |
.stackreserve⁺ |
.try |
.subsystem |
.ver |
.vtentry⁺ |
.vtfixup |
Label
.addon
Viz též:
.removeon | .other | .set | .get | .fire
add události (přidání handleru). CLS specifikuje pojmenovávací konvenci, konzistenční omezení a vyžaduje aby metoda add byla označena jako specialname..event\.addon CallingConvention Type [TypeSpec::] MethodName \([Param [, Param]*]\)
CallingConvention (CallConv)Type (Type)TypeSpec (TypeSpec)MethodName (MethodName)\.cctor | \.ctor | DottedName.cctor a .ctor.Param (Param).assembly extern
Viz též:
.assembly extern {} | .class extern {} | .class extern | .module extern
.assembly extern {}.mresource\.assembly extern Name
Name (DottedName)catch
Viz též:
fault | filter | finally | Label
.tryhandler, {}catch ExceptionType (handler Label to Label | {})
ExceptionType (TypeReference)handler Label to Labelhandler{} (ScopeBlock){}.class extern
Viz též:
.assembly extern {} |
.assembly extern |
.class extern {} |
.module extern
.class extern\.class extern Name
Name (DottedName).corflags
Viz též:
.emitbyte
\.corflags Value
Value (Int32)COMIMAGE_FLAGS_ILONLY = 0x1COMIMAGE_FLAGS_32BITREQUIRED = 0x2COMIMAGE_FLAGS_STRONGNAMESIGNED = 0x8COMIMAGE_FLAGS_TRACKDEBUGDATA = 0x10000.culture
Viz též:
.locale*
.assembly, .assembly extern\.culture Culture
Culture (QSTRING)System.Globalization.CultureInfo..custom
Viz též:
.param | .param type
.custom.
Obvyklé je přiřazení uživatelských atributů k assembly, modulu, třídě, interfacu, struktuře, metodě, proměnné (field), vlastnosti (property), generickému parametru a události.
Uživatelský atribut je připojen k položce, která mu bezprostředně předchází.
.assembly, .mresource, .assembly extern, .class, .method, {}, .property, .event\.custom CallingConvention Type [TypeSpec::] MethodName \([Param [, Param]*]\) [= \(Data\)]
CallingConvention (CallConv)Volací konvence konstruktoruType (Type)voidTypeSpec (TypeSpec)MethodName (MethodName).ctor protože je nutno volat konstruktor atributu.instance void myAttribute::.ctor
Param (Param)Data (Bytes)Prolog FixedArg* NumNamed NamedArg*PrologFixedArgvararg není povoleno.
(Elem) | (NumElem Elem+)SZARRAY, druhá pokud je.
Elem(Val) | (SerString) | (FiledOrPropType Val)
Valbool, char, float32, float64, int8, int16, int32, int64, unsigned int8, unsigned int16, unsigned int32, unsigned int64.
bool je uložen jako 1 byte s hodnotou 1 nebo 0, char jako 2 byty s Unicode znakem; ostatní typy mají obvyklou binární serializaci. Výčtový typ je uložen jako hodnota jeho integrálního typu.
SerStringstring a System.Type.PackedLen Bytes
PackedLennull má PackedLen hodnotu 0xFF a žádné byty jen nenásledují. Pokud má být hodnota prázdný řetězec, má hodnotu 0x00 a žádné byty jej nenásledují.System.Type se ukládá serializovaný string obsahující jeho kanonické jméno - celé jméno typu volitelně následované jménem assembly, kde je definován, kulturou a tokenem veřejného klíče. Pokud je assembly vynechána "pátrá" CLI nejdříve v aktuální assembly, pak v systémové knihovně (mscorlib) - to jsou také jediné dva případe, kdy je povoleno jméno assembly, verzi, kulturu a token veřejného klíče vynechat.FiledOrPropType ValSytem.Object. Uložená hodnota pak reprezentuje uloženou boxovanou instanci nějakého hodnotového typu (value-type).FiledOrPropTypeValnull. Obsah viz Val pro jednoduché a výčtové typy výše.NumElemSZARRAY. Jedná se o neznaménkový 32 bitový integer, který určuje počet elementů v SZARRAY. Hodnota 0xFFFFFFFF znamená, že hodnota argumentu je null.NumNamedNamedArg(FIELD | PROPERTY) FieldOrProptype FiedlOrPropName FixedArg
FIELDPROPERTYFieldOrPropTypeELEMENT_TYPE_BOOLEAN = 0x2, ELEMENT_TYPE_CHAR = 0x3, ELEMENT_TYPE_I1 = 0x4, ELEMENT_TYPE_U1 = 0x5, ELEMENT_TYPE_I2 = 0x6, ELEMENT_TYPE_U2 = 0x7, ELEMENT_TYPE_I4 = 0x8, ELEMENT_TYPE_U4 = 0x9, ELEMENT_TYPE_I8 = 0xA, ELEMENT_TYPE_U8 = 0xB, ELEMENT_TYPE_R4 = 0xC, ELEMENT_TYPE_R8 = 0xD, ELEMENT_TYPE_STRING = 0xEFieldOrPropNameFixedArgData je pak takováto:
Více o uživatelských atributech v kapitole Uživatelské atributy.
.data
Viz též:
.mresource {} |
.locals |
.field
.param
.class, .method, {}\.data [DataLabel = ] (DdItem | { DdItem [, DdItem]* })
DataLabel (Id)DdItem.data obsahovat více než jednu datovou položku, musí být datové položky uzavřeny ve složených závorkách, jako by se jednalo o blokový element.& \(Id\) | bytearray \(Bytes\) | char \* \(QSTRING\) | float32 [\(Float64/)][\[Int32\]] | float64 [\(Float64/)][\[Int32\]] | int8 [\(Int32/)][\[Int32\]] | int16 [\(Int32/)][\[Int32\]] | int32 [\(Int32/)][\[Int32\]] | int64 [\(Int64/)][\[Int32\]]
&\(Id\)bytearray \(Bytes\)char \* \(QSTRING\)float32 [\(Float64/)][\[Int32\]]float64 [\(Float64/)][\[Int32\]]int8 [\(Int32/)][\[Int32\]]int16 [\(Int32/)][\[Int32\]]int32 [\(Int32/)][\[Int32\]]int64 [\(Int64/)][\[Int32\]].entrypoint
Viz též:
.file
void, int32 nebo unsigned int32. Integer může být použit pro vrácení návratového kódu aplikace. 0 znamená normální ukončení, nenulové číslo chybu.
Dostupnost vstupního bodu může být libovolná (tedy i private) a ve všech ostatních ohledech se jedná o "obyčejnou" metodu.
.method, {}\.entrypoint
.export⁺.method\.export \[ordinal\] as name
Informace o této metodě byly namezeny v článku Unmanaged code can wrap managed methods na The Code Project.
fault
Viz též:
catch | filter | finally | Label | endfault
catch, které zachytává všechny
výjimky..tryhandler, {}fault (handler Label to Label | {})
handler Label to Labelhandler{} (ScopeBlock){}.field
Viz též:
.method |
.locals |
.param
.class\.field [\[Offset\]] FieldAttr* Type Name [= FieldInit | at DataLabel]?
Offset (Int32)explicit) layout.FieldAttr (FieldAttr)assembly | famandassem | family | famorassem | initonly | literal | marshal \(NativeType\) | notserialized | private | compilercontrolled | public | rtspecialname | specialname | static
assemblyFriend)famandassemfamily a assembly operátorem and (VB: žádný ekvivalent).familyProtected).famorassemfamily a assembly operátorem OR (VB: Protected Friend).privatePrivate).publicPublic).compilercontrolledliteralConst). Takovéto proměnné musí být přiřazena hodnota pomocí FieldInit a za běhu pro ní není rezervováno žádné místo v paměti. Musí být statická.
Konstanta se stane součástí metadat, které je nedostupná z kódu. Kompilátor nahradí přístup ke konstantě její hodnotou. Změna hodnoty konstanty tedy
vyžaduje rekompilaci všech assembly, které ji využívají.
initonlyReadOnly), tedy
proměnnou, která je konstantní po té, co je jí přiřazena hodnota. Změna hodnot těchto proměnných je možná jen v konstruktoru (instanční) nebo inicializátoru (statické) příslušného typu. Nemůže být měněna v jiné metodě nebo v konstruktoru zděděné třídy.ldfld nebo ldflda stane se kód neověřitelným. Pro neověřitelný kód VES nemusí kontrolovat jestli je hodnota pseudokonstanty měněna mimo konstruktor, ale pokud ano, je takový kód neplatný.staticnotserializedinitonly, literal, static, notserialized) mohou být libovolně kombinovány (s
výjimkou: literal musí být static).
Výchozím stavem je instanční nekonstantní proměnná, která může být
serializována.
marshal \(NativeType\)rtspecialnamespecialnameType (Type)Name (Id)FieldInit (FieldInit)
bool \((true | false)\) |
bytearray \(Bytes\) |
char \( Int32\) |
float32 \(Float64\) |
float32 \(Int32\) |
float64 \(Float64\) |
float64 \(Int32\) |
[unsigned] int8 \(Int32\) |
[unsigned] int16 \(Int32\) |
[unsigned] int32 \(Int32\) |
[unsigned] int64 \(Int64\) |
QSTRING |
nullref
unsigned u integerů*
bool \((true | false)\)true nebo falsebytearray \(Bytes\)char \( Int32\)float32 \(Float64\) | float32 \(Int32\) | float64 \(Float64\) | float64 \(Int32\)[unsigned] int8 \(Int32\) | [unsigned] int16 \(Int32\) | [unsigned] int32 \(Int32\) | [unsigned] int64 \(Int64\)QSTRINGnullrefDataLabel (Id).file
Viz též:
.module |
.entrypoint |
.module extern
.file má tři různé syntaxe, podle toho v jakém kontextu se vyskytuje.\.file [nometadata] FileName \.hash = \(Hash\) [\.entrypoint]
nometadataFileName (DottedName)Hash (Bytes).hash alghoritm. VES by měl přepočítat hash před přístupem k souboru. Pokud si hashe
nebudou odpovídat je chování nespecifikované..hash je ze syntaktického hlediska
volitelná. Kompilátor ilasm doplní hash při kompilaci, pokud je vynechán. Za běhu v binárním souboru, ale hash být uložen musí!*.entypointnometadata)..class extern\.file FileName
FileName (DottedName).mresource\.file FileName at Offset
FileName (DottedName)Offset (Int32).file alignment*\.file alignment Alignment
Alignment (Int32)filter
Viz též:
catch | fault | finally | Label | endfilter
catch klauzule.try{}, handlerfilter (Label | {})(handler Label to Label | {})
Label (Id){}{})handler Label to Labelhandler{}{}).{}.fire
Viz též:
.removeon | .other | .set | .get | .addon
fire události (vyvolání události). CLS specifikuje pojmenovávací konvenci, konzistenční omezení a vyžaduje aby metoda fire byla označena jako specialname..event\.fire CallingConvention Type [TypeSpec::] MethodName \([Param [, Param]*]\)
CallingConvention (CallConv)Type (Type)TypeSpec (TypeSpec)MethodName (MethodName)\.cctor | \.ctor | DottedName.cctor a .ctor.Param (Param).get
Viz též:
.removeon | .other | .set | .addon | .fire
get (getter) vlastnosti (property). CLS specifikuje pojmenovávací konvenci, konzistenční omezení a vyžaduje aby metoda get byla označena jako specialname..property\.get CallingConvention Type [TypeSpec::] MethodName \([Param [, Param]*]\)
CallingConvention (CallConv)Type (Type)TypeSpec (TypeSpec)MethodName (MethodName)\.cctor | \.ctor | DottedName.cctor a .ctor.Param (Param)handlercatch, fault, filter a finallycatch, fault, filter, finallyhandler From to To
From (Id nebo Int32*)To (Id nebo Int32*)){}.From a To byla deklarována dříve (v kódu) než jsou použita.*.hash
Viz též:
.hash alghoritm
.assembly extern\.hash = \(Hash\)
Hash (Bytes).hash alghoritm..hash alghoritm
Viz též:
.hash
.hash.
Hashovací algoritmus se používá k výpočtů hashů dalších souborů ze kterých se assembly skládá (pokud se skládá z více souborů) a je pro všechny soubory Stejný.
.assembly\.hash alghoritm Alghoritm
Alghoritm (Int32).imagebase*imagebase v PE hlavičce výstupního souboru. Hodnota specifikuje virtuální adresu, na kterou bude PE soubor načten do procesu.\.imagebase Address
Address (Int64).line or #line\.|#line Line [\: Column] [File] | #line Line FileMS*
.locale*
Viz též:
.culture
.assembly {}, protože ilasm tam nepodporuje .culture..assembly
Viz též:
.field
.locals.method, {}\.locals [init] \([\[LocalNumber\]]* Type [Name] [, [\[LocalNumber\]]* Type [Name]]*\)
initnull, číselné na 0).init.init specifikován u jedné direktivy .locals, budou se ostatní direktivy .locals ve stejné metodě chovat, jako by měli init specifikováno také, i pokud jej
specifikováno nemají.*Type (Type)Name (Id)LocalNumber (Int32)*{}
znovupoužít slot proměnné s vnějšnějšího bloku {} nebo .method {}.
Tím proměnná z vnitřního slotu získá přístup k proměnné z vnějšího slotu.
Toto se nazývá overlapping (překrývání).
Překrývání je možné jen pro proměnné stejného typu.*
.module
Viz též:
.module extern
.module není přítomna, ilasm ji sám doplní a inicializuje ji na fyzický název souboru (včetně přípony, přípona je
velkými písmeny). ilasm také generuje Mvid GUID modulu.*\.module Name
Name (DottedName).module extern
Viz též:
.assembly extern {} |
.assembly extern |
.class extern {} |
.class extern |
.module |
.file
.module extern.\.module extern FileName
FileName (DottedName).module..namespace*\.namespace Name
Name Id.other
Viz též:
.removeon | .addon | .set | .get | .fire
.event, .property\.other CallingConvention Type [TypeSpec::] MethodName \([Param [, Param]*]\)
CallingConvention (CallConv)Type (Type)TypeSpec (TypeSpec)MethodName (MethodName)\.cctor | \.ctor | DottedName.cctor a .ctor.Param (Param).override
Viz též:
.override method
.override má dvě různé syntaxe podle toho
jestli je deklarována na úrovní .class {} nebo .method {}..override method s podporou generických typů..class\.override BaseType :: OverridenMethod with CallingConvention DerivedType :: OverridingMethod \([Param [, Param]]\)
BaseType (TypeSpec)OverridenMethod (MethodName).ctor | .cctor | DottedNameBaseType, která je implementována (název).CallingConvention (CallConv)OverridingMethod.DerivedType (TypeSpec)DerivedType. Správně utvořený program se zde odkazuje na stejný typ, na jehož úrovni se direktiva .override vyskytuje. Metadata zde umožňují popsat něco, co VES nemusí pochopit.OverridingMethod (MethodName).ctor | .cctor | DottedNameOverridenMethod. Param (Param)OverridenMethod i OverridingMethod..method, {}\.override BaseType :: OverridenMethod.override method
Viz též:
.override
.override method má dvě různé syntaxe podle toho jesli je deklarována na úrovní .class {} nebo .method {}..override o podporu generických metod..class\.override method BaseType :: OverridenMethod [<\[OverrideMethodGenArity\]>] with CallingConvention DerivedType :: OverridingMethod [<\[OverrideMethodGenArity\]>] \([Param [, Param]]\)
BaseType (TypeSpec)OverridenMethod (MethodName).ctor | .cctor | DottedNameBaseType, která je implementována (název).OverridenMethodGenArity (Int32)OverridenMethod.CallingConvention (CallConv)OverridingMethod.DerivedType (TypeSpec)DerivedType. Správně utvořený program se zde odkazuje na stejný typ, na jehož úrovni se direktiva .override vyskytuje. Metadata zde umožňují popsat něco, co VES nemusí pochopit.OverridingMethod (MethodName).ctor | .cctor | DottedNameOverridenMethod. OverridingMethodGenArity (Int32)OverridingMethod.Param (Param)OverridenMethod i OverridingMethod..method, {}\.override method BaseType :: OverridenMethod [<\[OverrideMethodGenArity\]>] \([Param [, Param]]\).pack
Viz též:
.size
.pack 2 umožňuje aby 32 bitové integery byly zarovnány na sudé adresy, zatímco bez této direktivy by byly zarovnány na adresy, které jsou násobkem 4. To neznamená, že se budou překrývat! To znamená, že pokud za sebe umístíte 2 bytový a 4 bytový integer, nebude mezi nimi mezera.
.class\.pack Align
Align (Int32).param
Viz též:
.param type |
.field
Number syntaxe).
.class, .method, {}\.pram \[Number\] [= FieldInit]
.permission
Viz též:
.permissionset
Soubor, .assembly, .class, .method, {}\.permission SecAction TypeReference \(Key = Value [, Key = Value]*\)
SecAction (SecAction)assert | demand | deny | inheritcheck | linkcheck | permitonly | reqopt | reqrefuse | request | prejitgrant*assertdemanddenyinheritchecklinkcheckreqoptrefuserequestprejitgrant*TypeReference (TypeReference)Key (SQSTRING)Value (SQSTRING).permissionset
Viz též:
.permission
Soubor, .assembly, .class, .method, {}\.permissionset SecAction \(Data\)
SecAction (SecAction).permissionData (Bytes).publickey
Viz též:
.publickeytoken
.assembly, .assembly extern\.publickey = \(PublicKey\)
PublicKey (Bytes).publickeytoken
Viz též:
.publickey
.assembly extern je možno uložit veřejný klíč toho, kdo externí assembly podepsal (.publickey) nebo jen jeho token. Ani jedno není povinné. Pokud je uloženo obojí, je token ignorován..assembly extern\.publickeytoken = \(Token\)
Token (Bytes).removeon
Viz též:
.addon | .other | .set | .get | .fire
remove události (odebrání handleru). CLS specifikuje pojmenovávací konvenci, konzistenční omezení a vyžaduje aby metoda remove byla označena jako specialname..event\.removeon CallingConvention Type [TypeSpec::] MethodName \([Param [, Param]*]\)
CallingConvention (CallConv)Type (Type)TypeSpec (TypeSpec)MethodName (MethodName)\.cctor | \.ctor | DottedName.cctor a .ctor.Param (Param).set
Viz též:
.removeon | .other | .addon | .get | .fire
set (setter) vlastnosti (property). CLS specifikuje pojmenovávací konvenci, konzistenční omezení a vyžaduje aby metoda set byla označena jako specialname..property\.set CallingConvention Type [TypeSpec::] MethodName \([Param [, Param]*]\)
CallingConvention (CallConv)Type (Type)TypeSpec (TypeSpec)MethodName (MethodName)\.cctor | \.ctor | DottedName.cctor a .ctor.Param (Param).size
Viz též:
.pack
.class\.size Size
Size (Int32).stackreserve⁺
Viz též:
.maxstack
\.stackreserve Number
Number (Int32).subsystem\.subsystem SubSystem
SubSystem (Int32).try.method, {}catch, fault, filter, finally, {}\.try (From to To | {}) ((catch TypeReference | fault | filter (Id | {}) | finally) (handler Id to Id | {}))+
From (Id)try).To (Id)try).From a To tedy "obalují" chráněný blok, tak jako složené závorky v následující syntaxi.From a To musí být deklarována v kódu dříve než je na ně odkazováno.{}catch, fault, filter a finally.
catch, fault, filter, finally) nesmějí začínat na stejné adrese.try a catch musí být skok za celou konstrukci. Např.:
.try {
… // chráněné instrukce
leave exitSEH // normální opuštění bloku
} catch [mscorlib]System.FormatException { // zachycení výjímky
… // ošetření výjímky
pop // vyjmutí výjímky ze zásobníku
leave exitSEH // normální opuštění handleru
}
exitSEH: // Pokračování zde
filter těsně předchází svému handleru.
Pokud se v něm rozhodne, že má dojít k ošetření výjimky, uloží na zásobník hodnotu EXCEPTION_EXECUTE_HANDLER (i4.1).
Poslední instrukcí bloku filter musí být endfilter.
V bloku filter nelze zakládat další bloky try.
finally musí být endfinally.fault musí být endfault..ver.assembly, .assembly extern\.ver Major:Minor:Build:Revision
Major (Int32)Minor (Int32)Build (Int32)Revision (Int32)Build a Revision rovno 0.
Individuální implementátoři by měly alespoň jednu ze složek Build a Revision nastavovat na nenulovou hodnotu, aby se
vyhli případné kolizi s pozdější verzí standardu.
.vtfixup.data.\.vtfixup [Number] [fromunmanaged | int32 | int64 | retainappdomain*]* at DataLabel
Number (Int32)int32int64int32 je výchozí, pokud není specifikován ani jeden.fromunmanagedretainappdomain*DataLabel (Id).method, {}Label :
Label (Id)Také existují datová návěští - DataLabel - jedná se o Id používaná direktivou data.
Ze syntaktického hlediska dále existuje seznam labelů Labels (LabelOrOffset [, LabelOrOffser]*, kde LabelOrOffset je Id (Id | Int32*)
Použité formátování | Obecné syntaktické elementy | Sémantika obecných elementů | Křížová reference direktiv | Blokové direktivy | Řádkové direktivy | Uživatelské atributy | Instrukce | CLI+CTS vs. CLS | Vysvětlivky a odkazy
Pseudo-uživatelské atributy | Speciální uživatelské atributy
Tato kapitola se zabývá významem pseudo-uživatelských a speciálních uživatelských atributů. Pro informace o způsobu definice a uložení vizte direktivu .custom.
CLI umožňuje použít jakoukoliv třídu jako atribut a aplikovat ji na jakoukoli položku metadat. CLS zavádí některá omezení.
Uživatelské atributy lze rozdělit do tří skupin:
Definovány ve jmenných prostorech System.Reflection, System.Runtime.CompilerServices a System.Runtime.InteropServices. Ne všechny jsou součástí současného standardu - některé rezervovány pro budoucí použití (označeny R; mohou být součástí implementace - třeba .NETu).
AssemblyAlgorithmIDAttributeRAssembly.HashAlgId.hash alghoritmAssemblyFlagsAttributeRAssembly.FlagsDllImportAttributeMethod.Flags.PinvokeImpl, vkládá nový řádek do ImplMappinvokeimplFieldOffsetAttributeFieldLayout.OffSet.fieldInAttributeParam.Flags.InMarshalAsAttributethe Field.Flags.HasFieldMarshal, Param.Flags.HasFieldMarshal, vkládá nový řádek do FieldMarshal.field, Param, .method {}MethodImplAttributeMethod.ImplFlags.method {} :: ImplAttrOutAttributeParam.Flags.Out StructLayoutAttribute.class, FieldOffsetAttributeComImportAttribute*TypeDef.Flags.Import.class {}OptionalAttribute*Param.Flags.OptionalNonSerializedAttribute*Field.Flags.NotSerialized .field :: notserializedPreserveSigAttribute*HRESULT nebo retval pro transformaci signaturyMethod.ImplFlags.PreserveSig.method{} :: preservesigSerializableAttribute*TypeDef.Flags.Serializable.class{} :: serializableAtribute definované CLS | Microsoft-specific atributy | Atributy zabezpečení | TLS atributy | Ostatní
Následující atributy definované CLS musí být podporovány správnými jazyky.
AttributeUsageAttributeObsoleteAttributeCLSCompliantAttributeKapitoly 21.2.3, 21.2.4, 21.2.5, 21.2.7, 21.2.8 obsahují speciální uživatelské atributy, používané Microsoftem. Jedná se o atributy kontrolující činnost CIL-to-native překladače, vzdálené volání (remoting), zabezpečení, interoperabilitu s nemanagovaným kódem a pseudo-uživatelské atributy pro assembly linker. Tyto atributy zde nejsou dále zmíněny.*
Pokud runtime "nepochopí" nějaký bezpečnostní atribut (zděděný od System.Security.Permissions.SecurityAttribute může odmítnou načít assembly s tímto atributem nebo může vyvolat
výjimku při pokusu o přístup k položce označené tímto atributem. (Platí i pro jiné vlastní atributy, které nemohou být instanciovány.)
CodeAccessSecurityAttributeDnsPermissionAttributeDnsPermissionEnvironmentPermissionAttributeEnvironmentPermissionFileIOPermissionAttributeFileIOPermissionReflectionPermissionAttributeReflectionPermissionSecurityAttributeCodeAccessSecurityAttribute od ní dědí.SecurityPermissionAttributeSocketPermissionAttributeSocketPermissionWebPermissionAttributeWebPermissionDokumentace obsahuje další atributy.*
Atributy pro nastavení TLS (Thread Local Storage)
ThreadStaticAttributeKontrolují různé záležitosti CLI
ConditionalAttributeDecimalConstantAttributeDecimalDefaultMemberAttributeInvokeMember.FaultModeAttributeFlagsAttributeIndexerNameAttributeParamArrayAttributevararg (viz CallConv).Použité formátování | Obecné syntaktické elementy | Sémantika obecných elementů | Křížová reference direktiv | Blokové direktivy | Řádkové direktivy | Uživatelské atributy | Instrukce | CLI+CTS vs. CLS | Vysvětlivky a odkazy
Prefixy:
constrained. | no. | readonly. | tail. | unaligned. | volatile.
Základní:
add | add.ovf/add.ovf.un | and | arglist | beq/beq.s | bge/bge.s | bge.un/bge.un.s | bgt/bgt.s | bgt.un/bgt.un.s | ble/ble.s | ble.un/ble.un.s | blt/blt.s | blt.un/blt.un.s | bne.un/bne.un.s | br/br.s | break | brfalse/brfalse.s/brnull/brnull.s/brzero/brzero.s | brtrue/brtrue.s/brinst/brinst.s | call | calli | ceq | cgt | cgt.un | ckfinite | clt | clt.un | conv.i1/conv.i2/conv.i4/conv.i8/conv.r4/conv.r8/conv.u1/conv.u2/conv.u4/conv.u8/conv.i/conv.u/conv.r.un | conv.ovf.i1/conv.ovf.i2/conv.ovf.i4/conv.ovf.i8/conv.ovf.u1/conv.ovf.u2/conv.ovf.u4/conv.ovf.u8/conv.ovf.i/conv.ovf.u | conv.ovf.i1.un/conv.ovf.i2.un/conv.ovf.i4.un/conv.ovf.i8.un/conv.ovf.u1.un/conv.ovf.u2.un/conv.ovf.u4.un/conv.ovf.u8.un/conv.ovf.i.un/conv.ovf.u.un | cpblk | div | div.un | dup | endfilter | endfault/endfinally | initblk | jmp | ldarg/ldarg.s/ldarg.0/ldarg.1/ldarg.2/ldarg.3 | ldarga/ldarga.s |
ldc.i4/ldc.i8/ldc.r4/ldc.r8/ldc.i4.0/ldc.i4.1/ldc.i4.2/ldc.i4.3/ldc.i4.4/ldc.i4.5/ldc.i4.6/ldc.i4.7/ldc.i4.8/ldc.i4.m1/ldc.i4.s |
ldftn | ldind.i1/ldind.i2/ldind.i4/ldind.i8/ldind.u1/ldind.u2/ldind.u4/ldind.r4/ldind.u8/ldind.r8/ldind.i/ldind.ref | ldloc/ldloc.s/ldloc.0/ldloc.1/ldloc.2/ldloc.3 | ldloca/ldloca.s | ldnull | leave/leave.s | lolcalloc | mul | mul.ovf/mul.ovf.un | neg | nop | not | or | pop | rem | rem.un | ret | shl | shr | shr.un | starg/starg.s | stind.i1/stind.i2/stind.i4/stind.i8/stind.r4/stind.r8/stind.i/stind.ref | stloc/stloc.s/stloc.0/stloc.1/stloc.2/stloc.3 | sub | sub.ovf/sub.ovf.un | switch | xor
Objektové:
box | callvirt | castclass | cpobj | initobj | isinst | ldelem | ldelem.i1/ldelem.i2/ldelem.i4/ldelem.i8/ldelem.u1/ldelem.u2/ldelem.u4/ldelem.u8/ldelem.r4/ldelem.r8/ldelem.i/ldelem.ref | ldelema | ldfld | ldflda | ldlen | ldobj | ldsfld | ldsflda | ldstr | ldtoken | ldvirtftn | mkrefany | newarr | newobj | refanytype | refanyval | rethrow | sizeof | stelem | stelem.i1/stelem.i2/stelem.i4/stelem.i8/stelem.r4/stelem.r8/stelem.i/stelem.ref | stfld | stobj | stsfld | throw | unbox | unbox.any
System.ExecutionEngineExceptionSystem.StackOverflowExceptionSystem.OutOfMemoryExceptionint32, int64, native int, F, O (reference na objekt, nerozlišuje typ referencovaného objektu), native unsigned int (jako nemanagovaný ukazatelový typ bez rozlišení typu objektu, na který ukazuje), & (managovaný ukazatel bez rozlišení typu objektu, na který ukazuje). Ukazatele a reference mohou být null, což odpovídá nule (0).| a / b | int32 | int64 | native int | F | & | O |
|---|---|---|---|---|---|---|
int32 | int32 | - | native int | - | & (add) | - |
int64 | - | int 64 | - | - | - | - |
native int | native int | - | native int | - |
& (add) | - |
F | - | - | - | F | - | - |
& | & (add, sub) | - | & (add, sub) | - | native int(sub) | - |
O | - | - | - | - | - | - |
& nejsou ověřitelné.
| Operand | int32 | int64 | native int | F | & | O |
|---|---|---|---|---|---|---|
| Výsledek | int32 | int64 | native int | F | - | - |
| a / b | int32 | int64 | native int | F | & | O |
|---|---|---|---|---|---|---|
int32 | + | - | + | - | - | - |
int64 | - | + | - | - | - | - |
native int | + | - | + | - | beq, beq.s, bne.un, bne.un.s, ceq
(vše neověřitelné) | - |
F | - | - | - | + | - | - |
& | - | - | beq, beq.s, bne.un, bne.un.s, ceq
(vše neověřitelné) | - | + | - |
O | - | - | - | - | - | beq, beq.s, bne.un, bne.un.s, ceq, cgt.un |
and, div.un, not, or, rem.un, xor
platí následující tabulka typů operandů a výsledku na zásobníku:| a / b | int32 | int64 | native int | F | & | O |
|---|---|---|---|---|---|---|
int32 | int32 | - | native int | - | - | - |
int64 | - | int 64 | - | - | - | - |
native int | native int | - | native int | - | - | - |
F | - | - | - | F | - | - |
& | - | - | - | - | - | - |
O | - | - | - | - | - | - |
| co / o kolik | int32 | int64 | native int | F | & | O |
|---|---|---|---|---|---|---|
int32 | int32 | - | int32 | - | - | - |
int64 | int64 |
- | int64 | - | - | - |
native int | native int | - | native int | - | - | - |
F | - | - | - | F | - | - |
& | - | - | - | - | - | - |
O | - | - | - | - | - | - |
add.ovf, add.ovf.un, mul.ovf.un, sub.ovf, sub.ovf.un
vyhazují výjimku při přetečení cílového datového typu a platí pro ně
následující tabulka:| a / b | int32 | int64 | native int | F | & | O |
|---|---|---|---|---|---|---|
int32 | int32 | - | native int | - | & (add.ovf.un) | - |
int64 | - | int 64 | - | - | - | - |
native int | native int | - | native int | - |
& (add.ovf.un) | - |
F | - | - | - | - | - | - |
& | & (add.ovf.un, sub.ovf.un) | - | & (add.ovf.un, sub.ovf.un) | - | native int(sub.ovf.un) | - |
O | - | - | - | - | - | - |
& jsou neověřitelné.& na int64, unsigned int64, native int
a native unsigned int jsou možné, ale neověřitelné.
Ostatní konverze typu & jsou nemožné.| metadata / zásobník | int32 |
native int |
int64 |
F |
& |
O |
|---|---|---|---|---|---|---|
| int8 | + | + | - | - | - | - |
| unsigned int 8, bool | + | + | - | - | - | - |
| int16 | + | + | - | - | - | - |
| unsigned int16, char | + | + | - | - | - | - |
| int32 | + | + | - | - | - | - |
| unsigned int32 | + | + | - | - | - | - |
| int64 | - | - | + | - | - | - |
| unsigned int64 | - | - | + | - | - | - |
| native int | + (znaménkové rozšíření) | + | - | - | - | - |
| native unsigned int | + (nulové rozšíření) | + (nulové rozšíření) | - | - | - | - |
| float32 | - | - | - | + | - | - |
| float64 | - | - | - | + | - | - |
| Class | - | - | - | - | - | + |
| By-ref | - | + (neověřitelné, začne používat GC) | - | - | + | - |
| Ref any | - | - | - | - | - | - |
.maxstack direktiva je povinná. Pokud program
specifikuje v direktivě menší číslo než jaké vyplívá ze statické a
analýzy kódu, je nevalidní a tudíž i neověřitelný, a nemusí být
spuštěn. .maxstack se nevztahuje ke skutečnému průběhu
programu, ale k výsledkům jeho statické analýzy.Slouží jako prefixy jiných instrukcí a modifikují jejich chování.
constrained. | no. | readonly. | tail. | unaligned. | volatile.
constrained. FE16Volat člena na hodnotě typu proměnné. Účelem je volání instrukce callvirt nezávislé na tom jestli typ je hodnotový nebo referenční.
constrained. thisTypecallvirt..., ptr, arg1, ..., argN → ..., ptr, arg1, ..., argN
ptr&) na thisTypethisType je referenční ptr je dereferencován a předán jako this-pointer instrukci callvirt.thisType je hodnotový typ, který implementuje metodu, ptr je předán instrukci call implementované typem.thisType je hodnotový typ a neimplementuje metodu, je ptr zaboxován a předán jako this-pointer instrukci callvirt (může se stát jen pro metody typů System.Object, System.ValueType a System.Enum).callvirt. thisType musí být platný typedef, typeref nebo typespec token metadat.ptr je managovaný pointer (&) na thisTypecallvirtno. FE19Přeskočit případnou kontrolu selhání. Následující instrukce nemusí provádět určenou kontrolu selhání
no.{typecheck|rangecheck|nullcheck}typecheckcastclass, unbox, ldelema, stelemInvalidCastException může být vyvolána, pokud kontrola není vynechána a selže.rangecheckldelem.*, ldelema, stelem.*IndexOutOfRangeException může být vyvolána, pokud kontrola nebyla vynechána a selhala.nullcheckldfld, stfld, callvirt, ldvirtftn, ldelem.*, stelem.*, ldelemaNullReferenceException může být vyvolána, pokud kontrola nebyla vynechána a selhala.no. není povoleno.readonly. FE1ENásledující instrukce vrátí managovaný ukazatel jen ke čtení a nebude provádět typovou kontrolu.
tail. FE14Následující volání ukončí aktuální metodu. Rámec aktuální metody bude zahozen před voláním. Návratová hodnota volané metody se stane návratovou hodnotou aktuální metody.
Z bezpečnostních důvodů může být ignorována v některých případech. Ignorována v synchronizovaných metodách. Implementace mohou předponu ignorovat i v dalších případech (ale ne vždy).
tail.call, calli, callvirtret. Kromě parametrů volané metody se při dosažení instrukce na zásobníku nic nevyskytuje. Není cílem skoku.unaligned. FE12Následující ukazatelová instrukce může být nezarovnaná (vzhledem k přirozené velikosti typu & nebo nemanagovaného ukazatele native int a následující instrukci).
volatile. FE13Následující ukazatel (addr) je nestálý (volatile). Tzn. že čtení z takové
adresy nemůže být cachováno a vícenásobná ukládání nemohou být zahozena. Typické použití, je pokud adresa náleží jinému vláknu. Přístup k takovému umístění musí být atomický.
add | add.ovf/add.ovf.un | and | arglist | beq/beq.s | bge/bge.s | bge.un/bge.un.s | bgt/bgt.s | bgt.un/bgt.un.s | ble/ble.s | ble.un/ble.un.s | blt/blt.s | blt.un/blt.un.s | bne.un/bne.un.s | br/br.s | break | brfalse/brfalse.s/brnull/brnull.s/brzero/brzero.s | brtrue/brtrue.s/brinst/brinst.s | call | calli | ceq | cgt | cgt.un | ckfinite | clt | clt.un | conv.i1/conv.i2/conv.i4/conv.i8/conv.r4/conv.r8/conv.u1/conv.u2/conv.u4/conv.u8/conv.i/conv.u/conv.r.un | conv.ovf.i1/conv.ovf.i2/conv.ovf.i4/conv.ovf.i8/conv.ovf.u1/conv.ovf.u2/conv.ovf.u4/conv.ovf.u8/conv.ovf.i/conv.ovf.u | conv.ovf.i1.un/conv.ovf.i2.un/conv.ovf.i4.un/conv.ovf.i8.un/conv.ovf.u1.un/conv.ovf.u2.un/conv.ovf.u4.un/conv.ovf.u8.un/conv.ovf.i.un/conv.ovf.u.un | cpblk | div | div.un | dup | endfilter | endfault/endfinally | initblk | jmp | ldarg/ldarg.s/ldarg.0/ldarg.1/ldarg.2/ldarg.3 | ldarga/ldarga.s |
ldc.i4/ldc.i8/ldc.r4/ldc.r8/ldc.i4.0/ldc.i4.1/ldc.i4.2/ldc.i4.3/ldc.i4.4/ldc.i4.5/ldc.i4.6/ldc.i4.7/ldc.i4.8/ldc.i4.m1/ldc.i4.s |
ldftn | ldind.i1/ldind.i2/ldind.i4/ldind.i8/ldind.u1/ldind.u2/ldind.u4/ldind.r4/ldind.u8/ldind.r8/ldind.i/ldind.ref | ldloc//ldloc.s/ldloc.0/ldloc.1/ldloc.2/ldloc.3 | ldloca/ldloca.s | ldnull | leave/leave.s | lolcalloc | mul | mul.ovf/mul.ovf.un | neg | nop | not | or | pop | rem | rem.un | ret | shl | shr | shr.un | starg/starg.s | stind.i1/stind.i2/stind.i4/stind.i8/stind.r4/stind.r8/stind.i/stind.ref | stloc/stloc.s/stloc.0/stloc.1/stloc.2/stloc.3 | sub | sub.ovf/sub.ovf.un | switch | xor
Instrukce nezávislé na objektovém modelu nebo CTS. Pokrývají základní operace.
add 58Součet dvou čísel
Sečte value1 a value2 a vrátí výsledek na zásobník.
Pro integery nedetekuje přetečení (viz. add.ovf) pro čísla s plovoucí čárkou vrací při přetečení +inf nebo -inf.
add..., value1, value2 → ..., resultadd.ovf D6; add.ovf.un D7Sečte znaménkové/neznaménkové integery s kontrolou přetečení
Sečte value1 a value2 a vrátí výsledek na zásobník.
add.ovf; add.ovf.un..., value1, value2 → ..., resultSystem.OverflowExceptionand 5FBitový AND dvou celočíselných hodnot
Provede bytový AND value1 a value2. Výsledek vrátí na zásobník.
and..., value1, value2 → ..., resultarglist FE00Vrátí handle seznamu argumentů aktuální metody
Vrátí handle typu System.RuntimeArgumentHandle, který
reprezentuje seznam argumentů aktuální metody. Handle je platný jen během života aktuální metody - může být předáván do dalších metod, pokud metoda, které patří je "naživu".
Instrukce může být vykonána jen v rámci metody s proměnným počtem argumentů vararg.
arglist... → ..., argListHandleSystem.RuntimeArgumentHandlebeq 3B; beq.s 2ESkok na cíl při shodě (branch if equal)
Skočí na cíl, pokud value1 je ekvivalentní (rovná se) value2.
target32 je 4 bytový (target8 1 bytový) znaménkový offset relativní k adrese začátku následující instrukce.
Nemůže být použita k opuštění bloků try, catch, filter a
finally (viz leave).
beq target32; beq.s target8..., value1, value2 → ..., bge 3C; bge.s 2FSkok na cíl pokud je větší nebo rovno.
Skočí na cíl (target32 - 4 bytový; target8 - 1 bytový) pokud value1 => value2.
target32 (resp. target8) je
znaménkový 4 (1) bytový offset cíle vůči začátku instrukce následující po této instrukci.
bge target32; bge.s target8..., value1, value2→ ..., bge.un 41; bge.un.s 34Skočí na cíl pokud je vetší nebo rovno (neznaménková verze)
Skočí na target32 (target8, pokud value1 >= value2 (neznaménkové porovnání).
target32 je 32 bitový offset (target8 8 bitový) cíle skoku vůči začátku následující instrukce.
bge.un target32; bge.un.s target8..., value1, value2 → ...bgt 3D; bgt.s 30Skočí na cíl pokud je větší.
Skočí na cíl target32 (target8), pokud value1 > value2.
target32 reprezentuje 32 bitový (target8 8 bitový) offset konce skoku vůči začátku následující instrukce.
bgt target32; bgt.s target8..., value1, value2 → ...bgt.un 42; bgt.un.s 35Skočí na cíl pokud je větší (neznaménková verze).
Skočí na cíl target32 (target8), pokud value1 > value2 (neznaménkové porovnání).
target32 reprezentuje 32 bitový (target8 8 bitový) offset konce skoku vůči začátku následující instrukce.
bgt.un target32; bgt.un.s target8..., value1, value2 → ...ble 3E; ble.s 31Skočí na cíl pokud je menší nebo rovno.
Skočí na cíl target32 (target8), pokud value1 <= value2.
target32 reprezentuje 32 bitový (target8 8 bitový) offset konce skoku vůči začátku následující instrukce.
ble target32; ble.s target8..., value1, value2 → ...ble.un 43; ble.un.s 36Skočí na cíl pokud je menší nebo rovno (neznaménkové porovnání).
Skočí na cíl target32 (target8), pokud value1 <= value2 (neznaménkové porovnání).
target32 reprezentuje 32 bitový (target8 8 bitový) offset konce skoku vůči začátku následující instrukce.
ble.un target32; ble.un.s target8..., value1, value2 → ...blt 3F; blt.s 32Skočí na cíl pokud je menší.
Skočí na cíl target32 (target8), pokud value1 < value2.
target32 reprezentuje 32 bitový (target8 8 bitový) offset konce skoku vůči začátku následující instrukce.
blt target32; blt.s target8..., value1, value2 → ...blt.un 44; blt.un.s 37Skočí na cíl pokud je menší (neznaménková verze).
Skočí na cíl target32 (target8), pokud value1 < value2 (neznaménkové porovnání).
target32 reprezentuje 32 bitový (target8 8 bitový) offset konce skoku vůči začátku následující instrukce.
blt.un target32; blt.un.s target8..., value1, value2 → ...bne.un 40; bne.un.s 33Skok pokud není rovno
Skočí na cíl target32 (target8) pokud value1 není rovno value2.
target32 reprezentuje 32 bitový (target8 8 bitový) offset konce skoku vůči začátku následující instrukce.
bne.un target32; bne.un.s target8..., value1, value2 → ...br 38; br.s 2BNepodmíněný skok
Skočí na cíl target32 (nebo target8).
target32 reprezentuje 32 bitový (target8 8 bitový) offset konce skoku vůči začátku následující instrukce.
br target32; br.s target8... → ...leave).break 01Informuje debugger o dosažení breakpointu.
Posílá debuggeru signál, že došlo k dosažení breakpointu. Nemá vliv na stav interpretu. Velikost této instrukce je nejmenší možná, takže breakpoint může být založen s minimálním vlivem na okolní kód. Výsledkem této instrukce může být vyvolání debuggeru, nic nebo bezpečnostní výjimka - to záleží na implementaci.
break... → ...brfalse 39; brfalse.s 2C; brnull 39; brnull.s 2C; brzero 39; brzero.s 2CSkok pokud je false, null nebo nula
Skočí na target32 (target8), pokud value je false, null nebo nula.
brnull a brzero je alias k brfalse; brnull.s a brzero.s je alias k brfalse.s.
value může být int32, int64, &, O, native int nebo nemanagovaný pointer.
target32 reprezentuje 32 bitový offset cíle, target8 8 bitový. Offset se počítá od začátku následující instrukce.
brfalse target32; brfalse.s target8;
brnull target32; brnull.s target8;
brzero target32; brzero.s target8
..., value → ...brtrue 3A; brtrue.s 2D; brinst 3A; brinst.s 2DSkok pokud je false, null nebo nula
Skočí na target32 (target8), pokud value je nenulová, true nebo nenullová.
brinst je alias k brtrue; brinst.s je alias k brtrue.s.s.
value může být int32, int64, &, O, native int nebo nemanagovaný pointer.
target32 reprezentuje 32 bitový offset cíle, target8 8 bitový. Offset se počítá od začátku následující instrukce.
brfalse target32; brfalse.s target8;
brnull target32; brnull.s target8;
brzero target32; brzero.s target8
..., value → ...call 28Volání metody
Zavolá metodu indikovanou deskriptorem method, což je matadata token typu methodref, methoddef nebo methodspec. Určuje metodu, která bude zavolána, volací konvenci a počet parametrů očekávaných na zásobníku.
Metadata token obsahuje všechny informace potřebné k zavolání metody (jestli je instanční, statická, globální, virtuální) a je z něj určena adresa (na rozdíl od callvirt, kde se konkrétní metoda určí podle konkrétního typu objektu.
Pokud metoda není definována na typu uvedeném v metadata tokenu, hledá se metoda nahoru v dědicí hierarchii (při kompilaci, ne za běhu).
Argumenty se na zásobníku nacházejí zleva doprava. Pokud je potřeba, je před argumenty umístěn this-pointer.
Pokud se call použije k volání virtuální metody, je skutečná metoda, která se použije určena staticky (lze použít např. k volání metody rodičovské třídy).
Návratová hodnota retVal nemusí být vždy přítomna.
call method..., arg1, ..., argN → ..., [retVal]Syste.SecurityExceptionSystem.MethodAccessExceptionprivate nebo protected metodě.System.MissinMethodExceptionmethod ukazuje na platný token metadat. Typy objektů na zásobníku jsou konzistentní s typy očekávanými metodou. Metoda je dostupná z kontextu volajícího (caller). Metoda není abstraktní (má implementaci).calli 29Nepřímé volání metody
Nepřímo zavolá metodu s parametry uloženými na zásobníku. Metoda je na zásobníku určena parametrem ftn (ukazatel na vstupní bod metody; ukazatel do nativního kódu cílového stroje; může být vytvořen ldftn nebo ldvirtftn nebo může přijít z nemanagovaného kódu).
callsitedescr obsahuje samostatný metadata token, který popisuje argumenty metody, jejich typy a volací konvenci (není kontrolována dynamicky).
Argumenty jsou na zásobníku umístěny zleva doprava. Pokud se jedná o instanční metodu, je před argumenty umístěn this-pointer.
Návratová hodnota retVal nemusí být vždy přítomna.
calli callsitedescr..., arg1, ..., argN, ftn → ..., [retVal]System.SecurityExceptionftn obsahuje ukazatel na metodu jejíž
signatuře odpovídá callsitedescr. Počty a typy argumentů odpovídají signatuře.ftn je vygenerován instrukcí ldftn nebo ldvirtftn.ceq FE01Test na rovnost
Uloží na zásobník 1 (Int32) pokud value1 = value2, jinak 0. Pro nezařazená čísla s plovoucí čárkou (NaN) vrátí vždy 0.
ceq..., value1, value2 → ..., resultcgt FE02Porovnání ne větší než.
Uloží na zásobník 1 (Int32), když value1 > value2, jinak 0.
Pro floating-pointy vrátí 0 pokud je jedno z čísel NaN. Plus a
mínus nekonečno je řazeno podle očekávání.
cgt..., value1, value2 → ..., resultcgt.un FE03Porovnání větší než (neznaménkové)
Uloží na zásobník 1 (Int32), když value1 > value2 (neznaménkové porovnání). Pro plovoucí čísla uloží jedničku i pokud value1 je neporovnatelné s value2. Nekonečna jsou porovnávána podle očekávání.
cgt.un..., value1, value2 → ..., resultckfinite C3Kontrola konečného reálného čísla
Vyhodí výjimku, pokud value není konečné číslo - tzn. je to NaN nebo ±∞. Hodnota na zásobníku zůstává.
ckfinite..., value → ..., valueSystem.ArithmeticExceptionF).clt FE04Porovnání menší než.
Uloží na zásobník 1 (Int32) pokud value1 < value2, jinak 0. Pro floating-pointy vrátí 0, pokud jedno z čísel je NaN. Nekonečna jsou řazena podle očekávání.
clt..., value1, value2 → ..., resultclt.un FE05Porovnání menší než.
Uloží na zásobník 1 (Int32) pokud value1 < value2 (neznaménkové porovnání), jinak 0. Pro floating-pointy vrátí 1, pokud jedno z čísel je NaN. Nekonečna jsou řazena podle očekávání.
clt.un..., value1, value2 → ..., resultconv.i1 67;
conv.i2 68;
conv.i4 69;
conv.i8 6A;
conv.r4 6B;
conv.r8 6C;
conv.u1 D2;
conv.u2 D1;
conv.u4 6D;
conv.u8 6E;
conv.i D3;
conv.u E0;
conv.r.un 76
Konverze
| instrukce | Logický typ výsledku | Fyzický typ výsledku | Poznámka |
|---|---|---|---|
conv.i1 | int8 | int32 |
|
conv.i2 | int16 | int32 |
|
conv.i4 | int32 | int32 |
|
conv.i8 | int64 | int64 |
|
conv.r4 | float32 | F |
|
conv.r8 | float64 | F |
|
conv.u1 | unsigned int8 | int32 |
|
conv.u2 | unsigned int16 | int32 |
|
conv.u4 | unsigned int32 | int32 |
|
conv.u8 | unsigned int64 | int64 |
|
conv.i | native int | native int |
|
conv.u | native unsigned int | native int |
|
conv.r.un | float32 nebo float64 | F |
Převede integer jako neznaménkový |
Převede hodnotu na zásobníku na jiný typ. Integery menší než 4B jsou uloženy jako 4B.
Při převodu plovoucí čárky na integery dochází k oříznutí čísla k nule. Pokud se číslo při konverzi z float64 na float32, do float32 nevejde je vráceno plus nebo mínus nekonečno.
Při přetečení při konverzi integerů jsou přetečené bity oříznuty (nedojde k
výjimce). Pokud je výsledek menší než int32 je znaménkově rozšířen.
Při přetečení při převodu plovoucího čísla na integer nebo při převodu NaN na integer je návratová hodnota nedefinovaná.
conv.r.un pochopí integer na zásobníku jako neznaménkový a převede jej na float32, pokud se do nej vejde bez ztráty přesnosti, jinak na float64.
conv.ovf.i1 B3;
conv.ovf.i2 B5;
conv.ovf.i4 B7;
conv.ovf.i8 B9;
conv.ovf.u1 B4;
conv.ovf.u2 B6;
conv.ovf.u4 B8;
conv.ovf.u8 BA;
conv.ovf.i D4;
conv.ovf.u D5;
Konverze s kontrolou přetečení
| instrukce | Logický typ výsledku | Fyzický typ výsledku |
|---|---|---|
conv.ovf.i1 | int8 | int32 |
conv.ovf.i2 | int16 | int32 |
conv.ovf.i4 | int32 | int32 |
conv.ovf.i8 | int64 | int64 |
conv.ovf.u1 | unsigned int8 | int32 |
conv.ovf.u2 | unsigned int16 | int32 |
conv.ovf.u4 | unsigned int32 | int32 |
conv.ovf.u8 | unsigned int64 | int64 |
conv.ovf.i | native int | native int |
conv.ovf.u | native unsigned int | native int |
Převede hodnotu na zásobníku na jiný typ. Integery menší než 4B jsou uloženy jako 4B.
Při převodu plovoucí čárky na integery dochází k oříznutí čísla k nule.
Pokud je výsledek menší než int32 je znaménkově rozšířen.
Při přetečení při převodu plovoucího čísla na integer nebo při převodu NaN na integer je návratová hodnota nedefinovaná.
conv.ovf.i1; conv.ovf.i2; conv.ovf.i4; conv.ovf.i8; conv.ovf.u1; conv.ovf.u2; conv.ovf.u4; conv.ovf.u8..., value → ..., resultSystem.OverflowExceptionconv.ovf.i1.un 82;
conv.ovf.i2.un 83;
conv.ovf.i4.un 84;
conv.ovf.i8.un 85;
conv.ovf.u1.un 86;
conv.ovf.u2.un 87;
conv.ovf.u4.un 88;
conv.ovf.u8.un 89;
conv.ovf.i.un 8A;
conv.ovf.u.un 8B;
Konverze (neznaménková) s kontrolou přetečení
| instrukce | Logický typ výsledku | Fyzický typ výsledku |
|---|---|---|
conv.ovf.i1.un | int8 | int32 |
conv.ovf.i2.un | int16 | int32 |
conv.ovf.i4.un | int32 | int32 |
conv.ovf.i8.un | int64 | int64 |
conv.ovf.u1.un | unsigned int8 | int32 |
conv.ovf.u2.un | unsigned int16 | int32 |
conv.ovf.u4.un | unsigned int32 | int32 |
conv.ovf.u8.un | unsigned int64 | int64 |
conv.ovf.i.un | native int | native int |
conv.ovf.u.un | native unsigned int | native int |
Převede hodnotu na zásobníku na jiný typ (vstupní hodnotu chápe jako neznaménkovou). Integery menší než 4B jsou uloženy jako 4B.
Při převodu plovoucí čárky na integery dochází k oříznutí čísla k nule.
Pokud je výsledek menší než int32 je znaménkově rozšířen.
Při přetečení při převodu plovoucího čísla na integer nebo při převodu NaN na integer je návratová hodnota nedefinovaná.
conv.ovf.i1; conv.ovf.i2; conv.ovf.i4; conv.ovf.i8; conv.ovf.u1; conv.ovf.u2; conv.ovf.u4; conv.ovf.u8..., value → ..., resultSystem.OverflowExceptioncpblk FE17Kopírování dat v paměti
Kopíruje blok velký size (v bytech, unsigned int32) začínající na adrese srcaddr (native int nebo &) na adresu destaddr (native int nebo &). Pokud se zdroj a cíl překrývají je chování nedefinované. Pokud není použit prefic unaligned, předpokládá, že sourceaddr i destaddr jsou zarovnány na přirozenou velikost stroje.
Instrukce je určena především ke kopírování struktur (než ke kopírování jakýchkoliv bytů). Všechny struktury uložené do paměti jsou CLI zarovnány na přirozenou velikost stroje, takže není potřeba se zabývat tím, jestli kód běží na 32b nebo 64b stroji.
cpblk..., destaddr, srcaddr, size → ...System.NullReferenceExceptiondiv 5BDělení
Vydělí dvě čísla. Celočíselné dělení ořezává k nule. Dlení konečného čísla nulou vytvoří nekonečno. Dělení nekonečna nekonečnem vytvoří NaN a dělení konečného čísla nekonečnem nulu.
0 / 0 = NaN; ∞ / ∞ = NaN; x / ∞ = 0; x / 0 = ∞; -x / 0 = -∞
div..., value1, value2 → ..., resultSystem.ArithmeticExceptionvalue1 je nejmenší možný integer a value2 je -1.)System.DivideByZeroExceptionvalue2 je 0.System.OverflowException*value1 je
nejmenší možný integer a value2 je -1.div.un 5CNeznaménkové dělení
Vydělí dvě čísla chápané jako neznaménkový integer.
div.un..., value1, value2 → ..., resultSystem.DivideByZeroExceptionvalue2 je 0dup 25Duplikace vrcholu zásobníku
Zduplikuje vrchol zásobníku.
dup..., value → ..., value, valueendfilter FE11Konec klauzule filter
Ukončí klauzule zachytávání chyb filter.
Používá se k návratu z filter klauzule.
Hodnota na zásobníku je int32 a může být jedna z následujících hodnot:
exception_continue_search)exception_execute_handler)Použití jiného integeru je nespecifikované.
Začátek obsluhy filtru musí být první instrukcí bloku filter. endfilter musí být poslední (tzn. jen jeden entfilter na jeden filter blok je povolen).
Průběh programu se do filter bloku nedostane za jiným
účelem než k určení zda má být ošetřena výjimka.
To nastane jen tehdy, byla-li jinde použita instrukce throw. V bloku filter není povoleno používat instrukce ret a leave.
Také zde nelze vytvořit vnořený blok try. Pokud dojde k
výjimce v bloku filter, je to interpretováno jako exception_continue_search.
endfilter..., value → ...int32 s povolenou hodnotou.int32 (a žádná jiná další!).endfault DC; endfinally DCKonec bloku finally nebo fault
Ukončuje blok finally nebo fault. Pak může začít/pokračovat odrolovávání zásobníku, dokud není nalezen handler
výjimky.
Na rozdíl of endfilter tyto instrukce se mohou ve svých blocích vyskytovat kdekoliv a kolikrátkoliv, nebo se nemusí vyskytovat vůbec. Mimo bloky, se ale vyskytovat nemohou.
Program nevstoupí do bloku finally nebo fault jinudy než přes CLI mechanizmus ošetřování výjimek.
Není možné "vyjet" z finally nebo fault bloku nebo zde použít instrukci ret nebo leave.
Instrukce vyčistí zásobník jako vedlejší efekt.
Instrukce jsou aliasy jedna ke druhé.
endfault; endfinally... → ...initblk FE18Inicializace bloku paměti
Nastaví byty v daném bloku paměti na danou hodnotu.
Nastaví size (unsigned int32) bytů od adresy addr (native int nebo &) na hodnotu value (unsigned int8). Předpokládá, že addr je zarovnána na přirozenou velikost stroje (ale je možno použít prefix unaligned..
Instrukce je určena k inicializaci struktur, které jsou od CLI vždy takto zarovnány, takže se není nutno
zabývat tím, jestli kód poběží na 32b nebo 64b platformě.
initblk..., addr, value, size → ...System.NullReferenceExceptionjmp 27Skok na metodu
Opustí aktuální metodu a skočí na jinou - definovanou metadata tokenem method (methodref nebo methoddef).
Aktuální argumenty jsou přeneseny do cílové metody.
jmp method → try, filter, catch, fault ani finally a nelze ji použít k přenesení kontroly mimo serializovaný region, jinak je výsledek nedefinovaný.ldarg FE09;
ldarg.s 0E;
ldarg.0 02;
ldarg.1 03;
ldarg.2 04;
ldarg.3 05;
Načtení argumentu na zásobník.
Načte na zásobník n-tý argument metody (0-based; Pozor na this-pointer). Typ načtené hodnoty je stejný jako typ argument uvedený v signatuře metody.
Instrukce ldarg.0, ldarg.1, ldarg.2 a ldarg.3 jsou efikasantnější pro první 4 argumenty metody. ldarg.s je
efikasantnější pro argumenty 4÷255 (num16 je typu unsigned int 16; num8 unsigned int8).
Pro metody s proměnným počtem argumentů, mohou být tyto instrukce použity jen pro pevné argumenty (viz arglist).
ldarg num16;
ldarg.s num8;
ldarg.0; ldarg.1; ldarg.2; ldarg.3
... → ..., valueldarga FE0A; ldarga.s 0FNačtení adresy argumentu
Načte na zásobník argumentu číslo argNum16 (unsigned int16) resp. argNum8 (unsigned int8).
Typ hodnoty na zásobníku je &. Argumenty se počítají od nuly (Pozor na this-pointer). Adresa je vždy zarovnána na přirozenou velikost stroje (hodí se pro cpblk a initblk).
Krátká verze, ldarga.s, by měla být používána pro
argumenty 0÷255.
Pokud metoda přijímá proměnný počet argumentů, lze pomocí této instrukce získat jen pevné argumenty.
ldarga se používá pro argumenty předávané jako reference (ByRef), jinak by měl být použit ldarg a starg.
ldarga argNum16; ldarga.s argNum8... → ..., addrldc.i4 20
ldc.i8 21
ldc.r4 22
ldc.r8 23
ldc.i4.0 16
ldc.i4.1 17
ldc.i4.2 18
ldc.i4.3 19
ldc.i4.4 1A
ldc.i4.5 1B
ldc.i4.6 1C
ldc.i4.7 1D
ldc.i4.8 1E
ldc.i4.m1 15
ldc.i4.s 1F
Načtení konstanty
Načte na zásobník konstantu daného typu, která je určena buďto operandem instrukce nebo přímo instrukcí samou.
ldc.r4 i ldc.r8 načtou konstantu typu F. ldc.i4.s typu int32.
Pro načtení konstanty typu int8 nebo int16, je potřeba po načtení použít instrukci conv.
ldc.i4 num32;
ldc.i8 num64;
ldc.r4 numr32;
ldr.r8 numr64;
ldc.i4.0;
ldc.i4.1;
ldc.i4.2;
ldc.i4.3;
ldc.i4.4;
ldc.i4.5;
ldc.i4.6;
ldc.i4.7;
ldc.i4.8;
ldc.i4.m1;
ldc.i4.s num8;
... → ..., numldftn FE06Načíst ukazatel na metodu
Uloží na zásobník nemanagovaný pointer (native int) na metodu method.
method musí být metadata token methodref nebo methoddef.
Uložená hodnota může být použita instrukcí calli, pokud se jedná o referenci na managovanou metodu nebo stub nemanagované metody.
Pointer samotný ukazuje do přeloženého nativního kódu, takže může být předáván i do nemanagovaného kódu (např. jako callback funkce).
Adresa metody může být vytvořena jen pro účel této instrukce (tzv. thunk).
ldftn method... → ..., ftnmethod je platný token metadat.native int - něco co může být použito ověřitelným voláním instrukce calli nebo pro vytvoření delegáta.ldind.i1 46;
ldind.i2 48;
ldind.i4 4A;
ldind.i8 4C;
ldind.u1 47;
ldind.u2 49;
ldind.u4 4B;
ldind.r4 4E;
ldind.u8 4C;
ldind.r8 4F;
ldind.i 4D;
ldind.ref 50;
Nepřímé načtení hodnoty na zásobník
Načte na zásobník hodnoty z adresy addr (nemanagovaný pointer (native int) nebo &). Typ hodnoty je určen příponou proměnné (znaménkový/neznaménkový integer příslušné velikosti, reálné číslo příslušné velikosti nebo O pro ldind.ref.
Instrukce ldind.* jsou aliasem pro instrukci ldobj pro určitý vestavěný typ.
addr musí být pozice s přirozeným zarovnáním stroje (pokud není použit unaligned. prefix; vše, co vytvářejí CIL instrukce je přirozeně zarovnáno.).
Pro datové typy větší jen 1B je pořadí bytů závislé na platformě. Pro integery kratší než 4B je nutné rozlišovat znaménkové a neznaménkové instrukce, aby CLI mohl provést znaménkové nebo neznaménkové rozšíření na int32. ldind.u8 je alias pro ldind.i8. ldind.i4 a ldind.u4 mají různé kódy, ale pracují identicky.
ldind.i1; ldind.i2; ldind.i4; ldind.i8; ldind.u1;
ldind.u2; ldind.u4; ldind.r4; ldind.u8; ldind.r8;
ldind.i; ldind.ref
..., addr → ..., valueSystem.NullReferenceExceptionaddr (nezarovnaná)ldloc FE0C;
ldloc.s 11;
ldloc.0 06;
ldloc.1 07;
ldloc.2 08;
ldloc.3 09;
Načtení lokální proměnné na zásobník.
Načte na zásobník lokální proměnnou identifikovanou indexem identifikovaným argumentem indx16 (int16) nebo indx8 (int8) nebo příponou instrukce.
ldloc.0, ldloc.1, ldloc.2 a ldloc.3 jsou efikasantnější pro přístup k prvním 4 lokálním proměnným než ldloc.s a ldloc.s je efikasantnější pro přístup k prvním 256 proměnným než ldloc.
Typ načtených dat je stejný jako typ lokální proměnné.
ldloc indx16; ldloc indx8... → ..., valueSystem.VerificationExceptionlocalsinit metody není nastaven a assembly obsahující metodu nemá oprávnění System.Security.Permissions.SecurityPermission.SkipVerification a CIL
neprovádí automatickou analýzu kódu za účelem
zjištění, že všechny proměnné jsou dříve zapsány než čteny.indx16 (resp. indx8) je platný index lokální
poměnné.indx16 65535 není platný! (protože implementace většinou používají int16 pro uložení jako indexu lokální proměnné tak pro uložení počtu lokálních proměnných. Těch může být maximálně 65535 - index 65534.localsinit metody nebo přiřazením do proměnné.
Druhá možnost je za účelem dodržení ověřitelnosti možná jen pro CLI, které provádí analýzu metody za účelem ověření, že proměnné nejsou
dříve čteny než zapsány.
ldloca FE0D; ldloca.s 12Načtení adresy lokální proměnné
Uloží na zásobník adresu lokální proměnné s indexem indx16 (int16) resp. indx8 (int8).
Adresa na zásobníku ukazuje na korektně přirozeně zarovnanou pozici a je typu &.
ldloca.s je efikasantnější variantou pro proměnné 0÷255.
ldloca indx16; ldloca.s indx8... → ..., addressSystem.VerificationExceptionlocalsinit metody není nastaven a assembly obsahující metodu nemá oprávnění System.Security.Permissions.SecurityPermission.SkipVerification a CIL
neprovádí automatickou analýzu kódu za účelem
zjištění, že všechny proměnné jsou dříve zapsány než čteny.indx16 (resp. indx8) je platný index lokální
proměnné.indx16 není 65535 (ze stejného důvodu jako u ldloc).localsinit metody nebo přiřazením do proměnné.
Druhá možnost je za účelem dodržení ověřitelnosti možná jen pro CLI, které provádí analýzu metody za účelem ověření, že proměnné nejsou
dříve čteny než zapsány.
ldnull 14Načíst nullový ukazatel
Načte na zásobník nullovou reference typu O.
ldnull... → ..., nullleave DD; leave.s DEOpuštění chráněného bloku
Bezpodmínečně opustí chráněný blok na adresu target16 (int16) resp. target8 (int8).
Cíl skoku je offset v bytech počítaný od začátku následující instrukce. Instrukce se používá k opuštění bloků try, filter a catch. Na rozdíl od instrukce br, která takto použita být nemůže.
Instrukce vyprázdní výpočetní zásobník a zapříčiní vykonání odpovídajících bloků finally.
Instrukci není možné použít o opuštění bloku finally, ale je jí možné použít ke skoku z bloku catch do asociovaného bloku try. Lze ji také použít k opuštění více vnořených bloků.
leave target16; leave.s target8... → localloc FE0FAlokovat paměť v lokálním prostoru
Alokuje paměť velikosti size (native unsigned int nebo unsigned int4) bytů v lokálním prostoru a vrátí adresu (nemanagovaný ukazatel typu native int)
prvního alokovaného bytu. Pokud flag metody localsinit je nastaven, je blok inicializován na nuly, jinak je tam ponecháno to, co tam bylo. Když aktuální metoda skončí, je takto alokovaná paměť volná k dalšímu použití.
Vrácená adresa je přirozeně zarovnaná (takže může být použita s instrukcemi stind a ldind.
mul 5ANásobení
Vynásobí čísla value1 a value2. Při přetečení při
celočíselné operaci je výsledek oříznut. Pro plovoucí operace 0 ∗ ∞ = NaN.
mul..., value1, value2 → ..., resultmul.ovf D8; mul.ovf.un D9Násobení s kontrolou přetečení
Vynásobí číla value1 a value2. Pokud se výsledek nevejde do cílového typu, dojde k
výjimce.
mul.ovf; mul.ovf.un..., value1, value2 → ...., resultSystem.OverflowExceptionneg 65Negace
Zneguje hodnotu na zásobníku a výsledek uloží na zásobník. Typ výsledku je stejný jako typ vstupu.
Not NaN = NaN
neg..., value → ...., resultnop 00Nic nedělej
Nic neudělá. Může být použita k vyplnění prostoru, pokud je bytecode patchovaný.
nop... → ...not 66Bitový doplněk
Vypočítá bitový doplněk celočíselné hodnoty na zásobníku. Výsledek je stejného typu jako vstup.
not..., value → ..., resultor 60Bitový or
Spočítá bitový or dvou integerů.
or..., value1, value2 → ..., resultpop 26Odstranit vrchol zásobníku
Odstraní vrchol zásobníku
..., top → ....rem 5DVypočítat zbytek po dělení
Vydělí čísla value1 a value2 a na
zásobník uloží zbytek po dělení.
Pro celá čísla dělení ořezává k nule. Znaménko výsledku je znaménko value1.
Pro plovoucí čísla platí, že pokud value2 je 0 nebo value1 je ∞, výsledek je NaN. Pokud value2 je ∞, výsledek je value1. (Toto se liší od IEC 60559:1989. Nelišící se výsledek poskytuje funkce System.Math.IEEERemainder.)
Pokud value2 je ±∞, výsledek je value1.*
rem..., value1, value2 → ..., resultSystem.DivideByZeroExceptionvalue2 je 0.System.ArithmeticExceptionvalue1 je nejmenší možný integer a value2 je -1.System.OverflowException*value1 je System.Int32.MaxValue a value2 je -1.rem.un 5EZbytek po dělení (neznaménkový)
Spočítá zbytek pod dělení dou čísel, jako by byla neznaménková. Není definováno pro plovoucí čísla.
rem.un..., value1, value2 → ..., resultSystem.DivideByZeroExceptionvalue2 je 0.ret 2ANávrat z metody
Navrátí se z aktuální metody. Návratový typ metody, pokud vůbec nějaký je, určuje typ hodnoty očekávané na zásobníku. Hodnota je odebrána ze zásobníku aktuální metody a vložena na zásobník metody, která ji zavolala.
ret[retVal]... → ..., [retVal]try, filter, catch a finally. Z try nebo catch použijte instrukci leave, jejímž cílem je instrukce ret umístěná mimo všechny bloky
výjimek.retVal je kompatibilní s návratovým typem metody.shl 62Levý celočíselný posuv
Posune celočíselnou hodnotu (int32, int64, native int) doleva o zadaný počet bitů. Nasouvá nuly.
Návratová hodnota není specifikována, pokud shiftAmount je větší nebo roven šířce value.
shl..., value, shiftAmmount → ..., resultshr 63Pravý celočíselný posuv
Posune celočíselnou hodnotu (int32, int64, native int) doprava o zadaný počet bitů. Nasouvá znaménko.
Návratová hodnota není specifikována, pokud shiftAmount je větší nebo roven šířce value.
shl..., value, shiftAmmount → ..., resultshr.un 64Pravý celočíselný posuv (neznaménkový)
Posune celočíselnou hodnotu (int32, int64, native int) doprava o zadaný počet bitů. Nasouvá nuly.
Návratová hodnota není specifikována, pokud shiftAmount je větší nebo roven šířce value.
shl..., value, shiftAmmount → ..., resultstarg FE0B; starg.s 10Uložit hodnoty do slotu argumentu
Uloží hodnotu ze zásobníku do slotu argumentu. starg.s je efikasantnější varianta pro prvních 256 argumentů. U metod s proměnným počtem argumentů, lze použít jen pro fixní argumenty.
start num16; startg.s num8..., value → ...num16 resp. num8 je číslo platného slotu argumentu.stind.i1 52;
stind.i2 53;
stind.i4 54;
stind.i8 55;
stind.r4 56;
stind.r8 57;
stind.i DF;
stind.ref 51;
Nepřímé uložení hodnoty
Uloží hodnoty val na adresu addr (nemanagovaný pointer native int nebo managovaný pointer &).
addr musí být přirozeně zarovnána (pokud není použit prefix unaligned.).
Pořadí bytů záleží na cílovém CPU. Všechny instrukce stind jsou zkratky instrukce stobj pro daný vestavěný typ.
Za účelem typové bezpečnosti musí být instrukce používána způsobem konzistentním s typem ukazatele.
stind.i1;stind.i2;stind.i4;stind.i8;stind.r4;stind.r8;stind.i;stind.ref..., addr, val → ...System.NullReferenceExceptionaddr není přirozeně zarovnána a prefix unaligned. není použit.addr je ukazatel, jehož typ je pro přiřazení kompatibilní s typem val.addr je & a val je pro přiřazení kompatibilní s addr.stloc FE0E;
stloc.s 13;
stloc.0 0A;
stloc.1 0B;
stloc.2 0C;
stloc.3 0D
Uložit hodnotu do lokální proměnné
Uloží hodnotu ze zásobníku do lokální proměnné specifikované indexem (indx16 - unsigned int 16, indx8 - unsigned int 8) nebo příponou instrukce.
Lokální proměnné jsou číslovány od 0. stloc.0, stloc.1, stloc.2 a stloc.3 jsou efikasantnější pro první 4 proměnné. stdloc.s je efikasantnější pro proměnné 4÷255.
Typ value musí odpovídat typu proměnné.
stloc indx16; stloc indx8; stloc.0; stloc.1; stloc.2; stloc.3 → indx16 resp. indx8 je platný index lokální proměnné.indx16 není 65535.value odpovídá typu lokální proměnné.sub 59Odčítání
Odečte dvě čísla. Nekontroluje přetečení celočíselné operace. Při přetečení plovoucí operace vrátí ±∞; při podtečení 0.
..., value1, value2 → ..., resultsub.ovf DA; sub.ovf.un DBOdčítání s kontrolou přetečení.
Odečte dvě hodnoty celočíselného typu. sub.ovf.un se k ním chová, jako by byly neznaménkové.
sub.ovf; sub.ovf.un..., value1, value2 → ..., resultSyste.OverflowExceptionswitch 45Tabulkový skok
Implementuje skokovou tabulku. Binárně je uložena jako opcode, unsigned int32 reprezentující počet cílů a daný počet int32 reprezentující cíle.
Cíle jsou offsety v bytech od začátku následující instrukce.
Instrukce vyzvedne ze zásobníku číslo jako neznaménkový integer a porovná jej s počtem cílů.
Pokud je value menší než počet cílů, je kontrola přenesena na value-tý cíl (číslovány od 0). Pokud value není menší než počet cílů, pokračuje se následující instrukcí!
switch (t1, t2, ..., tN)..., value → ...try, catch, filter a finally nejsou povoleny.xor 61Bitový xor
Provede bitový xor dvou hodnot.
xor..., value1, value2 → ..., resultbox | callvirt | castclass | cpobj | initobj | isinst | ldelem | ldelem.i1/ldelem.i2/ldelem.i4/ldelem.i8/ldelem.u1/ldelem.u2/ldelem.u4/ldelem.u8/ldelem.r4/ldelem.r8/ldelem.i/ldelem.ref | ldelema | ldfld | ldflda | ldlen | ldobj | ldsfld | ldsflda | ldstr | ldtoken | ldvirtftn | mkrefany | newarr | newobj | refanytype | refanyval | rethrow | sizeof | stelem | stelem.i1/stelem.i2/stelem.i4/stelem.i8/stelem.r4/stelem.r8/stelem.i/stelem.ref | stfld | stobj | stsfld | throw | unbox | unbox.any
Poskytují společnou efikasantní implementaci pro přístup k objektům, kterou může využít většina (ne nutně všechny) vyšší programovací jazyky. Zahrnují konvence CTS, například pozicování proměnných (fields) v objektech, late-bound volání metod, alokace a uvolňování paměti, ošetřování výjimek, boxování a deboxování.
Jedná se o "méně vestavěné" instrukce. Instrukce nemusí být přeložena na nativní instrukci - může být přeložena na volání operačního systému.
box 8CZaboxování
Zaboxuje boxovatelnou hodnotu. Pokud typeTok je hodnotový typ, převede val na boxovaný ekvivalent. To je uděláno tak, že se vytvoří nový objekt a data z val se do něj nakopírují. Pokud typeTok je referenční typ, instrukce neudělá nic.
box typeTok..., val → ..., objSystem.OutOfMemoryExceptionSystem.TypeLoadExceptiontypeTok nemůže být nalezen. Typicky nastane, když se CIL převádí do nativního kódu namísto za běhu.typeTok je platný typedef, typeref nebo typespec metadata token reprezentující boxovatelný typ.typeTok. Pokud typeTok je hodnotový typ nebo generický parametr, výsledný typ je boxovaný typeTok. Pokud typeTok je referenční typ, výsledný typ je typeTok.typeTok nesmí být byref, něco jako byref nebo void.callvirt 6FVolání virtuální funkce (přiřazené k objektu za běhu)
Zavolá late-bound metodu objektu. Metoda se vybere za běhu podle aktuálního typu objektu namísto výběru za kompilace, podle viditelného typu objektu. ůže být použita k volání virtuálních a instančních metod.
memthod je metadata token methoddef, methodref nebo methodspec poskytující jméno, třídu a signaturu metody. Pokud objekt obj implementuje metodu, jejíž jméno a signatura odpovídají uložené signatuře, zavolá se tato metoda. Pokud ne hledá se taková metoda po rodičovských třídách objektu obj. Pokud není nalezena, je to chyba.
Pokud má metoda návratovou hodnotu, je tato uložena na zásobník. Volaná metoda má dostupný objekt obj
jako argument 0 (this-pointer) a další argumenty od 1.
callvirt method..., obj, arg1, ..., argN → ..., [retVal]System.MissingMethodExceptionobj ani jeho rodičích. Typicky detekováno při převodu CIL do nativního kódu než za běhu.System.NullReferenceExceptionobj je null.System.SecurityExceptionobj je konzistentní s volanou metodou.tail vyžaduje další omezení.castclass 74Přetypování
Pokusí se přetypovat objekt typu O na typ class (metadata token typeref, typedef nebo typespec).
System.ArrayFoo může být přetypováno na Bar, pak Foo[] může být přetpováno na Bar[].obj je null, přetypování uspěje a výsledkem je null.castclass class..., obj1 → ..., obj2System.InvalidCastExceptionobj nemůže být přetypován na class (obj neimplementuje interface class, pokud class je interface, ani nedědí od class, pokud class je "obyčejná" třída).System.TypeLoadExceptionclass nemůže být nalezena. Typicky detekováno při převodu CIL do nativního kódu namísto za běhu.class je platný typeref, typedef nebo typespec metadata token.obj je vždy null nebo referenční typ.cpobj 70Kopírování hodnoty z jedné adresy na druhou
Zkopíruje objekt ze zdrojové pozice src (nemanagovaný nebo managovaný pointer) na adresu dest (nemanagovaný nebo managovaný pointer).
typeTok je metadata token typedef, typeref nebo typespec.
Chování není specifikováno, pokud objekt na adrese src není pro přiřazení kompatibilní s objektem na adrese dest.
Pokud typeTok je referenční typ, má cpobj stejný efekt jako sekvence ldind.ref a stind.ref.
cpobj typeTok..., dest, src → ...System.NullReferenceExceptionSystem.TypeLoadExceptiontypeTok nemůže být nalezen. Typicky detekováno při převodu CIL do nativního kódu namísto za běhu.typeTok je platný typedef, typeref nebo typespec, metadata token.&.src je pro přiřazení kompatibilní s typem dest. Pro výčty se jedná o kompatibilitu podtypů.initobj FE15Inicializace hodnoty na adrese
Inicializuje adresu dest (managovaný nebo nemanagovaný pointer) na výchozí hodnotu.
Pokud typeTok je hodnotový typ inicializuje všechny jeho proměnné (fields) na null nebo nulu odpovídajícího vestavěného typu. Po tom je instance připravena k volání konstruktoru hodnotového typu.
Pokud typeTok je referenční typ má instrukce stejný efekt jako sekvence ldnull a stind.ref.
Na rozdíl od newobj, tato instrukce nevolá CTor.
initobj typeTok..., dest → ...typeTok je platný metadata token typedef, typeref nebo typespec.dest je typu &, managovaný pointer, na stejný typ jako typeTok nebo typeTok je jeho podtyp.
Pro nereferenční typy si typ typeTok a dest musí exaktně odpovídat.
isinst 75Test jestli objekt je instancí třídy nebo interfacu
Testuje jestli objekt obj (O) je instancí třídy class. Pokud ano dojde k přetypování jako u castclass a výsledek je uložen na zásobník. Jinak je na zásobník uložen null. Pokud obj je null, výsledek je také null.
isinst class..., obj → ..., resultSystem.TypeLoadExceprionclass nemůže být nalezen. Typicky detekováno při převodu CIL na nativní kód namísto za běhu.class je platný metadata token typeref, typedef nebo typespec>.obj je vždy referenční typ nebo null.ldelem A3Načtení prvku pole
Z pole array načte položku na indexu index (native int nebo int32). Funguje pro 0-based 1-rozměrná pole. Typ návratové hodnoty je indikován metadata tokenem typeTok.
ldelem typeTok..., array, index → ..., valueSystem.IndexOutOfRangeExceptionindex je větší než hranice pole.System.NullReferenceExceptionarray je null.typeTok je platný metadata token typeref, typedef nebo typespec.array je vždy null nebo jednorozměrné 0-based pole.Null nebo správné 0-based jednorozměrné pole typu elem[]. Pokud typ pole je Null, typ elem je vzat z typeTok.index je typu native int.elem je podtyp typu typeTok.typeTok.ldelem.i1 90;
ldelem.i2 92;
ldelem.i4 94;
ldelem.i8 96;
ldelem.u1 91;
ldelem.u2 93;
ldelem.u4 95;
ldelem.u8 96;
ldelem.r4 98;
ldelem.r8 99;
ldelem.i 97;
ldelem.ref 9A
Načtení elementu pole
Načte na zásobník položku z pole array (O) na indexu index (native int nebo int32). Funguje pro 0-base 1D pole. Návratový typ je indikován příponou instrukce.
ldelem.u8 je alias k ldelem.i8.
ldelem.ref načte položku typu O. Skutečný typ je odvozen z typu pole vloženého na zásobník.
ldelem.i1;
ldelem.i2;
ldelem.i4;
ldelem.i8;
ldelem.u1;
ldelem.u2;
ldelem.u4;
ldelem.u8;
ldelem.r4;
ldelem.r8;
ldelem.i;
ldelem.ref
..., array, index → ..., valueSystem.NullReferenceExceprionarray je nullSystem.IndexOutOfRangeExceptionindex je záporný nebo větší než hranice pole.array je null nebo 0-based 1D pole jehož deklarovaný typ elementů exaktně odpovídá
typu podle přípony instrukce.index je native int nebo int32ldelema 8FNačíst adresu elementu pole
Načte na zásobník adresu elementu pole array (O) na indexu index (native int nebo int32). Funguje pro 0-based 1D pole. Typ elementu pole musí být class.
Návratovou hodnotou je managovaný pointer &.
Pro 1D ne 0-based pole vizte metodu Address třídy System.Array.
ldelama class..., array, index → ..., addressSystem.NullReferenceExceptionarray je null.System.IndexOutOfRangeExceprionindex je záporný nebo větší než hranice pole.System.ArrayTypeMisMatchExceptionclass je platný metadata token typeref, typedef nebo typespec.array je vždy null nebo 0-base 1D pole elementů typu, který exaktně odpovídá class.index je int32 nebo native int.ldfld 7BNačtení proměnné objektu (field)
Načte na zásobník hodnotu proměnní (field) objektu obj (O, &, nemanagovaný pointer native int nebo instance hodnotového typu).
Návratový typ je typ asociovaný s proměnnou. Lze načíst proměnnou instance i typu (obj null).
ldfld field..., obj → ..., valueSystem.FieldAccessExceptionfield není dostupná.System.MissingFieldExceptionfield nemůže být v metadatech nalezena. Typicky nastává při převodu CIL do nativního kódu namísto za běhu.System.NullReferenceExceptionobj je null a proměnná field není statická.field je platný metadata token fieldref nebo fielddef.obj je vždy kompatibilního typu s typem požadovaným pro hledání proměnné (field).obj není nemanagovaný pointer.ldflda 7CNačtení adresy proměnné (field)
Načte na zásobník adresu proměnné (field) field objektu obj (O nebo managovaný nebo nemanagovaný pointer). Návratová hodnota je typu &, pokud obj není nemanagovaný pointer - pak je vrácen nemanagovaný pointer (native int).
field může ukazovat na instanční nebo typovou proměnnou (field). V případě typové je obj null.
Použítí ldflda k získání adresy statické proměnné (field) init-only a použití tohoto ukazatele k modifikaci hodnoty mimo inicializátor typu může vést k nepředpokládatelnému chování.
ldflda field..., obj → ..., addrSystem.FieldAccessExceptionSystem.InvalidOperationExceptionobj není z aplikační domény, ze které je k němu přistupováno.System.MissingFieldExceptionfield nebyl v metadatech
nalezen. Typicky je kontrolováno při překladu CIL do
nativního kódu na místo za běhu.System.NullReferenceExceptionobj je null a proměnná (field) není statická.field je platný metadata token fieldrefobj je vždy kompatibilního typu s typem nutným k hledání proměnné.field není init-only.ldlen 8ENačtení délky pole
Načte délku (native unsigned int; počet elementů) pole na zásobník. Funguje pro 1D 0-base pole.
ldlen..., array → ..., lenghtSystem.NullreferenceExceptionarray je null.array je vždy null nebo 0-based 1D pole.ldobj 71Načtení hodnoty z adresy na zásobník
Zkopíruje hodnotu uloženou na adrese src (managovaný nebo nemanagovaný pointer) na zásobník.
Pokud typeTok je referenční typ, má stejný efekt jako ldind.ref.
Může být použita k předání hodnotového typu jako argumentu.
ldobj typeTok..., src → ..., valSystem.NullreferenceExceptionSystem.TypeLoadExceptiontypeTok nemůže být nalezen. Typicky detekováno při překladu CIL do nativního kódu namísto za běhu.typetok je platný typeref, typedef nebo typespec metadata token.src) musí být managovaný pointer na typ, který je podtypem typeTok. Statický typ hodnoty na zásobníku je typeTok.ldsfld 7ENačtení statické proměnné (field) třídy
Načte statickou proměnnou (field) třídy. Návratový typ je typ asociovaný s proměnnou (field).
ldsfld field... → ..., valueSystem.FieldAccessExceptionfield je nedostupnýSystem.MissingFieldExceptionNení v metadatech k nalezení. Typicky kontrolováno při překladu CIL do nativního kódu namísto za běhu.field je platný metadata token fieldref nebo fieldded ukazujíc na statickou proměnnou (field).ldsflda 7FNačíst adresu statické proměnné (field) třídy
Načte managovaný pointer na statickou proměnnou (field) třídy. Pokud field ukazuje na proměnnou, jejíž typ není managovaný, pak načte nemanagovaný pointer. Proměnná může být globální s přiřazeným RVA (relativní virtuální adresou od adresy, na kterou je načten PE soubor do paměti), pak je jeho paměť nemanagovaná.
Použití instrukce k načtení statické init-only proměnné (field) a použití ukazatele k modifikaci hodnoty mimo inicializátor třídy může vést k nepředpokládanému chování.
ldsflda field... → ..., addrSystem.FieldAccessExceprionfield není dostupný.System:fieldNotFoundExceptionfield není v metadatech k nalezení. Typicky kontrolováno při převodu CIL do nativního kódu namísto za běhu.field je platný metadata token fieldref nebo fielddef ukazující na statickou proměnnou (field).field není init-only.ldstr 72Načtení stringového literálu
Uloží na zásobník nový objekt typu String, který reprezentuje zadaný literál
uložený v metadatech. Instrukce alokuje paměť a provede potřebnou konverzi literálu z formátu používaného v PE souboru na formát
potřebný za běhu.
ldstr string... → ..., stringstring je platný metadata token stringového literálu.ldtoken D0Načít runtime reprezentaci tokenu metadat
Načte RuntimeHandle tokenu na zásobník. Ten může být použit pro reflection. Typy načtených handlů pro různé typy tokenů jsou následující:
| Typ metadata tokenu | Typ handlu |
|---|---|
methoddef |
RuntimeMethodHandle |
methodref | |
methodspec | |
typedef |
RuntimeTypeHandle |
typeref | |
typespec | |
fielddef |
RuntimeFieldHandle |
fieldref |
ldtoken token... → ..., RuntimeHandletoken je platný metadata token typu methoddef, methodref, methodspec, typedef, typeref, typespec, fielddef nebo fieldrefldvirtftn FE07Načíst ukazatel na virtuální metodu
Načte nemanagovaný pointer (native int) do nativního kódu implementujícího metodu method. Načtený ukazatel může být použit instrukcí calli, pokud ukazuje na managovanou metodu nebo na stup nemenagované metody.
Vrácený ukazatel ukazuje do nativního kódu, takže může být předán nemanagovanému kódu jako ukazatel na callback metodu, pokud nemanagovaný kód akceptuje použitou volací konvenci. Vrácená adresa může být jen "zástupce" vytvořený speciálně pro účel této instrukce.
ldvirtftn method..., object → ..., ftnSystem.NullReferenceExceptionobject je null.method je platný metadata token methoddef, methodref nebo methodspec referující nestatickou metodu definovanou na objektu object.native int - že je to ukazatel na metodu. Ten může být použit v ověřitelném volání instrukce calli nebo k vytvoření delegáta.mkrefany C6Vytvořit typovanou referenci
Podporuje předávání dynamicky typovaných referencí. ptr je managovaný nebo nemanagovaný ukazatel, který obsahuje adresu nějakých dat. class je metadata token popisující typ ukazatele.
Jediné, co lze s typovanou referencí dělat, je předat ji do metody, která ji požaduje. Volaná metoda, pak může použít instrukce refanytype a refanyval k obdržení typu a adresy.
mkrefany class..., ptr → ..., typedRefSystem.TypeLoadExceptionclass není k nalezení. Typicky kontrolováno při překladu managovaného kódu do nativního namísto za běhu.class platný typedef nebo typeref metadata token.ptr je ukazatel na typ class.ptr je managovaný pointer na instanci třídy.newarr 8DNové 1D 0-based pole
Vytvoří nové 0-base 1D pole s numElems (native int nebo int32) elementy typu etype. Elementy pole mohou být libovolného typu vč. hodnotových.
newarr etype..., numElements → ..., arraySystem.OutOfMemoryExceptionSystem.OverflowExceptionnumElems < 0.etype je pletný metadata token typeref, typedef nebo typespec.numElems je typu native int nebo int32.newobj Vytvořit nový objekt
Vytvoří nový objekt za použití daného CToru. Je alokován nový objekt, všechny proměnné (fields) instance jsou nastaveny na 0 nebo null odpovídajícího typu, pak je zavolán zvolený konstruktor a jsou mu předány argumenty a nově vytvářený objekt. Konstruktor dostane nově vytvářený objekt jako argument 0 (this-pointer).
0-base 1D pole se musejí vytvářet pomocí newarr. Ostatní pole se vytvářejí pomocí newobj.
Hodnotové typy se obvykle nevytvářejí pomocí newobj, ale lze to.
newobj ctor..., arg1, ..., argN → ..., objSystem.InvalidOperation:Exceptionctor je abstraktní.System.OutOfMemoryExceptionSystem.MissingMethodExceptionctor je platný methoddef nebo methodref metadata token.native int musí ukazovat na metodu správného typu.refanytype FE1DTyp typované reference
Z typované reference "vytáhne" její typ - token typu.
refanytype..., TypedRef → ..., typeTypedRef je platná typovaná reference vytvořená pomocí mkrefany.refanyval C2Hodnota typované reference
Z typované reference "vytáhne" adresu její hodnoty (&).
refanyvyl type..., TypedRef → ..., addressSystem.InvalidCastExceptiontype neodpovídá typu uloženému v typované referenci.System.TypeLoadExceptiontype není k nalezení.TypedRef je platná typovaná reference vytvořená pomocí mkrefany.rehtrow FE1AZnovuvyhodit aktuální výjimku
Znovuvyhodí aktuální výjimku. Korektní je jen v bloku catch, ale ne v handleru
výjimky v rámci bloku catch.
Vyhodí tu samou výjimku, jaká byla handlerem zachycena. Nemění její trasování zásobníku.
Pokud je použita mimo catch blok, bude vyhozena
výjimka, ale není definováno jaká.
→ catch, ne v nějakém handleru
výjimky uvnitř tohoto bloku.sizeof FE1CVelikost typu v bytech
Vrací velikost typu v bytech. typeTok může být generický parametr, referenční typ nebo hodnotový typ.
Definice hodnotového typu se může změnit mezi tím, kdy byl CIL vygenerován a kdy by spuštěn. Proto je zde instrukce sizeof umožňující zjisti velikost typu za běhu, bez
nutnosti volat metody frameworku. Výpočet může proběhnou za běhu nebo ři překladu CIL do nativního kódu. Výsledek udává velikost (v bytech; unsigned int32), kterou bude zabírat instance typu, pokud bude prvkem pole v poli. Jedná se o velikost včetně jakéhokoliv paddingu přidaného implementací.
sizeof typeTok... → ..., sizetypeTok je platný metadata token typeref, typedef nebo typespec.stelem A4Uložit element do pole
Nahradí prvek pole array (O) na 0-based indexu index (native int nebo int32) hodnotou value. value má typ jako typeTok.
stelem typeTok..., array, index, value → ...System.NullReferenceExceptionarray je null.System.IndexOutOfRangeExceptionindex je větší než hranice pole.System.ArrayTypeMisMatchExceptiontypeTok je platný metadata token typeref, typedef nebo typespec.array je null nebo 1D pole.Null nebo správné 0-based 1D pole s prvky typu elem. Pokud typ pole je Null, typ elem se odoví z operandu typeTok. Jinak elem musí být nadtyp operandu typeTok.index je typu native intvalue je pro přiřazení kompatibilní s typeTok.stelem.i1 9C;
stelem.i2 9D;
stelem.i4 9E;
stelem.i8 9F;
stelem.r4 A0;
stelem.r8 A1;
stelem.i 9B;
stelem.ref A2;
Uložení elementu do pole.
Nahradí položku pole array (O) na 0-based indexu index (int32 nebo native int) v 1D poli hodnotou value.
stelem.ref implicitně přetypuje value na typ položky pole před zapsáním. Toto přetypování může
selhat i pro ověřený kód!
Pro vícerozměrná nebo ne-0-base pole použijte metodu StoreElement System.Array.
stelem.i1; stelem.i2; stelem.i4; stelem.; stelem.i8; stelem.r4; stelem.r8; stelem.i; stelem.ref..., array, index, value → ...System.NullReferenceExceptionarray je null.System.IndexOutOfRangeExceptionindex je záporný nebo větší než hranice pole.System.ArrayTypeMismatchExceptionarray je 1D 0-based pole, jehož deklarovaný typ položek přesně odpovídá typu instrukce pole přípony.Null nebo správné 0-based 1D pole položek typu elem.array a typ hodnoty value je konzistentní s příponou instrukce. Pro stelem.ref stačí, když jak hodnota value tak položky pole jsou referenčního typu.stfld 7DUložit hodnotu do proměnné objektu (field)
Uloží do proměnné (field) field objektu obj (O nebo managovaný nebo nemanagovaný ukazatel) hodnotu value.
dtflf field..., obj, value → ...System.FieldAccessExceptionfield není dostupná.System.NullReferenceExceptionobj je null a proměnná není statická.System.MissingFieldExceptionfield je platný metadata token fielddef nebo fieldref.obj a value mají správný typ vzhledem k field.obj není nemanagovaný pointerstfld na statickou proměnnou (field) typu init-only mimo inicializátor typu, může vést k nepředpovídatelnému chování, ale
nemůže porušit integritu paměti a typovou bezpečnost, takže není testováno při ověřování.stobj 81Uložit hodnotu na adrese
Pokud typeTok je hodnotový typ, kopíruje instrukce hodnotu ze src na dest. Pokud typeTok je referenční typ má instrukce stejný efekt strind.ref.
stobj typeTok..., dest, src → ...System.NullReferenceExceptionSystem.TypeLoadExceptiontypeTok není k nalezení. Kontrola se typicky provádí pře překladu CIL do nativního kódu namísto za běhu.typeTok je platný metadata token typeref, typedef nebo typespec.src je referenční, musí být inicializován.dest musí být &.typeTok a typeTok musí být podtype typu cíle (pro hodnotové typy to znamená, že typeTok musí být stejný jako typ cíle).stsfld 80Uložení hodnoty do statické proměnné typu.
Do statické proměnné typu (field) uloží hodnotu.
stsfld field..., val → ...System.FieldAccessExceptionfield není dostupnáSystem.MissingFieldExceptionfield neí v metadatech k nalezení. Toto se typicky kontroluje při překladu CIL do nativního kódu a ne za běhu.field je platný metadata token fielddef nebo fieldref.value je vždy typu vhodného pro přiřazení do dané proměnné.throw 7AVyhození výjimky
Vyhodí výjimku object (O) a vyprázdní zásobník.
Z pohledu CLI může být vyhozen libovolný typ. CLS vyžaduje,a by vyhazovaný typ dědil od System.Exception.
throw..., object → ...System.NullReferenceExceptionobj je nulobjobj je vždy null nebo O.unbox 79Deboxace
Extrahuje z hodnoty typu boxovaný hodnotový typ ukazatel na hodnotový typ, který je v ní zaboxovaný
Výsledný ukazatel je typu & jen pro čtení.
Na rozdíl od box, unbox nekopíruje hodnotu. Typicky jen vypočítá adresu hodnoty v boxu.
unbox valuetype..., obj → ..., valueTypePtrSystem.InvalidCastExceptionobj není boxovaný hodnotový typ.obj je boxovaný enum a valuetype není jeho podtyp.System.NullReferenceExceptionobj je null.System.TypeLoadExceptionvaluetype je platný metadata token typeref, typedef nebo typespec.obj je vždy referenční typ (O) reprezentující boxovanou instanci hodnotového typu typu valuetype.unbox.any A5Převést boxovaný typ na hodnotový
Při aplikaci na boxovanou reprezentaci hodnotového typu jej deboxuje (ekvivalent posloupnosti unbox a ldobj). Při použití na referenční typ má stejný efekt jako castclass.
Pokud typeTok je generický parametr odvodí se chování ta běhu, pdoe aktuální instanciace generického typu.
unbox.any typeTok..., obj → ..., valueSystem.InvalidCastExceptionobj není (boxovaný) typSystem.NullReferenceExceptionobj je null.obj musí být referenční typ.typeTok je platný metadata token typeref, typedef nebo typespec.obj musí být inicializován.typeTok není byef ani nic podobného ani void.typeTok.Použité formátování | Obecné syntaktické elementy | Sémantika obecných elementů | Křížová reference direktiv | Blokové direktivy | Řádkové direktivy | Uživatelské atributy | Instrukce | CLI+CTS vs. CLS | Vysvětlivky a odkazy
Názvosloví | Přehled CLS omezení vůči CLI/CTS
CLI (common language infrastructure) a CTS (common type system) umožňují "spoustu věcí". CLS (Common Language Specification) je základní specifikace pro vysokoúrovňový programovací jazyk. Určuje co, by měly mít jazyky společného. Jedná se pouze o podmnožinu možností definovaných v CLI/CTS. CLS určuje jak se mají CLS kompatibilní jazyky zachovat k CLS nekompatibilním konstruktům.
add, remove a fire podle jejich jména a signatury, jako by to byly obyčejné metody.)sealed).sealed). Bázový typ může být buď negenerický typ, nebo plně specifikovaný generický typ (instance generického typu).| Vlastnost | CLS - Popis | CLI/CTS | CLS | # | ||
|---|---|---|---|---|---|---|
| Konzument | Rozšiřovatel | Framework | ||||
| CLS kompatibilita | CLS kompatibilita se týká jen toho, co je viditelné ven z definujíc assembly. | netýká se | netýká se | Když během kompilace kontroluje kompatibilitu dělá tak jen u vystavovaných elementů. | Vnitřně může být implementován "jakkoli". Typ je CLS kompatibilní, pokud všechny jeho veřejné části jsou CLS kompatibilní nebo jsou specificky označené jako CLS nekompatibilní (typ pak musí "fungovat" i bez nich). | 1 |
| Označení CLS kompatibility | Označuje se atributem CLSCompliantAttribute, kterému se předá true nebo false, podle toho jestli element je CLS kompatibilní nebo ne. Pokud je typ označen jako CLS nekompatibilní CLSCompliantAttribute(False), jeho elementy nesmějí být označeny CLSCompliantAttribute(True). |
Umožňuje jakýkoliv atribut kdekoliv | Může ignorovat členy, které nejsou díky porušení tohoto pravidla CLS kompatibilní. | Měl by kontrolovat porušení pravidla v době kompilace. Doporučeno je vyžadovat dodržení. | Musí dodržovat toto pravidlo. | 2 |
| Boxované hodnotové typy | Nejsou CLS kompatibilní | Umožňuje jejich použití kdekoliv | Nemusí importovat boxované hodnotové typy | Nemusí definovat syntax pro použití nebo definici boxovaných hodnotových typů | Nesmí exportovat boxované hodnotové typy | 3 |
| Znaky v názvech | Názvy musí dodržovat Dodatek 7 technické zprávy 15 standartu Unicode 3.0 pro znaky povolené jako začátek a součást názvu identifikátoru. Identifikátory musí být v kanonickém formátu normalizační formy C. Pro CLS účely jsou dva identifikátory shodné, pokud jejich mapování na malá písmena (podle Unicode standardu, lokálně nezávislé, 1:1) jsou stejná. Tedy, aby se dva identifikátory lišily, měly by se lišit více než jen ve velikosti písmen. Ale k přepisování (override) metod je nutná shoda na úrovni kódování s původním názvem (CLI podmínka, kterou CLS nemůže porušit). | Umožňuje jakýkoliv Unicode znak v názvu | Nemusí importovat typy, které toto pravidlo porušují. Musí poskytovat mechanizmus, jak přistupovat k elementu, který se jmenuje stejně, jako se jmenuje klíčové slovo jazyka. | Nemusí umět vytvářet typy, které toto pravidlo porušují, ale musí umět vytvářet typy, které se jmenují stejně jako klíčové slovo jazyka. | Nesmí exportovat typy, které toto pravidlo porušují. Měl by se vyhnout exportování typů, které se nebo jejichž elementy se jmenují stejně jako klíčová slova často používaná v jazycích. | 4 |
| Stejná jména | Jména ve stejném rozsahu platnosti musí být různá, s výjimkou přetěžování. | Jména musí být různá v rámci jednotlivých druhů elementů (metoda, proměnná, typ, vlastnost, událost), s výjimkou přetěžování. | Nemusí konzumovat typy, které porušují tato pravidla (po vynechání elementů označených jako CLS nekompatibilní) | Nemusí poskytovat syntax pro definici typů, které tato pravidla porušují. | Nesmí označit typ jako CLS kompatibilní, pokud jsou v rámci jeho CLS kompatibilních položek porušena tato pravidla. | 5 |
| Přetěžování | Proměnné (field) a typy musí mít různá jména. Metody, vlastnosti a události, které mají stejná jména se musí lišit více než návratovým typem (s výjimkou pravidla 39). | 6 | ||||
| Výčty | Podtyp výčtu musí být vestavěný integrální typ. Název
instanční proměnné výčtu musí být value__ a musí být označen
rtspecialname. |
Neklade nároky na název a atributy instanční proměnné | Akceptuje výčty dodržující toto pravidlo. Může ignorovat FlagsAttribute. |
Stejné jako konzument. Může ale nemusí umět vytvářet výčty | Nevystavuje výčty, které porušují pravidla a nepředpokládá, že výčty mají jen uvedené hodnoty. | 7 |
| Dostupnost při dědění | Při dědění a přepisování (overriding) se dostupnost
členů nemění (s výjimkou: při dědění od typu z jiné assembly
se family-or-assembly změní na family. |
Povoluje rozšiřování i zužování dostupnosti | Nemusí akceptovat typy, které rozšiřují dostupnost členů | Nemusí poskytovat syntax k rozšiřování dostupnosti členů | Nesmí záviset na schopnosti rozšiřovat dostupnost členů | 10 |
| Typy v signaturách a typové parametry | Všechny typy v signaturách musí být CLS kompatibilní. Všechny typy použité k instanciaci generického typu musí být CLS kompatibilní. | Umožňuje použití nekompatibilních typů | Nemusí akceptovat typy, jejich členy porušují tato pravidla | Nemusí poskytovat syntax k porušení těchto pravidel | Nesmí porušovat tato pravidla u vystavovaných typů a jejich členů | 11 |
| Typy použité v signaturách a pro instanciaci generických typů musí být dostupné všude tam, kde je dostupná signatura/typ. | Neklade tato omezení | 12 | ||||
| Typ literálu | CLS kompatibilní literál musí mít v metadatech uloženu hodnotu přesně stejného typu jako je jeho typ (nebo pod typu, pokud je jeho typ výčet) | Neklade omezení. Kompilátor musí provést přetypování. | Musí umět přečíst metadata inicializující statické literály a vložit hodnotu na místo použití literálu. Může předpokládat, že typ literálu a metadat je stejný. Nemusí podporovat konverzi. | Nesmí vytvářet literály, které se inicializují hodnotou jiného typu, než je jejich typ | Musí se vyhnout použití literálů inicializovaných metadaty jiného typu, než je jejich typ. Například: Kompilátor provede konverzi před uložením do metadat. | 13 |
| Typovaná reference | Typovaná reference (System.TypedReference)
není CLS kompatibilní |
Lze používat jen pro parametry a lokální proměnné. Nesmí být boxována. | Nemusí tento typ akceptovat | Nemusí umět tento typ produkovat nebo dědit od tříd či implementovat interfacy, které jej používají | Nesmí tento typ vystavovat | 14 |
| Volací konvence | Jediná povolená volací konvence je default.
Ani vararg není povolen. |
vararg stejně jako nemanagované volací
konvence jsou povoleny |
Nemusí akceptovat metody s proměnným počtem parametrů nebo nemanagovanou volací konvencí | Nemusí poskytovat syntax k vytváření metod s proměnným počtem parametrů nebo nemanagovanou volací konvencí | Metody s nemanagovanou volací konvencí nebo proměnným počtem parametrů nesmí být vystavovány | 15 |
| Pole | Prvky polí musí být CLS kompatibilní a všechny spodní meze polí musí být 0. K rozpoznání overloadů stačí skutečnost, že parametr je pole a typ prvku pole. | Podporuje pole s různými začátky a všech možných typů. | Nemusí podporovat pole CLS nekompatibilních typů.
Overloading se nemusí zabývat celou komplexitou polí. Pokud
syntaxe jazyka nepodporuje pole přímo, musí mít programátor
přístup k metodám Get, Set a Address
z System.Array. |
Nemusí poskytovat syntaxi pro definici polí CLS
nekompatibilních typů. Nemusí umět dědit od tříd
používajících pole CLS nekompatibilních typů. Musí poskytovat
přístup k System.Array, ale může předpokládat,
že prvky všech polí jsou CLS kompatibilní. Plná syntaxe pole
nutná k přepisu (overload) metody nemusí být viditelná
programátorovi. Pokud syntaxe jazyka nepodporuje pole přímo,
musí mít programátor přístup k metodám Get, Set
a Address z System.Array. |
Nesmí vystavovat CLS nekompatibilní pole. Pokud možno používat jen jednodimensionální 0-based pole jednoduchých pojmenovaných typů. Pokud možno vyhnout se přetěžování s polovými typy, pokud jej použije, dodržovat omezení. | 16 |
| Nemanagované ukazatele | Nejsou CLS kompatibilní | Možno používat | Nemusí umět | Nemusí poskytovat syntax pro jejich definici. | Nesmí být vystavovány | 17 |
| Interfacy | Nesmí požadovat implementaci nemanagovaných metod | Může požadovat | Nemusí umět | Nemusí mít mechanizmus k jejich implementaci | Nesmí vystavovat | 18 |
| Členy interfaců | Nesmí mít statické metody ani proměnné (fields) | Mohou | Nemusí akceptovat interfacy porušující tato pravidla | Nemusí poskytovat syntaxi pro vytváření interfaců porušujících tato pravidla | Nesmí vystavovat interfacy porušující pravidla | 19 |
| Volání konstruktoru báze | Konstruktor referenčního typu musí zavolat konstruktor báze dříve než přistoupí ke zděděným instančním datům. | Není nutné | Musí poskytovat syntaxi pro výběr konstruktoru, který má být zavolán při vytváření instance objektu | Musí poskytovat syntaxi pro definici konstruktorů s různými signaturami. Pokud konstruktor nedodržuje tato pravidla musí dojít k chybě při kompilaci. | Může předpokládat, že vytvoření objektu
zahrnuje volání konstruktoru a že žádný objekt není
inicializován 2×. System.Object.MemberwiseClone
a deserializace nepoužívají konstruktory. |
21 |
| Volání konstruktoru | Konstruktor nesmí být volán jindy než při inicializaci objektu a objekt nesmí být inicializován dvakrát | Není kontrolováno | 22 | |||
| CLS kompatibilita při dědění | System.Object je CLS kompatibilní. CLS
kompatibilní typ může dědit jen od CLS kompatibilního typu. |
- | - | - | - | 23 |
| Getter a setter | Getter a setter vlastnosti musí být označen specialname.
Musejí dodržovat pojmenovávací konvenci get_<PropName>
a set_<PropName>. |
není vyžadováno | Musí ignorovat bit specialname
při porovnávání jmen a musí dodržovat pravidla pro
identifikátory. Žádná další podpora pro vlastnosti není
vyžadována. Může vlastnosti nahradit voláním getteru a
setteru. |
Jako konzument. Nemusí podporovat deklaraci vlastností. | Měl by být designován i pro ty CLS kompatibilní jazyky, které nepoužívají speciální syntaxi pro přístup k vlastnostem. | 24 |
| Stejný typ accessorů | Všechny accessory vlastnosti musí být static, virtual
nebo instance. |
není vyžadováno | 26 | |||
| Typ vlastnosti | Typ vlastnosti musí být stejný jako návratový typ
getteru. Typy parametrů vlastnosti musí být stejné jako typy
parametrů getteru a až na poslední jako typy parametrů
setteru. Typy musí být CLS kompatibilní a nesmí se jednat o
managované ukazatele (nesmí být předávány odkazem (VB: ByRef)). |
není vyžadováno | 28 | |||
| Accessory událostí | Metody, které implementují událost, musí být označeny specialname. |
není vyžadováno | Musí ignorovat specialname při porovnávání
jmen. Další podpora pro události není nutná. Mohou se volat
jednotlivé accessory |
Jako konzument. Nemusí umět definovat události. | Měl by být designován i pro ty CLS kompatibilní jazyky, které nepoužívají speciální syntaxi pro přístup k událostem. | 29 |
| Dostupnost accessorů události | Dostupnost accessorů události musí být stejná | není vyžadováno | 30 | |||
Přítomnost add a remove |
Metody add a remove musí být buď obě přítomny nebo
nepřítomny |
není vyžadováno | 31 | |||
Parametry add a remove |
Obě metody mají jako jediný parametr stejného delegáta | není vyžadováno | 32 | |||
| Jména accessorů události | Accessory událostí musí dodržovat speciální pojmenovávací
konvenci (add_<EventName>, remove_<EventName>, raise_<EventName>).
Atribut specialname, musí být ignorován při
porovnávání jmen. |
není vyžadováno | 33 | |||
| Typy hodnot atributů | Jen System.Type, System.String,
System.Char, System.Boolean,
System.Byte, System.Int16, System.Int32,
System.Int64, System.Single, System.Double a výčty odvozené od CLS
kompatibilních typů |
Povoluje další (např. neznaménkové) typy | Je schopen číst atributy odpovídající těmto pravidlům | Jako konzument + umí vytvářet nové třídy a atributy a
připojovat atributy založené na existujících třídách
atributů k libovolným vytvářeným metadatům. Implementuje
pravidla pro System.AttributeUSageAttribute. |
Vystavuje jen CLS kompatibilní atributy, které dodržují System.AttributeUsageAttribute. |
34 |
modreq a modopt |
Veřejné modreq nejsou povoleny, povoluje
veřejné modopt, kterým nerozumí. |
Povoluje veřejné modopt i modreq |
Čte metadata obsahující volitelné modifikátory a korektně kopíruje signatury, které obsahují. Může tyto modifikátory ignorovat při porovnávání typů a přetěžování. Může ignorovat typy, které zůstanou nejednoznačné při ignorování volitelných modifikátorů a které obsahují povinné modifikátory. | Umí overridovat metody, jejichž signatury obsahují volitelné modifikátory. Musí kopírovat modifikátory z metadat, která importuje. Nemusí podporovat povinné modifikátory a nemusí umět vytvářet metody, které mají jakékoliv modifikátory v signatuře. | Nesmí používat povinné modifikátory ve veřejně viditelných signaturách, pokud nejsou označeny jako CLS nekompatibilní. Nesmí vystavit dva členy, které se liší jen ve volitelných modifikátorech (smí tak učinit v případě, že jen jeden z nich je označen jako CLS kompatibilní). | 35 |
| Globální metody a proměnné | Nejsou povoleny | Jsou povoleny | Nemusí podporovat | Nemusí umět vytvářet | Nesmí obsahovat | 36 |
| Overloading (přetěžování) | Jen vlastnosti (properties) a metody mohou být přetíženy | vůbec neřeší. přetěžování je záležitostí kompilátoru | Může předpokládat, že jen vlastnosti a metody jsou přetěžovány. Nemusí podporovat přetěžování na základě návratových typů, kromě operátorů přetypování. | Neměl by dovolit vytváření přetížení, které odporují uvedeným pravidlům. Nemusí podporovat přetěžování operátorů. | Nesmí vystavovat přetížení, která neodpovídají uvedeným pravidlům. Autoři by měli mít na paměti, že spousta jazyků nepodporuje přetěžování, přetěžování operátorů ani přetěžování konverzních operátorů. | 37 |
| Jak přetěžovat | Jen podle typu a počtu parametrů (s výjimkou op_Implicit
a op_Explicit) |
38 | ||||
| Operátory |
Unární
|
Operátory jsou obyčejné metody | nemusí podporovat | nemusí podporovat | ||
op_Implicit vs. op_Explicit |
Jedná se o různé typy konverze | nezabývá se | Pokud se vůbec podporuje, může je použít k různým způsobům automatického přetypování | Pokud podporuje může je využít k definici metod
přetypování na jiný typ / z jiného typu. Měl by poskytovat
alternativní metodu přístupu k operátorům - ToXxx
a FromXxx. |
Pokud jsou podporovány měly by být dostupné jako ToXxx
a FromXxx a volitelně jako op_Explicit
a op_Implicit. |
39 |
| Typ výjimek |
Vyhazované (thrown) objekty musí být nebo dědit od
System.Exception. |
není omezeno | Nemusí umět vyhazovat nebo zachytávat výjimky jiných typů | Musí podporovat vyhazování objektů typu System.Exception
a odděděných. Nemusí podporovat vyhazování ostatních typů. |
Nesmí vyhazovat objekty jiného typu než System.Exception
nebo jeho potomků mimo své hranice. |
40 |
| Typ atributů |
Atributy musí být typu System.Attribute
nebo od něj dědit. |
není omezeno | Nemusí podporovat atributy jiných typů | Musí podporovat vytváření vlastních atributů | Nesmí veřejně vystavovat atributy jiných typů | 41 |
| Vnořený generický typ | Vnořený generický typ musí mít alespoň tolik typových parametrů jako má jeho rodič. Tyto parametry si musí pozičně odpovídat. | není omezeno | Nemusí umět konzumovat typy porušující toto pravidlo | Jako konzument. Pokud bude podporovat typy vnořené v generických typech, musí vyžadovat toto pravidlo pro veřejně dostupné typy. | Nesmí vystavovat typy porušující toto pravidlo. | 42 |
| Název generického typu |
Název generického typu musí obsahovat počet generických
parametrů (za znakem `). Pro vnořené
generické typy se jedná o počet parametrů, které mají
navíc oproti rodiči. |
není vyžadováno | Nemusí konzumovat typy porušující toto pravidlo | Jako konzument. Pokud umí deklarovat generické typy, musí dodržet toto pravidlo. | Nesmí vystavovat typy porušující toto pravidlo | 43 |
| Omezení na typových parametrech potomků | Generická třída, které implementuje interface nebo dědí od báze, musí na své typové parametry uvalit taková omezení, aby byla splněna veškerá omezení vyžadovaná typem, od kterého dědí, a typy, které implementuje. | není vyžadováno | Nemusí konzumovat typy porušující toto pravidlo. Může se spolehnout na to, že veškerá potřebná omezení jsou uvedena u konkrétního typu (nemusí pátrat v jeho bázích po dalších omezeních). | Jako konzument. pokud umí vytvářet generické typy, musí dodržet toto pravidlo. | Nesmí vystavovat typy porušujíc toto pravidlo. | 44 |
| CLS kompatibilita restrikcí | Typy použité jako restrikce generických parametrů, musí být CLS kompatibilní. | není vyžadováno | Nemusí konzumovat typy porušující toto pravidlo | Jako konzument. Pokud umí vytvářet generické typy, musí kontrolovat dodržení pravidla. Nemusí poskytovat syntax umožňující jeho porušení. | Nesmí vystavovat typy porušující toto pravidlo. | 45 |
| Viditelnost členů generických typů | Členy generických typů jsou viditelné tak, jako by instance generického typu byla samostatný typ. | nezabývá se | Nemusí konzumovat typy porušující toto pravidlo | Musí kontrolovat, když kontroluje CLS kompatibilitu | Nesmí vystavovat typy porušující toto pravidlo. | 46 |
| Virtuální generické metody | Každá abstraktní virtuální generická metoda musí mít defaultní (neabstraktní) implementaci | není vyžadováno | nemá vliv | Nemusí poskytovat syntaxi pro overriding generických metod | Nesmí vystavovat typy porušující toto pravidlo bez toho, aby poskytl výchozí implementaci. | 47 |
| Stejné metody | Pokud mají stejný název, stejné typy parametrů a stejný typ návratové hodnoty | Povoluje. Signatura metody je komplexnější. | Může si vybrat kteroukoliv z metod | Nevytavovat takové metody | 48 | |
Použité formátování | Obecné syntaktické elementy | Sémantika obecných elementů | Křížová reference direktiv | Blokové direktivy | Řádkové direktivy | Uživatelské atributy | Instrukce | CLI+CTS vs. CLS | Vysvětlivky a odkazy
* = Microsoft specific
⁺ = nedokumentováno (informace nalezeny někde)
Kapitola© Đonny 2007 dzonny₪dzonny.cz Last update 25.1. 2009 v.1.1