Daily Curious Perversion of Programming #13

Az azthiszem nyílt titok, hogy van egy már-már perverzitásba hajló érdeklődésem az értelmetlenül nagyszerű és sosevolt operációs rendszerek, meg hardverek felé. Az talán kevésbé, bár semmiképpen sem váratlan, hogy ugyanígy vagyok a programozási nyelvekkel is...

Nem véletlenül vagyok pont én az az elvetemült állat, aki 2009-ben azzal szórakozik, hogy Free Pascalt portolgasson egy kb. 1000 felhasználót számláló PowerPC-s AmigaOS klónra. De ez persze kispálya, könnyed ujjgyakorlat. Az már picit erősebb, hogy kb. egy vagyok az optimista becslések szerint is kb. 5 emberből, akinek PowerD nyelven írt, kiadott szoftvere van. Kapaszkodni: a PowerD egy AmigaE alapú nyelv, amit azonban a készítője, a cseh amigás Martin Kuchinka, kissé a C nyelv felé közelített. És hogy mi az az AmigaE...?

Amigán egykor reneszánszukat élték a különböző agyahalott, egyszemélyes és értelmetlen programozási nyelvek. Az OS assemblyben is igen jól programozható, valamint szinte bármilyen fordító-library és libc támogatás nélkül normális végfelhasználói API-t nyújt a próbálkozóknak. Így igen könnyű egyszerű és mégis jól használható programozási nyelveket összetákolni rajta. A Motorola 68k (és a PowerPC) processzorcsalád is jó partner ebben, az assemblyje, gépi kódja logikus, némi gyakorlattal könnyen átlátható, élmény rájuk fordítót írni. Nem csoda hogy az OS és a hardver agybajainak hiányában az emberek teljesen retardált programozási nyelvek tákolásában élték ki perverzióikat. Az sem a szerencsétlen véletlenek összjátéka, hogy a legendás Brainfuck nyelv is Amigán született...

... az AmigaE egy Amigán elterjedt nyelv, és gyakorlatilag ma is második számú nyelv a C és a C++ mögött ezen a platformon. A nyelv kitalálója és az első fordító készítője az a Wouter van Oortmerssen, akinek hosszas bűnlajstromát az AmigaE mellett többek között pl. a Far Cry című játék díszíti. A nyelv népszerűségét jól mutatja, hogy mióta Wouter abbafejezte a fejlesztését, csaknem fél tucat különböző alternatív fordító született rá - szinte mind kizárólag Amigára, bár a legújabb PortablE pl. már Windows támogatással, valamint Java backenddel is rendelkezik...

Jelen postunk szereplője az ECX nevű alternatív E fordító, amiről azt érdemes tudni, hogy 1db svéd ember fejleszti - név szerint Leif Salomonsson - akinek ez a második önálló E fordító próbálkozása. Az ECX teljesen önálló produktum, ami amellett hogy fut 68k-s és PowerPC-s Amigákon és MorphOS-en is, inline assemblere, beépített object writere és linkere is van, ráadásul a "nagy" nyelvek fordítóihoz hasonlóan saját magában, és természetesen ezáltal E nyelven fejlesztődik. Az ilyen egyszemélyes nyelveken való programozásnak számtalan előnye és hátránya van. Előny, hogy személyesen kommunikálhatsz a készítővel és ha kívánságaid vannak, azok is jó eséllyel implementálásra kerülnek, főleg ha látszik, hogy komolyak a szándékaid a nyelvvel. Hátrány, hogyha kicsit is eltérsz a fejlesztő kódstílusától, akkor ingoványos területre tévedsz, amely általában tele van nem tesztelt, vagy félig befejezett funkciókkal, esetleg olyan triviális hibákkal, amire nem is gondolnál. És természetesen egy ilyenbe futottam bele a minap.

E-gyorstalpaló következik. E-ben ún. modulok vannak, amelyek igen hasonlóak a Pascal nyelv unitjaihoz, vagyis önálló kód és adathalmazt, valamint elvben önálló namespace-t is alkotnak. A modulok között alapból nincs átjárás, hacsak valamit nem EXPORT-ált szimbólumként definiálunk - vagy nem futunk bele egy compiler bugba. :) A most következő kódszösszenet bő egy hét intenzív szívásának és heveny anyázásának következménye, mert természetesen a probléma egy párezer soros kódban merült fel és eltartott egy darabig, mire a jelen szintre sikerült egyszerüsíteni a kódot, amely előhozza a hibát, valamint a generált gépi kód tanulmányozásával meggyőző bizonyítékot is sikerült mellette felhozni.

Mellesleg mint végül kiderült, elsősorban ez a hiba akadályozta meg, hogy a Function 2009 partyra bármilyen értelmes - vagy értelmetlen - release-t be tudjak adni... De ez mellékszál.

A hiba triggereléséhez két fájl szükséges. Az egyik egy modul, legyen a neve globm.e

OPT MODULE
OPT AMIGAOS

DEF x /* here this will be 4(a4) */
DEF z

EXPORT PROC globfunc()
   x:=1
   WriteF('x: \d\n',x)
ENDPROC

A másik fájl maga főprogram (glob.e):

OPT AMIGAOS

MODULE '*globm'

DEF g
DEF a /* this will be 4(a4) here */

PROC main()
   WriteF('a: \d\n',a)
   globfunc()
   WriteF('a: \d\n',a)
ENDPROC

Mint az látható, mind a modul, mind a főprogram igen egyszerű. Körülbelül arról szól, hogy definiálnak 4db globális változót, aztán a főprogram meghívja a modul egy funkcióját, amely annyit csinál, hogy értéket ad az egyik globális változónak. A főprogram meg a hívás előtt és a hivás után is kiírja egyik globális változójának értékét. A bugra természetesen fordítás és futtatás után derül fény:

12.Ram Disk:> glob
a: 0
x: 1
a: 1
12.Ram Disk:>

Hoppácska. :) A modul globális változójának módosítása a főprogram globális változóiba szemetel. A compiler bugot végképp egy kis 68k disassembly leplezi le, elsőként lássuk a globfunc()-ot.

link.w  a5,#0
move.l  d3,-(sp)
moveq   #0x1,d0
move.l  d0,0x4(a4) ; <- here "x" accessed as 4(a4)
...

A globális változók kezdőcíme az A4 regiszterben található. Az "x" változó a 4(A4) címen, vagyis az A4 regiszterben lévő címhez képest 4 byte-al eltolva található. Azonban, nézzük csak a main()-t...

link.w  a5,#0
move.l  d3,-(sp)
movea.l #0x62c,a0
move.l  a0,-(sp)
subq.l  #0x4,sp
move.l  0x4(a4),d0 ; <- here "a" accessed as 4(a4)
move.l  d0,0(sp)
moveq   #0x4,d3
move.l  d3,-(sp)
bsr.w   0xa0
...

Ez a függvény entry kódjának és az első WriteF()-nek a disassemblyje. Látható, hogy itt szintén a 4(A4) cím használódik, ezúttal az "a" változóhoz. Egy hét agyrém és rengeteg anyázás okozója, most megvagy.

A bugreport e-mail az imént elment. A fejleményekről később beszámolunk. Aki még idáig ép elmével bírta, az most menjen szépen Brainfuckolni... :)

Szerk (2009.09.29 18:58) : és a beígért fejlemény

Hozzászólások

E! Erdekes kis nyelv, sikitva rohogtunk rajta blalaval mogotted, annyira aranyos. :)

---
pontscho / fresh!mindworkz

Van egy masik e nyelv is, bar azt kis e-vel irjak, es elegge mas a felhasznalasi terulete :)
link