I-QEMU.js: manje ibucayi futhi nge-WASM

Ngesinye isikhathi nganquma ukuzijabulisa fakazela ukuhlehla kwenqubo futhi ufunde indlela yokwenza i-JavaScript (ngokunembile, i-Asm.js) kusuka kukhodi yomshini. I-QEMU yakhethelwa ucwaningo, futhi ngemva kwesikhathi esithile kwabhalwa i-athikili ngo-Habr. Emazwaneni ngalulekwa ukuthi ngenze kabusha iphrojekthi kuWebAssembly, futhi ngize ngiziyeke cishe sekuphelile Ngandlela-thile ngangingafuni iphrojekthi ... Umsebenzi wawuqhubeka, kodwa kancane kancane, futhi manje, maduzane kuleso sihloko sivele ukuhlaziya esihlokweni esithi “Pho kwaphela kanjani konke?” Ngiphendula impendulo yami enemininingwane, ngezwa "Lokhu kuzwakala njengendatshana." Hhayi-ke, uma ukwazi, kuzoba khona isihloko. Mhlawumbe othile uzokuthola kuwusizo. Kuyo umfundi uzofunda amaqiniso athile mayelana nokuklanywa kwe-backends yokukhiqiza ikhodi ye-QEMU, kanye nendlela yokubhala i-Just-in-Time compiler yohlelo lokusebenza lwewebhu.

Imisebenzi

Njengoba ngase ngivele ngafunda indlela "ngandlela-thile" yokuthungatha i-QEMU ku-JavaScript, kulokhu kwanqunywa ukuthi sikwenze ngokuhlakanipha futhi singaphindi amaphutha amadala.

Iphutha lokuqala: igatsha elisuka endaweni yokukhululwa

Iphutha lami lokuqala kwaba ukufokha inguqulo yami kusukela enguqulweni ekhuphuka nomfula 2.4.1. Khona-ke kwabonakala kuwumqondo omuhle kimina: uma ukukhululwa kwephuzu kukhona, khona-ke mhlawumbe kuzinzile kuno-2.4 elula, futhi nakakhulu igatsha. master. Futhi njengoba ngihlele ukungeza inani elifanelekile lezimbungulu zami, angizange ngidinge omunye umuntu nhlobo. Cishe kwaba kanjalo. Kodwa nansi into: I-QEMU ayimile, futhi ngesinye isikhathi baze bamemezela ukuthuthukiswa kwekhodi ekhiqizwe ngamaphesenti angu-10. "Yebo, manje ngizoba yiqhwa," ngacabanga futhi ngaphuka. Lapha sidinga ukuhlehla: ngenxa yemvelo yochungechunge olulodwa lwe-QEMU.js kanye neqiniso lokuthi i-QEMU yasekuqaleni ayisho ukungabikho kokucushwa okuningi (okungukuthi, ikhono lokusebenzisa kanyekanye izindlela ezimbalwa zekhodi ezingahlobene, kanye hhayi nje "ukusebenzisa wonke ama-kernel") kubalulekile kukho, imisebenzi eyinhloko yezintambo obekufanele "ngiyikhiphe" ukuze ngikwazi ukuyibiza ngaphandle. Lokhu kwadala ezinye izinkinga zemvelo ngesikhathi sokuhlanganisa. Nokho, iqiniso lokuthi ezinye izinguquko kusukela egatsheni master, engizame ngayo ukuhlanganisa ikhodi yami, nazo zathathwa i-cherry ekukhululweni kwephuzu (ngakho-ke egatsheni lami) futhi cishe bekungeke kube lula.

Ngokuvamile, nginqume ukuthi kusenengqondo ukulahla i-prototype, ngiyihlukanise ukuze ibe izingxenye futhi yakhe inguqulo entsha kusukela ekuqaleni ngokusekelwe kokuthile okusha futhi manje kusuka master.

Iphutha lesibili: Indlela ye-TLP

Empeleni, lokhu akulona iphutha, ngokuvamile, kuyisici sokudala iphrojekthi ngaphansi kwezimo zokungaqondi ngokuphelele kokubili "ukuhamba kuphi futhi kanjani?" futhi ngokuvamile "ingabe sizofika lapho?" Kulezi zimo izinhlelo ezixakile kwakuyinketho efanelekile, kodwa, ngokwemvelo, ngangingafuni ukuyiphinda ngokungadingekile. Ngalesi sikhathi ngangifuna ukukwenza ngokuhlakanipha: izibophezelo ze-athomu, izinguquko zekhodi eqaphelayo (hhayi "ukuhlanganisa izinhlamvu ezingahleliwe kuze kube yilapho ihlanganisa (ngezixwayiso)", njengoba uLinus Torvalds esho ngomuntu othile, ngokusho kwe-Wikiquote), njll.

Iphutha lesithathu: ukungena emanzini ngaphandle kokwazi i-ford

Angikakuqedi ngokuphelele lokhu, kodwa manje nginqume ukungalandeli indlela yokumelana nokuncane, futhi ngikwenze “njengomuntu omdala,” okungukuthi, ngibhale i-backend yami ye-TCG kusukela ekuqaleni, ukuze ngingakwenzi. kufanele usho kamuva, "Yebo, lokhu kunjalo, kancane, kodwa angikwazi ukulawula yonke into - ibhalwa kanjalo i-TCI..." Ngaphezu kwalokho, lokhu ekuqaleni kwakubonakala njengesixazululo esisobala, kusukela Ngenza ikhodi kanambambili. Njengoba bethi, “I-Ghent ibutheneу, kodwa hhayi leyo”: ikhodi, yiqiniso, kanambambili, kodwa ukulawula akukwazi ukudluliselwa kuyo kalula - kufanele iphushwe ngokucacile esipheqululini ukuze sihlanganiswe, okuholela entweni ethile evela emhlabeni we-JS, okusadingeka usindiswe ndawana thize. Kodwa-ke, ezakhiweni ezijwayelekile ze-RISC, ngokwazi kwami, isimo esijwayelekile siyisidingo sokusetha kabusha inqolobane yemiyalelo yekhodi evuselelwe kabusha - uma lokhu kungekona esikudingayo, ngakho-ke, kunoma yikuphi, kuseduze. Ngaphezu kwalokho, emzamweni wami wokugcina, ngafunda ukuthi ukulawula akubonakali kudluliselwa phakathi kwebhulokhi yokuhumusha, ngakho-ke asiyidingi ngempela i-bytecode ehunyushwe kunoma iyiphi i-offset, futhi singavele siyikhiqize kusukela kumsebenzi ku-TB. .

Bafika bakhahlela

Nakuba ngiqale ukubhala kabusha ikhodi emuva ngoJulayi, ukukhahlela komlingo kukhuphuke kungabonakali: ngokuvamile izincwadi ezivela ku-GitHub zifika njengezaziso mayelana nezimpendulo Zezinkinga Nezicelo Zokudonsa, kodwa lapha, kungazelelwe khuluma emculweni I-Binaryen njenge-backend ye-qemu kumongo, "Wenze into efana naleyo, mhlawumbe uzosho okuthize." Besikhuluma ngokusebenzisa umtapo wolwazi ohlobene wakwa-Emscripten I-Binaryen ukudala i-WASM JIT. Nokho, ngithe unelayisensi ye-Apache 2.0 lapho, futhi i-QEMU iyonke isatshalaliswa ngaphansi kwe-GPLv2, futhi ayihambelani kakhulu. Kungazelelwe kwavela ukuthi ilayisensi kungaba lungisa ngandlela thize (Angazi: mhlawumbe uyishintshe, mhlawumbe amalayisense amabili, mhlawumbe enye into...). Lokhu-ke kwangijabulisa, ngoba ngaleso sikhathi ngase ngibhekisisa ifomethi kanambambili WebAssembly, futhi ngandlela-thile ngangidabukile futhi ngingaqondakali. Kwakukhona futhi umtapo wolwazi owawuzoshwabadela amabhlogo ayisisekelo ngegrafu yoshintsho, ukhiqize i-bytecode, futhi uyiqhube kumhumushi uqobo, uma kunesidingo.

Kwase kuba nokunye incwadi ohlwini lwama-imeyili e-QEMU, kodwa lokhu kumayelana nombuzo othi, “Ubani oyidingayo noma kunjalo?” Futhi kunjalo kungazelelwe, kwavela ukuthi kwakudingeka. Okungenani, ungakwazi ukuhlanganisa ndawonye amathuba okusebenzisa uma isebenza ngokushesha noma kancane:

  • ukwethula okuthile okufundisayo ngaphandle kokufakwa nhlobo
  • i-virtualization ku-iOS, lapho, ngokusho kwamahemuhemu, okuwukuphela kwesicelo esinelungelo lokukhiqiza ikhodi ngendiza injini ye-JS (ingabe lokhu kuyiqiniso?)
  • ukuboniswa kwe-mini-OS - i-single-floppy, eyakhelwe ngaphakathi, zonke izinhlobo ze-firmware, njll...

Izici Zesikhathi Sokusebenza Sesiphequluli

Njengoba bese ngishilo, i-QEMU iboshelwe ku-multithreading, kodwa isiphequluli asinayo. Hhayi-ke, okungukuthi, cha... Ekuqaleni ibingekho nhlobo, kwase kuvela ama-WebWorkers - ngokwazi kwami, lokhu kuwukufunda okuningi okusekelwe ekudlulisweni komlayezo. ngaphandle kokuguquguquka okwabiwe. Ngokwemvelo, lokhu kudala izinkinga ezibalulekile lapho kufakwa ikhodi ekhona ngokusekelwe kumodeli yenkumbulo eyabiwe. Khona-ke, ngaphansi kwengcindezi yomphakathi, nayo yasetshenziswa ngaphansi kwegama SharedArrayBuffers. Yethulwa kancane kancane, bagubha ukwethulwa kwayo ezipheqululini ezahlukene, base begubha uNyaka Omusha, bese kuthi i-Meltdown... Ngemva kwalokho bafinyelela esiphethweni sokuthi isilinganiso sesikhathi simahhadla noma simahhadla, kodwa ngosizo lwenkumbulo eyabiwe kanye ne- intambo ikhulisa ikhawunta, kuyafana izosebenza kahle impela. Ngakho-ke sikhubaze ukufunda okuningi ngenkumbulo eyabiwe. Kubonakala sengathi kamuva bayibuyisela emuva, kodwa, njengoba kwacaca kusukela ekuhlolweni kokuqala, kukhona ukuphila ngaphandle kwayo, futhi uma kunjalo, sizozama ukukwenza ngaphandle kokuthembela ekufundweni okuningi.

Isici sesibili ukungenzeki kokukhohlisa kwezinga eliphansi ngesitaki: awukwazi ukumane uthathe, ulondoloze umongo wamanje bese ushintshela kwesisha ngesitaki esisha. Isitaki sezingcingo siphethwe umshini obonakalayo we-JS. Kubonakala sengathi, yini inkinga, njengoba sisanquma ukuphatha ukugeleza kwangaphambili ngesandla? Iqiniso liwukuthi i-block I/O ku-QEMU isetshenziswa ngama-coroutines, futhi kulapho ukukhwabanisa kwezitaki ezisezingeni eliphansi kuzoba usizo khona. Ngenhlanhla, i-Emscipten isivele iqukethe indlela yokusebenza kwe-asynchronous, ngisho nambili: Asyncify и I-Enterpreter. Esokuqala sisebenza nge-bloat ebalulekile kukhodi ye-JavaScript ekhiqiziwe futhi ayisasekelwa. Eyesibili "indlela elungile" yamanje futhi isebenza ngokukhiqiza i-bytecode kumhumushi womdabu. Isebenza, yebo, kancane, kodwa ayivimbi ikhodi. Yiqiniso, ukusekelwa kwama-coroutines ale ndlela kwakufanele kunikelwe ngokuzimela (besekuvele kunama-coroutines abhalelwe i-Asyncify futhi kwaba khona ukuqaliswa kwe-API efanayo ye-Emterpreter, obudinga nje ukuyixhuma).

Okwamanje, angikakakwazi ukuhlukanisa ikhodi ibe yinye ehlanganiswe ku-WASM futhi ihunyushwe kusetshenziswa i-Emterpreter, ngakho-ke amadivaysi avinjiwe awasebenzi okwamanje (bheka ochungechungeni olulandelayo, njengoba besho ...). Okusho ukuthi, ekugcineni kufanele uthole okuthile okufana nalokhu okunezingqimba ezihlekisayo:

  • ibhulokhi ehumushiwe I/O. Hhayi-ke, ubuyilindele ngempela i-NVMe efanisiwe ngokusebenza komdabu? 🙂
  • ihlanganiswe ngokwezibalo ikhodi eyinhloko ye-QEMU (umhumushi, amanye amadivaysi alingisiwe, njll.)
  • kuhlanganiswe ngokuguqukayo ikhodi yesivakashi ibe yi-WASM

Izici zemithombo ye-QEMU

Njengoba cishe usuqagele kakade, ikhodi yokulingisa izakhiwo zesivakashi kanye nekhodi yokukhiqiza imiyalelo yomshini wokusingatha kuhlukaniswa ku-QEMU. Eqinisweni, kuyinkimbinkimbi nakakhulu:

  • kukhona izakhiwo zezivakashi
  • kuyinto ama-accelerator, okungukuthi, i-KVM ye-virtualization yezingxenyekazi zekhompuyutha ku-Linux (yezinhlelo zezivakashi nezisingathi ezisebenzisanayo), i-TCG yokukhiqiza ikhodi ye-JIT noma kuphi. Ukuqala nge-QEMU 2.9, ukusekelwa kwezinga le-HAXM lokwenziwa kwehadiwe ku-Windows kwavela (imininingwane)
  • uma i-TCG isetshenziswa hhayi i-hardware virtualization, ngakho-ke inokusekelwa kokukhiqizwa kwekhodi ehlukile yesakhiwo ngasinye somsingathi, kanye nomhumushi wendawo yonke.
  • ... futhi kukho konke lokhu - okuzungezile okulingiswayo, ukusebenzelana komsebenzisi, ukufuduka, ukudlala kabusha irekhodi, njll.

Phela, bewazi: I-QEMU ayikwazi ukulingisa hhayi ikhompyutha yonke kuphela, kodwa futhi nephrosesa yenqubo ehlukile yomsebenzisi ku-kernel host, esetshenziswa, isibonelo, yi-AFL fuzzer yezinsimbi kanambambili. Mhlawumbe othile angathanda ukufaka le ndlela yokusebenza ye-QEMU iye ku-JS? 😉

Njengesoftware yamahhala ehlala isikhathi eside, i-QEMU yakhiwe ngocingo configure и make. Ake sithi unquma ukwengeza okuthile: i-backend ye-TCG, ukuqaliswa kwentambo, enye into. Ungajahi ukujabula/ukwethuka (dwebela ngokufanelekile) uma unethemba lokuxhumana ne-Autoconf - empeleni, configure I-QEMU's ngokusobala izibhale yona futhi ayikhiqizi lutho.

I-WebAssembly

Ngakho-ke yini le nto ebizwa ngeWebAssembly (aka WASM)? Lokhu kungena esikhundleni se-Asm.js, akusazenzisi ikhodi ye-JavaScript evumelekile. Ngokuphambene nalokho, iyinambambili futhi yenziwe kahle, futhi ngisho nokubhala inombolo ephelele kuyo akulula kakhulu: ukubumbana, kugcinwa ngefomethi. I-LEB128.

Kungenzeka ukuthi uzwile nge-algorithm yokuhlehla ye-Asm.js - lokhu ukubuyiselwa kwemiyalelo yokulawula ukugeleza “yezinga eliphezulu” (okungukuthi, uma-ke-ke, amaluphu, njll.), okuklanyelwe yona izinjini ze-JS, kusukela i-LLVM IR yezinga eliphansi, eduze nekhodi yomshini eyenziwe iphrosesa. Ngokwemvelo, ukumelwa okuphakathi kwe-QEMU kuseduze kwesibili. Kungase kubonakale sengathi nakhu, i-bytecode, ukuphela kokuhlushwa... Bese kuba khona amabhulokhi, uma-ke-okunye namalophu!..

Futhi lesi esinye isizathu esenza ukuthi i-Binaryen isebenziseke: ingakwazi ukwamukela ngokwemvelo amabhulokhi asezingeni eliphezulu eduze nalokho okungagcinwa ku-WASM. Kodwa futhi ingakhiqiza ikhodi kusuka kugrafu yamabhulokhi ayisisekelo kanye noshintsho phakathi kwabo. Yebo, sengishilo ukuthi ifihla ifomethi yokugcina i-WebAssembly ngemuva kwe-C/C++ API elula.

I-TCG (i-Tiny Code Generator)

I-TCG kwasekuqaleni i-backend ye-compiler C. Khona-ke, ngokusobala, ayikwazanga ukumelana nokuncintisana ne-GCC, kodwa ekugcineni ithole indawo yayo ku-QEMU njengendlela yokukhiqiza ikhodi yesikhulumi sokusingatha. Kukhona ne-backend ye-TCG ekhiqiza i-bytecode ethile engabonakali, eyenziwa ngokushesha ngumhumushi, kodwa nginqume ukugwema ukuyisebenzisa ngalesi sikhathi. Kodwa-ke, iqiniso lokuthi ku-QEMU selivele lingenzeka ukunika amandla ukushintshela ku-TB ekhiqizwayo ngomsebenzi tcg_qemu_tb_exec, kwabonakala kuwusizo kakhulu kimi.

Ukwengeza i-backend entsha ye-TCG ku-QEMU, udinga ukwakha uhla lwemibhalo olungaphansi tcg/<имя архитектуры> (esimweni esinjalo, tcg/binaryen), futhi iqukethe amafayela amabili: tcg-target.h и tcg-target.inc.c и bhalisa kumayelana configure. Ungabeka amanye amafayela lapho, kodwa, njengoba ungaqagela emagameni alaba ababili, bobabili bazofakwa ndawana thize: elilodwa njengefayela lesihloko elivamile (lifakiwe tcg/tcg.h, futhi leyo isivele ikulamanye amafayela ezinhlwini zemibhalo tcg, accel futhi hhayi kuphela), enye - kuphela njengekhodi yamazwibela tcg/tcg.c, kodwa inokufinyelela emisebenzini yayo emile.

Ukunquma ukuthi ngizochitha isikhathi esiningi ekuphenyweni okuningiliziwe kokuthi kusebenza kanjani, ngimane ngikopishe "amathambo" alawa mafayela amabili kolunye ukuqaliswa kwe-backend, ngibonisa lokhu ngokwethembeka kunhlokweni yelayisensi.

Файл tcg-target.h iqukethe ikakhulukazi izilungiselelo efomini #define-s:

  • mangaki amarejista kanye nobubanzi obunjani ekwakhiweni okuhlosiwe (sinabaningi njengoba sifuna, abaningi ngendlela esiyifunayo - umbuzo umayelana nokuthi yini ezokhiqizwa isiphequluli sibe yikhodi esebenza kahle kakhulu ekwakhiweni "okuhloswe ngokuphelele" ...)
  • ukuqondanisa kwemiyalelo yokusingatha: ku-x86, ngisho naku-TCI, imiyalelo ayihambisani nhlobo, kodwa ngizofaka isilondolozi sekhodi hhayi imiyalelo nhlobo, kodwa izikhombisi zezakhiwo zelabhulali ye-Binaryen, ngakho ngizothi: 4 amabhayithi
  • yimiphi imiyalelo yokuzikhethela i-backend engakhiqiza - sifaka yonke into esiyithola ku-Binaryen, vumela isisheshisi sihlukanise okunye kube lula ngokwaso
  • Ingakanani isayizi elinganiselwe yenqolobane ye-TLB ecelwe ingemuva. Iqiniso liwukuthi kwa-QEMU yonke into ibucayi: nakuba kunemisebenzi yomsizi eyenza umthwalo/isitolo kucatshangelwa i-MMU yesivakashi (besiyoba kuphi ngaphandle kwayo manje?), balondoloza inqolobane yabo yokuhumusha ngendlela yesakhiwo, i- ukucubungula okulula ukushumeka ngokuqondile kumabhulokhi okusakaza. Umbuzo uwukuthi, iyiphi i-offset kulesi sakhiwo ecutshungulwa kahle kakhulu ukulandelana okuncane nokusheshayo kwemiyalelo?
  • lapha ungakwazi ukulungisa inhloso yerejista eyodwa noma amabili abekelwe, unike amandla ukushayela i-TB ngomsebenzi futhi uchaze ngokuzithandela ezimbalwa ezimbalwa inline-imisebenzi efana flush_icache_range (kodwa lokhu akulona icala lethu)

Файл tcg-target.inc.c, yebo, imvamisa inkulu kakhulu ngosayizi futhi iqukethe imisebenzi eminingana eyisibopho:

  • ukuqalisa, okuhlanganisa nemikhawulo lapho imiyalelo ingasebenza khona ukuthi yiziphi izinhlelo zokusebenza. Ngikopishwe ngokusobala kwenye indawo engemuva
  • umsebenzi othatha umyalelo owodwa we-bytecode wangaphakathi
  • Ungaphinda ubeke imisebenzi eyisiza lapha, futhi ungasebenzisa imisebenzi emile kusuka tcg/tcg.c

Mina, ngizikhethele leli qhinga elilandelayo: emazwini okuqala ebhulokhi yokuhumusha elandelayo, ngibhale phansi izinkomba ezine: uphawu lokuqala (inani elithile endaweni eseduze. 0xFFFFFFFF, okunqume isimo samanje se-TB), umongo, imojuli ekhiqiziwe, nenombolo yomlingo yokulungisa iphutha. Ekuqaleni kwafakwa uphawu 0xFFFFFFFF - nkuphi n - inombolo encane ephozithivu, futhi isikhathi ngasinye lapho ibulawa ngotolika yayikhula ngo-1. Lapho ifinyelela 0xFFFFFFFE, ukuhlanganiswa kwenzeka, imojula yalondolozwa kuthebula lomsebenzi, yangeniswa “kuyisiqalisi” esincane, lapho ukubulawa kwaphuma khona. tcg_qemu_tb_exec, futhi imojuli ikhishiwe kumemori ye-QEMU.

Ukuze uchaze ezakudala, "I-Crutch, kungakanani okuhlanganiswe kulo msindo wenhliziyo ye-proger ...". Nokho, inkumbulo yayivuza ndawana thize. Ngaphezu kwalokho, bekuyinkumbulo ephethwe yi-QEMU! Nganginekhodi ukuthi, lapho ngibhala umyalo olandelayo (kahle, okungukuthi, i-pointer), isuse lowo isixhumanisi sakhe sasikule ndawo ngaphambili, kodwa lokhu akuzange kusize. Empeleni, esimweni esilula, i-QEMU yabela inkumbulo ekuqaleni bese ibhala ikhodi ekhiqizwe lapho. Lapho isigcinalwazi siphela, ikhodi ikhishelwa ngaphandle bese elandelayo iqala ukubhalwa endaweni yayo.

Ngemva kokufunda ikhodi, ngabona ukuthi iqhinga elinenombolo yomlingo lingivumele ukuthi ngingahluleki ekucekeleni phansi inqwaba ngokukhulula okuthile okungalungile kusigcinalwazi esingaqaliswanga ekudluleni kokuqala. Kodwa ubani ophinda abhale isilondolozi ukuze sidlule umsebenzi wami kamuva? Njengoba abathuthukisi be-Emscripten beluleka, lapho ngingena enkingeni, ngithumele ikhodi ewumphumela emuva kuhlelo lokusebenza lwendabuko, setha i-Mozilla Record-Replay kuyo ... Ngokuvamile, ekugcineni ngabona into elula: kubhulogi ngalinye, a struct TranslationBlock nencazelo yayo. Qagela ukuthi kuphi... Kunjalo, ngaphambi nje kwebhulokhi khona kubhafa. Ngokubona lokhu, nganquma ukuyeka ukusebenzisa izinduku (okungenani ezinye), futhi ngavele ngalahla inombolo yomlingo, ngase ngidlulisela amagama asele ku. struct TranslationBlock, ukudala uhlu oluxhumene olulodwa olungadluliswa ngokushesha lapho inqolobane yokuhumusha isethwe kabusha, futhi ikhulule inkumbulo.

Ezinye izinduku zisekhona: isibonelo, izikhombi ezimakiwe kubhafa yekhodi - ezinye zazo zimane nje BinaryenExpressionRef, okungukuthi, babheka izinkulumo ezidinga ukufakwa ngendlela eqondile kubhulokhi eyisisekelo ekhiqiziwe, ingxenye yisimo soshintsho phakathi kwama-BB, ingxenye lapho kufanele uhambe khona. Hhayi-ke, kunamabhulokhi asevele alungisiwe e-Relooper adinga ukuxhunywa ngokuya ngemibandela. Ukuze uzihlukanise, kusetshenziselwa ukucabangela ukuthi zonke ziqondaniswe okungenani ngamabhayithi amane, ukuze ukwazi ukusebenzisa ngokuphephile izingcezu ezimbili ezibalulekile zelebula, udinga nje ukukhumbula ukuyisusa uma kunesidingo. Ngendlela, amalebula anjalo asevele esetshenziswa ku-QEMU ukukhombisa isizathu sokuphuma ku-loop ye-TCG.

Ukusebenzisa i-Binaryen

Amamojula kuWebAssembly aqukethe imisebenzi, ngayinye equkethe umzimba, okuyinkulumo. Izisho ziyimisebenzi engajwayelekile futhi kanambambili, amabhulokhi ahlanganisa izinhlu zezinye izinkulumo, ukugeleza kokulawula, njll. Njengoba ngike ngasho, ukugeleza kokulawula lapha kuhlelwe ngokunembile njengamagatsha asezingeni eliphezulu, izihibe, izingcingo zokusebenza, njll. Ukungqubuzana kwemisebenzi akudluliswanga kusitaki, kodwa ngokusobala, njengaku-JS. Kukhona neziguquguqukayo zomhlaba wonke, kodwa angikazisebenzisi, ngakho-ke ngeke ngikutshele ngazo.

Imisebenzi ibuye ibe nokuguquguquka kwendawo, okunenombolo ukusuka ku-zero, yohlobo: int32 / int64 / iflothi / kabili. Kulokhu, okuguquguqukayo kokuqala kwendawo okungu-n ama-agumenti adluliselwe kumsebenzi. Sicela uqaphele ukuthi nakuba yonke into lapha ingelona izinga eliphansi ngokuphelele ngokuya ngokugeleza kokulawula, izinombolo eziphelele azikaphathi isibaluli “esisayiniwe/ esingasayiniwe”: indlela inombolo eziphatha ngayo incike kukhodi yokusebenza.

Ngokuvamile, i-Binaryen inikeza I-C-API elula: udala imojuli, kuye dala izisho - ezingajwayelekile, kanambambili, amabhlogo asuka kwezinye izinkulumo, ukugeleza kokulawula, njll. Bese udala umsebenzi onenkulumo njengomzimba wayo. Uma, njengami, unegrafu yenguquko yezinga eliphansi, ingxenye ye-relooper izokusiza. Ngokwazi kwami, kungenzeka ukusebenzisa ukulawulwa kwezinga eliphezulu kokugeleza kokubulawa kubhlokhi, inqobo nje uma kungahambi ngaphezu kwemingcele yebhulokhi - okungukuthi, kungenzeka ukwenza indlela yangaphakathi esheshayo / ihamba kancane. indlela yokuhlanganisa ngaphakathi kwekhodi yokucubungula inqolobane ye-TLB eyakhelwe ngaphakathi, kodwa hhayi ukuphazamisa ukugeleza kokulawula "kwangaphandle". Uma ukhulula i-relooper, amabhulokhi ayo ayakhululwa, uma ukhulula imojuli, izinkulumo, imisebenzi, njll. eyabelwe yona iyanyamalala. inkundla.

Kodwa-ke, uma ufuna ukuhumusha ikhodi ngokundiza ngaphandle kokudala okungadingekile kanye nokususwa kwesimo sotolika, kungase kube nengqondo ukubeka lo mqondo efayeleni le-C++, futhi ukusuka lapho uphathe ngokuqondile yonke i-C++ API yomtapo wolwazi, weqe ngomumo- ama-wrappers enziwe.

Ngakho ukukhiqiza ikhodi oyidingayo

// настроить глобальные параметры (можно поменять потом)
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);

... uma kukhona engikukhohliwe, ngiyaxolisa, lokhu nje ukumela isikali, futhi imininingwane ikumadokhumenti.

Futhi manje i-crack-fex-pex iyaqala, into enjengale:

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 thize uxhume imihlaba ye-QEMU ne-JS futhi ngesikhathi esifanayo ufinyelele imisebenzi ehlanganisiwe ngokushesha, kwakhiwe uhlu (ithebula lemisebenzi yokungenisa kusiqalisi), futhi imisebenzi ekhiqiziwe yafakwa lapho. Ukuze ubale ngokushesha inkomba, inkomba yebhulokhi yokuhumusha igama elinguziro yaqale yasetshenziswa njengayo, kodwa inkomba eyabalwa kusetshenziswa le fomula yaqala ukumane ingene ensimini struct TranslationBlock.

Ngendlela, idemo (okwamanje unelayisensi elufifi) isebenza kahle kuphela kuFirefox. Abathuthukisi be-Chrome babe ngandlela-thile akukalungi eqinisweni lokuthi othile angafuna ukudala izimo ezingaphezu kwenkulungwane zamamojula we-WebAssembly, ngakho-ke bamane banikeze i-gigabyte yesikhala sekheli esibonakalayo ngayinye...

Yilokho kuphela okwamanje. Mhlawumbe kuzoba nesinye isihloko uma kukhona onentshisekelo. Okungukuthi, kukhona okusele okungenani kuphela yenza amadivayisi we-block asebenze. Kungase futhi kube nengqondo ukwenza ukuhlanganiswa kwamamojula we-WebAssembly asynchronous, njengoba kuwumkhuba ezweni le-JS, njengoba kusenotolika ongenza konke lokhu kuze kube yilapho imojula yomdabu isilungile.

Ekugcineni imfumbe: uhlanganise kanambambili esakhiweni se-32-bit, kodwa ikhodi, ngokusebenza kwenkumbulo, ikhuphuka isuka ku-Binaryen, ndawana thize esitaki, noma kwenye indawo ku-2 GB ophezulu wesikhala sekheli esingu-32-bit. Inkinga ukuthi ngokombono kaBinaryen lokhu kufinyelela ikheli elikhulu kakhulu lomphumela. Uzungeza kanjani lokhu?

Ngendlela admin

Angigcinanga ngokuhlola lokhu, kodwa umcabango wami wokuqala wawuthi “Kuthiwani uma ngifaka i-32-bit Linux?” Khona-ke ingxenye engenhla yesikhala sekheli izothathwa i-kernel. Umbuzo kuphela ukuthi kuzokwenziwa malini: 1 noma 2 Gb.

Ngendlela yomhleli (inketho yabasebenzi)

Masivuthele ibhamuza phezulu kwesikhala sekheli. Mina ngokwami ​​angiqondi ukuthi kungani kusebenza - lapho vele kufanele kube nesitaki. Kodwa "singabasebenzi: konke kuyasisebenzela, kodwa akekho owaziyo ukuthi kungani..."

// 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));
}

... kuyiqiniso ukuthi ayihambisani noValgrind, kodwa, ngenhlanhla, uValgrind uqobo uphusha wonke umuntu lapho :)

Mhlawumbe othile uzonikeza incazelo engcono yokuthi le khodi yami isebenza kanjani...

Source: www.habr.com

Engeza amazwana