Qemu.js pẹlu atilẹyin JIT: o tun le yi mince pada sẹhin

Ni ọdun diẹ sẹhin Fabrice Bellard ti a kọ nipasẹ jslinux jẹ emulator PC ti a kọ ni JavaScript. Lẹhin iyẹn o kere ju diẹ sii Foju x86. Ṣugbọn gbogbo wọn, gẹgẹ bi mo ti mọ, jẹ awọn onitumọ, lakoko ti Qemu, ti a kọ tẹlẹ nipasẹ Fabrice Bellard kanna, ati, boya, eyikeyi emulator ode oni ti o bọwọ fun ara ẹni, nlo JIT akopọ ti koodu alejo sinu koodu eto agbalejo. O dabi fun mi pe o to akoko lati ṣe iṣẹ-ṣiṣe idakeji ni ibatan si ọkan ti awọn aṣawakiri yanju: Akopọ JIT ti koodu ẹrọ sinu JavaScript, fun eyiti o dabi ọgbọn julọ si ibudo Qemu. Yoo dabi, idi ti Qemu, awọn emulators ti o rọrun ati ore-olumulo wa - VirtualBox kanna, fun apẹẹrẹ - fi sori ẹrọ ati ṣiṣẹ. Ṣugbọn Qemu ni awọn ẹya ti o nifẹ pupọ

  • ìmọ orisun
  • agbara lati ṣiṣẹ laisi awakọ ekuro
  • agbara lati ṣiṣẹ ni ipo onitumọ
  • support fun kan ti o tobi nọmba ti awọn mejeeji ogun ati alejo faaji

Nipa aaye kẹta, Mo le ṣe alaye ni bayi pe ni otitọ, ni ipo TCI, kii ṣe awọn ilana ẹrọ alejo funrararẹ ni itumọ, ṣugbọn bytecode ti a gba lati ọdọ wọn, ṣugbọn eyi ko yi iyatọ naa pada - lati le kọ ati ṣiṣẹ. Qemu lori titun faaji, ti o ba ti o ba ni orire, A C alakojo ti to - kikọ a koodu monomono le ti wa ni felomiran.

Ati ni bayi, lẹhin ọdun meji ti ifamọ pẹlu koodu orisun Qemu ni akoko ọfẹ mi, apẹrẹ iṣẹ kan han, ninu eyiti o le ṣiṣẹ tẹlẹ, fun apẹẹrẹ, Kolibri OS.

Kí ni Emscripten

Ni ode oni, ọpọlọpọ awọn olupilẹṣẹ ti han, abajade ipari eyiti o jẹ JavaScript. Diẹ ninu, bii Iru Afọwọkọ, ni akọkọ ti pinnu lati jẹ ọna ti o dara julọ lati kọ fun wẹẹbu. Ni akoko kanna, Emscripten jẹ ọna lati mu koodu C tabi C ++ ti o wa tẹlẹ ki o si ṣajọ rẹ sinu fọọmu aṣawakiri-ṣeékà. Tan-an oju-ewe yii A ti gba ọpọlọpọ awọn ebute oko oju omi ti awọn eto olokiki daradara: nibiFun apẹẹrẹ, o le wo PyPy - nipasẹ ọna, wọn sọ pe wọn ti ni JIT tẹlẹ. Ni otitọ, kii ṣe gbogbo eto ni a le ṣajọ nirọrun ati ṣiṣẹ ni ẹrọ aṣawakiri kan - nọmba kan wa awọn ẹya ara ẹrọ, èyí tí o ní láti fara dà, bí ó ti wù kí ó rí, gẹ́gẹ́ bí àkọlé tí ó wà ní ojú ewé kan náà ti sọ pé “Emscripten le ṣee lò láti ṣàkójọ ó fẹ́rẹ̀ẹ́ jẹ́ èyíkéyìí šee C/C ++ koodu to JavaScript ". Ti o ni, nibẹ ni o wa nọmba kan ti mosi ti o wa ni aisọye ihuwasi ni ibamu si awọn bošewa, sugbon maa ṣiṣẹ lori x86 - fun apẹẹrẹ, unaligned wiwọle si awọn oniyipada, eyi ti o ti ni gbogbo idinamọ lori diẹ ninu awọn faaji. , Qemu jẹ eto eto-agbelebu ati , Mo fẹ lati gbagbọ, ati pe ko ti ni ọpọlọpọ awọn ihuwasi aisọye tẹlẹ - mu ati ṣajọ, lẹhinna tinker diẹ pẹlu JIT - ati pe o ti pari! Ṣugbọn kii ṣe iyẹn irú...

Akọkọ gbiyanju

Ni gbogbogbo, Emi kii ṣe eniyan akọkọ lati wa pẹlu imọran gbigbe Qemu si JavaScript. Ibeere kan wa lori apejọ ReactOS ti eyi ba ṣee ṣe nipa lilo Emscripten. Paapaa ni iṣaaju, awọn agbasọ ọrọ wa pe Fabrice Bellard ṣe eyi tikalararẹ, ṣugbọn a n sọrọ nipa jslinux, eyiti, bi mo ti mọ, jẹ igbiyanju kan lati ṣaṣeyọri iṣẹ ṣiṣe to ni ọwọ ni JS, ati pe a kọ lati ibere. Nigbamii, foju x86 ti kọ - awọn orisun ti a ko fi oju silẹ ni a fiweranṣẹ fun rẹ, ati pe, bi a ti sọ, “otitọ” ti o tobi julọ ti emulation jẹ ki o ṣee ṣe lati lo SeaBIOS bi famuwia. Ni afikun, o kere ju igbiyanju kan lati ibudo Qemu ni lilo Emscripten - Mo gbiyanju lati ṣe eyi socketpair, ṣugbọn idagbasoke, bi jina bi mo ti ye, ti a aotoju.

Nitorinaa, yoo dabi, nibi ni awọn orisun, eyi ni Emscripten - mu ati ṣajọ. Ṣugbọn awọn ile-ikawe tun wa ti Qemu da lori, ati awọn ile-ikawe ti awọn ile-ikawe wọnyẹn gbarale, ati bẹbẹ lọ, ọkan ninu wọn ni. libffi, eyi ti glib da lori. Awọn agbasọ ọrọ wa lori Intanẹẹti pe ọkan wa ninu akojọpọ nla ti awọn ebute oko oju omi ti awọn ile-ikawe fun Emscripten, ṣugbọn o nira lati gbagbọ: ni akọkọ, ko pinnu lati jẹ alakojọ tuntun, keji, o jẹ ipele kekere kan ile-ikawe lati kan gbe soke, ati ṣajọ si JS. Ati pe kii ṣe ọrọ kan ti awọn ifibọ apejọ - boya, ti o ba yi pada, fun diẹ ninu awọn apejọ pipe o le ṣe agbekalẹ awọn ariyanjiyan pataki lori akopọ ati pe iṣẹ naa laisi wọn. Ṣugbọn Emscripten jẹ ohun ti o ni ẹtan: lati jẹ ki koodu ti ipilẹṣẹ jẹ ki o faramọ si aṣawakiri ẹrọ aṣawakiri JS, diẹ ninu awọn ẹtan lo. Ni pataki, ohun ti a pe ni relooping - olupilẹṣẹ koodu kan nipa lilo LLVM IR ti o gba pẹlu diẹ ninu awọn ilana iyipada afọwọṣe n gbiyanju lati tun ṣe ifs, awọn losiwajulosehin, ati bẹbẹ lọ. O dara, bawo ni awọn ariyanjiyan ti kọja si iṣẹ naa? Nipa ti, bi awọn ariyanjiyan si awọn iṣẹ JS, iyẹn ni, ti o ba ṣeeṣe, kii ṣe nipasẹ akopọ.

Ni ibẹrẹ imọran kan wa lati kọ aropo fun libffi pẹlu JS ati ṣiṣe awọn idanwo boṣewa, ṣugbọn ni ipari Mo ni idamu nipa bi a ṣe le ṣe awọn faili akọsori mi ki wọn le ṣiṣẹ pẹlu koodu ti o wa tẹlẹ - kini MO le ṣe, bi nwọn ti sọ, "Ṣe awọn iṣẹ-ṣiṣe ki eka "Ṣe a ki Karachi?" Mo ni lati gbe libffi si miiran faaji, bẹ si sọrọ - da, Emscripten ni o ni awọn mejeeji macros fun opopo ijọ (ni Javascript, Yeah - daradara, ohunkohun ti faaji, ki awọn assembler), ati awọn agbara lati ṣiṣe awọn koodu ti ipilẹṣẹ lori awọn fly. Ni gbogbogbo, lẹhin tinkering pẹlu awọn ajẹkù libffi ti o gbẹkẹle pẹpẹ fun igba diẹ, Mo ni diẹ ninu koodu akojọpọ ati ṣiṣe rẹ lori idanwo akọkọ ti Mo wa kọja. Si iyalenu mi, idanwo naa ṣaṣeyọri. Iyalẹnu nipasẹ oloye-pupọ mi - ko si awada, o ṣiṣẹ lati ifilọlẹ akọkọ - Emi, ti ko gbagbọ oju mi, lọ lati wo koodu abajade lẹẹkansi, lati ṣe iṣiro ibiti o wa ni atẹle. Nibi Mo ti lọ eso fun akoko keji - ohun kan ṣoṣo ti iṣẹ mi ṣe ni ffi_call - eyi royin ipe ti o ṣaṣeyọri. Ko si ipe funrararẹ. Nitorinaa Mo firanṣẹ ibeere fifa akọkọ mi, eyiti o ṣe atunṣe aṣiṣe kan ninu idanwo ti o han gbangba si eyikeyi ọmọ ile-iwe Olympiad - awọn nọmba gidi ko yẹ ki o ṣe afiwe bi a == b ati paapaa bawo ni a - b < EPS - o tun nilo lati ranti module, bibẹẹkọ 0 yoo tan lati jẹ dogba pupọ si 1/3… Ni ​​gbogbogbo, Mo wa pẹlu ibudo kan ti libffi, eyiti o kọja awọn idanwo ti o rọrun julọ, ati pẹlu eyiti glib jẹ compiled - Mo pinnu pe yoo jẹ pataki, Emi yoo ṣafikun nigbamii. Ni wiwa niwaju, Emi yoo sọ pe, bi o ti wa ni jade, alakojo ko paapaa pẹlu iṣẹ libffi ninu koodu ikẹhin.

Ṣugbọn, bi Mo ti sọ tẹlẹ, diẹ ninu awọn idiwọn wa, ati laarin lilo ọfẹ ti ọpọlọpọ ihuwasi aisọye, ẹya ti ko dun diẹ sii ti farapamọ - JavaScript nipasẹ apẹrẹ ko ṣe atilẹyin multithreading pẹlu iranti pinpin. Ni opo, eyi le paapaa ni a pe ni imọran ti o dara, ṣugbọn kii ṣe fun koodu gbigbe ti faaji ti so mọ awọn okun C. Ni gbogbogbo, Firefox n ṣe idanwo pẹlu atilẹyin awọn oṣiṣẹ pinpin, ati pe Emscripten ni imuse pthread fun wọn, ṣugbọn Emi ko fẹ lati dale lori rẹ. Mo ni lati gbongbo multithreading laiyara lati koodu Qemu - iyẹn ni, wa ibi ti awọn okun ti nṣiṣẹ, gbe ara ti lupu ti n ṣiṣẹ ni o tẹle ara yii sinu iṣẹ lọtọ, ki o pe iru awọn iṣẹ bẹ ni ọkọọkan lati lupu akọkọ.

Igbiyanju keji

Ni aaye kan, o han gbangba pe iṣoro naa tun wa nibẹ, ati pe laiparuwo awọn crutches ni ayika koodu kii yoo yorisi eyikeyi ti o dara. Ipari: a nilo lati bakan systematize awọn ilana ti fifi crutches. Nitorinaa, ẹya 2.4.1, eyiti o jẹ alabapade ni akoko yẹn, ni a mu (kii ṣe 2.5.0, nitori, tani o mọ, awọn idun yoo wa ninu ẹya tuntun ti a ko tii mu, ati pe Mo ni to ti awọn idun ti ara mi. ), ati pe ohun akọkọ ni lati tun kọ silẹ lailewu thread-posix.c. O dara, iyẹn ni, bi ailewu: ti ẹnikan ba gbiyanju lati ṣe iṣẹ ṣiṣe ti o yori si didi, iṣẹ naa ni a pe lẹsẹkẹsẹ abort() - dajudaju, eyi ko yanju gbogbo awọn iṣoro ni ẹẹkan, ṣugbọn o kere ju o jẹ diẹ sii ni idunnu ju laiparuwo gbigba data aisedede.

Ni gbogbogbo, awọn aṣayan Emscripten ṣe iranlọwọ pupọ ni koodu gbigbe si JS -s ASSERTIONS=1 -s SAFE_HEAP=1 - wọn mu diẹ ninu awọn iru ihuwasi ti ko ṣe alaye, gẹgẹbi awọn ipe si adirẹsi ti ko ni ibamu (eyiti ko ṣe deede pẹlu koodu fun awọn eto ti a tẹ bi HEAP32[addr >> 2] = 1) tabi pipe iṣẹ kan pẹlu nọmba ti ko tọ ti awọn ariyanjiyan.

Nipa ọna, awọn aṣiṣe titete jẹ ọrọ ti o yatọ. Gẹgẹbi Mo ti sọ tẹlẹ, Qemu ni ẹhin onitumọ “idibajẹ” fun iran koodu TCI (onitumọ koodu kekere), ati lati kọ ati ṣiṣẹ Qemu lori faaji tuntun kan, ti o ba ni orire, olupilẹṣẹ C ti to. Awọn Koko-ọrọ. "ti o ba ni orire". Emi ko ni orire, ati pe o wa ni pe TCI nlo iraye si aiṣedeede nigbati o ba n ṣe itupalẹ bytecode rẹ. Iyẹn ni, lori gbogbo iru ARM ati awọn ile ayaworan miiran pẹlu iwọle ti o ni dandan, Qemu ṣe akopọ nitori wọn ni ẹhin TCG deede ti o ṣe agbekalẹ koodu abinibi, ṣugbọn boya TCI yoo ṣiṣẹ lori wọn jẹ ibeere miiran. Sibẹsibẹ, bi o ti wa ni jade, awọn iwe TCI fihan kedere nkankan iru. Bi abajade, awọn ipe iṣẹ fun kika aijọpọ ni a ṣafikun si koodu naa, eyiti a ṣe awari ni apakan miiran ti Qemu.

Òkiti ìparun

Bi abajade, iraye si aiṣedeede si TCI ni atunṣe, a ṣẹda lupu akọkọ ti a pe ni ero isise, RCU ati diẹ ninu awọn ohun kekere miiran. Ati nitorinaa Mo ṣe ifilọlẹ Qemu pẹlu aṣayan -d exec,in_asm,out_asm, eyi ti o tumọ si pe o nilo lati sọ iru awọn bulọọki ti koodu ti n ṣiṣẹ, ati ni akoko igbohunsafefe lati kọ kini koodu alejo jẹ, kini koodu agbalejo di (ni idi eyi, bytecode). O bẹrẹ, ṣiṣẹ ọpọlọpọ awọn bulọọki itumọ, kọ ifiranṣẹ aṣiṣe ti Mo fi silẹ pe RCU yoo bẹrẹ bayi ati… abort() inu iṣẹ kan free(). Nipa tinkering pẹlu iṣẹ naa free() A ṣakoso lati rii pe ninu akọsori ti ibi-ipamọ okiti, eyiti o wa ni awọn baiti mẹjọ ti o ṣaju iranti ti a pin, dipo iwọn bulọki tabi nkan ti o jọra, idoti wa.

Iparun okiti - bawo ni o ṣe wuyi ... Ni iru ọran bẹ, atunṣe ti o wulo wa - lati (ti o ba ṣeeṣe) awọn orisun kanna, ṣajọpọ alakomeji abinibi ati ṣiṣe rẹ labẹ Valgrind. Lẹhin akoko diẹ, alakomeji ti ṣetan. Mo ṣe ifilọlẹ pẹlu awọn aṣayan kanna - o kọlu paapaa lakoko ibẹrẹ, ṣaaju ki o to de ipaniyan. Ko dun, nitorinaa - nkqwe, awọn orisun kii ṣe deede kanna, eyiti kii ṣe iyalẹnu, nitori atunto awọn aṣayan oriṣiriṣi oriṣiriṣi, ṣugbọn Mo ni Valgrind - akọkọ Emi yoo ṣatunṣe kokoro yii, ati lẹhinna, ti Mo ba ni orire. , atilẹba yoo han. Mo n ṣiṣẹ ohun kanna labẹ Valgrind ... Y-y-y, y-y-y, uh-uh, o bẹrẹ, lọ nipasẹ ipilẹṣẹ ni deede ati gbe lọ kọja kokoro atilẹba laisi ikilọ kan nipa wiwọle iranti ti ko tọ, kii ṣe darukọ nipa isubu. Igbesi aye, bi wọn ti sọ, ko mura mi silẹ fun eyi - eto ikọlu kan duro jamba nigbati o ṣe ifilọlẹ labẹ Walgrind. Ohun ti o jẹ ohun ijinlẹ. Itumọ mi ni pe ni ẹẹkan ni agbegbe ti itọnisọna lọwọlọwọ lẹhin jamba lakoko ibẹrẹ, gdb fihan iṣẹ memset-a pẹlu kan wulo ijuboluwole lilo boya mmx, tabi xmm awọn iforukọsilẹ, lẹhinna boya o jẹ diẹ ninu iru aṣiṣe titete, botilẹjẹpe o tun ṣoro lati gbagbọ.

O dara, Valgrind ko dabi pe o ṣe iranlọwọ nibi. Ati pe nibi ohun irira julọ bẹrẹ - ohun gbogbo dabi pe o bẹrẹ paapaa, ṣugbọn awọn ipadanu fun awọn idi aimọ rara nitori iṣẹlẹ ti o le ti ṣẹlẹ awọn miliọnu awọn ilana sẹhin. Fun igba pipẹ, ko tilẹ ṣe kedere bi o ṣe le sunmọ. Ni ipari, Mo tun ni lati joko ati ṣatunṣe aṣiṣe. Titẹwe ohun ti akọsori ti a tun kọ pẹlu fihan pe ko dabi nọmba kan, ṣugbọn dipo iru data alakomeji kan. Ati pe, kiyesi i, okun alakomeji yii ni a rii ninu faili BIOS - iyẹn ni, ni bayi o ṣee ṣe lati sọ pẹlu igbẹkẹle ti o tọ pe o jẹ aponsedanu ifipamọ, ati pe o han gbangba pe o ti kọwe si ifipamọ yii. O dara, lẹhinna nkan bii eyi - ni Emscripten, daa, ko si aileto ti aaye adirẹsi, ko si awọn iho ninu rẹ boya, nitorinaa o le kọ ibikan ni aarin koodu lati gbejade data nipasẹ itọka lati ifilọlẹ ikẹhin, wo data naa, wo itọka, ati, ti ko ba yipada, gba ounjẹ fun ero. Lootọ, o gba to iṣẹju diẹ lati sopọ lẹhin iyipada eyikeyi, ṣugbọn kini o le ṣe? Bi abajade, a rii laini kan pato ti o daakọ BIOS lati ifipamọ igba diẹ si iranti alejo - ati pe, nitootọ, aaye ko to ninu ifipamọ naa. Wiwa orisun ti adiresi ifipamọ ajeji yẹn yorisi iṣẹ kan qemu_anon_ram_alloc ninu faili oslib-posix.c - ọgbọn ti eyi wa: nigbakan o le wulo lati ṣe afiwe adirẹsi naa si oju-iwe nla ti 2 MB ni iwọn, fun eyi a yoo beere mmap Ni akọkọ diẹ diẹ sii, lẹhinna a yoo da afikun pada pẹlu iranlọwọ munmap. Ati pe ti iru titete ko ba nilo, lẹhinna a yoo tọka abajade dipo 2 MB getpagesize() - mmap o yoo si tun fun jade ohun deedee adirẹsi ... Nitorina ni Emscripten mmap o kan awọn ipe malloc, ṣugbọn dajudaju ko ṣe deede lori oju-iwe naa. Ni gbogbogbo, kokoro kan ti o bajẹ mi fun oṣu meji kan ni a ṣe atunṣe nipasẹ iyipada ninu iwe awọn ila.

Awọn ẹya ara ẹrọ ti awọn iṣẹ ipe

Ati nisisiyi ero isise naa n ka nkan kan, Qemu ko ni jamba, ṣugbọn iboju ko tan-an, ati pe ẹrọ isise naa yarayara sinu awọn losiwajulosehin, ṣe idajọ nipasẹ iṣẹjade. -d exec,in_asm,out_asm. Apejuwe kan ti farahan: awọn idalọwọduro aago (tabi, ni gbogbogbo, gbogbo awọn idalọwọduro) ko de. Ati nitootọ, ti o ba ṣii awọn idilọwọ lati apejọ abinibi, eyiti o ṣiṣẹ fun idi kan, o gba aworan kanna. Ṣugbọn eyi kii ṣe idahun rara: lafiwe ti awọn itọpa ti a funni pẹlu aṣayan ti o wa loke fihan pe awọn ipa ipaniyan ti yapa ni kutukutu. Nibi o gbọdọ sọ pe afiwe ohun ti o gbasilẹ ni lilo ifilọlẹ emrun iṣẹjade n ṣatunṣe aṣiṣe pẹlu abajade ti apejọ abinibi kii ṣe ilana ẹrọ ẹrọ patapata. Emi ko mọ ni pato bi eto ti n ṣiṣẹ ni ẹrọ aṣawakiri kan ṣe sopọ si emrun, ṣugbọn diẹ ninu awọn ila ti o wa ninu iṣelọpọ jade lati wa ni atunṣe, nitorina iyatọ ninu iyatọ ko sibẹsibẹ jẹ idi kan lati ro pe awọn itọpa ti yapa. Ni gbogbogbo, o han gbangba pe ni ibamu si awọn ilana ljmpl Iyipada kan wa si awọn adirẹsi oriṣiriṣi, ati ipilẹṣẹ bytecode jẹ iyatọ pataki: ọkan ni itọnisọna kan lati pe iṣẹ oluranlọwọ, ekeji kii ṣe. Lẹhin lilọ awọn itọnisọna ati kikọ koodu ti o tumọ awọn ilana wọnyi, o han gbangba pe, ni akọkọ, lẹsẹkẹsẹ ṣaaju ninu iforukọsilẹ cr0 A ṣe igbasilẹ kan - tun lo oluranlọwọ - eyiti o yipada ero isise si ipo aabo, ati keji, pe ẹya js ko yipada si ipo aabo. Ṣugbọn otitọ ni pe ẹya miiran ti Emscripten ni aifẹ rẹ lati fi aaye gba koodu gẹgẹbi imuse awọn ilana. call ni TCI, eyi ti eyikeyi iṣẹ ijuboluwole esi ni iru long long f(int arg0, .. int arg9) - awọn iṣẹ gbọdọ wa ni a npe ni pẹlu awọn ti o tọ nọmba ti ariyanjiyan. Ti ofin yii ba ṣẹ, da lori awọn eto n ṣatunṣe aṣiṣe, eto naa yoo jẹ jamba (eyiti o dara) tabi pe iṣẹ ti ko tọ rara (eyiti yoo jẹ ibanujẹ lati yokokoro). Aṣayan kẹta tun wa - jẹ ki iran ti awọn olupopopo ti o ṣafikun / yọ awọn ariyanjiyan kuro, ṣugbọn lapapọ awọn apẹja wọnyi gba aaye pupọ, botilẹjẹpe ni otitọ Mo nilo diẹ diẹ sii ju awọn apẹja ọgọrun. Eyi nikan ni ibanujẹ pupọ, ṣugbọn o wa lati jẹ iṣoro to ṣe pataki diẹ sii: ninu koodu ti ipilẹṣẹ ti awọn iṣẹ-itumọ, awọn ariyanjiyan ti yipada ati iyipada, ṣugbọn nigbamiran iṣẹ naa pẹlu awọn ariyanjiyan ti ipilẹṣẹ ko pe - daradara, gẹgẹbi ninu imuse libffi mi. Ìyẹn ni pé, a kò pa àwọn olùrànlọ́wọ́ kan lásán.

O da, Qemu ni awọn atokọ ẹrọ ti a le ka ti awọn oluranlọwọ ni irisi faili akọsori bi

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

Wọn ti lo oyimbo funny: akọkọ, macros ti wa ni redefinition ninu awọn julọ burujai ọna DEF_HELPER_n, ati lẹhinna tan-an helper.h. Si iye ti Makiro naa ti fẹ sii sinu ipilẹṣẹ eto ati komama kan, lẹhinna a ti ṣalaye akopọ, ati dipo awọn eroja - #include <helper.h> Bi abajade, nikẹhin Mo ni aye lati gbiyanju ile-ikawe ni ibi iṣẹ pyparsing, ati pe a ti kọ iwe afọwọkọ kan ti o ṣe ipilẹṣẹ awọn ohun-itumọ gangan fun awọn iṣẹ ṣiṣe ti wọn nilo.

Ati nitorinaa, lẹhin ti ero isise naa dabi pe o ṣiṣẹ. O dabi pe o jẹ nitori iboju ko ṣe ipilẹṣẹ rara, botilẹjẹpe memtest86 + ni anfani lati ṣiṣẹ ni apejọ abinibi. Nibi o jẹ dandan lati ṣalaye pe koodu I/O bulọki Qemu ti kọ sinu awọn coroutines. Emscripten ni imuse arekereke tirẹ, ṣugbọn o tun nilo lati ṣe atilẹyin ninu koodu Qemu, ati pe o le ṣatunṣe ero isise naa ni bayi: Qemu ṣe atilẹyin awọn aṣayan -kernel, -initrd, -append, pẹlu eyiti o le bata Lainos tabi, fun apẹẹrẹ, memtest86+, laisi lilo awọn ẹrọ dina rara. Ṣugbọn eyi ni iṣoro naa: ni apejọ abinibi ọkan le rii iṣelọpọ ekuro Linux si console pẹlu aṣayan naa -nographic, ko si si abajade lati ẹrọ aṣawakiri si ebute lati ibiti o ti ṣe ifilọlẹ emrun, ko wa. Iyẹn ni, ko ṣe kedere: ero isise ko ṣiṣẹ tabi iṣelọpọ awọn aworan ko ṣiṣẹ. Ati lẹhinna o ṣẹlẹ si mi lati duro diẹ. O wa ni jade wipe "ero isise ti wa ni ko sun, sugbon nìkan si pawalara laiyara," ati lẹhin nipa iṣẹju marun kernel ju kan ìdìpọ awọn ifiranṣẹ lori awọn console ati ki o tesiwaju lati idorikodo. O han gbangba pe ero isise naa, ni gbogbogbo, ṣiṣẹ, ati pe a nilo lati ma wà sinu koodu fun ṣiṣẹ pẹlu SDL2. Laanu, Emi ko mọ bi a ṣe le lo ile-ikawe yii, nitorinaa ni awọn aaye kan Mo ni lati ṣiṣẹ ni laileto. Ni aaye kan, ila parallel0 tan loju iboju lori abẹlẹ buluu, eyiti o daba diẹ ninu awọn ero. Ni ipari, o jẹ pe iṣoro naa ni pe Qemu ṣi ọpọlọpọ awọn ferese foju ni window ti ara kan, laarin eyiti o le yipada ni lilo Konturolu-Alt-n: o ṣiṣẹ ni kikọ abinibi, ṣugbọn kii ṣe ni Emscripten. Lẹhin ti legbe kobojumu windows lilo awọn aṣayan -monitor none -parallel none -serial none ati awọn ilana lati fi agbara ṣe atunṣe gbogbo iboju lori fireemu kọọkan, ohun gbogbo ṣiṣẹ lojiji.

Coroutines

Nitorinaa, apẹẹrẹ ninu ẹrọ aṣawakiri n ṣiṣẹ, ṣugbọn o ko le ṣiṣẹ ohunkohun ti o nifẹ si ọkan-floppy ninu rẹ, nitori ko si bulọki I / O - o nilo lati ṣe atilẹyin fun awọn coroutines. Qemu ti ni ọpọlọpọ awọn ẹhin ẹhin coroutine, ṣugbọn nitori iru JavaScript ati olupilẹṣẹ koodu Emscripten, o ko le bẹrẹ awọn akopọ juggling nikan. Yoo dabi pe “ohun gbogbo ti lọ, a ti yọ pilasita kuro,” ṣugbọn awọn olupilẹṣẹ Emscripten ti ṣe abojuto ohun gbogbo tẹlẹ. Eyi jẹ imuse ohun ti o dun: jẹ ki a pe ipe iṣẹ kan bi ifura yii emscripten_sleep ati ọpọlọpọ awọn miiran ti nlo ẹrọ Asyncify, bakanna bi awọn ipe itọka ati awọn ipe si iṣẹ eyikeyi nibiti ọkan ninu awọn ọran meji ti tẹlẹ le waye siwaju si isalẹ akopọ. Ati ni bayi, ṣaaju ipe ifura kọọkan, a yoo yan ipo async kan, ati lẹsẹkẹsẹ lẹhin ipe, a yoo ṣayẹwo boya ipe asynchronous ti waye, ati pe ti o ba ni, a yoo fipamọ gbogbo awọn oniyipada agbegbe ni ipo async yii, tọka iṣẹ wo ni lati gbe iṣakoso lọ si igba ti a nilo lati tẹsiwaju ipaniyan, ati jade kuro ni iṣẹ lọwọlọwọ. Eyi ni ibi ti aaye wa fun kikọ ipa naa squandering - fun awọn iwulo ti ipaniyan koodu tẹsiwaju lẹhin ipadabọ lati ipe asynchronous, olupilẹṣẹ ṣe ipilẹṣẹ “stubs” ti iṣẹ ti o bẹrẹ lẹhin ipe ifura kan - bii eyi: ti awọn ipe ifura ba wa, lẹhinna iṣẹ naa yoo gbooro si ibikan n / 2 igba - eyi tun wa, ti ko ba ṣe akiyesi pe lẹhin ipe asynchronous kọọkan, o nilo lati ṣafikun fifipamọ diẹ ninu awọn oniyipada agbegbe si iṣẹ atilẹba. Lẹhinna, Mo paapaa ni lati kọ iwe afọwọkọ ti o rọrun ni Python, eyiti, da lori eto ti a fun ni ti awọn iṣẹ ti a lo pupọju ti o yẹ ki o “ko gba asynchrony laaye lati kọja nipasẹ ara wọn” (iyẹn ni, igbega akopọ ati ohun gbogbo ti Mo ṣapejuwe ko ṣe. ṣiṣẹ ninu wọn), tọkasi awọn ipe nipasẹ awọn itọka ninu eyiti awọn iṣẹ yẹ ki o foju parẹ nipasẹ alakojọ ki awọn iṣẹ wọnyi ko ni ka asynchronous. Ati lẹhinna awọn faili JS labẹ 60 MB jẹ kedere pupọ - jẹ ki a sọ pe o kere ju 30. Bi o tilẹ jẹ pe, ni kete ti Mo n ṣeto iwe afọwọkọ apejọ kan, ati lairotẹlẹ sọ awọn aṣayan asopọ asopọ jade, laarin eyiti o jẹ -O3. Mo nṣiṣẹ koodu ti ipilẹṣẹ, ati Chromium jẹ iranti ati ipadanu. Mo lẹhinna lairotẹlẹ wo ohun ti o n gbiyanju lati ṣe igbasilẹ… Daradara, kini MO le sọ, Emi yoo ti didi paapaa ti wọn ba ti beere lọwọ mi lati kawe pẹlu ironu ati mu Javascript 500+ MB pọ si.

Laanu, awọn sọwedowo ti o wa ninu koodu ikawe atilẹyin Asyncify ko jẹ ọrẹ patapata pẹlu longjmp-s ti o ti wa ni lilo ninu awọn foju isise koodu, ṣugbọn lẹhin kan kekere alemo ti o disables awọn wọnyi sọwedowo ati ki o fi agbara mu pada àrà bi o ba ti ohun gbogbo wà itanran, ṣiṣẹ koodu. Ati lẹhinna ohun ajeji kan bẹrẹ: nigbakan awọn sọwedowo ninu koodu amuṣiṣẹpọ ni a mu ṣiṣẹ - awọn kanna ti o kọlu koodu naa ti o ba jẹ pe, ni ibamu si ọgbọn ipaniyan, o yẹ ki o dina - ẹnikan gbiyanju lati mu mutex ti o ti mu tẹlẹ. Ni akoko, eyi ko jẹ iṣoro ọgbọn ninu koodu serialized - Mo n lo iṣẹ ṣiṣe lupu akọkọ boṣewa ti o pese nipasẹ Emscripten, ṣugbọn nigbakan ipe asynchronous yoo ṣii akopọ naa patapata, ati ni akoko yẹn yoo kuna. setTimeout lati lupu akọkọ - nitorinaa, koodu ti wọ inu aṣetunṣe lupu akọkọ laisi fifisilẹ aṣetunṣe iṣaaju. Atunko lori lupu ailopin ati emscripten_sleep, ati awọn iṣoro pẹlu mutexes duro. Koodu naa paapaa ti di ọgbọn diẹ sii - lẹhinna, ni otitọ, Emi ko ni koodu kan ti o mura fireemu ere idaraya atẹle - ero isise naa kan ṣe iṣiro nkan kan ati pe iboju ti ni imudojuiwọn lorekore. Bibẹẹkọ, awọn iṣoro naa ko duro sibẹ: nigbakan ipaniyan Qemu yoo pari ni idakẹjẹ laisi awọn imukuro tabi awọn aṣiṣe. Ni akoko yẹn Mo fi silẹ lori rẹ, ṣugbọn, n wo iwaju, Emi yoo sọ pe iṣoro naa ni eyi: koodu coroutine, ni otitọ, ko lo. setTimeout (tabi o kere ju kii ṣe nigbagbogbo bi o ṣe le ronu): iṣẹ emscripten_yield nìkan n ṣeto asia ipe asynchronous. Gbogbo koko ni pe emscripten_coroutine_next kii ṣe iṣẹ asynchronous: inu o ṣayẹwo asia, tunto ati gbe iṣakoso lọ si ibiti o nilo rẹ. Iyẹn ni, igbega ti akopọ dopin nibẹ. Iṣoro naa ni pe nitori lilo-lẹhin-ọfẹ, eyiti o han nigbati adagun coroutine jẹ alaabo nitori otitọ pe Emi ko daakọ laini koodu pataki kan lati ẹhin coroutine ti o wa, iṣẹ naa qemu_in_coroutine pada otitọ nigbati ni otitọ o yẹ ki o ti pada eke. Eyi yori si ipe kan emscripten_yield, loke eyi ti ko si ọkan lori akopọ emscripten_coroutine_next, akopọ naa ṣii si oke pupọ, ṣugbọn rara setTimeout, bi mo ti sọ tẹlẹ, ko ṣe afihan.

JavaScript koodu iran

Àti pé níhìn-ín, ní ti tòótọ́, ni ìlérí náà “yí ẹran tí a gé padà.” Be ko. Nitoribẹẹ, ti a ba ṣiṣẹ Qemu ninu ẹrọ aṣawakiri, ati Node.js ninu rẹ, lẹhinna, nipa ti ara, lẹhin iran koodu ni Qemu a yoo gba JavaScript ti ko tọ patapata. Ṣugbọn sibẹ, diẹ ninu iru iyipada iyipada.

Ni akọkọ, diẹ nipa bi Qemu ṣe n ṣiṣẹ. Jọwọ dariji mi lẹsẹkẹsẹ: Emi kii ṣe alamọdaju Qemu ati pe awọn ipinnu mi le jẹ aṣiṣe ni awọn aaye kan. Gẹgẹbi wọn ti sọ, "ero ọmọ ile-iwe ko ni lati ṣe deede pẹlu ero olukọ, awọn axiomatics Peano ati oye ti o wọpọ." Qemu ni nọmba kan ti awọn ile ayaworan alejo ti o ṣe atilẹyin ati fun ọkọọkan itọsọna kan wa bi target-i386. Nigbati o ba kọ, o le pato atilẹyin fun ọpọlọpọ awọn faaji alejo, ṣugbọn abajade yoo kan jẹ awọn alakomeji pupọ. Awọn koodu lati ṣe atilẹyin faaji alejo, lapapọ, n ṣe agbejade diẹ ninu awọn iṣẹ Qemu inu, eyiti TCG (Ipilẹṣẹ koodu Tiny) ti yipada tẹlẹ sinu koodu ẹrọ fun faaji agbalejo. Gẹgẹbi a ti sọ ninu faili readme ti o wa ninu itọsọna tcg, eyi jẹ apakan akọkọ ti alakojo C deede, eyiti a ṣe atunṣe nigbamii fun JIT. Nitorinaa, fun apẹẹrẹ, faaji ibi-afẹde ni awọn ofin ti iwe yii kii ṣe faaji alejo mọ, ṣugbọn faaji agbalejo. Ni aaye kan, paati miiran han - Tiny Code Interpreter (TCI), eyiti o yẹ ki o ṣiṣẹ koodu (fere awọn iṣẹ inu inu kanna) ni isansa ti olupilẹṣẹ koodu kan fun faaji ogun kan pato. Ni otitọ, bi awọn iwe-ipamọ rẹ ṣe sọ, onitumọ yii le ma ṣe nigbagbogbo daradara bi olupilẹṣẹ koodu JIT, kii ṣe ni iwọn nikan ni awọn ofin iyara, ṣugbọn tun ni agbara. Botilẹjẹpe Emi ko ni idaniloju pe apejuwe rẹ jẹ pataki patapata.

Ni akọkọ Mo gbiyanju lati ṣe ẹhin TCG ti o ni kikun, ṣugbọn yarayara ni idamu ninu koodu orisun ati pe ko ṣe alaye pipe ti awọn ilana bytecode, nitorinaa Mo pinnu lati fi ipari si onitumọ TCI naa. Eyi fun ọpọlọpọ awọn anfani:

  • nigbati o ba n ṣe olupilẹṣẹ koodu, o le wo kii ṣe apejuwe awọn ilana, ṣugbọn ni koodu onitumọ
  • o le ṣe awọn iṣẹ ṣiṣe kii ṣe fun gbogbo idinamọ itumọ ti o ba pade, ṣugbọn, fun apẹẹrẹ, nikan lẹhin ipaniyan ọgọrun
  • ti koodu ti ipilẹṣẹ ba yipada (ati pe eyi dabi pe o ṣee ṣe, ṣiṣe idajọ nipasẹ awọn iṣẹ pẹlu awọn orukọ ti o ni ọrọ patch), Emi yoo nilo lati sọ koodu JS ti ipilẹṣẹ, ṣugbọn o kere ju Emi yoo ni nkankan lati tunse rẹ lati.

Nipa aaye kẹta, Emi ko ni idaniloju pe patching ṣee ṣe lẹhin ti koodu ti ṣiṣẹ fun igba akọkọ, ṣugbọn awọn aaye meji akọkọ ti to.

Ni ibẹrẹ, koodu naa ti ipilẹṣẹ ni irisi iyipada nla ni adirẹsi ti itọnisọna bytecode atilẹba, ṣugbọn lẹhinna, ni iranti nkan nipa Emscripten, iṣapeye ti JS ti ipilẹṣẹ ati ṣiṣatunṣe, Mo pinnu lati ṣe agbekalẹ koodu eniyan diẹ sii, paapaa niwọn igba ti o ni agbara. wa jade pe aaye titẹsi kanṣoṣo sinu bulọọki itumọ ni Ibẹrẹ rẹ. Ko pẹ ju wi ti o ti ṣe, lẹhin igba diẹ a ni olupilẹṣẹ koodu ti ipilẹṣẹ koodu pẹlu ifs (botilẹjẹpe laisi awọn iyipo). Ṣugbọn orire buburu, o ṣubu, fifun ifiranṣẹ kan pe awọn itọnisọna jẹ diẹ ninu awọn ipari ti ko tọ. Jubẹlọ, awọn ti o kẹhin ilana ni yi recursion ipele wà brcond. O dara, Emi yoo ṣafikun ayẹwo kanna si iran ti itọnisọna yii ṣaaju ati lẹhin ipe loorekoore ati… ko si ọkan ninu wọn ti a ṣe, ṣugbọn lẹhin iyipada assert wọn tun kuna. Ni ipari, lẹhin ikẹkọ koodu ti ipilẹṣẹ, Mo rii pe lẹhin iyipada, itọka si itọnisọna lọwọlọwọ ti tun gbejade lati akopọ ati pe o ṣee ṣe atunkọ nipasẹ koodu JavaScript ti ipilẹṣẹ. Ati ki o wa ni jade. Alekun ifipamọ lati megabyte kan si mẹwa ko yorisi ohunkohun, ati pe o han gbangba pe olupilẹṣẹ koodu nṣiṣẹ ni awọn iyika. A ni lati ṣayẹwo pe a ko kọja awọn aala ti TB lọwọlọwọ, ati pe ti a ba ṣe, lẹhinna gbe adirẹsi ti TB ti o tẹle pẹlu ami iyokuro ki a le tẹsiwaju ipaniyan. Ni afikun, eyi yanju iṣoro naa “awọn iṣẹ ṣiṣe ti o yẹ ki o bajẹ ti nkan baiti koodu yii ba ti yipada?” — nikan ni iṣẹ ti o ni ibamu si idinamọ itumọ nilo lati jẹ asan. Nipa ọna, botilẹjẹpe Mo ṣatunṣe ohun gbogbo ni Chromium (niwọn igba ti Mo lo Firefox ati pe o rọrun fun mi lati lo ẹrọ aṣawakiri ọtọtọ fun awọn idanwo), Firefox ṣe iranlọwọ fun mi lati ṣatunṣe awọn aiṣedeede pẹlu boṣewa asm.js, lẹhin eyi koodu bẹrẹ lati ṣiṣẹ ni iyara ni Chromium.

Apẹẹrẹ koodu ti ipilẹṣẹ

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"]

ipari

Nitorinaa, iṣẹ naa ko ti pari, ṣugbọn o rẹ mi lati mu ikole igba pipẹ yii ni ikoko si pipe. Nitorinaa, Mo pinnu lati gbejade ohun ti Mo ni fun bayi. Koodu naa jẹ ẹru diẹ ni awọn aaye, nitori eyi jẹ idanwo, ati pe ko han tẹlẹ ohun ti o nilo lati ṣe. Boya, lẹhinna o tọ lati fun awọn iṣẹ atomiki deede lori oke diẹ ninu ẹya tuntun ti Qemu. Ni akoko yii, o tẹle ara ni Gita ni ọna kika bulọọgi: fun "ipele" kọọkan ti o kere ju ni ọna kan ti o ti kọja, asọye alaye ni Russian ti ni afikun. Lootọ, nkan yii jẹ si iwọn nla kan titumọ ipari ipari git log.

O le gbiyanju gbogbo rẹ nibi (ṣọra fun ijabọ).

Ohun ti n ṣiṣẹ tẹlẹ:

  • x86 foju isise nṣiṣẹ
  • Afọwọkọ iṣẹ kan wa ti olupilẹṣẹ koodu JIT lati koodu ẹrọ si JavaScript
  • Awoṣe kan wa fun apejọ awọn ile ayaworan alejo 32-bit miiran: ni bayi o le ṣe ẹwà Linux fun didi faaji MIPS ninu ẹrọ aṣawakiri ni ipele ikojọpọ

Kini ohun miiran ti o le ṣe

  • Iyara emulation. Paapaa ni ipo JIT o dabi pe o nṣiṣẹ losokepupo ju Foju x86 (ṣugbọn o ṣee ṣe pe odidi Qemu wa pẹlu ọpọlọpọ ohun elo ti a farawe ati awọn ayaworan)
  • Lati ṣe ni wiwo deede - ni otitọ, Emi kii ṣe olupilẹṣẹ wẹẹbu to dara, nitorinaa ni bayi Mo ti tun ṣe ikarahun Emscripten boṣewa bi o ti dara julọ ti MO le
  • Gbiyanju lati ṣe ifilọlẹ awọn iṣẹ Qemu eka diẹ sii - netiwọki, ijira VM, ati bẹbẹ lọ.
  • Imudojuiwọn: iwọ yoo nilo lati fi awọn idagbasoke diẹ rẹ silẹ ati awọn ijabọ kokoro si Emscripten ni oke, gẹgẹ bi awọn adèna tẹlẹ ti Qemu ati awọn iṣẹ akanṣe miiran ti ṣe. O ṣeun si wọn fun ni anfani lati lo ipalọlọ wọn si Emscripten gẹgẹbi apakan ti iṣẹ-ṣiṣe mi.

orisun: www.habr.com

Fi ọrọìwòye kun