hyväksymispäivä arvosana arvostelija Common Language Runtime Jukka Katajisto Helsinki 16.4.2005 Ohjelmointikielten kääntäjät -kurssin seminaarityö HELSINGIN YLIOPISTO Tietojenkäsittelytieteen laitos
Sisältö i 1 Johdanto 1 2 Common Language Runtime 2 3 Moduulitiedoston formaatti 4 4 Tyyppijärjestelmä 5 5 Yhteenveto 7 Lähteet 7
1 Johdanto 1 Common language runtime (CLR) on ajonaikainen käyttöympäristö, jossa.net ohjelmia suoritetaan. Se tarjoaa operointitason.net ohjelmien ja käyttöjärjestelmän väliin. Perusperiaatteiltaan se on hyvin lähellä muita tulkattavia ajoympäristöjä, joita ovat muun muassa GBasic, Smalltalk ja Java Virtual Machine (JVM) [Lid02]. Samanlaisuus on silti vain periaatteellista, koska CLR ei ole tulkki..net-ohjelmia generoidaan siihen suunnitelluilla kääntäjillä. Näitä ovat esimerkiksi Microsoft Visual C#.NET, Microsoft Visual Basic.NET, ILAsm ja monet muut. Ohjelma käännetään abstraktiin välitason muotoon, joka on riippumaton käytetystä ohjelmointikielestä, koneesta ja siinä olevasta käyttöjärjestelmästä. Abstrakti välitaso mahdollistaa eri ohjelmointikielillä toteutettujen.net ohjelmin hyvin läheisen vuorovaikutuksen. Ohjelmat eivät pelkästään pysty käyttämään toistensa metodeja vaan voivat myös periä eri kielellä kirjoitettuja luokkia. Common Language Infrastructure (CLI) määrittelee suoritettavan koodin ja suoritusympäristön. CLI sisältää neljä osaa, joita ovat: Common Type System (CTS), Metatieto, Common Language Specication (CLS), Virtual Execution System (VES). Sääntöjen joukko, joka varmistaa.net ohjelmien yhteentoimivuuden, tunnetaan nimellä common language specication (CLS). Kyseessä on European Computer Manufacturers Associationin (ECMA) julkaisema standardi 1. Standardi on vain ehdotus ja CLR voi suorittaa.net ohjelmia, jotka eivät ole täysin standardin mukai- 1 http://www.ecma-international.org/publications/les/ecma-st/ecma-335-part-i-iv.pdf
2 sia. Tällöin ei kuitenkaan ole takuuta sen yhteentoimivuudesta muiden ohjelmien kanssa kaikilla tasoilla..net ohjelmien välitason esitysmuoto sisältää kaksi pääosaa metatieto (metadata) ja hallittukoodi (managed code) [Lid02]. Metatieto kuvaa ohjelman rakenteiden kaikki osat ja niiden väliset suhteet. Näitä ovat muun muassa luokat, luokkien jäsenet ja ominaisuudet. Hallittukoodi kuvaa ohjelman toiminnallisuuden käännettynä binäärimuotoon, joka tunnetaan nimellä Microsoft intermediate language (MSIL) tai common intermediate language (CIL). Tässä työssä esitellään pintapuolisesti CLR:ää ja sitä miten.net-ohjelmat rakentuvat sekä miten niitä suoritetaan. 2 Common Language Runtime CLR on suunniteltu tukemaan mahdollisimman montaa ohjelmointikieltä [MeG01]. CLR tukee täysin Java ja c# tyylisiä olio-ohjelmointikieliä, mutta siihen on myös lisätty laajennuksia. Eräs näistä mahdollistaa osoittimien käytön c-tyyliin. Tällöi kuitenkin menetetään CLR:n tuki roskienkeruuseen, tyyppiturvallisuuteen ja muistin varaukseen. Toisesta ääripäästä löytyy tuki funktionaaliselle ohjelmoinnille. CLR toteuttaa standardin ML-kielen tehokkaan toteutuksen kannalta tarpeellisen Tailkutsukäskyn, jota hyödynnetään SML.NET-ohjelmointikielessä. CLR suorittaa.net-ohjelmia, joko hallitussa (managed) tai ei-hallitussa (unmanaged) tilassa. Hallitussa tilassa CLR hallinnoin ja suorittaa pääasiassa kolmea merkittävää aktiviteettia, joita ovat: tyyppi kontrolli (type control), rakenteellinen poikkeustenkäsittely (structured exception handling) ja roskienkeruu (garbage collection) [Lid02]. Tyyppi kontrolli verioi ja konvertoi olioiden tyyppejä ajonaikana. Poikkeustenkäsittely vastaa ei-hallittua poikkeuksienkäsittelyä C++:n tyyliin, mut-
3 ta suoritetaan CLR:n eikä käyttöjärjestelmän toimesta. Roskienkeruu tunnistaa ja hävittää oliot, jotka eivät ole enää käytössä. Ei-hallitussa tilassa ohjelmoija vastaa kyseisten toimintojen toteutuksesta. Tila kuitenkin mahdollistaa osoittimien käytön sekä COM-komponentteja suoritetaan wrapperin avulla tässä tilassa. Näin vanhat komponentit ovat kutsuttavissa.net-ohjelmasta minimaalisella työllä. CLR ympäristöön tarkoitettu.net-ohjelma koostuu yhdestä tai useammasta moduulista (managed executable), joista jokainen sisältää metatietoa ja mahdollisesti hallittua koodia..net-ohjelmia kutsutaan assemblyksi [MeG01]. Kuvassa 1 esimerkki assemblystä, joka koostuu useasta moduulista. Jokainen assembly sisältää yhden päämoduulin (prime module), joka sisältää assemblyn identiteettitiedot metatieto-osiossa. Kuva 1: Useasta moduulista koostua.net assembly [Lid02]. Kaksi tärkeää CLR:n alijärjestelmää ovat lataaja (loader) ja JIT-kääntäjä (just-intime compiler). Lataaja lukee moduulien metatietoa, ja sen perusteella luo muistiin sisäisen esityksen ja rakenteen luokista sekä niiden jäsenistä. Tämä tapahtuu vain pyydettäessä, joten luokkia joihin ei viitata ei myöskään ladata muistiin. Luokan
4 lataamisen yhteydessä lataaja suorittaa useita yhtenäisyystarkistuksia metatiedon pohjalta. CLR ei ole tulkki, joten se ei suorita CIL-koodia, vaan JIT-kääntäjä kääntää tarvittaessa CIL-koodia natiiviksi koodiksi, jota sen jälkeen suoritetaan. JITkääntäminen tapahtuu vain pyydettäessä ja käännetty osa säilytetään välimuistissa. Jos muistia on vähän käytössä voidaan käyttämättömiä osia poistaa ja taas tarvittaessa uudelleen kääntää. Lisäksi on mahdollista esikääntää ohjelma, jolloin ohjelman suorituksen yhteydessä kääntämisen sijaan käytetään esikäännettyä koodia. Tällöin alkuperäiset moduulit täytyy kuitenkin olla mukana, koska ainoastaan ne sisältävät metatiedon. Kuvassa 2 on esimerkki.net-ohjelman suorituksesta. Kuva 2:.NET-ohjelman luonti ja suoritus [Lid02]. 3 Moduulitiedoston formaatti Moduulitiedoston formaatti on laajennus Microsoft Windows Portable Executable and Common Object File Format -standardista (PE/COFF) [Lid02]. Koska moduulitiedosto on PE/COFF-standardin mukainen kohtelee käyttöjärjestelmä sitä samoin
5 Kuva 3:.NET moduulitiedosto [Lid02]. Kuva 4:.NET moduulitiedoston tekstiosa [Lid02]. kuin jos se olisi ajettava tiedosto. CLR spesinen tieto mahdollistaa kuitenkin sen, että kontrolli siirtyy CLR:lle heti kun käyttöjärjestelmä kutsuu (invoke) moduulia. Kuva 3 esittelee PE/COFF-tiedoston rakenteen. PE-tiedoston.text osassa sijaitsee oleellisin tieto ohjelmasta. Kyseistä osaa on mahdollista vain lukea. Se sisältää CIL-koodin sekä muita tietoja kuten: metatietotaulut, Import Address -taulun, CLR-otsikkotiedot ja unmanagement runtime startup -tyngän (stub). Lisäksi jos se on generoitu ILAsm-kääntäjällä se sisältää osiot hallituista resursseista, vahvan singnature hashkoodin ja unmanaged export -tyngän. Kuva 4 esittelee.text-osion rakenteen. 4 Tyyppijärjestelmä CLR tukee seuraavia primitiivisiä tyyppejä [MeG01]: object (System.Object), string (System.String), void (void paluutyyppi (return
6 type)), bool, char (16-bit Unicode), int8, unsigned int8, int16, unsigned int16, int32, unsigned int32, int64, unsigned int64 oat32, oat64, typed reference. Lisäksi järjestelmä tukee kone riippuvaisia käskyjä: int, unsigned int ja oat. Näiden arvo riippuu ohjelman ajamiseen käytetyn koneen arkkitehtuurista. Esimerkiksi Pentium 4:lla CLR määrittelee int:n automaattisesti int32:ksi kun taan IA64- prosessorilla int64:ksi. Seuraavilla tyyppikonstruktoreilla (type constructors) voidaan primitiivisiä tyyppejä yhdistää yhdistelmätyypeiksi (composite types): valuetype typeref, class typeref, type pinned, type[bounds] (moniulotteinen taulukko) CLR tukee todellisia moniulotteisia taulukoita, method callconv type*(params) funktio-osoitin, type& hallittu-osoitin tyyppiin, type* ei-hallittuosoitin tyyppiin.
5 Yhteenveto 7.Net Common language runtime on laitteisto ja ohjelmointikieli riippumaton ympäristö. Ympäristö on olio-pohjainen, tyyppiturvallinen sekä sisältää automaattisen roskienkerääjän..net-ohjelmien lähdekoodi käännetään neutraalille Common intermediate language -formaatille. Suoritusaikana ohjelmien CIL-koodi käännetään dynaamisesti natiiviksi koodiksi, joka suoritetaan sen jälkeen, eli CLR ei ole tulkki..net-ohjelman suoritus on tehokkuudeltaan samaa tasoa kuin Java HotSpot Clientillä ajettu Java-ohjelma [Sin03]. Isoin ero CLR:n ja JVM:n välillä on se, että CLR on alunperin suunniteltu tukemaan useaa eri ohjelmointikieltä kun taas Java on suunniteltu toimimaan mahdollisimman monella eri alustalla [Gou01]. CIL sisältää noin 220:tä eri käskyä, joista osa palvelee erilaisten ohjelmointikielten tehokasta toteutusta. Tällä hetkellä.net:iin on saatavilla kääntäjä yli 40:lle eri kielelle 2. Lähteet Gou01 Gough, K. J., Stacking them up: A Comparison of Virtual Machines, 2001. URL http://sky.fit.qut.edu.au/~gough/virtualmachines. ps. Lid02 Lidin, S., toimittaja, Inside Microsoft.NET IL Assembler. Microsoft Press, 2002. MeG01 Meijer, E. ja Gough, K. J., Technical Overview of the Commmon Language Runtime, 2001. URL http://research.microsoft.com/ ~emeijer/papers/clr.pdf. Sin03 Singer, J., Jvm versus clr: a comparative study. Proceedings of the 2nd 2 http://www.dotnetlanguages.net/dnl/resources.aspx
8 international conference on Principles and practice of programming in Java, Kilkenny City, Ireland, June 2003, Computer Science Press, Inc., sivut 167169.