Qemu.js nerutsigiro rweJIT: unogona kudzosera mince kumashure

Makore mashoma apfuura Fabrice Bellard yakanyorwa na jslinux iPC emulator yakanyorwa muJavaScript. Pashure paizvozvo pakanga pane zvimwe Virtual x86. Asi vese, sekuziva kwangu, vaive vaturikiri, nepo Qemu, yakanyorwa kare kare naFabrice Bellard mumwe chete, uye, pamwe, chero anozviremekedza emulator yemazuva ano, anoshandisa JIT kubatanidza kodhi yevaenzi kuita kodhi system system. Kwandiri zvaiita sekuti yaive nguva yekuita basa rakapesana nerezvinogadziriswa nemabhurawuza: JIT kuunganidzwa kwemuchina kodhi muJavaScript, iyo yaiita seine musoro kuchiteshi Qemu. Zvingaite senge, nei Qemu, kune akareruka uye mushandisi-ane hushamwari emulators - yakafanana VirtualBox, semuenzaniso - yakaiswa uye inoshanda. Asi Qemu ine akati wandei anonakidza maficha

  • open source
  • kugona kushanda pasina mutyairi wekernel
  • kugona kushanda mumuturikiri
  • tsigiro yenhamba huru yevose vari vaviri vaenzi uye vaenzi zvivakwa

Nezve chinhu chechitatu, ini ndinogona kutsanangura kuti, muTCI mode, haisi iyo mirairo yemuchina wevaenzi ivo pachavo inodudzirwa, asi iyo bytecode yakawanikwa kubva kwavari, asi izvi hazvichinje essence - kuitira kuvaka uye kumhanya. Qemu pane chivakwa chitsva, kana uine rombo rakanaka, A C compiler yakakwana - kunyora kodhi jenareta inogona kumisikidzwa.

Uye ikozvino, mushure memakore maviri ekutandara neiyo Qemu sosi kodhi munguva yangu yemahara, prototype inoshanda yakaonekwa, umo iwe unogona kutomhanya, semuenzaniso, Kolibri OS.

Chii chinonzi Emscripten

Mazuva ano, vagadziri vakawanda vakaonekwa, kuguma kweiyo JavaScript. Zvimwe, seType Script, zvakagadzirirwa kuti ive nzira yakanakisisa yekunyora pawebhu. Panguva imwecheteyo, Emscripten inzira yekutora iripo C kana C ++ kodhi uye kuiunganidza mubrowser-inoverengeka fomu. On peji ino Takaunganidza zviteshi zvakawanda zvezvirongwa zvinozivikanwa: panoSemuenzaniso, unogona kutarisa PyPy - nenzira, ivo vanoti vatova neJIT. Muchokwadi, haisi yega yega chirongwa chinogona kungounganidzwa uye kumhanya mubrowser - kune nhamba features, iyo yaunofanirwa kushivirira nayo, zvisinei, sekunyorwa kuri papeji imwe cheteyo kunoti "Emscripten inogona kushandiswa kuunganidza chero chero takurika C/C++ kodhi yeJavaScript". Kureva kuti, kune akati wandei maitiro asina kutsanangurwa maitiro zvinoenderana neyakajairwa, asi anowanzo shanda pa x86 - semuenzaniso, unigned access to variables, iyo inowanzorambidzwa pane mamwe maarchitecture. , Qemu is a cross-platform program uye, ndaida kutenda, uye haisati iine zvakawanda zvisina kutsanangurwa maitiro - tora uye uunganidze, wozofunga zvishoma neJIT - uye wapedza! Asi handizvo izvo nyaya...

First try

Kazhinji kutaura, ini handisi munhu wekutanga kuuya nepfungwa yekuendesa Qemu kuJavaScript. Paive nemubvunzo wakabvunzwa paReactOS forum kana izvi zvaibvira uchishandisa Emscripten. Kunyangwe kare, pakanga paine runyerekupe rwekuti Fabrice Bellard akaita izvi pachake, asi isu taitaura nezve jslinux, iyo, sekuziva kwangu, ingori kuyedza kuita nemaoko kuita zvakakwana muJS, uye yakanyorwa kubva pakutanga. Gare gare, Virtual x86 yakanyorwa - zvinyorwa zvisingazivikanwi zvakatumirwa kwairi, uye, sezvakataurwa, "chokwadi" chikuru chekutevedzera chakaita kuti zvikwanise kushandisa SeaBIOS se firmware. Pamusoro pezvo, pakave nekuedza kumwe chete kutakura Qemu ndichishandisa Emscripten - ndakaedza kuita izvi socketpair, asi budiriro, semanzwisisiro andinoita, yakanga yaoma.

Saka, zvinoita sekunge, heano masosi, heino Emscripten - tora uye uunganidze. Asi kunewo maraibhurari ayo Qemu anotsamira paari, uye maraibhurari anotsamira paari maraibhurari iwayo, nezvimwewo, uye rimwe rawo ndere libffi, iyo glib inoenderana. Paive nerunyerekupe paInternet kuti pakanga paine imwe muunganidzwa hombe wezviteshi zvemaraibhurari eEmscripten, asi zvakange zvakaoma kutenda: chekutanga, yaive isina kuitirwa kuve mugadziri mutsva, chechipiri, yaive yakaderera-level a. raibhurari yekungotora, uye kuunganidza kuJS. Uye haizi nyaya yekuiswa kwegungano - pamwe, kana ukamonyorora, kune mamwe magungano ekufona unogona kugadzira nharo dzinodiwa pane stack uye wodaidza basa racho pasina ivo. Asi Emscripten chinhu chinonyengera: kuitira kuti kodhi yakagadzirwa itaridzike kune browser JS injini optimizer, mamwe manomano anoshandiswa. Kunyanya, iyo inonzi relooping - kodhi jenareta inoshandisa yakagashirwa LLVM IR ine mamwe abstract shanduko mirairo inoedza kudzoreredza zvinonzwisisika ifs, zvishwe, nezvimwe. Zvakanaka, nharo dzinopfuudzwa sei kune basa? Nomuzvarirwo, senharo kumabasa eJS, kureva, kana zvichibvira, kwete kuburikidza ne stack.

Pakutanga pakanga paine pfungwa yekungonyora kutsiva libffi neJS uye kumhanya bvunzo dzakajairwa, asi pakupedzisira ndakavhiringika pamusoro pekugadzira mafaira emusoro wangu kuti vashande nekodhi iripo - chii chandingaite, sezvavanotaura, "Mashandiro acho akaoma here "Tiri mapenzi here?" Ini ndaifanira kutakura libffi kune imwe dhizaini, sekutaura - nerombo rakanaka, Emscripten ine ese macros emukati meungano (muJavascript, hongu - zvakanaka, chero dhizaini, saka muunganidzi), uye kugona kumhanya kodhi inogadzirwa panhunzi. Kazhinji, mushure mekutamba nepuratifomu-inotsamira libffi zvimedu kwenguva yakati, ndakawana imwe inosanganiswa kodhi ndokumhanya nayo pabvunzo yekutanga yandakawana. Zvakandishamisa kuti muedzo wacho wakabudirira. Ndakakatyamadzwa nehungwaru hwangu - hapana kuseka, chakashanda kubva pakuvhurwa kwekutanga - ini, ndichiri kusatenda maziso angu, ndakaenda kunotarisa kodhi yakabuda zvakare, kuti ndiongorore pekuchera kunotevera. Apa ndakaenda kunzungu kechipiri - chinhu chega chakaitwa nebasa rangu ffi_call - izvi zvakashuma kufona kwakabudirira. Pakanga pasina call pachayo. Saka ndakatumira chikumbiro changu chekutanga chekudhonza, icho chakagadzirisa chikanganiso muyedzo chakajeka kune chero mudzidzi weOlympiad - nhamba chaidzo hadzifanirwe kuenzaniswa se a == b uye kunyange sei a - b < EPS - iwe unofanirwawo kuyeuka module, kana zvisina kudaro 0 ichave yakaenzana zvakanyanya ne 1/3 ... Kazhinji, ndakauya neimwe chiteshi che libffi, iyo inopfuura bvunzo dzakareruka, uye iyo glib iri yakaunganidzwa - ndakafunga kuti zvingave zvakakosha, ini ndichawedzera gare gare. Ndichitarisa mberi, ndichataura kuti, sezvazvakazoitika, mugadziri haana kunyange kuisa libffi basa mukodhi yekupedzisira.

Asi, sezvandambotaura, pane zvimwe zvisingakwanisi, uye pakati pekushandiswa kwemahara kwemaitiro akasiyana-siyana asina kutsanangurwa, chimwe chinhu chisingafadzi chakavanzwa - JavaScript nedhizaini haitsigire kuwanda kwekuverenga nekugovana ndangariro. Mumusimboti, izvi zvinogona kazhinji kunzi izano rakanaka, asi kwete rekutumira kodhi ine dhizaini yakasungirirwa kune C tambo. Kazhinji kutaura, Firefox iri kuyedza kutsigira vashandi vakagovaniswa, uye Emscripten ine pthread yekuitisa kwavari, asi ini handina kuda kutsamira pazviri. Ini ndaifanira kudzura zvishoma nezvishoma kuverengera kubva kuQemu kodhi - ndiko kuti, kutsvaga kuti tambo dziri kupi, kufambisa muviri wechiuno ichimhanya mushinda iyi kuita rimwe basa rakasiyana, uye kudaidza mabasa akadaro rimwe nerimwe kubva kune chikuru loop.

Kuedza kwechipiri

Pane imwe nguva, zvakava pachena kuti dambudziko rakanga richiripo, uye kuti kurovera nemadondoro zvisina tsarukano kutenderedza kodhi kwaisazotungamira kune chero chakanaka. Mhedziso: isu tinoda neimwe nzira kuronga maitiro ekuwedzera madondoro. Naizvozvo, vhezheni 2.4.1, iyo yaive nyowani panguva iyoyo, yakatorwa (kwete 2.5.0, nekuti, hauzive, pachava netsikidzi mushanduro itsva iyo isati yabatwa, uye ndine zvakakwana zvangu. bugs), uye chinhu chekutanga chandakaita ndechekunyora zvakare zvakachengeteka thread-posix.c. Zvakanaka, ndiko kuti, zvakachengeteka: kana mumwe munhu akaedza kuita oparesheni inotungamira kuvharira, basa racho rakabva radaidzwa abort() - hongu, izvi hazvina kugadzirisa matambudziko ese kamwechete, asi zvirinani zvaive neimwe nzira inonakidza pane kugamuchira chinyararire data risingaenderane.

Kazhinji, Emscripten sarudzo dzinobatsira kwazvo pakutakura kodhi kuJS -s ASSERTIONS=1 -s SAFE_HEAP=1 - vanobata mamwe marudzi ehunhu husina kutsanangurwa, sekufona kukero isina kurongeka (iyo isingaenderane nekodhi yeakataipa arrays senge. HEAP32[addr >> 2] = 1) kana kudaidza chiitiko nenhamba isiriyo yenharo.

Nenzira, kukanganisa kwekugadzirisa inyaya yakasiyana. Sezvandambotaura, Qemu ine "yakaora" yekududzira kumashure kwekodhi kodhi TCI (mudiki kodhi muturikiri), uye kuvaka nekumhanyisa Qemu pane imwe architecture, kana uine rombo rakanaka, C compiler yakakwana. "kana waita rombo rakanaka". Ndakanga ndisina rombo rakanaka, uye zvakazoitika kuti TCI inoshandisa isina kurongeka yekuwana kana ichidhirowa bytecode yayo. Ndokunge, pamarudzi ese eArM uye mamwe madhizaini ane mukana wakaenzana, Qemu inounganidza nekuti vane yakajairwa TCG backend inogadzira kodhi yemuno, asi kana TCI ichashanda pavari mumwe mubvunzo. Nekudaro, sezvazvakazoitika, zvinyorwa zveTCI zvakaratidza chimwe chinhu chakafanana. Nekuda kweizvozvo, basa rinodaidzira rekuverenga risingaenzaniswi rakawedzerwa kune kodhi, iyo yakawanikwa mune imwe chikamu cheQemu.

Kuparadza murwi

Nekuda kweizvozvo, kusarongeka kwekuwana kuTCI kwakagadziriswa, chiuno chikuru chakagadzirwa icho chakazonzi processor, RCU uye zvimwe zvinhu zvidiki. Uye saka ndinovhura Qemu nesarudzo -d exec,in_asm,out_asm, zvinoreva kuti iwe unofanirwa kutaura kuti ndeapi mabhuraki ekodhi ari kuurayiwa, uye zvakare panguva yekutepfenyura kuti unyore kuti kodhi yevaenzi yaive yei, kodhi yevaenzi yakave yei (munyaya iyi, bytecode). Inotanga, inoita mabhuroki akati wandei, inonyora meseji yedebugging yandakasiya iyo RCU ichatanga uye ... abort() mukati mebasa free(). By tinkering pamwe basa free() Isu takakwanisa kuona kuti mumusoro wemurwi block, iyo iri mumabheti masere anotangira ndangariro yakagoverwa, panzvimbo yehukuru hwebhuroka kana chimwe chinhu chakafanana, pakanga paine marara.

Kuparadzwa kwemurwi - kwakanaka sei ... Muchiitiko chakadaro, kune mushonga unobatsira - kubva (kana zvichibvira) zvinyorwa zvakafanana, unganidza bhinari yekuzvarwa uye uite pasi peValgrind. Pashure penguva yakati, bhinari yakagadzirira. Ini ndinoivhura nesarudzo dzakafanana - inoparara kunyangwe panguva yekutanga, isati yasvika pakuurayiwa. Hazvinakidze, hongu - sezviri pachena, masosi anga asina kunyatsofanana, izvo hazvishamise, nekuti gadziridza akaongorora sarudzo dzakasiyana, asi ini ndine Valgrind - kutanga ndichagadzirisa iyi bug, uyezve, kana ndine rombo rakanaka. , yepakutanga ichaonekwa. Ndiri kumhanya chinhu chimwe chete pasi peValgrind ... Y-y-y, y-y-y, uh-uh, yakatanga, yakapfuura nekutanga kazhinji uye yakaenderera mberi yakapfuura bug yepakutanga pasina nyevero imwe chete pamusoro pekusavapo kwekuyeuka kwekuyeuka, kwete kutaura nezvekuwa. Hupenyu, sezvavanotaura, hauna kundigadzirira izvi - chirongwa chekuparara chinomira kuparara kana chakatangwa pasi peWalgrind. Chaive chakavanzika. Mafungiro angu ndeekuti kamwe padhuze nerairo yazvino mushure mekuparara panguva yekutanga, gdb yakaratidza basa. memset-a neinongedzo inoshanda uchishandisa chero mmx, kana xmm marejista, saka pamwe yaive imwe mhando yekukanganisa kwekugadzirisa, kunyangwe zvichiri kunetsa kutenda.

Zvakanaka, Valgrind haaite seanobatsira pano. Uye pano chinhu chinosemesa chakatanga - zvese zvinoita kunge zvinototanga, asi kubondera kwezvikonzero zvisingazivikanwe nekuda kwechiitiko chingave chakaitika mamirioni emirairo yapfuura. Kwenguva refu, zvakanga zvisiri pachena kuti ndosvika sei. Pakupedzisira, ndaifanira kugara pasi ndogadzirisa. Kudhinda izvo musoro wakanyorwa zvakare kwakaratidza kuti yaisaratidzika senhamba, asi kuti imwe mhando yebhinari data. Uye, tarisa uye tarisa, iyi tambo yebhinari yakawanikwa muBIOS faira - ndiko kuti, zvino zvaive zvichikwanisika kutaura nechivimbo chakanaka kuti yaiva buffer inofashukira, uye zviri pachena kuti yakanyorerwa kune iyi buffer. Zvakanaka, zvino chimwe chinhu chakadai - muEmscripten, nerombo rakanaka, hapana randomisation yekero nzvimbo, hapana maburi mairi kana, saka iwe unogona kunyora pane imwe nzvimbo pakati pekodhi kuti ubudise data neinongedza kubva pakatanga kwekupedzisira, tarisa data, tarisa pane pointer, uye, kana isina kuchinja, tora chikafu chekufunga. Chokwadi, zvinotora maminetsi mashoma kubatanidza mushure mekuchinja kupi, asi chii chaungaite? Nekuda kweizvozvo, mutsara chaiwo wakawanikwa wakateedzera BIOS kubva kune yechinguva buffer kuenda kundangariro yevaenzi - uye, zvechokwadi, pakanga pasina nzvimbo yakakwana mubuffer. Kutsvaga kunobva iyo isinganzwisisike buffer kero kwakaguma nebasa qemu_anon_ram_alloc mufaira oslib-posix.c - pfungwa yaivepo yaive iyi: dzimwe nguva zvinogona kubatsira kurongedza kero kune yakakura peji re2 MB muhukuru, pane izvi tichabvunza. mmap kutanga zvishoma, uye ipapo tichazodzorera yakawandisa nerubatsiro munmap. Uye kana kurongeka kwakadaro kusingadiwi, ipapo ticharatidza mhedzisiro panzvimbo ye2 MB getpagesize() - mmap icharamba ichipa kero yakarongwa... Saka muEmscripten mmap kungofona chete malloc, asi zvirokwazvo hazvienderane pane peji. Kazhinji, bug yakandishungurudza kwemwedzi mishoma yakagadziriswa nekuchinja Π΄Π²ΡƒΡ… mitsetse.

Zvimiro zvekufona mabasa

Uye ikozvino processor iri kuverenga chimwe chinhu, Qemu haaparare, asi skrini haibatike, uye processor inokurumidza kupinda muzvishwe, kutonga nezvakabuda. -d exec,in_asm,out_asm. A hypothesis yabuda: timer inokanganisa (kana, kazhinji, zvese zvinokanganisa) hazvisviki. Uye zvechokwadi, kana iwe ukasunungura zvinokanganisa kubva kugungano rekuzvarwa, iro nekuda kwechimwe chikonzero chakashanda, unowana mufananidzo wakafanana. Asi iyi yanga isiri mhinduro zvachose: kuenzanisa kwematanho akapihwa nesarudzo iri pamusoro yakaratidza kuti nzira dzekuuraya dzakatsaukana kare. Pano panofanira kutaurwa kuti kuenzanisa kwezvakarekodhwa uchishandisa launcher emrun debugging yakabuda pamwe nekubuda kwegungano rekuzvarwa haisi zvachose mechanical process. Ini handizive chaizvo kuti chirongwa chiri kushanda mubrowser chinobatana sei emrun, asi mimwe mitsara mune zvakabuda inoshanduka kuve yakarongwa patsva, saka musiyano uri mudiff hausati wave chikonzero chekufungidzira kuti nzira dzakatsaukana. Kazhinji, zvakava pachena kuti maererano nemirayiridzo ljmpl pane shanduko kuenda kumakero akasiyana, uye iyo bytecode inogadzirwa yakasiyana zvakanyanya: imwe ine rairo yekudaidza mubatsiri basa, imwe haina. Mushure mekutsvaga mirairo uye kudzidza kodhi inoshandura iyi mirairo, zvakava pachena kuti, kutanga, pakarepo pamberi payo murejista. cr0 kurekodha kwakaitwa - zvakare kushandisa mubatsiri - iyo yakashandura processor kuti iite yakachengetedzwa modhi, uye chechipiri, iyo js vhezheni haina kumbochinja kune yakachengetedzwa mode. Asi chokwadi ndechekuti chimwe chinhu cheEmscripten kusada kushivirira kodhi sekuita kwemirairo. call muTCI, iyo chero basa rekunongedza rinoguma mumhando long long f(int arg0, .. int arg9) - mabasa anofanirwa kudanwa nenhamba chaiyo yenharo. Kana mutemo uyu ukatyorwa, zvichienderana nemagadzirirwo ekugadzirisa, purogiramu inogona kukanganisa (izvo zvakanaka) kana kudana basa risina kunaka zvachose (izvo zvichave zvinosuruvarisa kugadzirisa). Panewo sarudzo yechitatu - gonesa chizvarwa chezviputi zvinowedzera / kubvisa nharo, asi pakazara aya mapeji anotora nzvimbo yakawanda, pasinei nokuti ini ndinongoda zvishoma kudarika zana. Izvi zvega zvinosuruvarisa, asi pakava nedambudziko rakakura: mukodhi yakagadzirwa yebasa rekuputira, nharo dzakashandurwa nekushandurwa, asi dzimwe nguva basa nemakakatanwa akagadzirwa harina kudanwa - zvakanaka, sezvakaita mu. yangu libffi kuita. Kureva kuti vamwe vabatsiri havana kuurayiwa.

Sezvineiwo, Qemu ine muchina-inoverengwa mazita evabatsiri ari muchimiro chemusoro faira senge

DEF_HELPER_0(lock, void)
DEF_HELPER_0(unlock, void)
DEF_HELPER_3(write_eflags, void, env, tl, i32)

Anoshandiswa zvinosetsa: kutanga, macros anotsanangurwa patsva nenzira inoshamisa DEF_HELPER_n, wobva wabatidza helper.h. Kusvika pamwero wekuti iyo macro inokwidziridzwa kuita yekutanga chimiro uye comma, uyezve array inotsanangurwa, uye panzvimbo yezvinhu - #include <helper.h> Somugumisiro, pakupedzisira ndakava nomukana wokuedza raibhurari kubasa pyparsing, uye script yakanyorwa inoburitsa chaizvo iwo mapeji emabasa chaiwo avanodiwa.

Uye saka, mushure meizvozvo processor yakaita seinoshanda. Zvinoita kunge nekuti skrini haina kumbotangwa, kunyangwe memtest86 + yakakwanisa kumhanya mugungano remunharaunda. Pano zvakakosha kujekesa kuti Qemu block I / O code yakanyorwa mumakoroti. Emscripten ine yayo yekunyepedzera kuita, asi yaitoda kutsigirwa mukodhi yeQemu, uye unogona kugadzirisa processor izvozvi: Qemu inotsigira sarudzo. -kernel, -initrd, -append, iyo yaunogona boot Linux kana, semuenzaniso, memtest86+, pasina kushandisa block zvishandiso zvachose. Asi heino dambudziko: mugungano rekuzvarwa munhu aigona kuona iyo Linux kernel yakabuda kune iyo console nesarudzo -nographic, uye hapana chinobuda kubva kubrowser kuenda kune terminal kubva kwayakavhurwa emrun, haana kuuya. Ndiko kuti, hazvina kujeka: iyo processor haisi kushanda kana iyo graphics yakabuda haisi kushanda. Uye zvakabva zvauya kwandiri kuti ndimirire zvishoma. Zvakazoitika kuti "processor haina kurara, asi kungobwaira zvishoma nezvishoma," uye mushure memaminitsi angangoita mashanu kernel yakakanda boka remeseji pane console ndokuramba yakarembera. Zvakava pachena kuti processor, kazhinji, inoshanda, uye isu tinofanirwa kuchera mukodhi yekushanda neSDL2. Sezvineiwo, handizive mashandisiro aiitwa raibhurari iyi, saka mune dzimwe nzvimbo ndaifanira kuita nemazvo. Pane imwe nguva, mutsetse parallel0 waipenya pachiratidziro pane yebhuruu kumashure, iyo yaikurudzira dzimwe pfungwa. Mukupedzisira, zvakazoitika kuti dambudziko nderekuti Qemu inovhura akati wandei mahwindo mahwindo mune imwe yemuviri hwindo, pakati paunogona kushandura uchishandisa Ctrl-Alt-n: inoshanda mune yekuzvarwa kuvaka, asi kwete muEmscripten. Mushure mekubvisa mahwindo asina kufanira uchishandisa sarudzo -monitor none -parallel none -serial none uye mirairo yekudhirowa nechisimba chidzitiro chese pane imwe neimwe furemu, zvese zvakangoerekana zvashanda.

Coroutines

Saka, kutevedzera mubrowser kunoshanda, asi haugone kumhanyisa chero chinhu chinonakidza single-floppy mairi, nekuti hapana block I/O - iwe unofanirwa kuita tsigiro yemakoroni. Qemu yatove neyakaverengeka coroutine backends, asi nekuda kwechimiro cheJavaScript uye Emscripten kodhi jenareta, haugone kungotanga juggling stacks. Zvingaita sekuti "zvese zvaenda, plaster iri kubviswa," asi vagadziri veEmscripten vakatotarisira zvese. Izvi zvinoitwa zvinosekesa: ngatifonerei nharembozha senge ichi fungidziro emscripten_sleep uye vamwe vakati wandei vachishandisa iyo Asyncify mashandiro, pamwe neinongedzo yekufona uye kufona kune chero basa uko imwe yemakesi maviri apfuura inogona kuitika mberi pasi pasi. Uye zvino, tisati tasvika kufona kwega kwega kwekufungidzira, isu tichasarudza async mamiriro, uye pakarepo mushure mekufona, isu tichatarisa kana asynchronous call yaitika, uye kana yavepo, isu tichachengetedza ese akasiyana emunharaunda mune ino async mamiriro, ratidza kuti ibasa ripi. kuendesa kutonga kune patinoda kuenderera mberi nekuita, uye kubuda basa razvino. Apa ndipo pane mukana wekudzidza maitiro kupambadza - kune zvinodiwa zvekuenderera mberi nekuita kodhi mushure mekudzoka kubva kune asynchronous kufona, mugadziri anogadzira "stubs" yebasa rinotanga mushure mekufona kwekufungidzira - seizvi: kana paine n kufungidzira mafoni, ipapo basa racho richawedzerwa kumwe n/2 nguva - izvi zvichiri, kana zvisiri Ramba uchifunga kuti mushure meimwe neimwe ingangoita asynchronous kufona, iwe unofanirwa kuwedzera kuchengetedza mamwe emunharaunda akasiyana kune yekutanga basa. Mushure mezvo, ini ndakatozonyora script iri nyore muPython, iyo, zvichibva pane yakapihwa seti yakanyanya kunyanya kushandiswa iyo inonzi "haibvumidze asynchony kuti ipfuure nepakati pavo" (kureva, kukwidziridzwa uye zvese zvandichangobva kutsanangura shanda mavari), inoratidza mafoni kuburikidza nemanongedzero umo mabasa anofanirwa kufuratirwa nemuunganidzi kuitira kuti aya mabasa arege kutorwa seasynchronous. Uye ipapo JS mafaira ari pasi pe 60 MB ari pachena akawandisa - ngatitii zvishoma 30. Kunyange zvazvo, pandakanga ndichigadzira script yegungano, uye netsaona ndakarasa nzira dzekubatanidza, pakati payo paiva. -O3. Ini ndinomhanyisa kodhi yakagadzirwa, uye Chromium inodya ndangariro nekuparara. Ini ipapo netsaona akatarisa zvaakanga achiedza kudhawunirodha ... Zvakanaka, chii chandingati, ndingadai ndakaoma nechando zvakare dai ndakanga ndakumbirwa kuti ndidzidze nekufunga uye optimize a 500+ MB Javascript.

Nehurombo, cheki muAsyncify tsigiro raibhurari kodhi yakanga isina hushamwari zvachose nayo longjmp-s iyo inoshandiswa mune chaiyo processor kodhi, asi mushure mechikamu chidiki chinodzima cheki idzi uye nechisimba kudzorera mamiriro sekunge zvese zvaive zvakanaka, kodhi yakashanda. Uye ipapo chinhu chinoshamisa chakatanga: dzimwe nguva macheki mukodhi yekuwiriranisa akakonzereswa - iwo akafanana iwo anorovera iyo kodhi kana, maererano nemaitiro ekuuraya, inofanira kuvharwa - mumwe munhu akaedza kubata yakatobatwa mutex. Neraki, iri rakazove risiri dambudziko rine musoro museriyesheni kodhi - ini ndaingoshandisa yakajairwa loop mashandiro akapihwa naEmscripten, asi dzimwe nguva iyo asynchronous call yainyatso kuburitsa stack, uye panguva iyoyo yaizotadza. setTimeout kubva kune main loop - nekudaro, iyo kodhi yakapinda main loop iteration pasina kusiya iyo yapfuura iteration. Nyorazve pane isingaperi loop uye emscripten_sleep, uye matambudziko nembeu akamira. Iyo kodhi yakatowedzera zvine musoro - mushure mezvose, ini handina imwe kodhi inogadzirira inotevera animation furemu - processor inongoverengera chimwe chinhu uye skrini inovandudzwa nguva nenguva. Nekudaro, matambudziko haana kugumira ipapo: dzimwe nguva kuurayiwa kwaQemu kwaingopera chinyararire pasina kusarudzika kana kukanganisa. Panguva iyoyo ndakazvirega, asi, ndichitarisa kumberi, ndichati dambudziko raive iri: iyo coroutine kodhi, chokwadi, haishandisi. setTimeout (kana kuti kwete kazhinji sezvaungafunga): basa emscripten_yield inongoseta iyo asynchronous call mureza. Chinhu chose ndechekuti emscripten_coroutine_next haisi basa reasynchronous: mukati inotarisa mureza, inoisa patsva uye inoendesa kutonga kwainodiwa. Ndiko kuti, kukwidziridzwa kwe stack kunogumira ipapo. Dambudziko raive rekuti nekuda kwekushandisa-mushure-kwemahara, iyo yakaonekwa apo dziva rekorati rakaremara nekuda kwekuti ini handina kutevedzera mutsara wakakosha wekodhi kubva kune iripo coroutine backend, basa. qemu_in_coroutine akadzoka chokwadi asi chokwadi chaifanira kunge chakadzoka chenhema. Izvi zvakaita kuti ndifonerwe emscripten_yield, pamusoro payo pakanga pasina munhu pamurwi emscripten_coroutine_next, murwi wacho wakapeturwa kusvika kumusoro chaiko, asi kwete setTimeout, sezvandambotaura, haina kuratidzwa.

JavaScript kodhi kugadzira

Uye heino, chokwadi, ndiyo yakavimbiswa "kudzorera nyama yakagurwa kumashure." Kwete saizvozvo. Zvechokwadi, kana tikamhanya Qemu mubrowser, uye Node.js mairi, saka, zvakasununguka, mushure mekuberekwa kwekodhi muQemu tichawana zvachose JavaScript isina kururama. Asi zvakadaro, imwe mhando ye reverse shanduko.

Chekutanga, zvishoma nezve mashandiro anoita Qemu. Ndokumbira mundiregerere ipapo ipapo: Ini handisi nyanzvi yekuvandudza Qemu uye mhedziso dzangu dzinogona kunge dzakakanganisa mune dzimwe nzvimbo. Sezvavanotaura, "mafungiro emudzidzi haafaniri kupindirana nemafungiro emudzidzisi, Peano's axiomatics uye pfungwa." Qemu ine imwe nhamba inotsigirwa yevaenzi zvivakwa uye kune yega yega pane dhairekitori senge target-i386. Paunenge uchivaka, unogona kutsanangura rutsigiro kune akati wandei evaenzi ekuvaka, asi mhedzisiro inongove akati wandei mabhanari. Iyo kodhi yekutsigira dhizaini yevaenzi, zvakare, inogadzira mamwe emukati maQemu mashandiro, ayo TCG (Tiny Code Generator) inotoshandura kuita kodhi yemuchina yekuvaka kweanotambira. Sezvakataurwa mufaira rekuverenga riri mu tcg dhairekitori, iyi pakutanga yaive chikamu chenguva dzose C compiler, iyo yakazogadziridzwa kuJIT. Naizvozvo, semuenzaniso, chivakwa chakanangwa maererano negwaro iri hachisiri chivakwa chevaenzi, asi chivakwa chevaenzi. Pane imwe nguva, chimwe chikamu chakaonekwa - Tiny Code Interpreter (TCI), iyo inofanirwa kuita kodhi (inenge yakafanana mukati mekushanda kwemukati) mukushaikwa kwekodhi jenareta yeimwe dhizaini yekuvakisa. Muchokwadi, sekutaura kunoita zvinyorwa zvaro, muturikiri uyu anogona kusaita nguva dzose seJIT code generator, kwete chete quantitatively maererano nekumhanya, asiwo qualitatively. Kunyangwe ini ndisina chokwadi chekuti tsananguro yake yakakosha zvachose.

Pakutanga ndakaedza kugadzira TCG yakazara-yakazara backend, asi yakakurumidza kuvhiringika mune iyo kodhi kodhi uye isina kunyatso kujeka rondedzero yebytecode mirairo, saka ndakasarudza kuputira TCI muturikiri. Izvi zvakapa mabhenefiti akawanda:

  • paunenge uchiita jenareta yekodhi, haugone kutarisa kutsanangurwa kwemirairo, asi pane kodhi yemuturikiri
  • unogona kugadzira mabasa kwete ega ega eshanduro block yasangana, asi, semuenzaniso, chete mushure mezana rekuuraya
  • kana kodhi yakagadzirwa ichichinja (uye izvi zvinoita sekunge zvinogoneka, tichitonga nemabasa ane mazita ane izwi chigamba), ini ndichada kumisa iyo yakagadzirwa JS kodhi, asi zvirinani ndichave nechimwe chinhu chekuigadzira patsva kubva.

Nezve poindi yechitatu, handina chokwadi chekuti chigamba chinogoneka mushure mekunge kodhi yaitwa kekutanga, asi mapoinzi maviri ekutanga akakwana.

Pakutanga, iyo kodhi yakagadzirwa muchimiro chekuchinja hombe kukero yeiyo yekutanga bytecode rairo, asi zvino, ndichirangarira chinyorwa nezve Emscripten, optimization yeyakagadzirwa JS uye relooping, ndakafunga kugadzira yakawedzera kodhi yemunhu, kunyanya sezvo empirically iyo. zvakazoitika kuti iyo chete yekupinda muvharo yeshanduro ndeyeKutanga kwayo. Pasina nguva yati yapera, mushure mechinguva takange tave nekodhi jenareta iyo yakagadzira kodhi ine ifs (zvisinei isina zvishwe). Asi rombo rakanaka, rakadonha, richipa meseji yekuti mirairo yaive yehurefu husina kururama. Uyezve, murairo wekupedzisira pane iyi recursion level yaive brcond. Zvakanaka, ini ndichawedzera cheki yakafanana kuchizvarwa cherairo iyi isati yasvika uye mushure mekudzokororwa kufona uye ... hapana kana mumwe wavo akaurayiwa, asi mushure mekusimbisa switch ivo vachiri kutadza. Pakupedzisira, mushure mekudzidza kodhi yakagadzirwa, ndakaona kuti mushure mekushandura, chinongedzo kune murairo wemazuva ano chinodzokororwa kubva pachigadziko uye zvichida chakanyorwa pamusoro peiyo yakagadzirwa JavaScript code. Uye saka zvakazoitika. Kuwedzera buffer kubva kune imwe megabyte kusvika gumi hakuna kutungamira kune chero chinhu, uye zvakava pachena kuti iyo code generator yaimhanya mumadenderedzwa. Taifanira kutarisa kuti hatina kupfuura miganhu yeTB yazvino, uye kana takadaro, tozopa kero yeTB inotevera nechiratidzo cheminus kuitira kuti tirambe tichiurayiwa. Uye zvakare, izvi zvinogadzirisa dambudziko "ndepi akagadzirwa mabasa anofanirwa kuvharwa kana chidimbu chebytecode chachinja?" - chete basa rinoenderana nebhuroko reshanduro rino rinofanirwa kusashanda. Nenzira, kunyange zvazvo ndakagadzirisa zvinhu zvose muChromium (sezvo ini ndichishandisa Firefox uye zviri nyore kwandiri kuti ndishandise imwe browser yekuedza), Firefox yakandibatsira kugadzirisa kusapindirana neasm.js standard, mushure mokunge kodhi yakatanga kushanda nekukurumidza mukati. Chromium.

Muenzaniso wekodhi yakagadzirwa

Compiling 0x15b46d0:
CompiledTB[0x015b46d0] = function(stdlib, ffi, heap) {
"use asm";
var HEAP8 = new stdlib.Int8Array(heap);
var HEAP16 = new stdlib.Int16Array(heap);
var HEAP32 = new stdlib.Int32Array(heap);
var HEAPU8 = new stdlib.Uint8Array(heap);
var HEAPU16 = new stdlib.Uint16Array(heap);
var HEAPU32 = new stdlib.Uint32Array(heap);

var dynCall_iiiiiiiiiii = ffi.dynCall_iiiiiiiiiii;
var getTempRet0 = ffi.getTempRet0;
var badAlignment = ffi.badAlignment;
var _i64Add = ffi._i64Add;
var _i64Subtract = ffi._i64Subtract;
var Math_imul = ffi.Math_imul;
var _mul_unsigned_long_long = ffi._mul_unsigned_long_long;
var execute_if_compiled = ffi.execute_if_compiled;
var getThrew = ffi.getThrew;
var abort = ffi.abort;
var qemu_ld_ub = ffi.qemu_ld_ub;
var qemu_ld_leuw = ffi.qemu_ld_leuw;
var qemu_ld_leul = ffi.qemu_ld_leul;
var qemu_ld_beuw = ffi.qemu_ld_beuw;
var qemu_ld_beul = ffi.qemu_ld_beul;
var qemu_ld_beq = ffi.qemu_ld_beq;
var qemu_ld_leq = ffi.qemu_ld_leq;
var qemu_st_b = ffi.qemu_st_b;
var qemu_st_lew = ffi.qemu_st_lew;
var qemu_st_lel = ffi.qemu_st_lel;
var qemu_st_bew = ffi.qemu_st_bew;
var qemu_st_bel = ffi.qemu_st_bel;
var qemu_st_leq = ffi.qemu_st_leq;
var qemu_st_beq = ffi.qemu_st_beq;

function tb_fun(tb_ptr, env, sp_value, depth) {
  tb_ptr = tb_ptr|0;
  env = env|0;
  sp_value = sp_value|0;
  depth = depth|0;
  var u0 = 0, u1 = 0, u2 = 0, u3 = 0, result = 0;
  var r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0, r6 = 0, r7 = 0, r8 = 0, r9 = 0;
  var r10 = 0, r11 = 0, r12 = 0, r13 = 0, r14 = 0, r15 = 0, r16 = 0, r17 = 0, r18 = 0, r19 = 0;
  var r20 = 0, r21 = 0, r22 = 0, r23 = 0, r24 = 0, r25 = 0, r26 = 0, r27 = 0, r28 = 0, r29 = 0;
  var r30 = 0, r31 = 0, r41 = 0, r42 = 0, r43 = 0, r44 = 0;
    r14 = env|0;
    r15 = sp_value|0;
  START: do {
    r0 = HEAPU32[((r14 + (-4))|0) >> 2] | 0;
    r42 = 0;
    result = ((r0|0) != (r42|0))|0;
    HEAPU32[1445307] = r0;
    HEAPU32[1445321] = r14;
    if(result|0) {
    HEAPU32[1445322] = r15;
    return 0x0345bf93|0;
    }
    r0 = HEAPU32[((r14 + (16))|0) >> 2] | 0;
    r42 = 8;
    r0 = ((r0|0) - (r42|0))|0;
    HEAPU32[(r14 + (16)) >> 2] = r0;
    r1 = 8;
    HEAPU32[(r14 + (44)) >> 2] = r1;
    r1 = r0|0;
    HEAPU32[(r14 + (40)) >> 2] = r1;
    r42 = 4;
    r0 = ((r0|0) + (r42|0))|0;
    r2 = HEAPU32[((r14 + (24))|0) >> 2] | 0;
    HEAPU32[1445307] = r0;
    HEAPU32[1445308] = r1;
    HEAPU32[1445309] = r2;
    HEAPU32[1445321] = r14;
    HEAPU32[1445322] = r15;
    qemu_st_lel(env|0, r0|0, r2|0, 34, 22759218);
if(getThrew() | 0) abort();
    r0 = 3241038392;
    HEAPU32[1445307] = r0;
    r0 = qemu_ld_leul(env|0, r0|0, 34, 22759233)|0;
if(getThrew() | 0) abort();
    HEAPU32[(r14 + (24)) >> 2] = r0;
    r1 = HEAPU32[((r14 + (12))|0) >> 2] | 0;
    r2 = HEAPU32[((r14 + (40))|0) >> 2] | 0;
    HEAPU32[1445307] = r0;
    HEAPU32[1445308] = r1;
    HEAPU32[1445309] = r2;
    qemu_st_lel(env|0, r2|0, r1|0, 34, 22759265);
if(getThrew() | 0) abort();
    r0 = HEAPU32[((r14 + (24))|0) >> 2] | 0;
    HEAPU32[(r14 + (40)) >> 2] = r0;
    r1 = 24;
    HEAPU32[(r14 + (52)) >> 2] = r1;
    r42 = 0;
    result = ((r0|0) == (r42|0))|0;
    if(result|0) {
    HEAPU32[1445307] = r0;
    HEAPU32[1445308] = r1;
    }
    HEAPU32[1445307] = r0;
    HEAPU32[1445308] = r1;
    return execute_if_compiled(22759392|0, env|0, sp_value|0, depth|0) | 0;
    return execute_if_compiled(23164080|0, env|0, sp_value|0, depth|0) | 0;
    break;
  } while(1); abort(); return 0|0;
}
return {tb_fun: tb_fun};
}(window, CompilerFFI, Module.buffer)["tb_fun"]

mhedziso

Saka, basa harisati rapera, asi ndaneta nekuunza pachivande ichi chivakwa chenguva refu kusvika pakukwana. Nokudaro, ndakasarudza kubudisa zvandinazvo ikozvino. Iyo kodhi inotyisa zvishoma munzvimbo, nekuti ichi chiyedzo, uye hachina kujeka pamberi pezvinofanira kuitwa. Pamwe, saka zvakakodzera kuburitsa zvakajairika maatomu pamusoro peimwe shanduro yemazuva ano yeQemu. Zvichakadaro, pane tambo muGita mune blog fomati: kune yega yega "nhanho" iyo yakave neimwe nzira yakapfuura, tsananguro yakadzama muchiRussia yakawedzerwa. Chaizvoizvo, chinyorwa ichi kusvika pamwero mukuru kudzokororwa kwemhedziso git log.

Unogona kuzviedza zvose pano (chenjerera traffic).

Chii chiri kutoshanda:

  • x86 virtual processor iri kushanda
  • Pane inoshanda prototype yeJIT kodhi jenareta kubva muchina kodhi kuenda kuJavaScript
  • Pane template yekuunganidza mamwe 32-bit mavakirwo evaenzi: izvozvi unogona kuyemura Linux yeMIPS yekuvakisa inotonhora mubrowser padanho rekurodha.

Chii chimwe chaungaita

  • Kurumidza kutevedzera. Kunyangwe muJIT modhi inoita kunge inomhanya zvishoma pane Virtual x86 (asi pane ingangoita Qemu yakazara ine yakawanda emulated hardware uye zvivakwa)
  • Kugadzira yakajairwa interface - kutaura chokwadi, ini handisi akanaka webhu kuvandudza, saka parizvino ndagadzirisa iyo yakajairwa Emscripten shell nepandinogona napo.
  • Edza kumhanya zvakanyanya kuomarara mabasa eQemu - networking, VM migration, nezvimwe.
  • UPS: iwe unozofanirwa kuendesa ako mashoma ekuvandudza uye bug mishumo kuEmscripten kumusoro, sezvakaita vatakuri vekare veQemu nemamwe mapurojekiti. Ndinotenda kwavari nekukwanisa kushandisa zvizere mupiro wavo kuEmscripten sechikamu chebasa rangu.

Source: www.habr.com

Voeg