QEMU.js: ngoku serious kunye ne-WASM

Kudala ndathatha isigqibo sokuzonwabisa ngqina ukubuyiselwa umva kwenkqubo kwaye ufunde ukwenza iJavaScript (ngakumbi, Asm.js) kwikhowudi yomatshini. I-QEMU yakhethwa kuvavanyo, kwaye emva kwexesha elithile kwabhalwa inqaku ngoHabr. Kumagqabantshintshi ndacetyiswa ukuba ndenze iprojekthi kwiWebAssembly, kwaye ndize ndiyeke phantse ndagqiba Ngandlela-thile andizange ndifune iprojekthi ... Umsebenzi wawuqhubeka, kodwa ngokukhawuleza, kwaye ngoku, kutshanje kuloo nqaku yavela. izimvo kumxholo othi “Yaphela njani ke yonke le nto?” Ukuphendula kwimpendulo yam eneenkcukacha, ndeva "Oku kuvakala njengenqaku." Ewe, ukuba unako, kuya kubakho inqaku. Mhlawumbi umntu uya kuyifumana iluncedo. Ukusuka kuyo umfundi uya kufunda ezinye iinyani malunga noyilo lwekhowudi ye-QEMU yokuvelisa i-backends, kunye nendlela yokubhala i-Just-in-Time compiler yesicelo sewebhu.

Iinjongo

Ekubeni sele ndifunde indlela "ngandlela-thile" i-port QEMU kwiJavaScript, ngeli xesha kwagqitywa ukuba yenze ngobulumko kwaye ingaphindi iimpazamo ezindala.

Inombolo yempazamo yokuqala: isebe elisuka kwindawo yokukhulula

Impazamo yam yokuqala yayikukufoka inguqulelo yam ukusuka kuguqulelo oluphezulu 2.4.1. Emva koko kwabonakala kum ingcamango elungileyo: ukuba ukukhululwa kwenqaku kukho, ngoko mhlawumbi kuzinzile ngakumbi kune-2.4 elula, kwaye ngakumbi isebe. master. Kwaye ekubeni bendicwangcise ukongeza inani elifanelekileyo leempazamo zam, andidingi mntu wumbi kwaphela. Mhlawumbi kwaba njalo. Kodwa nantsi into: I-QEMU ayimi, kwaye ngexesha elithile bade babhengeze ukuphuculwa kwekhowudi eyenziwe ngeepesenti ze-10. "Ewe, ngoku ndiya kukhenkcela," ndacinga kwaye ndaphuka. Apha kufuneka senze ukwehla: ngenxa yohlobo olulodwa lwe-QEMU.js kunye nenyaniso yokuba i-QEMU yasekuqaleni ayithethi ukungabikho kwemisonto emininzi (oko kukuthi, ukukwazi ukusebenza ngaxeshanye iindlela ezininzi zekhowudi ezingahambelaniyo, kwaye hayi nje "ukusebenzisa zonke iikernel") ibaluleke kakhulu kuyo, eyona misebenzi iphambili yentambo kuye kwafuneka "ndiyikhuphe" ukuze ndikwazi ukufowunela ngaphandle. Oku kudale iingxaki zendalo ngexesha lokudityaniswa. Noko ke, isibakala sokuba ezinye utshintsho ukusuka kwisebe master, endiye ndazama ngayo ukudibanisa ikhowudi yam, nayo yathathwa i-cherry kwindawo yokukhutshwa (kwaye ke ngoko kwisebe lam) mhlawumbi ngekhe yongeze lula.

Ngokubanzi, ndaye ndagqiba kwelokuba kusesengqiqweni ukulahla iprototype, ukuyiqhawula kumacandelo kwaye kwakhiwe inguqulelo entsha ukusuka ekuqaleni esekwe kwinto entsha kwaye ngoku master.

Impazamo yesibini: Indlela ye-TLP

Ngokwenene, oku akuyiyo impazamo, ngokubanzi, luphawu nje lokudala iprojekthi kwiimeko zokungaqondi ngokupheleleyo "kuphi kunye nendlela yokuhamba?" kwaye ngokubanzi "ngaba siya kufika apho?" Kwezi meko inkqubo enzima yayilukhetho olufanelekileyo, kodwa, ngokwemvelo, andizange ndifune ukuyiphinda ngokungeyomfuneko. Ngeli xesha ndandifuna ukuyenza ngobulumko: ukwenza i-athomu, utshintsho lwekhowudi (kwaye kungekhona "ukudibanisa abalinganiswa abangahleliwe kunye de ihlanganise (kunye nezilumkiso)", njengoko uLinus Torvalds wayetshilo malunga nomntu, ngokutsho kweWikiquote), njl.

Inombolo yempazamo yesithathu: ukungena emanzini ngaphandle kokwazi i-ford

Andikayisusi ngokupheleleyo le nto, kodwa ngoku ndithathe isigqibo sokungayilandeli indlela yokuchasana kwaphela, kwaye ndiyenze “njengomntu omdala,” oko kukuthi, bhala i-TCG yam yangasemva ukusuka ekuqaleni, ukuze Ukutsho kamva, "Ewe, oku kunjalo, ngokucothayo, kodwa andikwazi ukulawula yonke into - yindlela ebhalwe ngayo i-TCI ..." Ngaphezu koko, oku ekuqaleni kwakubonakala njengesisombululo esicacileyo, ekubeni Ndivelisa ikhowudi yokubini. Njengoko besithi, “I-Ghent iqokeleleneу, kodwa hayi laa”: ikhowudi, ngokuqinisekileyo, yokubini, kodwa ulawulo alunakugqithiselwa kuyo ngokulula - kufuneka lutyhalelwe ngokucacileyo kwisikhangeli ukuze siqulunqwe, okukhokelela kwinto ethile evela kwihlabathi le-JS, ekusafuneka ukuba ugcinwe ndaweni ithile. Nangona kunjalo, kwi-architectures ye-RISC eqhelekileyo, njengoko ndiqonda, imeko eqhelekileyo iyimfuneko yokusetha ngokucacileyo i-cache yomyalelo wekhowudi ehlaziyiweyo - ukuba oku ayisiyiyo into esiyidingayo, ngoko ke, nangayiphi na imeko, isondele. Ukongeza, kwiinzame zam zokugqibela, ndiye ndafunda ukuba ulawulo alubonakali lugqithiselwa embindini webhloko yokuguqulela, ngoko ke asiyifuni ngenyani i-bytecode etolikwe kuyo nayiphi na i-offset, kwaye sinokuyivelisa ngokulula ukusuka kumsebenzi kwi-TB. .

Bafika bakhaba

Nangona ndiqale ukubhala ikhowudi kwakhona ngoJulayi, ukukhaba komlingo kuye kwanyuka kungakhange kuqatshelwe: ngokwesiqhelo iileta ezivela kwiGitHub zifika njengezaziso malunga neempendulo kwiMiba kunye nezicelo zokutsalwa, kodwa apha, ngequbuliso khankanya kumsonto Binaryen njenge qemu backend kumxholo, "Wenze into enjalo, mhlawumbi uya kuthetha into." Besithetha ngokusebenzisa ithala leencwadi elinxulumene ne-Emscripten Ibhinaryen ukwenza i-WASM JIT. Ewe, nditshilo ukuba unelayisensi ye-Apache 2.0 apho, kwaye i-QEMU iyonke isasazwe phantsi kwe-GPLv2, kwaye ayihambelani kakhulu. Ngokukhawuleza kwavela ukuba ilayisenisi ingaba yilungise ngandlela thile (Andazi: mhlawumbi uyitshintshe, mhlawumbi ilayisensi emibini, mhlawumbi enye into ...). Kambe ke oku kwandonwabisa, kuba ngelo xesha ndandisele ndiyijongile ifomathi yokubini WebAssembly, kwaye ngandlela-thile ndandibuhlungu kwaye ndingaqondakali. Kwakukho nethala leencwadi elaliza kuqwenga iibhloko ezisisiseko ngegrafu yotshintsho, livelise i-bytecode, kwaye lide liyiqhube kwitoliki ngokwayo, ukuba kuyimfuneko.

Kwaphinda kwabakho okungakumbi ileta kuluhlu lokuposa lwe-QEMU, kodwa oku kungaphezulu malunga nombuzo othi, "Ngubani oyifunayo?" Kwaye kunjalo ngequbuliso, kwavela ukuba kuyimfuneko. Ubuncinci, unokukrwela kunye oku kulandelayo okunokwenzeka okusebenzisa, ukuba isebenza ngokukhawuleza okanye kancinci:

  • ukuqalisa into efundisayo ngaphandle kofakelo konke konke
  • i-virtualization kwi-iOS, apho, ngokutsho kwamahemuhemu, ekuphela kwesicelo esinelungelo lokuvelisa ikhowudi kwi-fly yi-injini ye-JS ( ngaba oku kuyinyaniso?)
  • umboniso we-mini-OS - enye-floppy, eyakhelwe-ngaphakathi, zonke iintlobo ze-firmware, njl.

Iimpawu zeBrowser Runtime

Njengoko besenditshilo, i-QEMU ibotshelelwe kwi-multithreading, kodwa isikhangeli asinayo. Ewe, oko kukuthi, hayi ... Ekuqaleni yayingekho konke konke, emva koko kwavela iWebWorkers - ngokokude ndiqonde, oku kuphindaphinda ngokusekwe kumyalezo ogqithisiweyo. ngaphandle kweenguqu ekwabelwana ngazo. Ngokwemvelo, oku kudala iingxaki ezibalulekileyo xa ufaka ikhowudi ekhoyo ngokusekwe kwimodeli yememori ekwabelwana ngayo. Emva koko, phantsi koxinzelelo loluntu, nayo yaphunyezwa phantsi kwegama SharedArrayBuffers. Yaziswa ngokuthe ngcembe, babhiyozela ukuqaliswa kwayo kwiiphequluli ezahlukeneyo, emva koko babhiyozela uNyaka oMtsha, emva koko i-Meltdown ... Emva koko bafikelela kwisigqibo sokuba i-coarse okanye i-coarse yokulinganisa ixesha, kodwa ngoncedo lwememori ekwabelwana ngayo kunye ne intambo inyusa ikhawuntari, iyafana iya kusebenza ngokuchanekileyo. Ke sikhubaze ukufunda okuninzi ngememori ekwabelwanayo ngayo. Kubonakala ngathi emva koko bayibuyisela kwakhona, kodwa, njengoko kwacaca kuvavanyo lokuqala, kukho ubomi ngaphandle kwayo, kwaye ukuba kunjalo, siya kuzama ukwenza ngaphandle kokuxhomekeka kwi-multithreading.

Inqaku lesibini kukungenzeki kobuqhetseba obukwinqanaba elisezantsi kunye nesitaki: awukwazi ukuthatha ngokulula, gcina umxholo wangoku kwaye utshintshele kwentsha ngesitaki esitsha. Isitaki sokufowuna silawulwa ngumatshini wenyani we-JS. Kubonakala ngathi, yintoni ingxaki, kuba sisagqiba ukulawula ukuhamba kwangaphambili ngokupheleleyo ngesandla? Inyani kukuba ibhloko ye-I / O kwi-QEMU iphunyezwa ngee-coroutines, kwaye kulapho ukuguqulwa kwe-stack ephantsi kuya kuba luncedo. Ngethamsanqa, i-Emscipten sele iqulethe indlela yokusebenza kwe-asynchronous, nokuba zimbini: Async и I-Enterpreter. Eyokuqala isebenza ngebloat ebalulekileyo kwikhowudi yeJavaScript eyenziweyo kwaye ayisaxhaswa. Okwesibini yindlela yangoku "indlela echanekileyo" kwaye isebenza ngokuvelisa i-bytecode kwitoliki yomthonyama. Isebenza, ewe, ngokuthe chu, kodwa ayikhuphi ikhowudi. Kuyinyani, inkxaso yee-coroutines zolu matshini kwafuneka igalelo ngokuzimeleyo (kwakukho ii-coroutines ezibhalelwe i-Asyncify kwaye bekukho ukuphunyezwa malunga ne-API efanayo ye-Emterpreter, ubufuna nje ukuzidibanisa).

Okwangoku, andizange ndikwazi ukwahlula ikhowudi ibe yinye ehlanganiswe kwi-WASM kwaye itolikwe ngokusebenzisa i-Emterpreter, ngoko ke izixhobo zebhlokhi azisebenzi okwangoku (jonga kuluhlu olulandelayo, njengoko bethetha ...). Oko kukuthi, ekugqibeleni kuya kufuneka ufumane into efana nale nto ihlekisayo yomaleko:

  • ibhloko etolikiweyo I/O. Ewe, ngaba ubulindele ukuba i-NVMe ifaniswe ngokusebenza kwemveli? 🙂
  • iqulunqwe ngokwestatiki ikhowudi yeQEMU engundoqo (umguquli, ezinye izixhobo ezilinganisiweyo, njl.njl.)
  • iqulunqwe ngamandla ikhowudi yeendwendwe kwi-WASM

Iimpawu zemithombo ye-QEMU

Njengoko sele uqikelele, ikhowudi yokulinganisa ulwakhiwo lweendwendwe kunye nekhowudi yokuvelisa imiyalelo yoomatshini bomamkeli yahlulwe kwi-QEMU. Enyanisweni, iyinto encinci ngakumbi:

  • kukho izakhiwo zeendwendwe
  • is ii-accelerators, oko kukuthi, i-KVM ye-hardware ye-virtualization kwi-Linux (yeendwendwe kunye neesistim ezihambelanayo kunye nomnye), i-TCG yokuvelisa ikhowudi ye-JIT naphi na. Ukuqala nge-QEMU 2.9, inkxaso ye-HAXM yomgangatho wokubonwa kwehardware kwiWindows yavela (iinkcukacha)
  • ukuba i-TCG iyasetyenziswa kwaye hayi i-hardware ye-virtualization, ngoko inenkxaso yokuvelisa ikhowudi eyahlukileyo kulwakhiwo lomkhosi ngamnye, kunye netoliki yendawo yonke.
  • ... kwaye malunga nayo yonke le nto - i-peripherals efanisiweyo, ujongano lomsebenzisi, ukufuduka, ukurekhoda kwakhona, njl.

Ngendlela, ubusazi: I-QEMU inokulinganisa kungekuphela nje ikhompyuter yonke, kodwa kunye neprosesa yenkqubo yomsebenzisi eyahlukileyo kwi-kernel yenginginya, esetyenziswa, umzekelo, yi-AFL fuzzer yesixhobo sokubini. Mhlawumbi umntu angathanda ukufaka le ndlela yokusebenza ye-QEMU ukuya kwi-JS? 😉

Njengoninzi lwesoftware yasimahla ekudala ikho, i-QEMU yakhiwe ngomnxeba configure и make. Masithi uthathe isigqibo sokongeza into: i-backend ye-TCG, ukuphunyezwa komsonto, enye into. Sukungxama ukonwaba / ukoyikeka (krwelela umgca njengoko kufanelekile) ngethemba lokunxibelelana ne-Autoconf- enyanisweni, configure I-QEMU's kuyabonakala ukuba izibhale ngokwayo kwaye ayiveliswanga kwanto.

WebAssembly

Ke yintoni le nto ibizwa ngokuba yiWebAssembly (aka WASM)? Oku kukubuyisela i-Asm.js, ayisazenzi ikhowudi yeJava esebenzayo. Ngokuchasene noko, ibhinari kuphela kwaye yenziwe yalungiswa, kwaye nokubhala nje inani elipheleleyo kuyo akukho lula kakhulu: ukubumbana, igcinwa kwifomathi. LEB128.

Usenokuba uvile malunga ne-algorithm ye-relooping ye-Asm.js - oku kukubuyiselwa kwemiyalelo yokulawula ukuhamba "kwizinga eliphezulu" (oko kukuthi, ukuba-ke-enye, i-loops, njl.), apho iinjini ze-JS ziyilelwe, ukusuka. inqanaba eliphantsi le-LLVM IR, kufutshane nekhowudi yomatshini eyenziwe ngumqhubekekisi. Ngokwemvelo, ukumelwa okuphakathi kwe-QEMU kusondele kwisibini. Kuya kubonakala ngathi nantsi, i-bytecode, ukuphela kwentuthumbo ... Kwaye ke kukho iibhloko, ukuba-ke-enye kunye neelophu!..

Kwaye esi sesinye isizathu sokuba kutheni i-Binaryen iluncedo: inokwamkela ngokwemvelo iibhloko ezikumgangatho ophezulu kufutshane nento eya kugcinwa kwi-WASM. Kodwa inokuvelisa ikhowudi kwigrafu yeebhloko ezisisiseko kunye noshintsho phakathi kwabo. Ewe, sele nditshilo ukuba ifihla ifomathi yokugcina iWebAssembly emva kweC / C ++ API efanelekileyo.

I-TCG (iKhowudi yoMveli weKhowudi encinci)

GTC yayikho ekuqaleni i-backend ye-compiler C. Emva koko, ngokucacileyo, ayinakumelana nokhuphiswano kunye ne-GCC, kodwa ekugqibeleni ifumene indawo yayo kwi-QEMU njengendlela yokuvelisa ikhowudi yeqonga lokusingatha. Kukho kwakhona i-backend ye-TCG eyenza i-bytecode ethile engabonakaliyo, eyenziwa ngokukhawuleza yitoliki, kodwa ndagqiba ekubeni ndiphephe ukuyisebenzisa ngeli xesha. Nangona kunjalo, into yokuba kwi-QEMU sele ikwazi ukwenza utshintsho kwi-TB eveliswayo ngomsebenzi. tcg_qemu_tb_exec, kwabonakala kuluncedo kakhulu kum.

Ukongeza i-backend entsha ye-TCG kwi-QEMU, kufuneka udale i-subdirectory tcg/<имя архитектуры> (kule meko, tcg/binaryen), kwaye iqulethe iifayile ezimbini: tcg-target.h и tcg-target.inc.c и ukumisela imalunga configure. Ungabeka ezinye iifayile apho, kodwa, njengoko unokuthelekelela kumagama ezi zimbini, ziya kufakwa zombini ndaweni ithile: enye njengefayile yentloko eqhelekileyo (ifakiwe tcg/tcg.h, kwaye leyo sele kwezinye iifayile kubalawuli tcg, accel kwaye hayi kuphela), enye - kuphela njengekhowudi yamazwi ngaphakathi tcg/tcg.c, kodwa inokufikelela kwimisebenzi yayo engatshintshiyo.

Ukuthatha isigqibo sokuba ndiza kuchitha ixesha elininzi kuphando oluneenkcukacha lwendlela esebenza ngayo, ndikhuphele "amathambo" ezi fayile zimbini ukusuka kolunye ukuphunyezwa kwe-backend, ngokunyanisekileyo ndibonisa oku kwisihloko selayisensi.

Ifayile tcg-target.h iqulathe ikakhulu useto kwifom #define-s:

  • zingaphi iirejista kunye nobubanzi obunjani kwi-architecture ekujoliswe kuyo (sibaninzi njengoko sifuna, abaninzi njengoko sifuna - umbuzo ungaphezulu malunga nokuba yintoni eya kuveliswa kwikhowudi esebenzayo ngakumbi ngumkhangeli "kwithagethi epheleleyo" yolwakhiwo. ...)
  • ukulungelelaniswa kwemiyalelo yenginginya: kwi-x86, kwaye nakwi-TCI, imiyalelo ayilungelelaniswanga konke konke, kodwa ndiza kubeka kwindawo yokugcina ikhowudi kungekhona imiyalelo konke konke, kodwa izikhombisi kwizakhiwo zethala leencwadi zeBinaryen, ngoko ndiza kuthi: 4 iibhayithi
  • yeyiphi imiyalelo ekhethiweyo i-backend enokuvelisa - sibandakanya yonke into esiyifumana kwi-Binaryen, vumela i-accelerator iphule ezinye zibe lula
  • Ithini imilinganiselo ye-TLB cache ecelwe ngasemva. Inyaniso kukuba kwi-QEMU yonke into inzulu: nangona kukho imisebenzi yomncedisi eyenza umthwalo / ivenkile ithathela ingqalelo undwendwe lwe-MMU (besiya kuba phi ngaphandle kwayo ngoku?), bagcina i-cache yabo yokuguqulela ngendlela yesakhiwo, ukusetyenzwa kwayo kukulungele ukuzinzisa ngokuthe ngqo kwiibhloko zosasazo. Umbuzo ngulo, yeyiphi i-offset kolu lwakhiwo ecutshungulwa ngokufanelekileyo lulandelelwano oluncinci nolukhawulezayo lwemiyalelo?
  • Apha unokwenza injongo yobhaliso olunye okanye ezimbini ezigciniweyo, yenza ukufowuna i-TB ngomsebenzi kwaye ukhethe ukuchaza ezimbalwa ezincinci. inline-imisebenzi efana flush_icache_range (kodwa akusiyo imeko yethu)

Ifayile tcg-target.inc.c, kunjalo, idla ngokuba nkulu kakhulu ngobukhulu kwaye iqulethe imisebenzi emininzi enyanzelekileyo:

  • ukuqaliswa, kubandakanywa nezithintelo apho imiyalelo inokusebenza kweziphi ii-operands. Ngokucacileyo ndikhutshelwe ndim kwenye indawo yangasemva
  • umsebenzi othatha umyalelo omnye wangaphakathi we-bytecode
  • Ungaphinda ubeke imisebenzi encedisayo apha, kwaye ungasebenzisa imisebenzi engatshintshiyo ukusuka tcg/tcg.c

Mna, ndakhetha esi sicwangciso silandelayo: kumagama okuqala kwibhloko yokuguqulela elandelayo, ndabhala phantsi izikhombisi ezine: uphawu lokuqala (ixabiso elithile kwindawo ekufutshane. 0xFFFFFFFF, eyamisela imeko yangoku ye-TB), umxholo, imodyuli evelisiweyo, kunye nenombolo yomlingo yokulungiswa kweempazamo. Ekuqaleni uphawu lwafakwa 0xFFFFFFFF - nphi n - inani elincinci eli-positive, kwaye ixesha ngalinye lisenziwa ngetoliki lalinyuka ngo-1. Xa lifikelela 0xFFFFFFFE, uqulunqo lwenzekile, imodyuli yagcinwa kwitheyibhile yomsebenzi, yangeniswa "kwisiqalisi" esincinci, apho ufezekiso luye lwavela. tcg_qemu_tb_exec, kwaye imodyuli yasuswa kwimemori ye-QEMU.

Ukuchaza i-classics, "I-Crutch, ingakanani idibaniswe kwesi sandi kwintliziyo ye-proger ...". Nangona kunjalo, inkumbulo yayivuza kwenye indawo. Ngaphezu koko, ibiyinkumbulo elawulwa yi-QEMU! Ndinekhowudi yokuba, xa ndibhala umyalelo olandelayo (kakuhle, oko kukuthi, isalathisi), ucime lowo unxibelelwano lwakhe lwalukule ndawo ngaphambili, kodwa oku akuzange kuncede. Ngokwenyani, kwimeko elula, i-QEMU yabela imemori ekuqaleni kwaye ibhala ikhowudi eyenziwe apho. Xa isithinteli siphela, ikhowudi ilahlelwa ngaphandle ize elandelayo iqalise ukubhalwa endaweni yayo.

Emva kokufunda ikhowudi, ndiye ndaqonda ukuba iqhinga ngenombolo yomlingo lindivumele ukuba ndingaphumeleli ekubhubhiseni imfumba ngokukhulula into engalunganga kwi-buffer engabonakaliyo kwipasi yokuqala. Kodwa ngubani ophinda abhale isithinteli ukuba sidlule umsebenzi wam kamva? Njengoko abaphuhlisi be-Emscripten becebisa, xa ndibalekela kwingxaki, ndafaka ikhowudi ephumayo emva kwesicelo somthonyama, setha iRekhodi ye-Mozilla-Replay kuyo ... Ngokuqhelekileyo, ekugqibeleni ndaqonda into elula: kwibhloko nganye, a struct TranslationBlock nenkcazelo yayo. Qikelela apho... Injalo loo nto, kanye phambi kwebhloko kanye kwi-buffer. Ndithe ndikuqonda oku, ndaye ndagqiba kwelokuba ndiyeke ukusebenzisa iintonga (ubuncinci ezinye), kwaye ngokulula ndayiphosa inombolo yomlingo, kwaye ndadlulisela amagama aseleyo kuwo. struct TranslationBlock, ukwenza uluhlu oludityanisiweyo olulodwa olunokugqithwa ngokukhawuleza xa i-cache yokuguqulela isetyenzisiwe, kwaye ikhulule imemori.

Ezinye iintonga zishiyekile: umzekelo, izikhombisi eziphawulweyo kwikhowudi yesithinteli - ezinye zazo zilula BinaryenExpressionRef, oko kukuthi, bajonge iintetho ezifuna ukufakwa ngokulandelelana kwibhloko esisiseko eyenziweyo, inxalenye yimeko yokutshintsha phakathi kwe-BBs, inxalenye yindawo yokuya kuyo. Ewe, kukho iibhloko esele zilungisiwe zeRelooper ezifuna ukuqhagamshelwa ngokwemiqathango. Ukuzahlula, uqikelelo lusetyenziswa ukuba zonke zilungelelaniswe ngama-byte amane, ukuze ukwazi ukusebenzisa ngokukhuselekileyo amasuntswana amabini abalulekileyo kwilebhile, kufuneka ukhumbule ukuyisusa ukuba kuyimfuneko. Ngendlela, iilebula ezinjalo sele zisetyenziswe kwi-QEMU ukubonisa isizathu sokuphuma kwi-loop ye-TCG.

Ukusebenzisa i-Binaryen

Iimodyuli kwiWebAssembly ziqulethe imisebenzi, nganye equlethe umzimba, oyintetho. Iintetho ziyimisebenzi engaqhelekanga kunye nebini, iibhloko ezibandakanya uluhlu lwamanye amabinzana, ukuhamba kolawulo, njl. Njengoko besenditshilo, ukuhamba kokulawula apha kucwangciswe ngokuchanekileyo njengamasebe akwinqanaba eliphezulu, iilophu, iifowuni zokusebenza, njl. Iingxoxo kwimisebenzi azigqithiswanga kwisitaki, kodwa ngokucacileyo, njengakwi-JS. Kukwakho izinto eziguquguqukayo zehlabathi, kodwa khange ndizisebenzise, ​​ngoko ke andizukukuxelela ngazo.

Imisebenzi nayo ineenguqu zendawo, ezibalwa ukusuka kwi-zero, yohlobo: int32 / int64 / i-float / kabini. Kulo mzekelo, iinguqu zokuqala n zasekuhlaleni ziingxoxo ezigqithiselwe kumsebenzi. Nceda uqaphele ukuba nangona yonke into elapha ingekho kumgangatho ophantsi ngokupheleleyo ngokwemigaqo yolawulo lokuhamba, amanani apheleleyo awakayiphathi “impawu ezisayiniweyo/ ezingatyikitywanga”: indlela eliziphatha ngayo inani ixhomekeke kwikhowudi yokusebenza.

Ngokuqhelekileyo, i-Binaryen ibonelela elula C-API: wenza imodyuli, kuye yenza amabinzana - unary, binary, blocks from other expressions, control flow, etc. Emva koko udala umsebenzi ngentetho njengomzimba wayo. Ukuba wena, njengam, unegrafu yenguqu esezantsi, icandelo le-relooper liya kukunceda. Njengoko ndiqonda, kuyenzeka ukuba kusetyenziswe ulawulo oluphezulu lokuhamba kokubulawa kwibhloko, nje ukuba ingahambi ngaphaya kwemida yebhloko - oko kukuthi, kunokwenzeka ukwenza indlela yangaphakathi ekhawulezayo / ecothayo. indlela yokwenza i-branching ngaphakathi kwekhowudi yokucubungula i-TLB ye-cache eyakhelwe-ngaphakathi, kodwa ukuphazamisa ukuhamba kokulawula "kwangaphandle". Xa ukhulula i-relooper, iibhloko zayo ziyakhululwa xa ukhulula imodyuli, intetho, imisebenzi, njl.njl. eyabelwe yona iyanyamalala. ibala.

Nangona kunjalo, ukuba ufuna ukutolika ikhowudi kubhabho ngaphandle kokudala okungeyomfuneko kunye nokucinywa komzekelo wokutolika, kunokuba sengqiqweni ukubeka le ngqiqo kwifayile yeC ++, kwaye ukusuka apho ulawule ngokuthe ngqo yonke iC++ API yethala leencwadi, ngokudlula ukulungele- ii-wrapers ezenziwe.

Ke ukwenza ikhowudi oyifunayo

// настроить глобальные параметры (можно поменять потом)
BinaryenSetAPITracing(0);

BinaryenSetOptimizeLevel(3);
BinaryenSetShrinkLevel(2);

// создать модуль
BinaryenModuleRef MODULE = BinaryenModuleCreate();

// описать типы функций (как создаваемых, так и вызываемых)
helper_type  BinaryenAddFunctionType(MODULE, "helper-func", BinaryenTypeInt32(), int32_helper_args, ARRAY_SIZE(int32_helper_args));
// (int23_helper_args приоб^Wсоздаются отдельно)

// сконструировать супер-мега выражение
// ... ну тут уж вы как-нибудь сами :)

// потом создать функцию
BinaryenAddFunction(MODULE, "tb_fun", tb_func_type, func_locals, FUNC_LOCALS_COUNT, expr);
BinaryenAddFunctionExport(MODULE, "tb_fun", "tb_fun");
...
BinaryenSetMemory(MODULE, (1 << 15) - 1, -1, NULL, NULL, NULL, NULL, NULL, 0, 0);
BinaryenAddMemoryImport(MODULE, NULL, "env", "memory", 0);
BinaryenAddTableImport(MODULE, NULL, "env", "tb_funcs");

// запросить валидацию и оптимизацию при желании
assert (BinaryenModuleValidate(MODULE));
BinaryenModuleOptimize(MODULE);

... ukuba ndiyilibele nantoni na, uxolo, oku kukumela nje isikali, kwaye iinkcukacha zikuxwebhu.

Kwaye ngoku i-crack-fex-pex iqala, into efana nale:

static char buf[1 << 20];
BinaryenModuleOptimize(MODULE);
BinaryenSetMemory(MODULE, 0, -1, NULL, NULL, NULL, NULL, NULL, 0, 0);
int sz = BinaryenModuleWrite(MODULE, buf, sizeof(buf));
BinaryenModuleDispose(MODULE);
EM_ASM({
  var module = new WebAssembly.Module(new Uint8Array(wasmMemory.buffer, $0, $1));
  var fptr = $2;
  var instance = new WebAssembly.Instance(module, {
      'env': {
          'memory': wasmMemory,
          // ...
      }
  );
  // и вот уже у вас есть instance!
}, buf, sz);

Ukuze ngandlela-thile udibanise ihlabathi le-QEMU kunye ne-JS kwaye ngexesha elifanayo ufikelele kwimisebenzi ehlanganisiweyo ngokukhawuleza, uluhlu lwenziwa (itafile yemisebenzi yokungenisa kwi-launcher), kwaye imisebenzi eyenziwe yafakwa apho. Ukubala ngokukhawuleza isalathiso, isalathiso sebloko yokuguqulela igama elinguziro saqale sasetyenziswa njengaso, kodwa ke isalathiso esibalwe kusetyenziswa le fomyula saqala ukungena kwibala. struct TranslationBlock.

Ngendlela, umboniso (okwangoku unelayisensi emfiliba) isebenza kakuhle kuphela kwiFirefox. Abaphuhlisi beChrome babe ngandlela ithile ayilunganga Kwinyani yokuba umntu othile angafuna ukwenza ngaphezulu kwewaka lemizekelo yeemodyuli zeWebAssembly, ke ngoko babele igigabyte yendawo yedilesi yenyani nganye...

Kuphelele apho okwangoku. Mhlawumbi kuya kubakho elinye inqaku ukuba nabani na onomdla. Oko kukuthi, kusekho ubuncinci kuphela yenza izixhobo zebhloko zisebenze. Kusenokuba sengqiqweni ukwenza ukudityaniswa kweemodyuli zeWebAssembly ezingahambelaniyo, njengoko kuqhelekile kwilizwe le-JS, kuba kusekho itoliki enokwenza konke oku de imodyuli yemveli ilungile.

Ekugqibeleni iqhina: uqokelele ibhinari kwi-32-bit ye-architecture, kodwa ikhowudi, ngokusebenzisa imisebenzi yememori, inyuka isuka e-Binaryen, kwenye indawo kwi-stack, okanye kwenye indawo kwi-2 GB ephezulu ye-32-bit indawo yedilesi. Ingxaki kukuba kwimbono kaBinaryen le nto ifikelela kwidilesi enkulu kakhulu yesiphumo. Ukujikeleza njani oku?

Ngendlela admin

Khange ndigqibe ukuvavanya oku, kodwa ingcinga yam yokuqala yayikukuba "Kuthekani ukuba ndifake i-32-bit Linux?" Emva koko inxalenye ephezulu yendawo yedilesi iya kuhlala yi-kernel. Umbuzo kuphela kukuba kuya kuhlala kangakanani: 1 okanye 2 Gb.

Ngendlela yomdwelisi wenkqubo (ukhetho lwabasebenzi)

Masivuthele iqamza phezulu kwindawo yedilesi. Mna ngokwam andiqondi ukuba kutheni isebenza - apho sele sele kufuneka kubekho isitaki. Kodwa "singabasebenzi: yonke into iyasisebenzela, kodwa akukho mntu waziyo ukuba kutheni ..."

// 2gbubble.c
// Usage: LD_PRELOAD=2gbubble.so <program>

#include <sys/mman.h>
#include <assert.h>

void __attribute__((constructor)) constr(void)
{
  assert(MAP_FAILED != mmap(1u >> 31, (1u >> 31) - (1u >> 20), PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
}

... kuyinyani ukuba ayihambelani neValgrind, kodwa, ngethamsanqa, iValgrind ngokwayo ityhala wonke umntu ngaphandle apho :)

Mhlawumbi umntu uya kunika inkcazo engcono malunga nendlela le khowudi yam esebenza ngayo ...

umthombo: www.habr.com

Yongeza izimvo