Common Intermediate Language
Common Intermediate Language (CIL, vyslovovano jako ,,sil", pripadne ,,kil", drive Microsoft Intermediate Language, MSIL) je v informatice nejnizsi clovekem citelny programovaci jazyk definovany specifikaci Common Language Infrastructure pouzivany projekty .NET Framework a Mono. Jazyky, ktere se zameruji na CLI kompatibilni prostredi, jsou sestavovany do bajtkodu. CIL patri mezi objektove orientovane jazyky vyhradne zasobnikoveho typu (anglicky stack-based). Provaden je prostrednictvim virtualniho stroje.
CIL byl puvodne behem uvolnovani beta .NET jazyku znam jako Microsoft Intermediate Language (MSIL). Vzhledem ke standardizaci C# a Common Language Infrastructure je bajtkod nove a oficialne oznacovan jako CIL.
Zakladni informace
[editovat | editovat zdroj]Pri kompilovani .NET programovacich jazyku je zdrojovy kod prelozen do CIL kodu (nepouziva se platformne nebo do vypocetne specificky objektovy kod). CIL je procesorove a zaroven platforme nezavisly soubor instrukci, ktere mohou byt realizovany v jakemkoli prostredi podporujicim Common Language Infrastructure (muze se jednat bud o .NET runtime pro operacni system Microsoft Windows, nebo samostatne odvozene Mono, ktere pracuje pod operacnimi systemy UNIXoveho typu). CIL kod je za behu overovan z hlediska bezpecnosti, a proto poskytuje lepsi zabezpeceni a spolehlivost, nez nativne kompilovane binarni soubory.
Proces spusteni vypada takto:
- Zdrojovy kod je preveden do Common Intermediate Language, CLI ekvivalent k nizsim programovacim jazykum pro CPU.
- CIL je pak preveden do bajtkodu a je vytvoreno .NET assembly.
- Po provedeni .NET assembly, jeho bajtkod projde skrz provozni JIT kompilator, aby generoval nativni kod.
- Nativni kod je zpracovavan pomoci procesoru.
Instrukce
[editovat | editovat zdroj]CIL bytecode ma instrukce pro nasledujici skupiny uloh:
- Nacitani a ukladani
- Aritmeticke
- Typ konverze
- Vytvareni objektu a manipulaci s nimi
- Operand managementu zasobniku (push / pop)
- Kontrola prevodu (vetveni - Branching)
- Volani metod
- Vyvolani vyjimky
- Synchronizace
Vypocetni model
[editovat | editovat zdroj]Common Intermediate Language je povazovan za objektove orientovany jazyk zasobnikoveho typu (stack-based). To znamena, ze data jsou ukladana z registru do zasobniku misto toho, aby byla odkladana do pameti jako ve vetsine CPU architektur.
V assembleru x86 architektury IA-32 by to mohlo vypadat nasledovne:
mov ecx, eax
Odpovidajici kod v CIL by mohl vypadat takto:
ldloc.1
add
stloc.0 // a = a + b or a += b;
V programu jsou pouzity dve lokalne promenne, ktere jsou presunuty do fronty. Kdyz je pridana instrukce zavolana, operand je ze zasobniku vyzvednut a vysledek je na nej obratem ulozen. Hodnota je pak vyzvednuta a ulozena jako prvni lokalni promenna.
Objektove-orientovane koncepty
[editovat | editovat zdroj]V objektove-orientovanem konceptu muzete vytvaret objekty, volat metody a pouzivat dalsi typy clenu, jako jsou napriklad pole. CIL je navrzen jako objektove orientovany a vsechny metody (az na vyjimky) musi byt obsazene v prislusne tride.
Priklad staticke metody:
{
.method public static int32 Add(int32, int32) cil managed
{
.maxstack 2
.locals init (
[0] int32 num1,
[1] int32 num2
)
ldloc.0
ldloc.1
add
stloc.0 // a = a + b or a += b;
ret // return a;
}
}
Pouzita metoda nevyzaduje zadnou deklaraci instance tridy Foo, protoze je staticka. To znamena, ze nalezi do tridy a muze byt nasledne pouzita jako v tomto pripade v C#.
V CIL
ldc.i4.3
call int32 Foo::Add(int32, int32)
stloc.0
Instance trid
[editovat | editovat zdroj]Instance tridy obsahuje nejmene jeden konstruktor a nejake dalsi cleny. Tato trida ma sadu metod reprezentujicich akce objektu Car.
{
.method public specialname rtspecialname
instance void .ctor(int32, int32) cil managed
{
/* Constructor */
}
.method public void Move(int32) cil managed
{
/* Omitting implementation */
}
.method public void TurnRight() cil managed
{
/* Omitting implementation */
}
.method public void TurnLeft() cil managed
{
/* Omitting implementation */
}
.method public void Break() cil managed
{
/* Omitting implementation */
}
}
Vytvareni objektu
[editovat | editovat zdroj]Instance trid jsou v C# vytvareny nasledujicim zpusobem:
Car yourCar = new Car(1, 3);
Prikazy jsou priblizne stejne jako tyto instrukce:
ldc.i4.4
newobj instance void Car::.ctor(int, int)
stloc.0 // myCar = new Car(1, 4);
ldc.i4.1
ldc.i4.3
newobj instance void Car::.ctor(int, int)
stloc.1 // yourCar = new Car(1, 3);
Vyvolani metody instance
[editovat | editovat zdroj]Napriklad metody jsou volany nasledovne:
V CIL:
ldc.i4.3
call instance void Car::Move(int32)
Metadata
[editovat | editovat zdroj].NET zaznamenava informace o kompilovanych tridach jako metadata. Proces cteni techto metadat se nazyva zrcadleni (reflection). Metadata mohou byt data v podobe atributu. Ty mohou byt volne rozsireny o atributy tridy, cimz se stavaji velmi silnym nastrojem.
Priklad
[editovat | editovat zdroj]Priklad je napsan v CIL a demonstruje kod ,,Hello, World":
.assembly extern mscorlib {}
.method static void Main()
{
.entrypoint
.maxstack 1
ldstr "Hello, world!"
call void [mscorlib]System.Console::WriteLine(string)
ret
}
Tento kod muze byt porovnan s odpovidajicim kodem Java bytecode:
{
outer:
for (int i = 2; i < 1000; i++)
{
for (int j = 2; j < i; j++)
{
if (i % j == 0)
goto outer;
}
Console.WriteLine(i);
}
}
V CIL-syntaxi by zapis vypadal nasledovne:
{
.entrypoint
.maxstack 2
.locals init (int32 V_0,
int32 V_1)
IL_0000: ldc.i4.2
stloc.0
br.s IL_001f
IL_0004: ldc.i4.2
stloc.1
br.s IL_0011
IL_0008: ldloc.0
ldloc.1
rem
brfalse.s IL_0000
ldloc.1
ldc.i4.1
add
stloc.1
IL_0011: ldloc.1
ldloc.0
blt.s IL_0008
ldloc.0
call void [mscorlib]System.Console::WriteLine(int32)
ldloc.0
ldc.i4.1
add
stloc.0
IL_001f: ldloc.0
ldc.i4 0x3e8
blt.s IL_0004
ret
}
Vyse je spravna reprezentace toho, jak vypada CIL blizko VM urovne. Kdyz jsou zkompilovane metody ulozeny v tabulkach a instrukce zase v bytech uvnitr assembly, ktery je prenosne spustitelnym souborem (Portable Executable-file).
Vyvoj
[editovat | editovat zdroj]CIL assembly a instrukce jsou generovany bud kompilatorem, nebo nastrojem zvanym IL Assembler (ILASM). Slozene IL muze byt take znovu rozlozeno do kodu - uzitim IL Disassembler (ILDASM). Podobne, jako v pripade Java bytecode, existuji tez nastroje, ktere nabizeji dekompilaci IL do jazyku vyssi urovne (napr. C#, Visual Basic .NET). Za jejich vlajkovou lod lze povazovat aplikaci .NET Reflector. Tyto nastroje vsak maji protivahy, jez usiluji o zneprehledneni kodu pri zachovani plne funkcionality tak, aby dekompilace do jazyku vyssi urovne selhala.
Kompilace just-in-time
[editovat | editovat zdroj]Kompilace Just in Time (JIT) preklada bajtkod do kodu vykonatelneho primo mikroprocesorem, tj. do tzv. ,,nativniho kodu". Tento preklad je provaden behem provadeni programu. JIT kompilace poskytuje optimalizace specificke pro prostredi, typovou bezpecnost kontrolovanou za behu a verifikaci. K dosazeni tohoto kompilator testuje metadata nashromazdena behem prekladu na nepovolene pristupy do pameti.
Reference
[editovat | editovat zdroj]V tomto clanku byl pouzit preklad textu z clanku Common Intermediate Language na anglicke Wikipedii.