Qemu.js nwere nkwado JIT: nri ka nwere ike ịlaghachi azụ

Afọ ole na ole gara aga Fabrice Bellard nke jslinux dere bụ emulator PC nke edere na Javascript. Mgbe nke ahụ gasịrị, e nwere ma ọ dịkarịa ala ọzọ Virtual x86. Mana ha niile, dịka m maara, bụ ndị ntụgharị okwu, ebe Qemu, nke otu Fabrice Bellard dere na mbụ, ma eleghị anya, emulator ọgbara ọhụrụ ọ bụla na-asọpụrụ onwe ya, na-eji JIT nchịkọta nke koodu ndị ọbịa n'ime koodu sistemụ nnabata. Ọ dị m ka ọ bụ oge iji mejuputa ọrụ dị iche n'ihe metụtara nke ihe nchọgharị na-edozi: Nchikota koodu igwe n'ime Javascript, nke ọ dị ka ihe ezi uche dị na ya na ọdụ ụgbọ mmiri Qemu. Ọ ga-adị ka, gịnị kpatara Qemu, e nwere emulators dị mfe na enyi na enyi - otu VirtualBox, dịka ọmụmaatụ - arụnyere ma rụọ ọrụ. Mana Qemu nwere ọtụtụ njiri mara mma

  • isi mmalite
  • ike ịrụ ọrụ na-enweghị onye ọkwọ ụgbọ ala kernel
  • ike ịrụ ọrụ na ọnọdụ ntụgharị okwu
  • nkwado maka ọnụ ọgụgụ buru ibu nke ma ụlọ ọrụ ndị ọbịa na ndị ọbịa

Banyere isi ihe nke atọ, enwere m ike ịkọwa ugbu a na n'eziokwu, na ọnọdụ TCI, ọ bụghị ntuziaka igwe ndị ọbịa ka a na-atụgharị n'onwe ha, mana bytecode enwetara n'aka ha, mana nke a anaghị agbanwe ihe bụ isi - iji wuo ma na-agba ọsọ. Qemu na a ọhụrụ architecture, ma ọ bụrụ na ị na-enwe chioma, A C compiler ezuru - ide a code generator nwere ike yigharịrị.

Ma ugbu a, mgbe afọ abụọ nke oge ntụrụndụ na koodu Qemu gachara n'oge efu m, apụtala ụdị ọrụ, nke ị nwere ike ịgba ọsọ, dịka ọmụmaatụ, Kolibri OS.

Kedu ihe bụ Emscripten

N'oge a, ọtụtụ ndị nchịkọta apụtala, njedebe ya bụ Javascript. Ụfọdụ, dị ka Ụdị Script, bu ụzọ bu ụzọ bụrụ ụzọ kacha mma isi dee maka webụ. N'otu oge ahụ, Emscripten bụ ụzọ isi were koodu C ma ọ bụ C++ dị adị wee chịkọta ya n'ụdị enwere ike ịgụ ihe nchọgharị. Gbanye nke a Anyị anakọtara ọtụtụ ọdụ ụgbọ mmiri nke mmemme ama ama: ebe aDịka ọmụmaatụ, ị nwere ike ilele PyPy - n'ụzọ, ha na-ekwu na ha enweelarị JIT. N'ezie, ọ bụghị mmemme ọ bụla nwere ike ịchịkọta ma na-agba ọsọ na ihe nchọgharị - enwere ọnụọgụ atụmatụ, nke ị ga-anagide, Otú ọ dị, dị ka ihe odide ahụ dị n’otu peeji ahụ na-ekwu “Emscripten pụrụ iji chịkọta ihe fọrọ nke nta ka ọ bụrụ nke ọ bụla. obere C/C++ code na JavaScript." Ya bụ, e nwere ọtụtụ ọrụ ndị na-akọwapụtaghị omume dị ka ọkọlọtọ, ma na-emekarị na-arụ ọrụ na x86 - dị ka ihe atụ, unaligned ohere variables, nke a na-amachibidoro na ụfọdụ architectures. , Qemu bụ usoro ihe omume cross-platform na , Achọrọ m ikwere, ma ọ nwebeghị ọtụtụ àgwà a na-akọwaghị - were ya ma chịkọta, wee tinker ntakịrị na JIT - ma ị mechara! ikpe...

Buru ụzọ nwaa

N'ikwu okwu n'ozuzu, abụghị m onye mbụ chepụtara echiche nke ibubata Qemu na Javascript. Enwere ajụjụ a jụrụ na nnọkọ ReactOS ma ọ bụrụ na nke a ga-ekwe omume iji Emscripten. Ọbụna na mbụ, e nwere asịrị na Fabrice Bellard mere nke a n'onwe ya, ma anyị na-ekwu banyere jslinux, nke, dị ka m maara, bụ nanị mgbalị iji aka iji aka rụọ ọrụ zuru oke na JS, ma dee ya site na ọkọ. Mgbe e mesịrị, e dere Virtual x86 - e biputere isi mmalite ndị na-enweghị isi, na, dị ka ekwuru, nnukwu "ezigbo" nke nṅomi mere ka o kwe omume iji SeaBIOS dị ka ngwa ngwa. Na mgbakwunye, enwere opekata mpe otu mbọ iji Emscripten webata Qemu - m nwara ime nke a socketpair, mana mmepe, dị ka m ghọtara, jụrụ oyi.

Yabụ, ọ ga - adị ka ebe a bụ isi mmalite, nke a bụ Emscripten - were ya ma chịkọta. Mana enwerekwa ọba akwụkwọ ndị Qemu dabere na ya, na ọba akwụkwọ ndị ụlọ akwụkwọ ndị ahụ dabere, wdg, otu n'ime ha bụ. libffi, nke glib dabere na. E nwere asịrị na ịntanetị na e nwere otu n'ime nnukwu nchịkọta ọdụ ụgbọ mmiri nke Emscripten, ma ọ siri ike ikwere n'ụzọ ụfọdụ: nke mbụ, e bughị n'obi ka ọ bụrụ onye nchịkọta ọhụrụ, nke abụọ, ọ dị oke ala. Ọbá akwụkwọ ka ị bulie, ma chịkọta na JS. Ma ọ bụghị naanị ihe ntinye mgbakọ - eleghị anya, ọ bụrụ na ị na-atụgharị ya, maka ụfọdụ mgbakọ na-akpọ òkù ị nwere ike ịmepụta arụmụka dị mkpa na nchịkọta ma kpọọ ọrụ ahụ na-enweghị ha. Mana Emscripten bụ ihe dị aghụghọ: iji mee ka koodu emepụtara yie ihe nchọgharị JS engine optimizer nke ọma, a na-eji aghụghọ ụfọdụ. Karịsịa, ihe a na-akpọ relooping - onye na-emepụta koodu na-eji LLVM IR enwetara ya na ụfọdụ ntuziaka mgbanwe na-adịghị ahụkebe na-anwa imepụtaghachi ifs, loops, wdg. Ọfọn, kedu ka esi agafe arụmụka na ọrụ ahụ? Dị ka o kwesịrị ịdị, dị ka arụmụka na ọrụ JS, ya bụ, ọ bụrụ na ọ ga-ekwe omume, ọ bụghị site na nchịkọta.

Na mbido enwere echiche iji dee nnọchi maka libffi na JS wee mee ule ọkọlọtọ, mana n'ikpeazụ enwere m mgbagwoju anya etu esi eme faịlụ nkụnye m ka ha wee rụọ ọrụ na koodu dị - gịnị ka m ga-eme, dị ka ha na-ekwu, "Ọrụ ndị dị mgbagwoju anya" Ànyị bụ ndị nzuzu?" Ekwesịrị m ibubata libffi gaa na ihe owuwu ọzọ, dị ka a pụrụ isi kwuo ya - ọ dabara nke ọma, Emscripten nwere ma macro maka mgbakọ inline (na Javascript, ee - nke ọma, ihe ọ bụla ụlọ ọrụ ahụ, yabụ onye na-agbakọta), yana ikike ịme koodu emepụtara na ofufe. N'ozuzu, mgbe ijiri iberibe libffi dabere n'elu ikpo okwu ruo oge ụfọdụ, enwetara m ụfọdụ koodu agbakọtara wee gbaa ya na ule mbụ m nwetara. O juru m anya na ule ahụ gara nke ọma. Iju anya site na ọgụgụ isi m - enweghị egwuregwu, ọ na-arụ ọrụ site na mmalite mbụ - M, ka na-ekwenyeghị na anya m, gara leba anya na koodu ahụ pụtakwara ọzọ, iji nyochaa ebe m ga-egwu ala ọzọ. N'ebe a, agara m mkpụrụ nke ugboro abụọ - naanị ihe ọrụ m mere bụ ffi_call - nke a kọrọ oku na-aga nke ọma. Enweghị oku n'onwe ya. Ya mere, ezigara m arịrịọ m ịdọrọ nke mbụ, nke deziri njehie na ule nke doro anya na nwa akwụkwọ Olympiad ọ bụla - ọnụ ọgụgụ dị adị ekwesịghị iji tụnyere. a == b na ọbụna otú a - b < EPS - ịkwesịrị icheta modul ahụ, ma ọ bụghị ya, 0 ga-apụta na 1/3 nke ukwuu ... N'ozuzu, abịara m na ọdụ ụgbọ mmiri libffi, nke na-agafe ule kachasị mfe, na nke glib bụ. chịkọtara - M kpebiri na ọ ga-adị mkpa, m ga-agbakwunye ya ma emechaa. Na-ele anya n'ihu, m ga-ekwu na, dị ka ọ tụgharịrị, onye nchịkọta anaghị agụnye ọrụ libffi na koodu ikpeazụ.

Ma, dị ka m na-ekwu, e nwere ụfọdụ adịghị ike, na n'etiti free ojiji nke dị iche iche na-akọwaghị omume, a ọzọ wetara mma e zoro - Javascript site imewe adịghị akwado multithreading na òkè ebe nchekwa. N'ụkpụrụ, nke a nwere ike na-akpọkarị ezi echiche, mana ọ bụghị maka koodu ọdụ ụgbọ mmiri nke ejikọtara ụkpụrụ ya na eriri C. N'ikwu okwu n'ozuzu, Firefox na-anwale ịkwado ndị ọrụ na-ekekọrịta, na Emscripten nwere mmejuputa pthread maka ha, mana achọghị m ịdabere na ya. M ga-eji nwayọọ nwayọọ wepụ multithreading na Qemu code - ya bụ, chọpụta ebe eri na-agba ọsọ, bugharịa ahụ nke loop na-agba ọsọ na eri a n'ime ọrụ dị iche iche, na-akpọ ọrụ ndị dị otú ahụ otu otu site na isi loop.

Gbalịa ugboro abụọ

N'oge ụfọdụ, ọ bịara doo anya na nsogbu ahụ ka dị, na ịkwanye crutches gburugburu koodu ahụ n'ụzọ na-adịghị mma agaghị ebute ihe ọma ọ bụla. Mmechi: anyị kwesịrị n'ụzọ ụfọdụ systematize usoro nke na-agbakwụnye crutches. Ya mere, mbipute 2.4.1, nke dị ọhụrụ n'oge ahụ, e weere (ọ bụghị 2.5.0, n'ihi na, ị maghị, a ga-enwe chinchi na ọhụrụ version nke na-nwebeghị, na m na-ezuru nke m. ahụhụ), na ihe mbụ m mere bụ idegharị ya n'enweghị nsogbu thread-posix.c. Ọfọn, ya bụ, dị ka nchekwa: ọ bụrụ na mmadụ gbalịrị ịrụ ọrụ na-eduga na igbochi, a na-akpọ ọrụ ahụ ozugbo abort() - N'ezie, nke a ewepụghị nsogbu niile n'otu oge, ma ọ dịkarịa ala, ọ bụ ihe na-atọ ụtọ karịa iji nwayọọ na-enweta data na-ekwekọghị ekwekọ.

N'ozuzu, nhọrọ Emscripten na-enye aka nke ukwuu n'ịkwanye koodu na JS -s ASSERTIONS=1 -s SAFE_HEAP=1 - ha na-ejide ụfọdụ ụdị omume a na-akọwaghị, dị ka oku na-aga na adreesị na-edoghị anya (nke na-adabaghị na koodu maka ụdị ederede dị ka. HEAP32[addr >> 2] = 1) ma ọ bụ na-akpọ ọrụ na nọmba arụmụka na-ezighi ezi.

Site n'ụzọ, njehie nhazi bụ okwu dị iche. Dị ka m kwuru na mbụ, Qemu nwere ihe ndabere ntụgharị okwu "degenerate" maka koodu ọgbọ TCI (obere onye ntụgharị okwu), na iji wuo ma na-agba ọsọ Qemu na ụlọ ọhụrụ, ọ bụrụ na ị nwere ihu ọma, onye nchịkọta C zuru ezu. Keywords "Ọ bụrụ na ị nwere chioma". Enwere m ihe ndabara, ma ọ tụgharịrị na TCI na-eji ohere enweghị nkwekọrịta mgbe ọ na-atụgharị bytecode ya. Nke ahụ bụ, n'ụdị ARM niile na ụlọ ọrụ ndị ọzọ nwere ohere dị larịị, Qemu na-achịkọta n'ihi na ha nwere azụ azụ TCG nkịtị nke na-ewepụta koodu obodo, mana TCI ọ ga-arụ ọrụ na ha bụ ajụjụ ọzọ. Otú ọ dị, dị ka ọ tụgharịrị, akwụkwọ TCI gosipụtara n'ụzọ doro anya ihe yiri ya. N'ihi nke a, etinyere oku ọrụ maka ịgụ ihe na-edoghị anya na koodu ahụ, nke achọtara n'akụkụ ọzọ nke Qemu.

Nbibi nke obo

N'ihi ya, a na-edozi ohere na-enweghị njikọ na TCI, e kere isi loop nke a na-akpọkwa processor, RCU na ụfọdụ obere ihe ndị ọzọ. Ya mere, m ji nhọrọ ahụ malite Qemu -d exec,in_asm,out_asm, nke pụtara na ịkwesịrị ikwu nke blocks nke koodu na-egbu, nakwa n'oge mgbasa ozi iji dee ihe ọbịa koodu bụ, ihe host code ghọrọ (na nke a, bytecode). Ọ na-amalite, na-eme ọtụtụ ngọngọ ntụgharị, dee ozi nbibi m hapụrụ na RCU ga-amalite ugbu a na... daa. abort() n'ime a ọrụ free(). Site na itinye aka na ọrụ ahụ free() Anyị jisiri ike chọpụta na na nkụnye eji isi mee nke ikpo okwu, nke dị na asatọ bytes na-ebute ebe nchekwa ekenyela, kama nha ngọngọ ma ọ bụ ihe yiri ya, e nwere ihe mkpofu.

Nbibi nke ikpo okwu - otú mara mma ... N'ọnọdụ dị otú ahụ, e nwere ọgwụgwọ bara uru - site na (ma ọ bụrụ na ọ ga-ekwe omume) otu isi mmalite, kpọkọta ọnụọgụ abụọ nke ala ma mee ya n'okpuru Valgrind. Mgbe oge ụfọdụ gasịrị, ọnụọgụ abụọ dị njikere. M na-eji otu nhọrọ ahụ malite ya - ọ na-akụda ọbụna n'oge mmalite, tupu ya eruo n'ezie. Ọ bụ ihe na-adịghị mma, n'ezie - o doro anya na isi mmalite abụghị otu, nke na-abụghị ihe ijuanya, n'ihi na configured scouted si dịtụ iche nhọrọ, ma m nwere Valgrind - mbụ m ga-edozi ahụhụ a, na mgbe ahụ, ọ bụrụ na m nwere chioma. , nke mbụ ga-apụta. M na-agba otu ihe ahụ n'okpuru Valgrind ... Y-y-y, y-y-y, uh-uh, ọ malitere, na-aga site na mmalite na-emekarị ma gaa n'ihu na mbụ ahụhụ na-enweghị otu ịdọ aka ná ntị banyere ịnweta ebe nchekwa na-ezighi ezi, ọ bụghị ikwu banyere ọdịda. Ndụ, dị ka ha na-ekwu, akwadebeghị m maka nke a - a mkpọka mmemme na-akwụsị mkpọka mgbe a malitere n'okpuru Walgrind. Ihe ọ bụ ihe omimi. Echiche m bụ na n'otu oge na nso ntụziaka ugbu a mgbe mkpọka kwụsịrị n'oge mmalite, gdb gosipụtara ọrụ. memset-a nwere ezigbo pointer na-eji nke ọ bụla mmx, ma ọ bụ xmm na-edebanye aha, mgbe ahụ ikekwe ọ bụ ụdị njehie nhazi, ọ bụ ezie na ọ ka siri ike ikwere.

Ọ dị mma, Valgrind eyighị ka ọ na-enyere aka ebe a. Na ebe a bụ ihe kasị asọ oyi malitere - ihe niile yiri ọbụna na-amalite, ma mkpọka n'ihi na nnọọ amaghị ihe mere n'ihi ihe omume nke nwere ike mere ọtụtụ nde ntụziaka gara aga. Ruo ogologo oge, o dochaghị anya otú e si agakwuru. N'ikpeazụ, m ka ga-anọdụ ala megharịa. Ibipụta ihe eji edegharị nkụnye eji isi mee ihe gosiri na ọ dịghị ka ọnụọgụgụ, kama ọ bụ ụdị data ọnụọgụ abụọ. Ma, lee, a chọtara eriri ọnụọgụ abụọ a na faịlụ BIOS - ya bụ, ugbu a, ọ ga-ekwe omume iji obi ike kwuo na ọ bụ ihe na-ekpuchi ihe na-ekpuchi ya, ma o doro anya na e dere ya na nke a. Ọfọn, mgbe ahụ ihe dị ka nke a - na Emscripten, ọ dabara nke ọma, ọ dịghị randomization nke adreesị ohere, ọ dịghị oghere na ya ma, otú i nwere ike dee ebe n'etiti koodu ka mmepụta data site pointer si ikpeazụ igba egbe, lee na data, lee pointer, na, ọ bụrụ na ọ agbanwebeghị, nweta nri maka echiche. N'ezie, ọ na-ewe nkeji ole na ole iji jikọta mgbe mgbanwe ọ bụla gasịrị, ma gịnị ka ị ga-eme? N'ihi ya, a chọtara otu ahịrị nke depụtaghachiri BIOS site na nchekwa nwa oge na ebe nchekwa ndị ọbịa - na, n'ezie, enweghị ohere zuru ezu na nchekwa. Ịchọta isi iyi nke adreesị nchekwa ahụ arụpụtala ọrụ qemu_anon_ram_alloc na faịlụ oslib-posix.c - mgbagha enwere nke a: mgbe ụfọdụ ọ nwere ike ịba uru itinye adreesị ahụ na ibe buru ibu nke 2 MB n'ogo, maka nke a, anyị ga-ajụ. mmap mbụ ntakịrị ntakịrị, mgbe ahụ, anyị ga-eweghachi ngafe site n'enyemaka munmap. Ma ọ bụrụ na ọ dịghị mkpa itinye n'ọnọdụ dị otú ahụ, mgbe ahụ, anyị ga-egosi na ya pụta kama 2 MB getpagesize() - mmap ọ ka ga-enye adreesị ahaziri ahazi... Ya mere na Emscripten mmap naanị ịkpọ malloc, ma n'ezie ọ naghị adaba na ibe. N'ozuzu, otu ahụhụ nke kpasuru m iwe ruo ọnwa ole na ole ka e meziri site na mgbanwe nri ahịrị.

Akụkụ nke ọrụ ịkpọ oku

Ma ugbu a, onye nrụpụta na-agụta ihe, Qemu anaghị ada ada, mana ihuenyo anaghị agbanye, na processor na-abanye ngwa ngwa n'ime loops, na-ekpe ikpe site na mmepụta. -d exec,in_asm,out_asm. Echiche apụtala: nkwụsị oge (ma ọ bụ, n'ozuzu, nkwụsịtụ niile) anaghị abata. Ma n'ezie, ọ bụrụ na ị kpọghee ihe nkwụsịtụ site na mgbakọ obodo, nke na-arụ ọrụ n'ihi ihe ụfọdụ, ị ga-enweta foto yiri ya. Mana nke a abụghị azịza ma ọlị: ntụle nke akara ndị e nyere na nhọrọ a dị n'elu gosiri na ụzọ ogbugbu ahụ dị iche n'oge. N'ebe a, a ghaghị ikwu na atụnyere ihe e dekọrọ site na iji ihe mmalite emrun nrụpụta nrụpụta na mmepụta nke mgbakọ obodo abụghị usoro nrụzi kpamkpam. Amaghị m kpọmkwem ka mmemme na-agba ọsọ na ihe nchọgharị si ejikọta emrun, ma ụfọdụ ahịrị dị na mmepụta na-emezigharị, ya mere, ọdịiche dị na ọdịiche ahụ abụbeghị ihe kpatara iche na trajectories agbawawo. N'ozuzu, ọ bịara doo anya na dịka ntuziaka ahụ si dị ljmpl enwere mgbanwe na adreesị dị iche iche, na bytecode emepụtara dị iche iche: otu nwere ntuziaka iji kpọọ ọrụ enyemaka, nke ọzọ adịghị. Mgbe emechara ntuziaka ahụ ma mụọ koodu nke sụgharịrị ntuziaka ndị a, ọ bịara doo anya na, nke mbụ, ozugbo tupu ya na ndekọ aha. cr0 Emere ndekọ - na-ejikwa onye inyeaka - nke gbanwere processor ka ọ bụrụ ọnọdụ echedoro, na nke abụọ, na ụdị js agbanwebeghị na ọnọdụ echedoro. Mana nke bụ eziokwu bụ na akụkụ ọzọ nke Emscripten bụ enweghị mmasị ịnabata koodu dịka mmejuputa ntuziaka. call na TCI, nke nrịbama ọrụ ọ bụla na-arụpụta ụdị long long f(int arg0, .. int arg9) -A ga-akpọrịrị ọrụ na ọnụọgụ arụmụka ziri ezi. Ọ bụrụ na emebi iwu a, dabere na ntọala ntọhapụ, mmemme ahụ ga-adaba (nke dị mma) ma ọ bụ kpọọ ọrụ na-ezighi ezi ma ọlị (nke ga-abụ ihe nwute na debug). Enwekwara nhọrọ nke atọ - mee ka ọgbọ nke ndị na-ekpuchi ihe na-agbakwụnye / wepụ esemokwu, ma na mkpokọta ndị a na-ekpuchi ihe na-ewe ọtụtụ ohere, n'agbanyeghị na n'eziokwu m chọrọ naanị ntakịrị ihe karịrị otu narị wrappers. Naanị nke a dị nnọọ mwute, ma e mesịrị bụrụ nsogbu dị njọ karị: na koodu emepụtara nke ọrụ wrapper, a gbanwere arụmụka ma gbanwee, ma mgbe ụfọdụ, a naghị akpọ ọrụ na arụmụka ndị a na-emepụta - nke ọma, dị ka na. mmejuputa libffi m. Ya bụ, e gbughị ụfọdụ ndị enyemaka.

Ọ dabara nke ọma, Qemu nwere ndepụta ndị enyemaka nwere ike ịgụta n'ụdị faịlụ nkụnye eji isi mee dịka

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

A na-eji ha eme ihe na-atọ ọchị: nke mbụ, a na-akọwapụta macros n'ụzọ kachasị njọ DEF_HELPER_n, wee gbanye helper.h. Ruo n'ókè nke na-agbasa macro n'ime ihe nhazi ihe nhazi na rịkọm, mgbe ahụ, a na-akọwa usoro, na kama ihe - #include <helper.h> N'ihi ya, emechara m nwee ohere ịnwale ọbá akwụkwọ na-arụ ọrụ pyparsing, na e dere script na-ewepụta kpọmkwem ihe wrappers maka kpọmkwem ọrụ ndị dị ha mkpa.

Ya mere, mgbe ahụ processor yiri ka ọ na-arụ ọrụ. Ọ dị ka ọ bụ n'ihi na ebidobeghị ihuenyo ahụ, ọ bụ ezie na memtest86+ nwere ike ịgba ọsọ na mgbakọ obodo. N'ebe a, ọ dị mkpa ịkọwapụta na edere koodu I/O nke Qemu na coroutines. Emscripten nwere mmejuputa aghụghọ nke ya, mana ọ ka dị mkpa ka akwado ya na koodu Qemu, ma ị nwere ike mebie processor ugbu a: Qemu na-akwado nhọrọ. -kernel, -initrd, -append, nke ị nwere ike buo Linux ma ọ bụ, dịka ọmụmaatụ, memtest86+, na-ejighi ngwaọrụ ngọngọ ma ọlị. Mana nke a bụ nsogbu ahụ: na mgbakọ obodo mmadụ nwere ike ịhụ mmepụta kernel Linux na njikwa na nhọrọ -nographic, na enweghị mmepụta site na ihe nchọgharị ahụ gaa na njedebe site na ebe ewepụtara ya emrun, ọ bịaghị. Ya bụ, ọ bụghị ihe doro anya: processor anaghị arụ ọrụ ma ọ bụ mmepụta eserese anaghị arụ ọrụ. O wee ruo m ka m chere ntakịrị. Ọ tụgharịrị na "processor anaghị ehi ụra, kama ọ na-eji nwayọọ nwayọọ na-egbu maramara," mgbe ihe dị ka nkeji ise gachara, kernel tụbara ụyọkọ ozi na console wee gaa n'ihu kwụgidere. Ọ bịara doo anya na processor, n'ozuzu, na-arụ ọrụ, na anyị kwesịrị igwu n'ime koodu maka ịrụ ọrụ na SDL2. O di nwute, amaghi m ka esi eji oba akwukwo a, ya mere n'ebe ufodu ana m eme ihe n'adighi nma. N'oge ụfọdụ, ahịrị parallel0 na-egbuke egbuke na ihuenyo na-acha anụnụ anụnụ, nke na-atụ aro ụfọdụ echiche. N'ikpeazụ, ọ tụgharịrị na nsogbu ahụ bụ na Qemu na-emepe ọtụtụ windo mebere n'otu windo anụ ahụ, n'etiti nke ị nwere ike ịgbanwe site na iji Ctrl-Alt-n: ọ na-arụ ọrụ n'ime ụlọ, ma ọ bụghị na Emscripten. Mgbe ewepụsịrị windo na-enweghị isi na-eji nhọrọ -monitor none -parallel none -serial none na ntuziaka ka ike megharịa ihuenyo dum na etiti ọ bụla, ihe niile na-arụ ọrụ na mberede.

Coroutines

Ya mere, iṅomi na ihe nchọgharị ahụ na-arụ ọrụ, ma ị nweghị ike ịme ihe ọ bụla na-adọrọ mmasị na otu-floppy n'ime ya, n'ihi na ọ dịghị ngọngọ I / O - ịkwesịrị ịme nkwado maka coroutines. Qemu enweelarị ọtụtụ coroutine backends, mana n'ihi ọdịdị Javascript na onye na-emepụta koodu Emscripten, ị nweghị ike ịmalite ikpokọta juggling. Ọ ga-adị ka "ihe niile agaala, a na-ewepụ plasta," ma ndị na-emepụta Emscripten elekọtaworị ihe niile. A na-emejuputa nke a nke ọma: ka anyị kpọọ oku ọrụ dị ka nke a na-enyo enyo emscripten_sleep na ọtụtụ ndị ọzọ na-eji usoro Asyncify, yana oku pointer na oku na-aga ọrụ ọ bụla ebe otu n'ime ikpe abụọ gara aga nwere ike ịdaba n'ihu n'ime nchịkọta. Ma ugbu a, tupu oku ọ bụla na-enyo enyo, anyị ga-ahọrọ ọnọdụ async, ozugbo oku a gachara, anyị ga-elele ma oku asynchronous mere, ma ọ bụrụ na ọ nwere, anyị ga-echekwa mgbanwe mpaghara niile na ọnọdụ async a, gosi ọrụ dị na ya. nyefee njikwa na mgbe anyị kwesịrị ịga n'ihu na-egbu , ma pụọ ​​​​na ọrụ dị ugbu a. Nke a bụ ebe enwere ohere maka ịmụ mmetụta na-emefusị ihe - maka mkpa nke na-aga n'ihu na koodu ogbugbu mgbe ọ lọghachiri site na oku asynchronous, onye nchịkọta ahụ na-emepụta "stubs" nke ọrụ na-amalite mgbe oku enyo enyo - dị ka nke a: ọ bụrụ na enwere oku na-enyo enyo, mgbe ahụ, ọrụ ahụ ga-agbasa ebe n / 2. ugboro - nke a ka dị, ma ọ bụrụ na ọ bụghị Buru n'uche na mgbe oku ọ bụla nwere ike ịmegharị, ịkwesịrị ịgbakwunye ichekwa ụfọdụ mgbanwe mpaghara na ọrụ mbụ. N'ikpeazụ, enwere m ọbụna ide ederede dị mfe na Python, bụ nke, dabere na ọrụ ndị a na-ejikarị eme ihe nke a na-eche na "anaghị ekwe ka asynchrony gafere n'onwe ha" (ya bụ, nkwalite nchịkọta na ihe niile m kọwapụtara adịghị eme ya. na-arụ ọrụ n'ime ha), na-egosi oku site na ntụnye aka nke ndị na-achịkọta kwesịrị ileghara ọrụ ndị a anya ka eweghara ọrụ ndị a ka asynchronous. Na mgbe ahụ, faịlụ JS n'okpuru 60 MB doro anya nke ukwuu - ka anyị kwuo ma ọ dịkarịa ala 30. Ọ bụ ezie na, ozugbo m na-edozi edemede mgbakọ, na-atụfu na mberede nhọrọ njikọ njikọ, n'ime ha bụ. -O3. Ana m agba koodu emepụtara, Chromium na-erikwa ebe nchekwa wee daa. M wee na mberede lere ihe ọ na-achọ ibudata... Ọfọn, gịnị ka m ga-ekwu, m gaara ajụkwa oyi ma ọ bụrụ na a gwara m ka m jiri nlezianya mụọ ihe ma kwalite 500+ MB Javascript.

Ọ dị nwute, akwụkwọ ndenye ego ndị dị na koodu ọba akwụkwọ nkwado Asyncify abụghị enyi na enyi longjmp-s na-eji na mebere processor code, ma mgbe a obere kwachie na-ewepụ ndị a ndenye ego na ike na-eweghachi ọnọdụ dị ka a ga-asị na ihe niile dị mma, koodu na-arụ ọrụ. Ma mgbe ahụ, ihe dị ịtụnanya malitere: mgbe ụfọdụ a na-eme nyocha na koodu mmekọrịta - otu ndị ahụ na-akụda koodu ahụ ma ọ bụrụ na, dị ka usoro ihe omume ahụ si dị, ekwesịrị igbochi ya - mmadụ gbalịrị ijide mutex ejidelarị. Ọ dabara nke ọma, nke a bịara bụrụ nsogbu ezi uche dị na ya na koodu serialized - naanị m na-eji arụ ọrụ isi loop nke Emscripten nyere, mana mgbe ụfọdụ oku asynchronous ga-ewepụ ngwugwu ahụ kpamkpam, n'oge ahụ ọ ga-ada. setTimeout site na isi loop - ya mere, koodu ahụ abanyela n'isi ntinye aka na-ahapụghị ọkwa gara aga. Degharịa na akaghị ngwụcha na emscripten_sleep, na nsogbu na mutexes kwụsịrị. Koodu ahụ aghọwo ihe ezi uche dị na ya - ka emechara, n'ezie, enweghị m koodu na-akwado etiti animation na-esote - onye nrụpụta na-agbakọ ihe na ihuenyo na-emelite kwa oge. Agbanyeghị, nsogbu ndị a akwụsịghị ebe ahụ: mgbe ụfọdụ ogbugbu Qemu ga-akwụsị n'obere nkịtị na-enweghị ihe ọ bụla ma ọ bụ mperi. N'oge ahụ, m kwụsịrị na ya, ma, na-ele anya n'ihu, m ga-ekwu na nsogbu bụ nke a: coroutine code, n'ezie, adịghị eji. setTimeout (ma ọ bụ ma ọ dịkarịa ala ọ bụghị mgbe niile ka ị nwere ike iche): ọrụ emscripten_yield na-edobe ọkọlọtọ oku na-emekọ ihe. Isi ihe niile bụ nke ahụ emscripten_coroutine_next abụghị ọrụ asynchronous: n'ime, ọ na-enyocha ọkọlọtọ, megharịa ya ma na-ebufe njikwa na ebe achọrọ ya. Ya bụ, nkwalite nke tojupụtara na-akwụsị n'ebe ahụ. Nsogbu bụ na n'ihi iji-mgbe-free, nke pụtara mgbe ọdọ mmiri coroutine nwere nkwarụ n'ihi na emeghị m akara dị mkpa nke koodu site na coroutine backend dị ugbu a, ọrụ ahụ. qemu_in_coroutine laghachiri ezi mgbe n'ezie ọ kwesịrị ịlaghachi ụgha. Nke a butere ịkpọ oku emscripten_yield, n'elu nke ọ dịghị onye nọ na tojupụtara emscripten_coroutine_next, nchịkọta ahụ kpọsara ruo n'elu, mana mba setTimeout, dị ka m kwuru na mbụ, egosighi.

Ọgbọ koodu Javascript

Ma ebe a, n'ezie, bụ nkwa ahụ e kwere ná nkwa “na-atụgharị anụ e gweriri azụ azụ.” Ọ bụchaghị. N'ezie, ọ bụrụ na anyị na-agba ọsọ Qemu na ihe nchọgharị, na Node.js na ya, mgbe ahụ, ndammana, mgbe koodu ọgbọ na Qemu anyị ga-esi kpamkpam na-ezighị ezi JavaScript. Ma ka, ụfọdụ ụdị mgbanwe mgbanwe.

Nke mbụ, ntakịrị gbasara ka Qemu si arụ ọrụ. Biko gbaghara m ozugbo: Abụghị m onye nrụpụta Qemu ọkachamara na nkwubi okwu m nwere ike ịmehie n'ebe ụfọdụ. Dị ka ha na-ekwu, "echiche nke nwa akwụkwọ ekwesịghị ikwekọ n'echiche nke onye nkụzi, Peano's axiomatics and common sense." Qemu nwere ọnụ ọgụgụ ụfọdụ nke ụlọ obibi ndị ọbịa na-akwado yana nke ọ bụla enwere ndekọ dịka target-i386. Mgbe ị na-ewu ụlọ, ị nwere ike ịkọwa nkwado maka ọtụtụ ụlọ ndị ọbịa, mana nsonaazụ ga-abụ naanị ọnụọgụ abụọ. Koodu na-akwado ụkpụrụ ụlọ ndị ọbịa, n'aka nke ya, na-ewepụta ụfọdụ arụmọrụ Qemu dị n'ime, nke TCG (Obere Code Generator) atụgharịlarị bụrụ koodu igwe maka ụlọ ọrụ nnabata. Dịka ekwuru na faịlụ readme dị na ndekọ tcg, nke a bụbu akụkụ nke mkpokọta C mgbe niile, bụ nke emeziri maka JIT. Ya mere, dịka ọmụmaatụ, ihe owuwu ebumnuche n'ihe gbasara akwụkwọ a abụghịzi ihe owuwu ndị ọbịa, kama ọ bụ ihe owuwu ndị ọbịa. N'oge ụfọdụ, akụkụ ọzọ pụtara - Tiny Code Interpreter (TCI), nke kwesịrị ime koodu (ihe fọrọ nke nta ka ọ bụrụ otu ọrụ dị n'ime ya) na enweghị onye na-emepụta koodu maka ụlọ ọrụ ụlọ ọrụ. N'ezie, dị ka akwụkwọ ya na-ekwu, onye ntụgharị okwu a nwere ike ọ gaghị arụ ọrụ mgbe niile yana onye na-emepụta koodu JIT, ọ bụghị naanị n'ụdị ọsọ, kamakwa n'ụzọ dị mma. Ọ bụ ezie na ejighị m n'aka na nkọwa ya dabara adaba kpamkpam.

Na mbụ, agbalịrị m ime ka azụ azụ TCG zuru oke, mana ọ gbagwojuru anya ngwa ngwa na koodu isi mmalite yana nkọwa zuru oke nke ntuziaka bytecode, yabụ ekpebiri m ịkechi onye ntụgharị okwu TCI. Nke a nyere ọtụtụ uru:

  • Mgbe ị na-emejuputa koodu generator, ị nwere ike ọ bụghị na nkọwa nke ntuziaka, kama na onye ntụgharị koodu
  • ị nwere ike ịmepụta ọrụ ọ bụghị maka ngọngọ ntụgharị asụsụ ọ bụla zutere, mana, dịka ọmụmaatụ, naanị mgbe mmegbu nke narị afọ gachara
  • Ọ bụrụ na koodu emepụtara gbanwere (nke a yiri ka ọ ga-ekwe omume, na-ekpe ikpe site na ọrụ ndị nwere aha nwere patch okwu), ọ ga-adị m mkpa imebi koodu JS emepụtara, ma ọ dịkarịa ala, m ga-enwe ihe m ga-emeghachi ya.

Banyere isi ihe nke atọ, ejighị m n'aka na patching ga-ekwe omume mgbe emechara koodu ahụ maka oge mbụ, mana isi ihe abụọ mbụ zuru ezu.

Na mbụ, a na-emepụta koodu ahụ n'ụdị nnukwu mgbanwe na adreesị nke ntụziaka bytecode mbụ, ma mgbe ahụ, na-echeta isiokwu banyere Emscripten, njikarịcha nke JS emepụtara na relooping, ekpebiri m ịmepụta ọtụtụ koodu mmadụ, karịsịa ebe ọ bụ na empirically. tụgharịrị na naanị ebe ntinye n'ime ngọngọ ntụgharị bụ mmalite ya. N'oge na-adịghị anya ka emechara, mgbe obere oge gasịrị, anyị nwere koodu generator nke na-emepụta koodu na ifs (n'agbanyeghị na-enweghị loops). Ma chi ọma, ọ dara, na-enye ozi na ntuziaka ndị ụfọdụ na-ezighị ezi ogologo. Ọzọkwa, ntụziaka ikpeazụ na ọkwa nlọghachi azụ a bụ brcond. Ọ dị mma, m ga-agbakwunye otu nlele na ọgbọ nke ntụziaka a tupu na mgbe oku na-aga n'ihu na ... ọ dịghị otu n'ime ha ka egburu, ma mgbe mgbanwe nkwenye ahụ gasịrị, ha ka dara. N'ikpeazụ, mgbe m mụsịrị koodu emepụtara, achọpụtara m na mgbe mgbanwe ahụ gasịrị, a na-ebughachi ihe nrịbama nke ntụziaka ugbu a site na nchịkọta ma eleghị anya na-edegharị ya site na koodu Javascript emepụtara. Ya mere ọ tụgharịrị. Ịbawanye ihe nchekwa site na otu megabyte ruo iri edugaghị na ihe ọ bụla, ọ bịara doo anya na code generator na-agba ọsọ na gburugburu. Anyị aghaghị ịchọpụta na anyị agabigaghị ókè TB dị ugbu a, ma ọ bụrụ na anyị mere ya, nyezie adreesị nke TB ọzọ na akara mwepu ka anyị wee nwee ike ịga n'ihu na-egbu. Na mgbakwunye, nke a na-edozi nsogbu ahụ "Olee ọrụ ewepụtara kwesịrị imebi ma ọ bụrụ na mpempe bytecode agbanweela?" - naanị ọrụ dabara na ngọngọ ntụgharị a ka a ga-emebi. Site n'ụzọ, ọ bụ ezie na m debugged ihe niile dị na Chromium (ebe ọ bụ na m na-eji Firefox ma ọ na-adịrị m mfe iji ihe nchọgharị dị iche maka nnwale), Firefox nyeere m aka mezie ndakọrịta na ọkọlọtọ asm.js, mgbe nke ahụ gasịrị koodu malitere ịrụ ọrụ ngwa ngwa na. Chromium.

Ọmụmaatụ nke koodu emepụtara

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

nkwubi

Ya mere, ọrụ ahụ ka agwụbeghị, mana ike agwụla m na nzuzo weta ihe owuwu ogologo oge a zuru oke. Ya mere, ekpebiri m ibipụta ihe m nwere ugbu a. Koodu ahụ dị ntakịrị egwu na ebe, n'ihi na nke a bụ nnwale, ọ bụghịkwa ihe doro anya n'ọdịnihu ihe kwesịrị ime. Eleghị anya, mgbe ahụ ọ bara uru ịnye mmemme atọmịk nkịtị n'elu ụdị Qemu ọgbara ọhụrụ. Ka ọ dị ugbu a, e nwere eriri na Gita na usoro blọgụ: maka "ọkwa" ọ bụla nke agafeela ma ọ dịkarịa ala, agbakwunyere nkọwa zuru ezu na Russian. N'ezie, isiokwu a bụ n'ụzọ dị ukwuu n'ịkọghachi nkwubi okwu ahụ git log.

Ị nwere ike ịnwale ya niile ebe a (kpachara anya maka okporo ụzọ).

Ihe na-arụ ọrụ ugbua:

  • x86 virtual processor na-agba ọsọ
  • Enwere ihe nlere nke na-arụ ọrụ nke koodu JIT site na koodu igwe gaa na Javascript
  • Enwere ndebiri maka ịchịkọta ụlọ ndị ọbịa 32-bit ndị ọzọ: ugbu a ị nwere ike ịmasị Linux maka ihe owuwu MIPS na-akụ oyi na ihe nchọgharị ahụ na ọkwa nbudata.

Kedu ihe ọzọ ị nwere ike ime

  • Mee emulation ngwa ngwa. Ọbụlagodi na ọnọdụ JIT ọ dị ka ọ na-agba ọsọ nwayọ karịa Virtual x86 (mana enwere ike Qemu dum nwere otutu ngwaike na ihe owuwu).
  • Iji mee interface nkịtị - n'eziokwu, abụghị m ezigbo onye nrụpụta weebụ, yabụ ugbu a emegharịrị m shei Emscripten ọkọlọtọ dịka m nwere ike.
  • Gbalịa ịmalite ọrụ Qemu dị mgbagwoju anya - ịkparịta ụka n'Ịntanet, Mbugharị VM, wdg.
  • Gbasie: ị ga-achọ ịnyefe mmepe ole na ole gị na akụkọ ahụhụ na Emscripten upstream, dị ka ndị na-ebu ụzọ Qemu na ọrụ ndị ọzọ mere. Daalụ maka inwe ike iji onyinye ha nyere Emscripten n'ezoghị ọnụ dịka akụkụ nke ọrụ m.

isi: www.habr.com

Tinye a comment