CLI (tietotekniikka)

**Common Language Infrastructure** (CLI) on avoin ja standardoitu määrittely ohjelmien suoritusympäristöstä ja välikielisestä tavukoodista. CLI:n tavoite on, että useilla eri korkean tason ohjelmointikielillä kirjoitetut ohjelmat voidaan kääntää samaan välikieleen ja suorittaa useilla eri laitteisto- ja käyttöjärjestelmäalustoilla ilman, että ohjelmia täytyy kirjoittaa uudelleen kullekin alustalle erikseen. CLI määrittelee suoritettavan koodin esitystavan sekä virtuaalisen suoritusalustan, joka vastaa koodin lataamisesta, tarkastamisesta ja suorittamisesta.

CLI määrittelee muun muassa yhteisen tyyppijärjestelmän, ohjelmista kerättävän metatiedon, välikielen käskykannan, virtuaalisen suoritusalustan sekä joukon perusluokkakirjastoja. Microsoftin .NET Framework, .NET ja Mono ovat tunnetuimpia CLI:tä toteuttavia ympäristöjä. CLI on kuitenkin pelkkä spesifikaatio: se ei itsessään ole ajonaikainen ympäristö, vaan toteutukset kuten Common Language Runtime (CLR) toteuttavat standardissa kuvatun toiminnallisuuden käytännössä.

## Historia

CLI kehitettiin Microsoftin johdolla osaksi .NET-arkkitehtuuria 2000-luvun taitteessa tavoitteena tarjota kieli- ja alustariippumaton pohja .NET-ympäristölle. Microsoft, Hewlett-Packard, Intel ja muut yritykset toimittivat spesifikaation Ecma Internationalille standardoitavaksi 2000-luvun alussa.

Ecma International hyväksyi CLI:tä kuvaavan ECMA-335-standardin ensimmäisen painoksen joulukuussa 2001. Vuonna 2003 CLI standardoitiin myös kansainväliseksi ISO/IEC-standardiksi ISO/IEC 23271. Standardia on sittemmin päivitetty useita kertoja; myöhemmät painokset ovat tuoneet muun muassa generisten tyyppien ja kirjastoihin liittyvien laajennusten tuen.

Voimassa oleva ECMA-335-standardin kuudes painos (kesäkuu 2012) ja ISO/IEC 23271:2012 -painos jakavat CLI:n useaan osaan (*partitions*), jotka kuvaavat erikseen arkkitehtuurin, metadatan, välikielen käskykannan sekä profiilit ja standardikirjastot.

## Standardointi

Common Language Infrastructure on määritelty Ecma Internationalin standardissa ECMA-335: Common Language Infrastructure (CLI), joka on julkaistu avoimesti Ecman verkkosivuilla. Standardi kuvaa CLI:n yleisen arkkitehtuurin, yhteisen tyyppijärjestelmän (CTS), virtuaalisen suoritusalustan (VES), metatietojen formaatin, välikielen käskykannan (CIL) sekä joukon perusluokkakirjastoja.

Myöhemmin CLI on standardoitu myös ISO/IEC-standardina ISO/IEC 23271, jonka uusin painos (2012) vastaa sisällöllisesti Ecma-standardiin tehtyjä päivityksiä. ECMA- ja ISO-standardeihin sovelletaan tavanomaisesti RAND-tyyppistä (*reasonable and non-discriminatory*) patenttipolitiikkaa, ja Microsoft on erillisessä patenttijulistuksessa sitoutunut myöntämään lisenssit ECMA-335-standardiin tarvittaviin patentteihinsa syrjimättömällä perusteella.

Vuonna 2009 Microsoft ilmoitti soveltavansa Microsoft Community Promise -lupausta ECMA-334- (C#) ja ECMA-335- (CLI) standardeihin, mikä tarjoaa lisäturvaa yhteensopivia toteutuksia kehittäville tahoille erityisesti avoimen lähdekoodin projekteissa.

## Yleiskuvaus ja tavoitteet

CLI määrittelee kolme tasoa:
* korkean tason ohjelmointikielet (esimerkiksi C#, Visual Basic .NET ja F# sekä muut CLI:tä tukevat kielet),
* välikielinen tavukoodi (*Common Intermediate Language*, CIL),
* sekä virtuaalinen suoritusalusta, joka huolehtii tavukoodin suorittamisesta kohdeympäristössä.

Tämä jaottelu mahdollistaa sen, että eri kielillä kirjoitetut ohjelmat voivat käyttää samoja kirjastoja ja tyyppejä, ja että sama välikoodia sisältävä ohjelmakoodi voidaan suorittaa useilla eri alustoilla. CLI:n tavoitteena on tukea kieliriippumatonta komponenttikehitystä (*language independence*), tarjota vahva tyyppiturvallisuus ja hallittu muistinhallinta, mahdollistaa korkean suorituskyvyn toteutukset erilaisilla laitteistoilla sekä tarjota vakioitu joukko perusluokkakirjastoja yleisimpiä ohjelmointitehtäviä varten.

CLI määrittelee myös käsitteet hallittu koodi (*managed code*) ja hallittu data, joilla viitataan koodiin ja tietorakenteisiin, joita suoritusalusta seuraa ja hallitsee esimerkiksi muistinhallinnan, tietoturvan ja poikkeusten käsittelyn osalta.

## Rakenteen osa-alueet

ECMA-335 jakaa Common Language Infrastructuren useaan pääosa-alueeseen. Yleisesti esitetty jaottelu sisältää seuraavat kokonaisuudet:

* Common Type System (CTS)
* Metatiedot
* Common Intermediate Language (CIL)
* Common Language Specification (CLS)
* Virtual Execution System (VES)
* Standardikirjastot (*Base Class Library* ja muut perusluokkakirjastot)

### Common Type System (CTS)

Common Type System (CTS) on yhteinen tyyppijärjestelmä, joka määrittelee, miten tyypit ja arvojen esitysmuodot kuvataan CLI-ympäristössä. CTS määrittelee muun muassa:
* primitiiviset tietotyypit (esimerkiksi kokonaisluvut ja liukuluvut),
* viite- ja arvotyypit,
* taulukot, luokat, rakenteet, rajapinnat ja delegaatit,
* sekä säännöt perinnälle, näkyvyydelle ja virtuaalisille metodeille.

CTS:n tarvoite on varmistaa, että eri ohjelmointikielillä määritellyt tyypit voidaan esittää yhteisessä muodossa ja että ne voivat olla vuorovaikutuksessa keskenään ilman tyyppiristiriitoja. Tämä mahdollistaa esimerkiksi sen, että yhdellä kielellä toteutettu kirjasto voidaan ottaa käyttöön toisella kielellä ilman erillistä kääntäjäkohtaista sovittamista.

### Metatiedot

CLI edellyttää, että ohjelmakoodiin liitetään kattavat metatiedot ohjelman rakenteesta. Metatiedot kuvaavat esimerkiksi kokoonpanojen (*assemblyjen*), tyyppien, jäsenien, attribuuttien ja viittausten rakenteen. Ne tallennetaan samaan fyysiseen tiedostoon CIL-koodin kanssa, ja niitä käytetään:
* tyypinlataukseen ja linkitykseen,
* heijastukseen (*reflection*),
* suoritusympäristön tietoturva- ja käyttöoikeustarkastuksiin,
* sekä työkalujen, kuten kääntäjien ja debuggerien, toiminnan tukemiseen.

Metatiedot tekevät CLI:stä voimakkaasti metadatavetoisen ympäristön, jossa suuri osa kielen ja kirjastojen rakenteesta on luettavissa ja käsiteltävissä ajonaikaisesti.

### Common Intermediate Language (CIL)

Common Intermediate Language (CIL) on pinoon perustuva välikieli ja käskykanta, johon CLI-yhteensopivilla ohjelmointikielillä kirjoitetut ohjelmat käännetään. CIL on riippumaton käyttöjärjestelmästä ja prosessoriarkkitehtuurista ja muodostaa rajapinnan korkean tason kielten ja virtuaalisen suoritusalustan välillä.

### Common Language Specification (CLS)

Common Language Specification (CLS) on CTS:stä johdettu alijoukko sääntöjä, joiden tarkoituksena on varmistaa mahdollisimman laaja kielien välinen yhteentoimivuus. CLS määrittelee esimerkiksi:
* millaisia nimiä, näkyvyysmääreitä ja tyyppirakenteita julkisissa rajapinnoissa saa käyttää,
* miten poikkeuksia, tapahtumia ja ominaisuuksia esitetään,
* sekä mitkä CTS-ominaisuudet ovat ”turvallisia” muiden kielten näkökulmasta.

Kääntäjä, joka tuottaa CLS-yhteensopivaa koodia, voi merkitä kirjaston CLS-yhteensopivaksi. Tällöin muut CLS:ää tukevat kielet voivat luottaa siihen, että kirjaston julkinen rajapinta on käytettävissä ilman kieleen sidottuja erikoistapauksia.

### Virtual Execution System (VES)

Virtual Execution System (VES) on CLI:n määrittelemä virtuaalinen suoritusalusta, joka lataa, tarkastaa ja suorittaa CLI-yhteensopivia ohjelmia. VES lukee kokoonpanojen CIL-koodin ja metatiedot, suorittaa tyyppiturvallisuuteen liittyvät tarkastukset ja huolehtii muistinhallinnasta sekä poikkeusten käsittelystä.

Käytännön esimerkki VES-toteutuksesta on Common Language Runtime (CLR).

### Standardikirjastot

CLI määrittelee joukon standardikirjastoja, jotka tarjoavat perustoiminnallisuutta yleisiin ohjelmointitehtäviin. Näiden ytimessä on usein Base Class Library (BCL), joka sisältää muun muassa:
* perus- ja kokoelmatyypit,
* syöte- ja tulostustoiminnot (esimerkiksi tiedostojen ja virtojen käsittely),
* perusverkko-, säie- ja ajastustoiminnot,
* sekä perustason tietoturva- ja diagnostiikkaluokat.

Standardikirjastot on määritelty siten, että CLI-toteutukset voivat laajentaa niitä tai tarjota omia lisäkirjastojaan, mutta yhteinen ydin takaa ohjelmien siirrettävyyden ja kielten välisen yhteentoimivuuden.

## Ohjelmien kääntäminen ja suoritus

CLI määrittelee välikielen (CIL) ja virtuaalisen suoritusalustan (VES), mutta ei lukitse sitä, miten CIL-koodi muunnetaan natiiviksi konekieleksi. Yleinen malli on, että kunkin ohjelmointikielen kääntäjä tuottaa CIL-koodia ja metatiedot, minkä jälkeen suoritusalusta lataa kokoonpanon, tarkastaa sen ja kääntää CIL-koodin kohdeympäristön konekieleksi ennen suorittamista.

Käytännön toteutuksissa hyödynnetään sekä ajonaikaista kääntämistä (*just-in-time*, JIT) että etukäteiskääntämistä (*ahead-of-time*, AOT). JIT-kääntäminen mahdollistaa dynaamisen optimoinnin, kun taas AOT voi parantaa käynnistysnopeutta ja pienentää riippuvuutta ajonaikaisista komponenteista. Yksityiskohtaisempi kuvaus JIT- ja AOT-tekniikoista on esitetty CIL- ja CLR-artikkeleissa.

## Toteutukset

Common Language Infrastructurea toteuttavia ympäristöjä ovat muun muassa:

* .NET Framework – Microsoftin alkuperäinen .NET-toteutus, joka on suunnattu ensisijaisesti Windows-ympäristöön.
* .NET – .NET Frameworkia seurannut avoimen lähdekoodin, monialustainen .NET-toteutus.
* Mono – avoimen lähdekoodin toteutus, jonka .NET-tuki perustuu C#- ja CLI-standardeihin ja jota on käytetty erityisesti Linux-ympäristöissä, mobiilialustoilla ja pelimoottoreissa.
* .NET Compact Framework ja .NET Micro Framework – .NET-ympäristön supistetut toteutukset sulautetuille ja resurssirajoitteisille laitteille.
* Historiallisesti myös hankkeet kuten DotGNU Portable.NET ovat pyrkineet tarjoamaan riippumattomia CLI-toteutuksia.

Käytännössä kukin toteutus voi tarjota eri laajuisen joukon standardikirjastoja ja alustaerityisiä laajennuksia, kunhan se noudattaa ECMA-335- ja ISO/IEC 23271 -standardien olennaisia osia.

## Suhde CLR:ään ja .NET-arkkitehtuuriin

Common Language Infrastructure on arkkitehtuurinen ja kielellinen määrittely, kun taas Common Language Runtime (CLR) on yksi konkreettinen VES-toteutus, joka toteuttaa CLI:n määrittelemät toiminnot Windows-ympäristössä ja .NET-ympäristöissä. CLR huolehtii muun muassa CIL-koodin kääntämisestä natiiviksi, roskienkeruusta, poikkeusten käsittelystä ja tietoturvatarkastuksista. CLI muodostaa siten .NET-arkkitehtuurin kieliriippumattoman ytimen, jonka päälle eri kielet, kirjastot ja työkalut rakentuvat, kun taas CLR on yksi tapa toteuttaa tämä malli käytännössä.

## Katso myös

* .NET Framework
* .NET
* Common Language Runtime
* CIL (tietotekniikka)
* Välikieli
* Virtuaalikone
* Ajonaikainen kääntäminen
* Ohjelmointikieli

## Lähteet