QEMU.js: kounye a grav ak WASM

Yon fwa sou yon tan mwen deside pou plezi pwouve reversibilite nan pwosesis la epi aprann kijan pou jenere JavaScript (plis jisteman, Asm.js) nan kòd machin. QEMU te chwazi pou eksperyans lan, epi kèk tan apre yo te ekri yon atik sou Habr. Nan kòmantè yo, mwen te konseye yo renouvle pwojè a nan WebAssembly, e menm kite tèt mwen prèske fini Mwen yon jan kanmenm pa t 'vle pwojè a ... Travay la te ale sou, men trè dousman, e kounye a, dènyèman nan atik sa a te parèt. kòmantè sou sijè a "Se konsa, ki jan tout bagay te fini?" An repons a repons detaye mwen an, mwen tande "Sa a son tankou yon atik." Oke, si ou kapab, pral gen yon atik. Petèt yon moun ap jwenn li itil. Soti nan li lektè a pral aprann kèk reyalite sou konsepsyon an nan backend jenerasyon kòd QEMU, osi byen ke kòman yo ekri yon du jis nan tan pou yon aplikasyon entènèt.

travay

Depi mwen te deja aprann ki jan yo "yon jan kanmenm" pò QEMU nan JavaScript, fwa sa a li te deside fè li avèk sajès epi yo pa repete ansyen erè.

Erè nimewo yon sèl: branch soti nan lage pwen

Premye erè mwen se te fouchèt vèsyon mwen an soti nan vèsyon an en 2.4.1. Lè sa a, li te sanble m 'yon bon lide: si lage pwen egziste, Lè sa a, li se pwobableman pi estab pase senp 2.4, e menm plis konsa branch lan. master. E depi mwen te planifye pou ajoute yon bon kantite pinèz pwòp mwen, mwen pa t 'bezwen okenn lòt moun nan ditou. Sa a se pwobableman ki jan li te tounen soti. Men, isit la nan bagay la: QEMU pa kanpe toujou, ak nan kèk pwen yo menm te anonse optimize nan kòd la pwodwi pa pousan 10. "Yeah, kounye a mwen pral friz," Mwen te panse ak kraze. Isit la nou bezwen fè yon digresyon: akòz nati yon sèl-threaded nan QEMU.js ak lefèt ke QEMU orijinal la pa vle di absans milti-threading (ki se, kapasite nan ansanm opere plizyè chemen kòd ki pa gen rapò, ak pa sèlman "itilize tout nwayo") se kritik pou li, fonksyon prensipal yo nan fil mwen te oblije "vire li soti" pou kapab rele soti deyò. Sa a te kreye kèk pwoblèm natirèl pandan fizyon an. Sepandan, lefèt ke kèk nan chanjman ki soti nan branch lan master, ak ki mwen te eseye rantre kòd mwen an, yo te tou Cherry te chwazi nan lage nan pwen (ak Se poutèt sa nan branch mwen an) tou pwobableman pa ta te ajoute konvenyans.

An jeneral, mwen te deside ke li toujou fè sans pou jete pwototip la, demonte li pou pati ak bati yon nouvo vèsyon grate ki baze sou yon bagay ki pi fre e kounye a master.

Erè nimewo de: metodoloji TLP

Nan sans, sa a se pa yon erè, an jeneral, li se jis yon karakteristik nan kreye yon pwojè nan kondisyon nan enkonpreyansyon konplè nan tou de "kote ak ki jan pou avanse pou pi?" ak an jeneral "èske nou pral la?" Nan kondisyon sa yo pwogram maladwa se te yon opsyon ki jistifye, men, natirèlman, mwen pa t 'vle repete li san nesesite. Fwa sa a, mwen te vle fè li avèk sajès: komèt atomik, chanjman kòd konsyan (epi pa "stringing karaktè o aza ansanm jiskaske li konpile (ak avètisman)", jan Linus Torvalds te di yon fwa sou yon moun, dapre Wikiquote), elatriye.

Erè nimewo twa: antre nan dlo a san yo pa konnen ford la

Mwen toujou pa debarase m de sa a nèt, men kounye a mwen deside pa swiv chemen pi piti rezistans nan ditou, epi fè li "tankou granmoun," sètadi, ekri backend TCG mwen nan grafouyen, pou yo pa. gen pou di pita, "Wi, sa a se nan kou, tou dousman, men mwen pa ka kontwole tout bagay - se konsa TCI yo ekri ..." Anplis, sa a okòmansman te sanble tankou yon solisyon evidan, depi Mwen jenere kòd binè. Jan yo di, “Gant te rasanbleу, men se pa sa a": kòd la se, nan kou, binè, men kontwòl pa ka tou senpleman transfere nan li - li dwe klèman pouse nan navigatè a pou konpilasyon, sa ki lakòz yon sèten objè ki soti nan mond lan JS, ki toujou bezwen. dwe sove yon kote. Sepandan, sou achitekti RISC nòmal, jan mwen konprann, yon sitiyasyon tipik se bezwen klèman Reyajiste kachèt enstriksyon an pou kòd rejenere - si sa a se pa sa nou bezwen, Lè sa a, nan nenpòt ka, li fèmen. Anplis de sa, nan dènye tantativ mwen an, mwen te aprann ke kontwòl pa sanble yo dwe transfere nan mitan an nan blòk tradiksyon an, kidonk nou pa reyèlman bezwen bytecode entèprete nan nenpòt ki konpanse, epi nou ka tou senpleman jenere li nan fonksyon an sou TB. .

Yo vini epi yo choute

Malgre ke mwen te kòmanse reekri kòd la an Jiyè, yon kout pye majik te monte inapèsi: anjeneral lèt ki soti nan GitHub rive kòm notifikasyon sou repons a Pwoblèm ak demann Pull, men isit la, toudenkou mansyone nan fil Binaryen kòm yon backend qemu nan kontèks la, "Li te fè yon bagay konsa, petèt li pral di yon bagay." Nou t ap pale sou itilizasyon bibliyotèk Emscripten ki gen rapò Binaryen pou kreye WASM JIT. Oke, mwen te di ke ou gen yon lisans Apache 2.0 la, ak QEMU kòm yon antye distribye anba GPLv2, epi yo pa trè konpatib. Toudenkou li te tounen soti ke yon lisans kapab ranje li yon jan kanmenm (Mwen pa konnen: petèt chanje li, petèt lisans doub, petèt yon lòt bagay...). Sa a, nan kou, te fè m 'kontan, paske lè sa a mwen te deja gade ak anpil atansyon fòma binè WebAssembly, e mwen te yon jan kanmenm tris ak enkonpreyansib. Te gen tou yon bibliyotèk ki ta devore blòk debaz yo ak graf tranzisyon an, pwodwi bytecode a, e menm kouri li nan entèprèt la tèt li, si sa nesesè.

Lè sa a, te gen plis lèt la sou lis adrès QEMU a, men sa a se plis sou kesyon an, "Ki moun ki bezwen li de tout fason?" Epi li se toudenkou, li te tounen soti li te nesesè. Nan yon minimòm, ou ka grate ansanm posiblite sa yo pou itilize, si li travay plis oswa mwens vit:

  • lanse yon bagay edikatif san okenn enstalasyon ditou
  • Virtualization sou iOS, kote, dapre rimè, aplikasyon an sèlman ki gen dwa pou jenerasyon kòd sou vole a se yon motè JS (èske sa a vre?)
  • demonstrasyon nan mini-OS - sèl-diskèt, bati-an, tout kalite firmwèr, elatriye ...

Karakteristik Runtime Navigatè

Kòm mwen te deja di, QEMU mare ak multithreading, men navigatè a pa genyen li. Oke, se sa ki, non ... Okòmansman li pa t egziste ditou, Lè sa a, WebWorkers te parèt - jan mwen konprann, sa a se multithreading ki baze sou mesaj pase. san yo pa pataje varyab. Natirèlman, sa a kreye gwo pwoblèm lè pòtab kòd ki deja egziste ki baze sou modèl memwa pataje. Lè sa a, anba presyon piblik, li te aplike tou sou non an SharedArrayBuffers. Li te piti piti prezante, yo selebre lansman li nan navigatè diferan, Lè sa a, yo selebre Nouvèl Ane sa a, ak Lè sa a, Meltdown ... Apre sa yo te rive nan konklizyon an ki koryas oswa koryas mezi a tan, men avèk èd nan memwa pataje ak yon fil ogmante kontwa an, li nan tout menm bagay la li pral travay byen avèk presizyon. Se konsa, nou enfim multithreading ak memwa pataje. Li sanble ke yo pita vire l 'tounen sou, men, kòm li te vin klè nan eksperyans nan premye, gen lavi san li, epi si se konsa, nou pral eseye fè li san yo pa konte sou multithreading.

Karakteristik nan dezyèm se enposib nan manipilasyon ba-nivo ak chemine a: ou pa ka tou senpleman pran, sove kontèks aktyèl la epi chanje nan yon nouvo ak yon nouvo chemine. Pile apèl la jere pa machin vityèl JS la. Li ta sanble, ki pwoblèm nan, depi nou toujou deside jere ansyen koule yo konplètman manyèlman? Reyalite a se ke blòk I / O nan QEMU aplike atravè coroutines, e sa a se kote manipilasyon pil ba-nivo ta vin an sou la men. Erezman, Emscipten deja gen yon mekanis pou operasyon asynchrone, menm de: Asyncify и Entèprèt. Premye a ap travay nan gonfman enpòtan nan kòd JavaScript pwodwi a epi li pa sipòte ankò. Dezyèm lan se aktyèl "fason kòrèk" ak travay nan jenerasyon bytecode pou entèprèt natif natal la. Li travay, nan kou, tou dousman, men li pa gonfle kòd la. Se vre, sipò pou koroutin pou mekanis sa a te dwe kontribye poukont yo (te gen deja koroutin ekri pou Asyncify e te gen yon aplikasyon apeprè menm API a pou Emterpreter, ou jis bezwen konekte yo).

Nan moman sa a, mwen poko jere divize kòd la nan yon sèl konpile nan WASM ak entèprete lè l sèvi avèk Emterpreter, kidonk aparèy blòk yo poko travay (gade nan pwochen seri a, jan yo di...). Sa vle di, nan fen a ou ta dwe jwenn yon bagay tankou bagay sa a komik kouch:

  • entèprete blòk I/O. Oke, èske ou reyèlman espere imite NVMe ak pèfòmans natif natal? 🙂
  • Kòd QEMU prensipal konpile statik (tradiktè, lòt aparèy imite, elatriye)
  • dinamik konpile kòd envite nan WASM

Karakteristik sous QEMU

Kòm pwobableman ou deja dvine, kòd pou imite achitekti envite ak kòd pou jenere enstriksyon machin lame yo separe nan QEMU. An reyalite, li se menm yon ti kras pi difisil:

  • gen achitekti envite
  • gen akseleratè, sètadi, KVM pou Virtualization pyès ki nan konpitè sou Linux (pou sistèm envite ak lame konpatib youn ak lòt), TCG pou jenerasyon kòd JIT nenpòt kote. Kòmanse ak QEMU 2.9, sipò pou estanda virtualizasyon pyès ki nan konpitè HAXM sou Windows parèt (detay yo)
  • si yo itilize TCG epi yo pa Virtualization pyès ki nan konpitè, Lè sa a, li gen sipò jenerasyon kòd separe pou chak achitekti lame, osi byen ke pou entèprèt inivèsèl la.
  • ... ak alantou tout sa a - periferik imite, koòdone itilizatè, migrasyon, dosye-replay, elatriye.

By wout la, èske w te konnen: QEMU ka imite pa sèlman òdinatè a tout antye, men tou, processeur a pou yon pwosesis itilizatè separe nan nwayo a lame, ki itilize, pou egzanp, pa fuzzer AFL pou instrumentation binè. Petèt yon moun ta renmen pò mòd operasyon QEMU sa a nan JS? 😉

Tankou pifò lojisyèl gratis depi lontan, QEMU bati atravè apèl la configure и make. Ann di ou deside ajoute yon bagay: yon backend TCG, aplikasyon fil, yon lòt bagay. Pa prese pou w kontan / laperèz (soulinye jan sa apwopriye) nan pwospè pou w kominike ak Autoconf - an reyalite, configure QEMU a aparamman ekri pwòp tèt ou epi li pa pwodwi nan anyen.

asanble entènèt

Se konsa, ki bagay sa a rele WebAssembly (aka WASM)? Sa a se yon ranplasman pou Asm.js, pa pretann yo dwe kòd JavaScript valab ankò. Okontrè, li se piman binè ak optimize, e menm tou senpleman ekri yon nonb antye relatif nan li se pa trè senp: pou konpak, li estoke nan fòma a. LEB128.

Ou ka tande pale de algorithm relooping pou Asm.js - sa a se restorasyon "wo nivo" enstriksyon kontwòl koule (ki vle di, si-lè sa a-lòt, bouk, elatriye), pou ki motè JS yo fèt, soti nan LLVM IR a ba-nivo, pi pre kòd machin lan egzekite pa processeur a. Natirèlman, reprezantasyon entèmedyè QEMU se pi pre dezyèm lan. Li ta sanble ke isit la li se, bytecode, nan fen touman an ... Lè sa a, gen blòk, si-lè sa a lòt bagay ak bouk! ..

Epi sa a se yon lòt rezon ki fè Binaryen itil: li ka natirèlman aksepte blòk wo nivo tou pre sa ki ta dwe estoke nan WASM. Men, li kapab tou pwodwi kòd nan yon graf nan blòk debaz ak tranzisyon ant yo. Oke, mwen te deja di ke li kache fòma depo WebAssembly dèyè pratik C/C++ API a.

TCG (Tiny Code Generator)

TCG te orijinèlman backend pou du C. Lè sa a, aparamman, li pa t 'kapab kenbe tèt ak konpetisyon an ak GCC, men nan fen a li te jwenn plas li nan QEMU kòm yon mekanis jenerasyon kòd pou platfòm la lame. Genyen tou yon backend TCG ki jenere kèk bytecode abstrè, ki se imedyatman egzekite pa entèprèt la, men mwen deside pou fè pou evite itilize li fwa sa a. Sepandan, lefèt ke nan QEMU li deja posib yo pèmèt tranzisyon an nan pwodwi TB a atravè fonksyon an tcg_qemu_tb_exec, li te tounen trè itil pou mwen.

Pou ajoute yon nouvo backend TCG nan QEMU, ou bezwen kreye yon sous-anyè tcg/<имя архитектуры> (nan ka sa, tcg/binaryen), epi li gen de dosye: tcg-target.h и tcg-target.inc.c и preskri se tout sou configure. Ou ka mete lòt dosye la, men, jan ou ka devine nan non de sa yo, yo tou de pral enkli yon kote: youn kòm yon dosye header regilye (li enkli nan tcg/tcg.h, e ke youn deja nan lòt fichye nan repèrtwar yo tcg, accel epi pa sèlman), lòt la - sèlman kòm yon snippet kòd nan tcg/tcg.c, men li gen aksè a fonksyon estatik li yo.

Deside ke mwen ta pase twòp tan sou envestigasyon detaye sou fason li fonksyone, mwen tou senpleman kopye "skelèt yo" nan de fichye sa yo soti nan yon lòt aplikasyon backend, onètman endike sa a nan tèt lisans lan.

dosye tcg-target.h gen sitou anviwònman nan fòm lan #define-s:

  • konbyen rejis ak ki lajè ki genyen sou achitekti sib la (nou gen anpil jan nou vle, otan ke nou vle - kesyon an se plis sou sa ki pral pwodwi nan kòd pi efikas pa navigatè a sou achitekti "konplètman sib" ...)
  • aliyman nan enstriksyon lame: sou x86, e menm nan TCI, enstriksyon yo pa aliyen ditou, men mwen pral mete nan tanpon an kòd pa enstriksyon nan tout, men endikasyon nan estrikti bibliyotèk Binaryen, Se konsa, mwen pral di: 4 byte
  • ki enstriksyon opsyonèl backend la ka jenere - nou enkli tout sa nou jwenn nan Binaryen, kite akseleratè a kraze rès la nan sa ki pi senp tèt li
  • Ki gwosè apwoksimatif kachèt TLB backend la mande. Reyalite a se ke nan QEMU tout bagay se grav: byenke gen fonksyon asistan ki fè chaj / magazen an konsiderasyon MMU envite (kote nou ta ye san li kounye a?), yo sove kachèt tradiksyon yo nan fòm lan nan yon estrikti, la. pwosesis ki se pratik yo entegre dirèkteman nan blòk emisyon. Kesyon an se, ki konpanse nan estrikti sa a ki pi efikasman trete pa yon sekans ti ak vit nan kòmandman?
  • isit la ou ka ajiste objektif youn oswa de rejis rezève, pèmèt rele TB atravè yon fonksyon epi opsyonèlman dekri yon koup nan ti inline-fonksyon tankou flush_icache_range (men sa a se pa ka nou an)

dosye tcg-target.inc.c, nan kou, anjeneral pi gwo nan gwosè epi li gen plizyè fonksyon obligatwa:

  • inisyalizasyon, ki gen ladan restriksyon sou ki enstriksyon ka opere sou ki operand. flagran kopye pa m 'soti nan yon lòt backend
  • fonksyon ki pran yon enstriksyon bytecode entèn
  • Ou kapab tou mete fonksyon oksilyè isit la, epi ou ka tou itilize fonksyon estatik nan tcg/tcg.c

Pou tèt mwen, mwen te chwazi estrateji sa a: nan premye mo yo nan pwochen blòk tradiksyon an, mwen te ekri kat konsèy: yon mak demaraj (yon sèten valè nan vwazinaj la. 0xFFFFFFFF, ki te detèmine eta aktyèl TB a), kontèks, modil pwodwi, ak nimewo majik pou debogaj. Okòmansman, yo te mete mak la 0xFFFFFFFF - nkote n - yon ti nimewo pozitif, epi chak fwa li te egzekite atravè entèprèt la li te ogmante pa 1. Lè li te rive 0xFFFFFFFE, konpilasyon te pran plas, modil la te sove nan tablo fonksyon an, enpòte nan yon ti "lanseur", nan ki ekzekisyon te ale nan tcg_qemu_tb_exec, epi yo te retire modil la nan memwa QEMU.

Pou parafraze klasik yo, "Crutch, konbyen ki mare nan son sa a pou kè proger la...". Sepandan, memwa a te koule yon kote. Anplis, se te memwa jere pa QEMU! Mwen te gen yon kòd ki, lè w ap ekri pwochen enstriksyon an (byen, se sa ki, yon konsèy), efase youn ki gen lyen ki te nan kote sa a pi bonè, men sa a pa t ede. Aktyèlman, nan ka ki pi senp la, QEMU asiyen memwa nan demaraj epi ekri kòd la pwodwi la. Lè tanpon an fini, kòd la jete deyò epi pwochen an kòmanse ekri nan plas li.

Apre etidye kòd la, mwen reyalize ke jwe fent la ak nimewo majik la pèmèt mwen pa echwe sou destriksyon pil pa libere yon bagay ki mal sou yon tanpon ki pa inisyalize sou premye pas la. Men, ki moun ki reekri tanpon an pou kontoune fonksyon mwen an pita? Kòm devlopè Emscripten yo konseye, lè mwen te rankontre yon pwoblèm, mwen te pote kòd la ki te lakòz tounen nan aplikasyon natif natal la, mete Mozilla Record-Replay sou li... An jeneral, nan fen mwen reyalize yon bagay ki senp: pou chak blòk, a struct TranslationBlock ak deskripsyon li yo. Devine kote... Sa a dwat, jis anvan blòk la dwa nan tanpon an. Reyalize sa a, mwen deside kite sèvi ak beki (omwen kèk), epi tou senpleman jete nimewo majik la, epi transfere mo ki rete yo nan struct TranslationBlock, kreye yon lis yon sèl lye ki ka byen vit travèse lè kachèt tradiksyon an reset, ak libere memwa.

Gen kèk beki rete: pou egzanp, make endikasyon nan tanpon kòd la - kèk nan yo se tou senpleman BinaryenExpressionRef, se sa ki, yo gade nan ekspresyon yo ki bezwen yo dwe lineyèman mete nan blòk la debaz pwodwi, pati se kondisyon an pou tranzisyon ant BBs, pati se kote yo ale. Oke, gen deja prepare blòk pou Relooper ki bezwen konekte selon kondisyon yo. Pou fè distenksyon ant yo, yo itilize sipozisyon an ke yo tout aliyen pa omwen kat byte, kidonk, ou ka san danje sèvi ak pi piti de ti siyifikatif pou etikèt la, ou jis bezwen sonje retire li si sa nesesè. By wout la, etikèt sa yo deja itilize nan QEMU pou endike rezon ki fè yo soti nan bouk TCG la.

Sèvi ak Binaryen

Modil nan WebAssembly genyen fonksyon, chak ladan yo gen yon kò, ki se yon ekspresyon. Ekspresyon yo se operasyon inèr ak binè, blòk ki fòme ak lis lòt ekspresyon, koule kontwòl, elatriye. Kòm mwen te deja di, koule kontwòl isit la òganize jisteman kòm branch wo nivo, bouk, apèl fonksyon, elatriye. Agiman nan fonksyon yo pa pase sou pil la, men klèman, jis tankou nan JS. Genyen tou varyab mondyal, men mwen pa te itilize yo, kidonk mwen pa pral di ou sou yo.

Fonksyon yo gen tou varyab lokal yo, nimewote soti nan zewo, nan kalite: int32 / int64 / float / doub. Nan ka sa a, premye n varyab lokal yo se agiman yo pase nan fonksyon an. Tanpri sonje ke byenke tout bagay isit la pa totalman ba-nivo an tèm de koule kontwòl, nonm antye yo toujou pa pote atribi "siyen / san siyen": ki jan nimewo a konpòte depann sou kòd operasyon an.

Anjeneral pale, Binaryen bay senp C-API: ou kreye yon modil, nan li kreye ekspresyon - inèr, binè, blòk soti nan lòt ekspresyon, kontwòl koule, elatriye. Lè sa a, ou kreye yon fonksyon ak yon ekspresyon kòm kò li. Si ou, tankou mwen, gen yon graf tranzisyon ki ba nivo, eleman relooper la ap ede ou. Osi lwen ke mwen konprann, li posib yo sèvi ak kontwòl wo nivo nan koule nan ekzekisyon nan yon blòk, osi lontan ke li pa ale pi lwen pase limit yo nan blòk la - se sa ki, li posib fè chemen entèn rapid / ralanti. chemen branche andedan kòd pwosesis TLB kachèt ki entegre, men pa entèfere ak koule kontwòl "ekstèn". Lè ou libere yon relooper, blòk li yo libere, lè ou libere yon modil, ekspresyon, fonksyon, elatriye ki afekte li disparèt. tèren.

Sepandan, si ou vle entèprete kòd sou vole san yo pa kreye ak efase nesesè nan yon egzanp entèprèt, li ka fè sans pou mete lojik sa a nan yon dosye C++, epi soti nan la dirèkteman jere tout API C++ nan bibliyotèk la, kontoune pare-. te fè vlope.

Se konsa, jenere kòd la ou bezwen

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

BinaryenSetOptimizeLevel(3);
BinaryenSetShrinkLevel(2);

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

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

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

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

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

... si mwen bliye anyen, padon, sa a se jis reprezante echèl la, ak detay yo nan dokiman an.

Epi, koulye a krak-fex-pex la kòmanse, yon bagay tankou sa a:

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

Yo nan lòd yo yon jan kanmenm konekte mond yo nan QEMU ak JS epi an menm tan an aksè nan fonksyon yo konpile byen vit, yo te kreye yon etalaj (yon tablo nan fonksyon pou enpòte nan lans la), ak fonksyon yo pwodwi yo te mete la. Pou kalkile endèks la byen vit, yo te itilize endèks blòk tradiksyon mo zewo a kòm li, men Lè sa a, endèks la kalkile lè l sèvi avèk fòmil sa a te kòmanse tou senpleman anfòm nan jaden an. struct TranslationBlock.

By wout la, Demo (kounye a ak yon lisans twoub) sèlman travay byen nan Firefox. Devlopè Chrome yo te yon jan kanmenm pa pare a lefèt ke yon moun ta vle kreye plis pase yon mil ka nan modil WebAssembly, kidonk yo tou senpleman asiyen yon gigaocte nan espas adrès vityèl pou chak ...

Se tout pou kounye a. Petèt pral gen yon lòt atik si nenpòt moun ki enterese. Savwa, gen rete omwen jis fè aparèy blòk travay. Li ta ka fè sans tou pou fè konpilasyon modil WebAssembly asynchrone, jan sa abitye nan mond JS la, paske toujou gen yon entèprèt ki ka fè tout bagay sa yo jiskaske modil natif natal la pare.

Finalman yon devinèt: ou te konpile yon binè sou yon achitekti 32-ti jan, men kòd la, atravè operasyon memwa, monte soti nan Binaryen, yon kote sou chemine a, oswa yon lòt kote nan 2 GB anwo espas adrès la 32-ti jan. Pwoblèm lan se ke soti nan pwen de vi Binaryen sa a se aksè twò gwo yon adrès rezilta. Ki jan yo jwenn alantou sa a?

Nan fason admin

Mwen pa t 'te fini tès sa a, men premye panse mwen te "E si mwen enstale Linux 32-bit?" Lè sa a, pati siperyè espas adrès la pral okipe pa nwayo a. Sèl kesyon an se konbyen yo pral okipe: 1 oswa 2 Gb.

Nan fason yon pwogramè (opsyon pou pratik)

Ann soufle yon ti wonn nan tèt espas adrès la. Mwen menm mwen pa konprann poukisa li travay - la deja dwe gen yon pil. Men, "nou se pratik: tout bagay ap travay pou nou, men pèsonn pa konnen poukisa..."

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

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

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

... se vre ke li pa konpatib ak Valgrind, men, erezman, Valgrind tèt li trè efektivman pouse tout moun soti la :)

Petèt yon moun ap bay yon pi bon eksplikasyon sou kijan kòd mwen an fonksyone...

Sous: www.habr.com

Add nouvo kòmantè