Qemu.js cum JIT auxilio: inpensam adhuc converti potest

Ante paucos annos Fabricii Bellard scripsit jslinux PC aemulus scriptum est in JavaScript. Post hoc erat certe plus Virtual x86. Sed omnes, quantum scio, interpretes fuerunt, dum Qemu, ab eodem Fabricio Bellard multo antea conscripta, et, probabiliter, quilibet sui respectu moderni emulatoris, utitur JIT compilatione hospitis in codice hospitii in codicem sistendi. Visum est mihi tempus esse ad effectum deducendi oppositum negotium in relatione ad illum qui navigatores solvendi sunt: ​​JIT compilationem machinae codicem in JavaScript, pro quo maxime logicum visum est ad portum Qemu. Videtur, cur Qemu, simpliciores et amici emulatores user-eidem VirtualBox, exempli gratia - inaugurati et opera. Sed Qemu habet multa interesting features

  • aperta principium
  • facultatem ad opus sine kernel exactoris
  • facultatem ad operari modus interpres
  • subsidium magnum utriusque militiae et hospitis architecturae

Circa tertium punctum nunc explicare possum re vera, in TCI modo, non ipsae instructiones machinae hospites interpretatae, sed bytecode ab eis impetratae, sed hoc non mutat essentiam - ut aedificetur et currat. Qemu in nova architectura, si felix es, A C compilator satis est - scribendo codicem generans differri potest.

Nunc autem, post biennium otiose tinnientium cum Qemu codice fonte in libera hora, exemplar opus apparuit, in quo iam currere potes, exempli gratia, Kolibri OS.

Quid est Emscripten

Hodie multi compilatores apparuerunt, cuius finis effectus est JavaScript. Nonnulli, sicut Typus Script, initio destinati sunt optima ratione scribendae interretialis. Eodem tempore, Emscripten modo C vel C++ exsistens codicem capiendi est et in formam navigatoris legendi compilare. On hoc page Multas portuum notarum programmata collegimus; hicExempli gratia, potes intueri PyPy - obiter se iam habere JIT. Re vera, non omnis progressio simpliciter componi potest et in navigatro currere - numerus sunt featuresquam tamen ferendum est, cum inscriptionem eadem pagina dicat "Emscripten fere ullius scribere posse. Portable C/C++ codice ad JavaScript", hoc est, plures operationes quae sunt mores indefiniti secundum mensuram, sed plerumque laborant in x86 - exempli gratia, unaligned accessus ad variabiles, quae plerumque in quibusdam architecturis prohibentur. , Qemu progressio est transversalis et , credere volui , et non iam multum indefinitae conversationis continet - sume et compone , deinde paulum tinker cum JIT - et factum es! causa...

Primum attentent

Generaliter loquendo, primus homo non sum ascendet cum idea portandi Qemu JavaScript. Quaesitum est de ReactOS foro, si hoc Emscripten fieri posset. Etiam antea rumores erant Fabricii Bellard hoc personaliter fecisse, sed de jslinux loquebantur, quod, quantum scio, justum est conatum manualem satis facere in JS, et de integro scriptum est. Postea Virtual x86 conscripta est - fontes inobfuscati pro eo collocati sunt, et, ut dictum est, maior "realismus" aemulationis effecit ut SeaBIOS ut firmware uti posset. Praeterea unus saltem conatus erat utens Emscripten portum Qemu - id facere conatus sum socketpairsed progressus, quantum intelligo, constringebatur.

Ita, ut videtur, hic sunt fontes, hic Emscripten β€” sumo et compilato. Sed sunt etiam bibliothecae unde Qemu pendent, et bibliothecae unde pendent illae bibliothecae, et una earum est etc. libffie, quae captura dependet. Rumores in interreti erant unam esse in magna collectione portuum bibliothecarum Emscripten, sed aliquo modo incredibilia: primo, non intendebatur novum compilator esse, deinde, quod erat nimis humilis; bibliothecam, ut mox legas, et ad JS. Et non solum res conventus adiicit - probabiliter, si detorqueas, per convocationes quasdam necessarias rationes in ACERVUS generare potes et munus sine illis voca. Sed Emscripten res captiosa est: ut codicem generatum ad optimizeri machinam navigatoris notam respiciat, aliquae sycophantiae adhibentur. Speciatim, sic dicta reclinatio - codicem generans utens recepta LLVM IR cum instructionibus quibusdam abstractis transitum probabilem ifs, loramenta recreare conatur, etc. Quomodo argumenta ad munus? Nempe ut rationes ad JS functiones, hoc est, si fieri potest, non per acervum.

In principio notio erat ut simpliciter scriberem substitutionem libffi cum JS et vexillum probatum currere, sed in fine confusum habui quomodo limas titulos meos facerem ut cum codice existente operarentur - quid facere possum; ut aiunt, "tane sunt operae tam implicatae" Tam stupidi sumus?" Habui ad portum libffi ad aliam architecturam, ut ita dicam - fortunate, Emscripten utrumque macros pro inline conventus (in Javascript, yeah - bene, quidquid architecturae, sic coadiutoris), et facultatem ad codicem generatum in musca currendum est. In genere, cum aliquandiu libffi fragmentorum suggesto-dependens, codicem aliquem compilabilem nactus sum et in primo experimento incidi. Ad me mirum, probatio superabat. Obstupuit ingenio meo - sine ioco, elaboravit a prima immissione - ego, oculis meis adhuc non credens, codicem denuo inspicere accessi, ubi deinde fodere perpenderem. Ecce iterum veni nuces - id solum meum munus fecit ffi_call - Haec rettulit prosperam vocationem. Nullam dictum dictum ipsum. Misi igitur petitionem meam primum viverra, qui errorem in probatione emendavit, qui patet cuilibet discipulo Olympiadis β€” reali numero comparari non debet. a == b et quomodo a - b < EPS - Etiam moduli meminisse debes, aliter 0 eventurum esse valde aequalem 1/3... In genere accessi ad portum quemdam libffi, qui probat simplicissima transit, et cum quo capsula est. Composuit - decrevi oporteret, postea addam. Prospiciens, dicam, ut evenit, compilator ne munus libffi in postremo codice includere.

Sed, ut iam dixi, quaedam limitationes sunt, et in usu liberorum variarum indefinitorum morum, injucundior pluma abscondita est - JavaScript by designing not supporting multithreading with shared memory. Principio, haec fere etiam utilem dici potest, non tamen ad codicem portandum cuius architectura filis C ligatur. In universum, Firefox experitur cum adiutoribus communibus adiuvandis, et Emscripten pthread pro eis exsecutionem habet, sed ab ea pendere nolebat. Mihi ad multiplicationem e codice Qemu lente eruendam - id est, invenio ubi stamina currunt, corpus ansa in hoc filo currens in functionem separatam moveo, et tales functiones singulatim e principali ansa vocamus.

Secundum conatus

In aliquo loco, apparuit quaestionem ibi adhuc esse, et fortuito fusum circa codicem non ad aliquod bonum ducere. Conclusio: opus est aliquo modo disponere processus fusum addendi. Ideo versio 2.4.1, quae tunc erat recens, capta est (non 2.5.0, quia, qui scit, erunt cimices in nova versione nondum comprehensa, et satis habeo de cimicibus meis. ) , & primum erat illud tuto rescribere thread-posix.c. Bene, id est, quasi tutum: si quis operationem suam impediret quae operam dare conabatur, munus statim appellatur abort() - Utique hoc non statim problemata omnia solvebat, sed saltem aliquo modo iucundius erat quam tacite accipiendo inconstanter data.

In genere, optiones Emscripten valde utiles sunt in codice portando ad JS' -s ASSERTIONS=1 -s SAFE_HEAP=1 - quaedam indefinita morum genera capiunt, ut vocat ad electronica unaligned (quae minime consentanea est cum codice pro typum vestit sicut HEAP32[addr >> 2] = 1) vel munus vocare cum iniuria multis argumentis.

Viam noctis errores separati sunt. Ut iam dixi, Qemu interpretativum codicem generationis TCI (codici minimi interpretis) habet, et Qemu in nova architectura aedificare et currere, si felix es, a C compilator satis est. "Si felix es". Infelix fui, et evenit ut TCI accessu unaligned utitur cum suo bytecode parsing. Hoc est, in omnibus generibus ARM et aliis architecturae accessu necessariis aequatis, Qemu componit quia normalem TCG backend habent qui codicem indigenam gignit, sed an TCI in illis operabitur alia quaestio est. Tamen, ut evenit, documenta TCI clare aliquid simile indicant. Quam ob rem, munus postulat ut lectio nonnisi in codice additae sint, quae in alia parte Qemu repertae sunt.

exitium acervus

Quam ob rem unaligned accessus ad TCI correctus est, ansa principalis creata est quae vicissim appellatur processus, RCU et quaedam alia parva. Itaque Qemu deduco cum optione -d exec,in_asm,out_asmquod significat necesse est dicere quos insulis de codice exercentur, et etiam tempore passim ad scribendum, quis hospes codicem, quis hospes codicem factus sit (in hoc casu, bytecode). Initium est, plures translationes caudices exsequitur, nuntium debugging scribit, quem reliqui RCU nunc incipiet et ruinis ... abort() intra munus free(). Per tinkering ad munus free() Curavimus invenire in capite aggeris, quod in octo bytes praecedentibus memoriae datum est, loco clausus magnitudinis vel simile quid, purgamentum esse.

Destructio acervi - quam bellus... In tali casu remedium utile est - ex eisdem fontibus (si fieri potest) binarium indigenam congrega et sub Valgrind currere. Post aliquod tempus binarius paratus erat. Iisdem optionibus eam deduco - etiam durante initialization ingruat, antequam exsecutionem attingat. Ingrata est, sane - apparenter, fontes non prorsus iidem erant, quod mirum non est, quia speculatores leviter diversas bene figurant, sed ego Valgrind - primum hunc cimex figam, deinde, si sum felix. originale apparebit. Idem curro sub Valgrind... Y-y-y, y-y-y, uh-uh, incepit, per initializationem regulariter ivit et praeter cimex originalis praeterivit sine una monitione de accessu falsa memoria, ne dicam de lapsu. Vita, ut aiunt, ad hoc me non praeparavit - progressio cessat fragor sub Walgrind immissa. Quid esset mysterium. Mea hypothesis est quod semel in vicinia instructionis hodiernae post fragorem in initializatione, gdb opus ostendit memset-a cum valida monstratorem utens vel mmx, or xmm tabulae, tunc fortasse aliquae species erroris alignment fuit, quamquam adhuc credibile est.

Bene, Valgrin hic adiuvare non videtur. Et hic res foedissima coepit - omnia etiam incipere videntur, sed inruerit ob rationes omnino ignotas ob eventum quod decies traditionum ante evenire potuit. Diu ne adire quidem satis clarum fuit. In fine, sedere et lusione adhuc habui. Typographia quae caput cum rescriptum est ostendit non videri numerum, sed speciem aliquae notitiae binariae. Et, ecce, ecce chorda haec binaria in BIOS fasciculo inventa est, hoc est, nunc rationabili fiducia fieri potuit quiddam superfluum esse, et etiam perspicuum est hanc quiddam esse scriptam. Quid igitur simile huic - in Emscripten, feliciter, nullum est spatium inscriptionis randomization, vel nulla perforata, ut alicubi scribere possis in medio codice ad output data per monstratorem e ultimis immittendis; data, vide monstratorem et, si non mutatum, praemeditari cibum sume. Verum, post quamlibet mutationem copulare minuta duo habet, sed quid potes? Quam ob rem certa linea inventa est quae BIOS descripsi ex temporali quiddam hospitii memoriae - et quidem spatium in quiddam non satis erat. Inveniens fons illius quiddam mirae inscriptionis consecutum est in functione qemu_anon_ram_alloc in file oslib-posix.c β€” logica haec erat: interdum utilis esse potest ad electronicam ad ingentem paginam 2 MB magnitudinis ponendam, hoc enim quaeramus. mmap prius paulo plus, deinde excessum cum auxilio reddemus munmap. Et si talis dam non requiritur, tunc eventum indicabimus loco 2 MB getpagesize() - mmap adhuc dabit inscriptionem alignatam... Sic in Emscripten mmap sicut vocat mallocsed in pagina utique non apponit. Fere cimex qui me frustravit per duos menses correctus est per mutationem Π΄Π²ΡƒΡ… munimenta.

Features of vocatio munera

Et nunc processus aliquid numerat, Qemu non fragorem facit, sed velum non vertit, et processus cito in loramenta exit, per output diiudicans. -d exec,in_asm,out_asm. Exorta est hypothesis: timor obloquitur (vel generatim omnia obloquitur) non perveniunt. Et quidem, si obloquitur ab indigena ecclesia, quae aliqua ratione operata est, similem imaginem nancisceris. Sed hoc omnino responsum non fuit: comparatio vestigia cum optionis praedictae editae demonstraverunt executionem trajectoriae valde mature deflexisse. Hic dicendum est comparationem eorum quae in usu Launlatoris scripta sunt emrun debugging output with the output of the native assembly, non est omnino processus mechanicus. Prorsus nescio quomodo programma currens in navigatro coniungit emrunsed nonnullae lineae in output eveniunt ordinandae, ut differentiae in diss nondum ratio ponatur, quod trajectoriae discesserint. Communiter patuit secundum mandatum ljmpl est transitus ad varias inscriptiones, ac bytecode generatus fundamentaliter diversus est: una continet disciplinam ut munus adiutorium vocet, altera non. Postquam in mandatis ac pervestigatione codicis, qui has traditiones vertit, patuit, primum statim ante in registro. cr0 recordatio facta est - etiam utens adiutorio quod processus mutaverunt ad modum munitum, et deinde quod versio numquam mutabitur ad modum munitum. Sed plane est aliud notam Emscripten suam gravate ferre codicem sicut instructionum exsecutionem call in TCI, quod munus quodlibet monstratorem in specie consequitur long long f(int arg0, .. int arg9) - functiones dicendae cum recto numero argumentorum. Si haec regula violatur, secundum debugging occasus, propositum erit vel ruinam (quod bonum est) vel munus omnino malum appellabit (quod ludificari triste erit). Est etiam tertia optio - generationem involucris quae argumenta addunt / removent, sed in summa his involucris multum spatii capiunt, non obstante quod tantum paulo plus quam centum involucris egeo. Hoc solum valde triste est, sed problema gravius ​​evasit: in codice generato functionum membranae argumenta convertuntur et convertuntur, interdum autem munus cum argumentis generatis non vocatur - bene, sicut in. mi libffi deducantur. Hoc est, aliqui adiutores simpliciter non sunt executi.

Fortunate Qemu tabulas subsidiorum apparatus-readabiles habet in forma tituli fasciculi capitis

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

Usi sunt admodum ridiculi: primum, macros maxime in prodigioso modo redintegrantur DEF_HELPER_net volvitur helper.h. Quatenus tortor dilatatur in structuram initializer et commate, ac deinde ordinata definitur, et pro elementis β€” #include <helper.h> Quam ob rem facultas tandem operam bibliothecam experiendi habui pyparsinget scriptum erat involucris illos prorsus generare ad functiones ad quas exiguntur.

Itaque posteaquam processus laborare videbatur. Esse videtur, quia velum initialis numquam fuit, licet memtest86+ currere in conventu indigena posset. Hic enucleare necesse est codicem Qemu I/O in coroutinis scriptum esse. Emscripten suam exsecutionem valde insidiosam habet, sed adhuc in codice Qemu sustentari opus est, et nunc processus debug potest: Qemu optiones sustinet. -kernel, -initrd, -append, cum qua Linux vel, exempli gratia, memtest86+, sine machinis omnino usuris coarctare potes. Sed hic est problema: in conventu vernanali Linux nucleum output ad consolatorium per optionem videre potuit. -nographic, et nullum ex pasco output ad terminum unde deducebatur emrunnon venit. Id est, non liquet: processus non laborat vel output graphics non operatur. Et tunc mihi in mentem venit aliquantulum exspectare. Evenit quod "processus non dormit, sed lente simpliciter nictans", et post quinque fere minutas nucleus fasciculum nuntii in consolatorium proiecit et perseuerat ad suspendium. Patuit processus, in genere, opera, et necesse est nos fodere in codice operandi cum SDL2. Dolendum est, nescio quomodo hac bibliotheca uti, sic alicubi temere facere habui. In aliquo puncto, linea parallel0 in velum micabat in plano caeruleo, quod nonnullas cogitationes suggessit. Ad extremum, evenit ut problema esset quod Qemu plures fenestras virtuales in una fenestra physica aperit, inter quas Ctrl-Alt-n utens commutare potes: laborat in aedificando indigena, non autem in Emscripten. Post tollendum necesse fenestras uti optiones -monitor none -parallel none -serial none mandavitque ut totum velum in singulis tabulis vehementer redintegraret, subito omnia fecit.

Coroutines

Ergo aemulatio in operibus navigatoris, sed non potes currere aliquid interesting unius floppy in eo, quia impedimentum non est I/O - opus est auxilium coroutines efficere. Qemu iam plures coroutinos backends habet, sed ex natura JavaScript et in codice Emscripten generantis, modo acervos praestigiatores incipere non potes. Omnia, ut videtur, remoto emplastro, sed tincidunt emscripteni omnia iam curaverunt. Hoc impletur satis ridiculum: vocemus functionem sic suspectam emscripten_sleep et plures alii mechanismum Asyncify utentes, et monstratorem vocat et vocat ad aliquem functionem ubi unus e duobus superioribus casus ulterius descendit acervus. Nunc autem, ante quamlibet suspicionem vocationis, contextum asyncon eligemus et statim post vocationem reprehendemus utrum asynchrona vocatio acciderit, et si habet, omnes variabiles locales in hoc contextu async, quem functionem indicant. potestatem transferendi ad cum exsecutionem prosequendam et praesens munus exit. Hoc est, ubi laxius studet effectus spargens β€” ob necessitates exsecutionis codicis permanentis post reditum ab asynchrono vocatione, compilator "stabulas" functionis initium post vocationem suspectam generat β€” hoc modo: si suspecta sunt n vocat, tunc munus alicubi n/2 dilatabitur. temporibus β€” hoc etiamnum est, nisi Meminerint post unamquamque vocationem asynchronam potentialiter, necesse est addere aliquas variabiles locales functioni originali servatas. Postmodum etiam simplicem scriptionem Pythonis scribere debebam, quae ex praescripto munerum praecipue accensorum, quae velut "asynchronyam per se transire non sinunt" (id est, acervus promotionis et omnia quae modo descripsimus non faciunt. in eis opus), indicat vocat per indicium, in quibus functiones a compilator praetermittendae sunt ut haec munera asynchrona non considerentur. Et tunc files JS sub 60 MB nimis perspicue sunt - dicamus saltem 30. Etsi semel scriptum conventum instituebam et casualiter eiecerunt optiones vinculorum, in quibus erat. -O3. Generatum codicem curro, et Chromium corrodit memoria et ruinis. Tunc accidens spectavi quid conaretur download... Bene, quid dicam, nimium congelatum haberem, si quaesitus essem ad cogitandum studium et optimize a 500+ MB Javascript.

Infeliciter, compescmenta in Asyncify subsidii bibliothecae codicis non omnino amicae erant longjmp-s quae in codice processus virtualis adhibitae sunt, sed post parvam commissuram quae impedit et disablet ac fortiter contextus restaurat ac si omnia denique essent, signum operatum est. Ac deinde res nova coepit: interdum in synchronisationi codicillos cohibetiones utitur - eaedem quae codicem incidant, si, secundum logicam exsecutionem, obstruetur - aliquis conatus est mutex iam captam arripere. Fortunate, hoc evenit ut problema logicum non in codice serialized - me solum utens ansa principalis functionis ansae ab Emscripten provisa esset, sed interdum asynchronous vocationi acervum penitus evolveret, et in ipso momento deficeret. setTimeout e principali ansa - ita, signum principale ansam iterationem ingressus est, nulla prior iteratione relicto. Rescripserunt in infinitum ansam et emscripten_sleepac difficultates mutexas. Codex etiam magis logicus factus est - etenim non habeo aliquem codicem qui proximum corpus animationis praeparat - processus iustus aliquid computat et per intervalla renovatur. Nihilominus quaestiones ibi non cessabant: interdum Qemu exsecutio simpliciter tacite terminaretur sine ullis exceptionibus vel erroribus. Illo momento in ea dedi, sed prospiciens, rem hanc esse dicam: coroutinum codicem re vera non utitur. setTimeout (vel certe non quotiens putes): function emscripten_yield simpliciter ponit asynchronum vexillum vocat. Totum illud est emscripten_coroutine_next munus asynchronum non est: vexillum interius cohibet, reponit ac transfert ubi opus est. ACERVUS idest promotio ibi terminatur. Problema erat propter usum post-liberum, quod apparuit cum piscina coroutina debilitata erat ob id quod non scripsi lineam magni momenti codicis a coroutino existente munus. qemu_in_coroutine verum reddidit, cum tamen falsum reddidisset. Inde ad vocationem emscripten_yieldsupra quod nullus in acervo emscripten_coroutine_nextACERVUS in summo vertice explicatur, sed no setTimeoutut iam dixi, exhibitus non est.

JavaScript codice generation

Et hic revera promittitur "tritum cibum reverti." Non realiter. Scilicet, si currimus Qemu in pasco, et Node.js in eo, naturaliter, post codicem generationis in Qemu habebimus omnino iniuriam JavaScript. Sed tamen aliqua transmutatio inversa est.

Prius pauca quomodo Qemu operatur. Dimitte me statim: non sum professio Qemu elit et conclusiones meae in nonnullis locis erroneae possunt. Ut aiunt, "opinio discipulorum non convenit cum sententia magistri, axiomatica Peano et sensus communis." Qemu certos architecturas hospites sustentatas habet et singulis directorium simile est target-i386. Cum aedificaretur, aliquot architecturae hospites sustentare potes, sed effectus iustus erit plures binarii. Codex ad hospitem architecturam sustinendam, vicissim operationes quasdam internas Qemu generat, quas TCG (Tiny Code Generator) iam in machinam pro architectura hospitii vertit. Sicut in tabula readme in indice tcg posita, haec fuit prima pars compilatoris regularis C, quae postea JIT accommodata est. Ergo, exempli gratia, architectura scopum in verbis huius documenti non iam architectura hospitatur, sed architectura militiae. In aliquo puncto, alia pars apparuit - Codicis Vegrandis Interpres (TCI), qui codicem (fere eadem operationes internas) exequi debet, in absente codici generantis ad certum exercitum architecturae. Re quidem vera, ut documenta eius asserit, interpres hic non semper praestare potest sicut in codice generantis JIT, non solum quantitatis secundum celeritatem, sed etiam qualitatem. Quanquam haud scio an descriptionem eius omnino pertineat.

In primis conabar emissarium TCG backend reddere, sed cito confundi in codice fonte et non plane perspicua descriptione instructionum bytecode, unde constitui interpretem TCI involvere. Hic multa commoda dedit;

  • cum generans codicem exsequens, non descriptionem instructionum, sed ad interpretem codicem spectare potes
  • munera generare potes non pro omni translatione scandali congresso, sed, exempli gratia, tantum post supplicium centesimum
  • si codicem generatum mutat (quod fieri posse videtur, functionibus nominibus in quibus verbi commissurae diiudicandis) infirmare debeo codicem JS codicem genitum, sed saltem habebo aliquid ex eo regenerare.

Tertium punctum attinet, non certo scio persactionem fieri posse postquam primum signum efficitur, sed prima duo puncta satis sunt.

Initio, codice generatus est in forma magnae switchi ad electronicam informationis originalis bytecode, sed tunc, recordans articulum de Emscripten, optimizatione JS generatae et revolvens, decrevi codicem humaniorem generare, praesertim cum empirice illum evenit ut unicum punctum ingressum in translatione interclusum suum initium esse. Non citius dictum quam factum est, postquam codicem generantis habuimus, qui codicem cum ifs genitum (etsi sine loramento habebamus). Sed adversa fortuna, id ingruebat, nuntium praebens falsae longitudinis mandata esse. Ultima autem instructio in hoc gradu recursionis fuit brcond. Bene, generationi huius instructionis ante et post vocationi recursivae identitatem addam et ... non unus ex illis est exsecutus, sed postquam asserunt transitum adhuc defecerunt. In fine, codice generato perscrutatus, intellexi post transitum, monstratorem hodiernae instructionis e ACERVA relatum esse et probabiliter a JavaScript codice genito overscriptum esse. Et ita evenit. Augendo quiddam ab uno megabyte ad decem non ad aliquid duxi, et patuit codicem generantis in circulis currendum esse. Inhibere debebamus nos terminos currentis TB non excedere, et si fecerimus, inscriptione sequentis TB cum signo minus edamus ut executionem continuare possimus. Praeterea, haec quaestio solvit "quae functiones generatae infirmari debent si haec particula bytecode mutata?" β€” solum munus, quod huic translationi clausus correspondet, infirmari debet. Obiter, etsi omnia Chromium debuged (quoniam Firefox utar et facilior mihi est separato navigatro experimentis utar), Firefox me adiuvit incompatibilitatem rectam cum vexillo asm.js, post quem codicem ocius laborare coepit. Chromium.

Exemplum codice generatae

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

conclusio,

Opus igitur non perficitur, sed taedet furtim hanc diuturnitatem constructionis ad perfectionem perferre. Itaque quod habeo nunc edendum decrevi. Codex in locis parum FORMIDULOSUS est, quia hoc experimentum est, et quid fieri oporteat ante non liquet. Probabiliter, tunc valet emittere normales atomos in versione aliqua recentioris Qemu. Interim filum in Gita exstat in forma diarii: nam utrumque "gradum" quod saltem aliquo modo praeteriit, accurata commentatio in Russia adiecta est. Hic articulus est magna ex parte narratio conclusionis git log.

Vos can experiri omnes hic (cave negotiationis).

Quod iam opus est;

  • x86 processus virtualis cursus
  • Est opus prototypum codice generantis JIT ex machina codice ad JavaScript
  • Exemplum est alias architecturae hospitum 32 frenum convocandi: nunc mirari potes Linux pro architectura MIPS congelatio in navigatro in scaena oneratione

Quid aliud potestis facere?

  • Accelerare aemulationem. Etiam in JIT modus tardius currere videtur quam Virtual x86 (sed potentia est tota Qemu cum multae odio et architecturae aemulatae)
  • Ut normalem interface - ingenue, elit web bonus non sum, nunc vexillum Emscripten putamen reformavi ut potui.
  • Conare functiones magis implicatas Qemu mittere - networking, VM migratio, etc.
  • UPD: paucas evolutiones tuas submittere et cimex nuntia ad Emscripten fluvium, sicut priores ianitores Qemu et alia incepta fecerunt. Eis gratias ago quod Emscripten pro parte operis mei implicite uti possem collatione sua.

Source: www.habr.com