1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749 |
- var rhino3dm = (() => {
- var _scriptDir = import.meta.url;
-
- return (
- async function(config) {
- var rhino3dm = config || {};
- // The Module object: Our interface to the outside world. We import
- // and export values on it. There are various ways Module can be used:
- // 1. Not defined. We create it here
- // 2. A function parameter, function(Module) { ..generated code.. }
- // 3. pre-run appended it, var Module = {}; ..generated code..
- // 4. External script tag defines var Module.
- // We need to check if Module already exists (e.g. case 3 above).
- // Substitution will be replaced with actual code on later stage of the build,
- // this way Closure Compiler will not mangle it (e.g. case 4. above).
- // Note that if you want to run closure, and also to use Module
- // after the generated code, you will need to define var Module = {};
- // before the code. Then that object will be used in the code, and you
- // can continue to use Module afterwards as well.
- var Module = typeof rhino3dm != 'undefined' ? rhino3dm : {};
- // See https://caniuse.com/mdn-javascript_builtins_object_assign
- // See https://caniuse.com/mdn-javascript_builtins_bigint64array
- // Set up the promise that indicates the Module is initialized
- var readyPromiseResolve, readyPromiseReject;
- Module['ready'] = new Promise(function(resolve, reject) {
- readyPromiseResolve = resolve;
- readyPromiseReject = reject;
- });
- ["_main","_fflush","___getTypeName","__embind_initialize_bindings","onRuntimeInitialized"].forEach((prop) => {
- if (!Object.getOwnPropertyDescriptor(Module['ready'], prop)) {
- Object.defineProperty(Module['ready'], prop, {
- get: () => abort('You are getting ' + prop + ' on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js'),
- set: () => abort('You are setting ' + prop + ' on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js'),
- });
- }
- });
- // --pre-jses are emitted after the Module integration code, so that they can
- // refer to Module (if they choose; they can also define Module)
- // {{PRE_JSES}}
- // Sometimes an existing Module object exists with properties
- // meant to overwrite the default module functionality. Here
- // we collect those properties and reapply _after_ we configure
- // the current environment's defaults to avoid having to be so
- // defensive during initialization.
- var moduleOverrides = Object.assign({}, Module);
- var arguments_ = [];
- var thisProgram = './this.program';
- var quit_ = (status, toThrow) => {
- throw toThrow;
- };
- // Determine the runtime environment we are in. You can customize this by
- // setting the ENVIRONMENT setting at compile time (see settings.js).
- // Attempt to auto-detect the environment
- var ENVIRONMENT_IS_WEB = typeof window == 'object';
- var ENVIRONMENT_IS_WORKER = typeof importScripts == 'function';
- // N.b. Electron.js environment is simultaneously a NODE-environment, but
- // also a web environment.
- var ENVIRONMENT_IS_NODE = typeof process == 'object' && typeof process.versions == 'object' && typeof process.versions.node == 'string';
- var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
- if (Module['ENVIRONMENT']) {
- throw new Error('Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)');
- }
- // `/` should be present at the end if `scriptDirectory` is not empty
- var scriptDirectory = '';
- function locateFile(path) {
- if (Module['locateFile']) {
- return Module['locateFile'](path, scriptDirectory);
- }
- return scriptDirectory + path;
- }
- // Hooks that are implemented differently in different runtime environments.
- var read_,
- readAsync,
- readBinary,
- setWindowTitle;
- // Normally we don't log exceptions but instead let them bubble out the top
- // level where the embedding environment (e.g. the browser) can handle
- // them.
- // However under v8 and node we sometimes exit the process direcly in which case
- // its up to use us to log the exception before exiting.
- // If we fix https://github.com/emscripten-core/emscripten/issues/15080
- // this may no longer be needed under node.
- function logExceptionOnExit(e) {
- if (e instanceof ExitStatus) return;
- let toLog = e;
- if (e && typeof e == 'object' && e.stack) {
- toLog = [e, e.stack];
- }
- err('exiting due to exception: ' + toLog);
- }
- if (ENVIRONMENT_IS_NODE) {
- if (typeof process == 'undefined' || !process.release || process.release.name !== 'node') throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)');
- // `require()` is no-op in an ESM module, use `createRequire()` to construct
- // the require()` function. This is only necessary for multi-environment
- // builds, `-sENVIRONMENT=node` emits a static import declaration instead.
- // TODO: Swap all `require()`'s with `import()`'s?
- const { createRequire } = await import('module');
- /** @suppress{duplicate} */
- var require = createRequire(import.meta.url);
- // These modules will usually be used on Node.js. Load them eagerly to avoid
- // the complexity of lazy-loading.
- var fs = require('fs');
- var nodePath = require('path');
- if (ENVIRONMENT_IS_WORKER) {
- scriptDirectory = nodePath.dirname(scriptDirectory) + '/';
- } else {
- // EXPORT_ES6 + ENVIRONMENT_IS_NODE always requires use of import.meta.url,
- // since there's no way getting the current absolute path of the module when
- // support for that is not available.
- scriptDirectory = require('url').fileURLToPath(new URL('./', import.meta.url)); // includes trailing slash
- }
- // include: node_shell_read.js
- read_ = (filename, binary) => {
- // We need to re-wrap `file://` strings to URLs. Normalizing isn't
- // necessary in that case, the path should already be absolute.
- filename = isFileURI(filename) ? new URL(filename) : nodePath.normalize(filename);
- return fs.readFileSync(filename, binary ? undefined : 'utf8');
- };
- readBinary = (filename) => {
- var ret = read_(filename, true);
- if (!ret.buffer) {
- ret = new Uint8Array(ret);
- }
- assert(ret.buffer);
- return ret;
- };
- readAsync = (filename, onload, onerror) => {
- // See the comment in the `read_` function.
- filename = isFileURI(filename) ? new URL(filename) : nodePath.normalize(filename);
- fs.readFile(filename, function(err, data) {
- if (err) onerror(err);
- else onload(data.buffer);
- });
- };
- // end include: node_shell_read.js
- if (process['argv'].length > 1) {
- thisProgram = process['argv'][1].replace(/\\/g, '/');
- }
- arguments_ = process['argv'].slice(2);
- // MODULARIZE will export the module in the proper place outside, we don't need to export here
- process['on']('uncaughtException', function(ex) {
- // suppress ExitStatus exceptions from showing an error
- if (!(ex instanceof ExitStatus)) {
- throw ex;
- }
- });
- // Without this older versions of node (< v15) will log unhandled rejections
- // but return 0, which is not normally the desired behaviour. This is
- // not be needed with node v15 and about because it is now the default
- // behaviour:
- // See https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode
- process['on']('unhandledRejection', function(reason) { throw reason; });
- quit_ = (status, toThrow) => {
- if (keepRuntimeAlive()) {
- process['exitCode'] = status;
- throw toThrow;
- }
- logExceptionOnExit(toThrow);
- process['exit'](status);
- };
- Module['inspect'] = function () { return '[Emscripten Module object]'; };
- } else
- if (ENVIRONMENT_IS_SHELL) {
- if ((typeof process == 'object' && typeof require === 'function') || typeof window == 'object' || typeof importScripts == 'function') throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)');
- if (typeof read != 'undefined') {
- read_ = function shell_read(f) {
- return read(f);
- };
- }
- readBinary = function readBinary(f) {
- let data;
- if (typeof readbuffer == 'function') {
- return new Uint8Array(readbuffer(f));
- }
- data = read(f, 'binary');
- assert(typeof data == 'object');
- return data;
- };
- readAsync = function readAsync(f, onload, onerror) {
- setTimeout(() => onload(readBinary(f)), 0);
- };
- if (typeof scriptArgs != 'undefined') {
- arguments_ = scriptArgs;
- } else if (typeof arguments != 'undefined') {
- arguments_ = arguments;
- }
- if (typeof quit == 'function') {
- quit_ = (status, toThrow) => {
- logExceptionOnExit(toThrow);
- quit(status);
- };
- }
- if (typeof print != 'undefined') {
- // Prefer to use print/printErr where they exist, as they usually work better.
- if (typeof console == 'undefined') console = /** @type{!Console} */({});
- console.log = /** @type{!function(this:Console, ...*): undefined} */ (print);
- console.warn = console.error = /** @type{!function(this:Console, ...*): undefined} */ (typeof printErr != 'undefined' ? printErr : print);
- }
- } else
- // Note that this includes Node.js workers when relevant (pthreads is enabled).
- // Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and
- // ENVIRONMENT_IS_NODE.
- if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
- if (ENVIRONMENT_IS_WORKER) { // Check worker, not web, since window could be polyfilled
- scriptDirectory = self.location.href;
- } else if (typeof document != 'undefined' && document.currentScript) { // web
- scriptDirectory = document.currentScript.src;
- }
- // When MODULARIZE, this JS may be executed later, after document.currentScript
- // is gone, so we saved it, and we use it here instead of any other info.
- if (_scriptDir) {
- scriptDirectory = _scriptDir;
- }
- // blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.
- // otherwise, slice off the final part of the url to find the script directory.
- // if scriptDirectory does not contain a slash, lastIndexOf will return -1,
- // and scriptDirectory will correctly be replaced with an empty string.
- // If scriptDirectory contains a query (starting with ?) or a fragment (starting with #),
- // they are removed because they could contain a slash.
- if (scriptDirectory.indexOf('blob:') !== 0) {
- scriptDirectory = scriptDirectory.substr(0, scriptDirectory.replace(/[?#].*/, "").lastIndexOf('/')+1);
- } else {
- scriptDirectory = '';
- }
- if (!(typeof window == 'object' || typeof importScripts == 'function')) throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)');
- // Differentiate the Web Worker from the Node Worker case, as reading must
- // be done differently.
- {
- // include: web_or_worker_shell_read.js
- read_ = (url) => {
- var xhr = new XMLHttpRequest();
- xhr.open('GET', url, false);
- xhr.send(null);
- return xhr.responseText;
- }
- if (ENVIRONMENT_IS_WORKER) {
- readBinary = (url) => {
- var xhr = new XMLHttpRequest();
- xhr.open('GET', url, false);
- xhr.responseType = 'arraybuffer';
- xhr.send(null);
- return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response));
- };
- }
- readAsync = (url, onload, onerror) => {
- var xhr = new XMLHttpRequest();
- xhr.open('GET', url, true);
- xhr.responseType = 'arraybuffer';
- xhr.onload = () => {
- if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
- onload(xhr.response);
- return;
- }
- onerror();
- };
- xhr.onerror = onerror;
- xhr.send(null);
- }
- // end include: web_or_worker_shell_read.js
- }
- setWindowTitle = (title) => document.title = title;
- } else
- {
- throw new Error('environment detection error');
- }
- var out = Module['print'] || console.log.bind(console);
- var err = Module['printErr'] || console.warn.bind(console);
- // Merge back in the overrides
- Object.assign(Module, moduleOverrides);
- // Free the object hierarchy contained in the overrides, this lets the GC
- // reclaim data used e.g. in memoryInitializerRequest, which is a large typed array.
- moduleOverrides = null;
- checkIncomingModuleAPI();
- // Emit code to handle expected values on the Module object. This applies Module.x
- // to the proper local x. This has two benefits: first, we only emit it if it is
- // expected to arrive, and second, by using a local everywhere else that can be
- // minified.
- if (Module['arguments']) arguments_ = Module['arguments'];legacyModuleProp('arguments', 'arguments_');
- if (Module['thisProgram']) thisProgram = Module['thisProgram'];legacyModuleProp('thisProgram', 'thisProgram');
- if (Module['quit']) quit_ = Module['quit'];legacyModuleProp('quit', 'quit_');
- // perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message
- // Assertions on removed incoming Module JS APIs.
- assert(typeof Module['memoryInitializerPrefixURL'] == 'undefined', 'Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead');
- assert(typeof Module['pthreadMainPrefixURL'] == 'undefined', 'Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead');
- assert(typeof Module['cdInitializerPrefixURL'] == 'undefined', 'Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead');
- assert(typeof Module['filePackagePrefixURL'] == 'undefined', 'Module.filePackagePrefixURL option was removed, use Module.locateFile instead');
- assert(typeof Module['read'] == 'undefined', 'Module.read option was removed (modify read_ in JS)');
- assert(typeof Module['readAsync'] == 'undefined', 'Module.readAsync option was removed (modify readAsync in JS)');
- assert(typeof Module['readBinary'] == 'undefined', 'Module.readBinary option was removed (modify readBinary in JS)');
- assert(typeof Module['setWindowTitle'] == 'undefined', 'Module.setWindowTitle option was removed (modify setWindowTitle in JS)');
- assert(typeof Module['TOTAL_MEMORY'] == 'undefined', 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY');
- legacyModuleProp('read', 'read_');
- legacyModuleProp('readAsync', 'readAsync');
- legacyModuleProp('readBinary', 'readBinary');
- legacyModuleProp('setWindowTitle', 'setWindowTitle');
- var IDBFS = 'IDBFS is no longer included by default; build with -lidbfs.js';
- var PROXYFS = 'PROXYFS is no longer included by default; build with -lproxyfs.js';
- var WORKERFS = 'WORKERFS is no longer included by default; build with -lworkerfs.js';
- var NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js';
- assert(!ENVIRONMENT_IS_SHELL, "shell environment detected but not enabled at build time. Add 'shell' to `-sENVIRONMENT` to enable.");
- // include: support.js
- var STACK_ALIGN = 16;
- var POINTER_SIZE = 4;
- function getNativeTypeSize(type) {
- switch (type) {
- case 'i1': case 'i8': case 'u8': return 1;
- case 'i16': case 'u16': return 2;
- case 'i32': case 'u32': return 4;
- case 'i64': case 'u64': return 8;
- case 'float': return 4;
- case 'double': return 8;
- default: {
- if (type[type.length - 1] === '*') {
- return POINTER_SIZE;
- }
- if (type[0] === 'i') {
- const bits = Number(type.substr(1));
- assert(bits % 8 === 0, 'getNativeTypeSize invalid bits ' + bits + ', type ' + type);
- return bits / 8;
- }
- return 0;
- }
- }
- }
- // include: runtime_debug.js
- function legacyModuleProp(prop, newName) {
- if (!Object.getOwnPropertyDescriptor(Module, prop)) {
- Object.defineProperty(Module, prop, {
- configurable: true,
- get: function() {
- abort('Module.' + prop + ' has been replaced with plain ' + newName + ' (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)');
- }
- });
- }
- }
- function ignoredModuleProp(prop) {
- if (Object.getOwnPropertyDescriptor(Module, prop)) {
- abort('`Module.' + prop + '` was supplied but `' + prop + '` not included in INCOMING_MODULE_JS_API');
- }
- }
- // forcing the filesystem exports a few things by default
- function isExportedByForceFilesystem(name) {
- return name === 'FS_createPath' ||
- name === 'FS_createDataFile' ||
- name === 'FS_createPreloadedFile' ||
- name === 'FS_unlink' ||
- name === 'addRunDependency' ||
- // The old FS has some functionality that WasmFS lacks.
- name === 'FS_createLazyFile' ||
- name === 'FS_createDevice' ||
- name === 'removeRunDependency';
- }
- function missingGlobal(sym, msg) {
- Object.defineProperty(globalThis, sym, {
- configurable: true,
- get: function() {
- warnOnce('`' + sym + '` is not longer defined by emscripten. ' + msg);
- return undefined;
- }
- });
- }
- missingGlobal('buffer', 'Please use HEAP8.buffer or wasmMemory.buffer');
- function missingLibrarySymbol(sym) {
- if (typeof globalThis !== 'undefined' && !Object.getOwnPropertyDescriptor(globalThis, sym)) {
- Object.defineProperty(globalThis, sym, {
- configurable: true,
- get: function() {
- // Can't `abort()` here because it would break code that does runtime
- // checks. e.g. `if (typeof SDL === 'undefined')`.
- var msg = '`' + sym + '` is a library symbol and not included by default; add it to your library.js __deps or to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE on the command line';
- // DEFAULT_LIBRARY_FUNCS_TO_INCLUDE requires the name as it appears in
- // library.js, which means $name for a JS name with no prefix, or name
- // for a JS name like _name.
- var librarySymbol = sym;
- if (!librarySymbol.startsWith('_')) {
- librarySymbol = '$' + sym;
- }
- msg += " (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE=" + librarySymbol + ")";
- if (isExportedByForceFilesystem(sym)) {
- msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you';
- }
- warnOnce(msg);
- return undefined;
- }
- });
- }
- }
- function unexportedRuntimeSymbol(sym) {
- if (!Object.getOwnPropertyDescriptor(Module, sym)) {
- Object.defineProperty(Module, sym, {
- configurable: true,
- get: function() {
- var msg = "'" + sym + "' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)";
- if (isExportedByForceFilesystem(sym)) {
- msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you';
- }
- abort(msg);
- }
- });
- }
- }
- // end include: runtime_debug.js
- // end include: support.js
- // === Preamble library stuff ===
- // Documentation for the public APIs defined in this file must be updated in:
- // site/source/docs/api_reference/preamble.js.rst
- // A prebuilt local version of the documentation is available at:
- // site/build/text/docs/api_reference/preamble.js.txt
- // You can also build docs locally as HTML or other formats in site/
- // An online HTML version (which may be of a different version of Emscripten)
- // is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
- var wasmBinary;
- if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];legacyModuleProp('wasmBinary', 'wasmBinary');
- var noExitRuntime = Module['noExitRuntime'] || true;legacyModuleProp('noExitRuntime', 'noExitRuntime');
- if (typeof WebAssembly != 'object') {
- abort('no native wasm support detected');
- }
- // Wasm globals
- var wasmMemory;
- //========================================
- // Runtime essentials
- //========================================
- // whether we are quitting the application. no code should run after this.
- // set in exit() and abort()
- var ABORT = false;
- // set by exit() and abort(). Passed to 'onExit' handler.
- // NOTE: This is also used as the process return code code in shell environments
- // but only when noExitRuntime is false.
- var EXITSTATUS;
- /** @type {function(*, string=)} */
- function assert(condition, text) {
- if (!condition) {
- abort('Assertion failed' + (text ? ': ' + text : ''));
- }
- }
- // We used to include malloc/free by default in the past. Show a helpful error in
- // builds with assertions.
- // include: runtime_strings.js
- // runtime_strings.js: String related runtime functions that are part of both
- // MINIMAL_RUNTIME and regular runtime.
- var UTF8Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf8') : undefined;
- /**
- * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given
- * array that contains uint8 values, returns a copy of that string as a
- * Javascript String object.
- * heapOrArray is either a regular array, or a JavaScript typed array view.
- * @param {number} idx
- * @param {number=} maxBytesToRead
- * @return {string}
- */
- function UTF8ArrayToString(heapOrArray, idx, maxBytesToRead) {
- var endIdx = idx + maxBytesToRead;
- var endPtr = idx;
- // TextDecoder needs to know the byte length in advance, it doesn't stop on
- // null terminator by itself. Also, use the length info to avoid running tiny
- // strings through TextDecoder, since .subarray() allocates garbage.
- // (As a tiny code save trick, compare endPtr against endIdx using a negation,
- // so that undefined means Infinity)
- while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr;
- if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {
- return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));
- }
- var str = '';
- // If building with TextDecoder, we have already computed the string length
- // above, so test loop end condition against that
- while (idx < endPtr) {
- // For UTF8 byte structure, see:
- // http://en.wikipedia.org/wiki/UTF-8#Description
- // https://www.ietf.org/rfc/rfc2279.txt
- // https://tools.ietf.org/html/rfc3629
- var u0 = heapOrArray[idx++];
- if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; }
- var u1 = heapOrArray[idx++] & 63;
- if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; }
- var u2 = heapOrArray[idx++] & 63;
- if ((u0 & 0xF0) == 0xE0) {
- u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
- } else {
- if ((u0 & 0xF8) != 0xF0) warnOnce('Invalid UTF-8 leading byte ' + ptrToString(u0) + ' encountered when deserializing a UTF-8 string in wasm memory to a JS string!');
- u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63);
- }
- if (u0 < 0x10000) {
- str += String.fromCharCode(u0);
- } else {
- var ch = u0 - 0x10000;
- str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
- }
- }
- return str;
- }
- /**
- * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the
- * emscripten HEAP, returns a copy of that string as a Javascript String object.
- *
- * @param {number} ptr
- * @param {number=} maxBytesToRead - An optional length that specifies the
- * maximum number of bytes to read. You can omit this parameter to scan the
- * string until the first \0 byte. If maxBytesToRead is passed, and the string
- * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the
- * string will cut short at that byte index (i.e. maxBytesToRead will not
- * produce a string of exact length [ptr, ptr+maxBytesToRead[) N.B. mixing
- * frequent uses of UTF8ToString() with and without maxBytesToRead may throw
- * JS JIT optimizations off, so it is worth to consider consistently using one
- * @return {string}
- */
- function UTF8ToString(ptr, maxBytesToRead) {
- return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : '';
- }
- /**
- * Copies the given Javascript String object 'str' to the given byte array at
- * address 'outIdx', encoded in UTF8 form and null-terminated. The copy will
- * require at most str.length*4+1 bytes of space in the HEAP. Use the function
- * lengthBytesUTF8 to compute the exact number of bytes (excluding null
- * terminator) that this function will write.
- *
- * @param {string} str - The Javascript string to copy.
- * @param {ArrayBufferView|Array<number>} heap - The array to copy to. Each
- * index in this array is assumed
- * to be one 8-byte element.
- * @param {number} outIdx - The starting offset in the array to begin the copying.
- * @param {number} maxBytesToWrite - The maximum number of bytes this function
- * can write to the array. This count should
- * include the null terminator, i.e. if
- * maxBytesToWrite=1, only the null terminator
- * will be written and nothing else.
- * maxBytesToWrite=0 does not write any bytes
- * to the output, not even the null
- * terminator.
- * @return {number} The number of bytes written, EXCLUDING the null terminator.
- */
- function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) {
- // Parameter maxBytesToWrite is not optional. Negative values, 0, null,
- // undefined and false each don't write out any bytes.
- if (!(maxBytesToWrite > 0))
- return 0;
- var startIdx = outIdx;
- var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator.
- for (var i = 0; i < str.length; ++i) {
- // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
- // unit, not a Unicode code point of the character! So decode
- // UTF16->UTF32->UTF8.
- // See http://unicode.org/faq/utf_bom.html#utf16-3
- // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description
- // and https://www.ietf.org/rfc/rfc2279.txt
- // and https://tools.ietf.org/html/rfc3629
- var u = str.charCodeAt(i); // possibly a lead surrogate
- if (u >= 0xD800 && u <= 0xDFFF) {
- var u1 = str.charCodeAt(++i);
- u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF);
- }
- if (u <= 0x7F) {
- if (outIdx >= endIdx) break;
- heap[outIdx++] = u;
- } else if (u <= 0x7FF) {
- if (outIdx + 1 >= endIdx) break;
- heap[outIdx++] = 0xC0 | (u >> 6);
- heap[outIdx++] = 0x80 | (u & 63);
- } else if (u <= 0xFFFF) {
- if (outIdx + 2 >= endIdx) break;
- heap[outIdx++] = 0xE0 | (u >> 12);
- heap[outIdx++] = 0x80 | ((u >> 6) & 63);
- heap[outIdx++] = 0x80 | (u & 63);
- } else {
- if (outIdx + 3 >= endIdx) break;
- if (u > 0x10FFFF) warnOnce('Invalid Unicode code point ' + ptrToString(u) + ' encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x10FFFF).');
- heap[outIdx++] = 0xF0 | (u >> 18);
- heap[outIdx++] = 0x80 | ((u >> 12) & 63);
- heap[outIdx++] = 0x80 | ((u >> 6) & 63);
- heap[outIdx++] = 0x80 | (u & 63);
- }
- }
- // Null-terminate the pointer to the buffer.
- heap[outIdx] = 0;
- return outIdx - startIdx;
- }
- /**
- * Copies the given Javascript String object 'str' to the emscripten HEAP at
- * address 'outPtr', null-terminated and encoded in UTF8 form. The copy will
- * require at most str.length*4+1 bytes of space in the HEAP.
- * Use the function lengthBytesUTF8 to compute the exact number of bytes
- * (excluding null terminator) that this function will write.
- *
- * @return {number} The number of bytes written, EXCLUDING the null terminator.
- */
- function stringToUTF8(str, outPtr, maxBytesToWrite) {
- assert(typeof maxBytesToWrite == 'number', 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!');
- return stringToUTF8Array(str, HEAPU8,outPtr, maxBytesToWrite);
- }
- /**
- * Returns the number of bytes the given Javascript string takes if encoded as a
- * UTF8 byte array, EXCLUDING the null terminator byte.
- *
- * @param {string} str - JavaScript string to operator on
- * @return {number} Length, in bytes, of the UTF8 encoded string.
- */
- function lengthBytesUTF8(str) {
- var len = 0;
- for (var i = 0; i < str.length; ++i) {
- // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
- // unit, not a Unicode code point of the character! So decode
- // UTF16->UTF32->UTF8.
- // See http://unicode.org/faq/utf_bom.html#utf16-3
- var c = str.charCodeAt(i); // possibly a lead surrogate
- if (c <= 0x7F) {
- len++;
- } else if (c <= 0x7FF) {
- len += 2;
- } else if (c >= 0xD800 && c <= 0xDFFF) {
- len += 4; ++i;
- } else {
- len += 3;
- }
- }
- return len;
- }
- // end include: runtime_strings.js
- // Memory management
- var HEAP,
- /** @type {!Int8Array} */
- HEAP8,
- /** @type {!Uint8Array} */
- HEAPU8,
- /** @type {!Int16Array} */
- HEAP16,
- /** @type {!Uint16Array} */
- HEAPU16,
- /** @type {!Int32Array} */
- HEAP32,
- /** @type {!Uint32Array} */
- HEAPU32,
- /** @type {!Float32Array} */
- HEAPF32,
- /** @type {!Float64Array} */
- HEAPF64;
- function updateMemoryViews() {
- var b = wasmMemory.buffer;
- Module['HEAP8'] = HEAP8 = new Int8Array(b);
- Module['HEAP16'] = HEAP16 = new Int16Array(b);
- Module['HEAP32'] = HEAP32 = new Int32Array(b);
- Module['HEAPU8'] = HEAPU8 = new Uint8Array(b);
- Module['HEAPU16'] = HEAPU16 = new Uint16Array(b);
- Module['HEAPU32'] = HEAPU32 = new Uint32Array(b);
- Module['HEAPF32'] = HEAPF32 = new Float32Array(b);
- Module['HEAPF64'] = HEAPF64 = new Float64Array(b);
- }
- var STACK_SIZE = 65536;
- if (Module['STACK_SIZE']) assert(STACK_SIZE === Module['STACK_SIZE'], 'the stack size can no longer be determined at runtime')
- var INITIAL_MEMORY = Module['INITIAL_MEMORY'] || 16777216;legacyModuleProp('INITIAL_MEMORY', 'INITIAL_MEMORY');
- assert(INITIAL_MEMORY >= STACK_SIZE, 'INITIAL_MEMORY should be larger than STACK_SIZE, was ' + INITIAL_MEMORY + '! (STACK_SIZE=' + STACK_SIZE + ')');
- // check for full engine support (use string 'subarray' to avoid closure compiler confusion)
- assert(typeof Int32Array != 'undefined' && typeof Float64Array !== 'undefined' && Int32Array.prototype.subarray != undefined && Int32Array.prototype.set != undefined,
- 'JS engine does not provide full typed array support');
- // If memory is defined in wasm, the user can't provide it.
- assert(!Module['wasmMemory'], 'Use of `wasmMemory` detected. Use -sIMPORTED_MEMORY to define wasmMemory externally');
- assert(INITIAL_MEMORY == 16777216, 'Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically');
- // include: runtime_init_table.js
- // In regular non-RELOCATABLE mode the table is exported
- // from the wasm module and this will be assigned once
- // the exports are available.
- var wasmTable;
- // end include: runtime_init_table.js
- // include: runtime_stack_check.js
- // Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode.
- function writeStackCookie() {
- var max = _emscripten_stack_get_end();
- assert((max & 3) == 0);
- // If the stack ends at address zero we write our cookies 4 bytes into the
- // stack. This prevents interference with the (separate) address-zero check
- // below.
- if (max == 0) {
- max += 4;
- }
- // The stack grow downwards towards _emscripten_stack_get_end.
- // We write cookies to the final two words in the stack and detect if they are
- // ever overwritten.
- HEAPU32[((max)>>2)] = 0x2135467;
- HEAPU32[(((max)+(4))>>2)] = 0x89BACDFE;
- // Also test the global address 0 for integrity.
- HEAPU32[0] = 0x63736d65; /* 'emsc' */
- }
- function checkStackCookie() {
- if (ABORT) return;
- var max = _emscripten_stack_get_end();
- // See writeStackCookie().
- if (max == 0) {
- max += 4;
- }
- var cookie1 = HEAPU32[((max)>>2)];
- var cookie2 = HEAPU32[(((max)+(4))>>2)];
- if (cookie1 != 0x2135467 || cookie2 != 0x89BACDFE) {
- abort('Stack overflow! Stack cookie has been overwritten at ' + ptrToString(max) + ', expected hex dwords 0x89BACDFE and 0x2135467, but received ' + ptrToString(cookie2) + ' ' + ptrToString(cookie1));
- }
- // Also test the global address 0 for integrity.
- if (HEAPU32[0] !== 0x63736d65 /* 'emsc' */) {
- abort('Runtime error: The application has corrupted its heap memory area (address zero)!');
- }
- }
- // end include: runtime_stack_check.js
- // include: runtime_assertions.js
- // Endianness check
- (function() {
- var h16 = new Int16Array(1);
- var h8 = new Int8Array(h16.buffer);
- h16[0] = 0x6373;
- if (h8[0] !== 0x73 || h8[1] !== 0x63) throw 'Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)';
- })();
- // end include: runtime_assertions.js
- var __ATPRERUN__ = []; // functions called before the runtime is initialized
- var __ATINIT__ = []; // functions called during startup
- var __ATEXIT__ = []; // functions called during shutdown
- var __ATPOSTRUN__ = []; // functions called after the main() is called
- var runtimeInitialized = false;
- function keepRuntimeAlive() {
- return noExitRuntime;
- }
- function preRun() {
- if (Module['preRun']) {
- if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
- while (Module['preRun'].length) {
- addOnPreRun(Module['preRun'].shift());
- }
- }
- callRuntimeCallbacks(__ATPRERUN__);
- }
- function initRuntime() {
- assert(!runtimeInitialized);
- runtimeInitialized = true;
- checkStackCookie();
- SOCKFS.root = FS.mount(SOCKFS, {}, null);
- if (!Module["noFSInit"] && !FS.init.initialized)
- FS.init();
- FS.ignorePermissions = false;
- TTY.init();
- callRuntimeCallbacks(__ATINIT__);
- }
- function postRun() {
- checkStackCookie();
- if (Module['postRun']) {
- if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
- while (Module['postRun'].length) {
- addOnPostRun(Module['postRun'].shift());
- }
- }
- callRuntimeCallbacks(__ATPOSTRUN__);
- }
- function addOnPreRun(cb) {
- __ATPRERUN__.unshift(cb);
- }
- function addOnInit(cb) {
- __ATINIT__.unshift(cb);
- }
- function addOnExit(cb) {
- }
- function addOnPostRun(cb) {
- __ATPOSTRUN__.unshift(cb);
- }
- // include: runtime_math.js
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc
- assert(Math.imul, 'This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
- assert(Math.fround, 'This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
- assert(Math.clz32, 'This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
- assert(Math.trunc, 'This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
- // end include: runtime_math.js
- // A counter of dependencies for calling run(). If we need to
- // do asynchronous work before running, increment this and
- // decrement it. Incrementing must happen in a place like
- // Module.preRun (used by emcc to add file preloading).
- // Note that you can add dependencies in preRun, even though
- // it happens right before run - run will be postponed until
- // the dependencies are met.
- var runDependencies = 0;
- var runDependencyWatcher = null;
- var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
- var runDependencyTracking = {};
- function getUniqueRunDependency(id) {
- var orig = id;
- while (1) {
- if (!runDependencyTracking[id]) return id;
- id = orig + Math.random();
- }
- }
- function addRunDependency(id) {
- runDependencies++;
- if (Module['monitorRunDependencies']) {
- Module['monitorRunDependencies'](runDependencies);
- }
- if (id) {
- assert(!runDependencyTracking[id]);
- runDependencyTracking[id] = 1;
- if (runDependencyWatcher === null && typeof setInterval != 'undefined') {
- // Check for missing dependencies every few seconds
- runDependencyWatcher = setInterval(function() {
- if (ABORT) {
- clearInterval(runDependencyWatcher);
- runDependencyWatcher = null;
- return;
- }
- var shown = false;
- for (var dep in runDependencyTracking) {
- if (!shown) {
- shown = true;
- err('still waiting on run dependencies:');
- }
- err('dependency: ' + dep);
- }
- if (shown) {
- err('(end of list)');
- }
- }, 10000);
- }
- } else {
- err('warning: run dependency added without ID');
- }
- }
- function removeRunDependency(id) {
- runDependencies--;
- if (Module['monitorRunDependencies']) {
- Module['monitorRunDependencies'](runDependencies);
- }
- if (id) {
- assert(runDependencyTracking[id]);
- delete runDependencyTracking[id];
- } else {
- err('warning: run dependency removed without ID');
- }
- if (runDependencies == 0) {
- if (runDependencyWatcher !== null) {
- clearInterval(runDependencyWatcher);
- runDependencyWatcher = null;
- }
- if (dependenciesFulfilled) {
- var callback = dependenciesFulfilled;
- dependenciesFulfilled = null;
- callback(); // can add another dependenciesFulfilled
- }
- }
- }
- /** @param {string|number=} what */
- function abort(what) {
- if (Module['onAbort']) {
- Module['onAbort'](what);
- }
- what = 'Aborted(' + what + ')';
- // TODO(sbc): Should we remove printing and leave it up to whoever
- // catches the exception?
- err(what);
- ABORT = true;
- EXITSTATUS = 1;
- // Use a wasm runtime error, because a JS error might be seen as a foreign
- // exception, which means we'd run destructors on it. We need the error to
- // simply make the program stop.
- // FIXME This approach does not work in Wasm EH because it currently does not assume
- // all RuntimeErrors are from traps; it decides whether a RuntimeError is from
- // a trap or not based on a hidden field within the object. So at the moment
- // we don't have a way of throwing a wasm trap from JS. TODO Make a JS API that
- // allows this in the wasm spec.
- // Suppress closure compiler warning here. Closure compiler's builtin extern
- // defintion for WebAssembly.RuntimeError claims it takes no arguments even
- // though it can.
- // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed.
- /** @suppress {checkTypes} */
- var e = new WebAssembly.RuntimeError(what);
- readyPromiseReject(e);
- // Throw the error whether or not MODULARIZE is set because abort is used
- // in code paths apart from instantiation where an exception is expected
- // to be thrown when abort is called.
- throw e;
- }
- // {{MEM_INITIALIZER}}
- // include: memoryprofiler.js
- // end include: memoryprofiler.js
- // include: URIUtils.js
- // Prefix of data URIs emitted by SINGLE_FILE and related options.
- var dataURIPrefix = 'data:application/octet-stream;base64,';
- // Indicates whether filename is a base64 data URI.
- function isDataURI(filename) {
- // Prefix of data URIs emitted by SINGLE_FILE and related options.
- return filename.startsWith(dataURIPrefix);
- }
- // Indicates whether filename is delivered via file protocol (as opposed to http/https)
- function isFileURI(filename) {
- return filename.startsWith('file://');
- }
- // end include: URIUtils.js
- /** @param {boolean=} fixedasm */
- function createExportWrapper(name, fixedasm) {
- return function() {
- var displayName = name;
- var asm = fixedasm;
- if (!fixedasm) {
- asm = Module['asm'];
- }
- assert(runtimeInitialized, 'native function `' + displayName + '` called before runtime initialization');
- if (!asm[name]) {
- assert(asm[name], 'exported native function `' + displayName + '` not found');
- }
- return asm[name].apply(null, arguments);
- };
- }
- var wasmBinaryFile;
- if (Module['locateFile']) {
- wasmBinaryFile = 'rhino3dm.wasm';
- if (!isDataURI(wasmBinaryFile)) {
- wasmBinaryFile = locateFile(wasmBinaryFile);
- }
- } else {
- // Use bundler-friendly `new URL(..., import.meta.url)` pattern; works in browsers too.
- wasmBinaryFile = new URL('rhino3dm.wasm', import.meta.url).href;
- }
- function getBinary(file) {
- try {
- if (file == wasmBinaryFile && wasmBinary) {
- return new Uint8Array(wasmBinary);
- }
- if (readBinary) {
- return readBinary(file);
- }
- throw "both async and sync fetching of the wasm failed";
- }
- catch (err) {
- abort(err);
- }
- }
- function getBinaryPromise() {
- // If we don't have the binary yet, try to to load it asynchronously.
- // Fetch has some additional restrictions over XHR, like it can't be used on a file:// url.
- // See https://github.com/github/fetch/pull/92#issuecomment-140665932
- // Cordova or Electron apps are typically loaded from a file:// url.
- // So use fetch if it is available and the url is not a file, otherwise fall back to XHR.
- if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER)) {
- if (typeof fetch == 'function'
- && !isFileURI(wasmBinaryFile)
- ) {
- return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function(response) {
- if (!response['ok']) {
- throw "failed to load wasm binary file at '" + wasmBinaryFile + "'";
- }
- return response['arrayBuffer']();
- }).catch(function () {
- return getBinary(wasmBinaryFile);
- });
- }
- else {
- if (readAsync) {
- // fetch is not available or url is file => try XHR (readAsync uses XHR internally)
- return new Promise(function(resolve, reject) {
- readAsync(wasmBinaryFile, function(response) { resolve(new Uint8Array(/** @type{!ArrayBuffer} */(response))) }, reject)
- });
- }
- }
- }
- // Otherwise, getBinary should be able to get it synchronously
- return Promise.resolve().then(function() { return getBinary(wasmBinaryFile); });
- }
- // Create the wasm instance.
- // Receives the wasm imports, returns the exports.
- function createWasm() {
- // prepare imports
- var info = {
- 'env': asmLibraryArg,
- 'wasi_snapshot_preview1': asmLibraryArg,
- };
- // Load the wasm module and create an instance of using native support in the JS engine.
- // handle a generated wasm instance, receiving its exports and
- // performing other necessary setup
- /** @param {WebAssembly.Module=} module*/
- function receiveInstance(instance, module) {
- var exports = instance.exports;
- Module['asm'] = exports;
- wasmMemory = Module['asm']['memory'];
- assert(wasmMemory, "memory not found in wasm exports");
- // This assertion doesn't hold when emscripten is run in --post-link
- // mode.
- // TODO(sbc): Read INITIAL_MEMORY out of the wasm file in post-link mode.
- //assert(wasmMemory.buffer.byteLength === 16777216);
- updateMemoryViews();
- wasmTable = Module['asm']['__indirect_function_table'];
- assert(wasmTable, "table not found in wasm exports");
- addOnInit(Module['asm']['__wasm_call_ctors']);
- removeRunDependency('wasm-instantiate');
- }
- // wait for the pthread pool (if any)
- addRunDependency('wasm-instantiate');
- // Prefer streaming instantiation if available.
- // Async compilation can be confusing when an error on the page overwrites Module
- // (for example, if the order of elements is wrong, and the one defining Module is
- // later), so we save Module and check it later.
- var trueModule = Module;
- function receiveInstantiationResult(result) {
- // 'result' is a ResultObject object which has both the module and instance.
- // receiveInstance() will swap in the exports (to Module.asm) so they can be called
- assert(Module === trueModule, 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?');
- trueModule = null;
- // TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, the above line no longer optimizes out down to the following line.
- // When the regression is fixed, can restore the above USE_PTHREADS-enabled path.
- receiveInstance(result['instance']);
- }
- function instantiateArrayBuffer(receiver) {
- return getBinaryPromise().then(function(binary) {
- return WebAssembly.instantiate(binary, info);
- }).then(function (instance) {
- return instance;
- }).then(receiver, function(reason) {
- err('failed to asynchronously prepare wasm: ' + reason);
- // Warn on some common problems.
- if (isFileURI(wasmBinaryFile)) {
- err('warning: Loading from a file URI (' + wasmBinaryFile + ') is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing');
- }
- abort(reason);
- });
- }
- function instantiateAsync() {
- if (!wasmBinary &&
- typeof WebAssembly.instantiateStreaming == 'function' &&
- !isDataURI(wasmBinaryFile) &&
- // Don't use streaming for file:// delivered objects in a webview, fetch them synchronously.
- !isFileURI(wasmBinaryFile) &&
- // Avoid instantiateStreaming() on Node.js environment for now, as while
- // Node.js v18.1.0 implements it, it does not have a full fetch()
- // implementation yet.
- //
- // Reference:
- // https://github.com/emscripten-core/emscripten/pull/16917
- !ENVIRONMENT_IS_NODE &&
- typeof fetch == 'function') {
- return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function(response) {
- // Suppress closure warning here since the upstream definition for
- // instantiateStreaming only allows Promise<Repsponse> rather than
- // an actual Response.
- // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure is fixed.
- /** @suppress {checkTypes} */
- var result = WebAssembly.instantiateStreaming(response, info);
- return result.then(
- receiveInstantiationResult,
- function(reason) {
- // We expect the most common failure cause to be a bad MIME type for the binary,
- // in which case falling back to ArrayBuffer instantiation should work.
- err('wasm streaming compile failed: ' + reason);
- err('falling back to ArrayBuffer instantiation');
- return instantiateArrayBuffer(receiveInstantiationResult);
- });
- });
- } else {
- return instantiateArrayBuffer(receiveInstantiationResult);
- }
- }
- // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback
- // to manually instantiate the Wasm module themselves. This allows pages to run the instantiation parallel
- // to any other async startup actions they are performing.
- // Also pthreads and wasm workers initialize the wasm instance through this path.
- if (Module['instantiateWasm']) {
- try {
- var exports = Module['instantiateWasm'](info, receiveInstance);
- return exports;
- } catch(e) {
- err('Module.instantiateWasm callback failed with error: ' + e);
- // If instantiation fails, reject the module ready promise.
- readyPromiseReject(e);
- }
- }
- // If instantiation fails, reject the module ready promise.
- instantiateAsync().catch(readyPromiseReject);
- return {}; // no exports yet; we'll fill them in later
- }
- // Globals used by JS i64 conversions (see makeSetValue)
- var tempDouble;
- var tempI64;
- // === Body ===
- var ASM_CONSTS = {
-
- };
- /** @constructor */
- function ExitStatus(status) {
- this.name = 'ExitStatus';
- this.message = 'Program terminated with exit(' + status + ')';
- this.status = status;
- }
- function callRuntimeCallbacks(callbacks) {
- while (callbacks.length > 0) {
- // Pass the module as the first argument.
- callbacks.shift()(Module);
- }
- }
-
- /**
- * @param {number} ptr
- * @param {string} type
- */
- function getValue(ptr, type = 'i8') {
- if (type.endsWith('*')) type = '*';
- switch (type) {
- case 'i1': return HEAP8[((ptr)>>0)];
- case 'i8': return HEAP8[((ptr)>>0)];
- case 'i16': return HEAP16[((ptr)>>1)];
- case 'i32': return HEAP32[((ptr)>>2)];
- case 'i64': return HEAP32[((ptr)>>2)];
- case 'float': return HEAPF32[((ptr)>>2)];
- case 'double': return HEAPF64[((ptr)>>3)];
- case '*': return HEAPU32[((ptr)>>2)];
- default: abort('invalid type for getValue: ' + type);
- }
- return null;
- }
- function ptrToString(ptr) {
- assert(typeof ptr === 'number');
- return '0x' + ptr.toString(16).padStart(8, '0');
- }
-
- /**
- * @param {number} ptr
- * @param {number} value
- * @param {string} type
- */
- function setValue(ptr, value, type = 'i8') {
- if (type.endsWith('*')) type = '*';
- switch (type) {
- case 'i1': HEAP8[((ptr)>>0)] = value; break;
- case 'i8': HEAP8[((ptr)>>0)] = value; break;
- case 'i16': HEAP16[((ptr)>>1)] = value; break;
- case 'i32': HEAP32[((ptr)>>2)] = value; break;
- case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[((ptr)>>2)] = tempI64[0],HEAP32[(((ptr)+(4))>>2)] = tempI64[1]); break;
- case 'float': HEAPF32[((ptr)>>2)] = value; break;
- case 'double': HEAPF64[((ptr)>>3)] = value; break;
- case '*': HEAPU32[((ptr)>>2)] = value; break;
- default: abort('invalid type for setValue: ' + type);
- }
- }
- function warnOnce(text) {
- if (!warnOnce.shown) warnOnce.shown = {};
- if (!warnOnce.shown[text]) {
- warnOnce.shown[text] = 1;
- if (ENVIRONMENT_IS_NODE) text = 'warning: ' + text;
- err(text);
- }
- }
- function ___assert_fail(condition, filename, line, func) {
- abort('Assertion failed: ' + UTF8ToString(condition) + ', at: ' + [filename ? UTF8ToString(filename) : 'unknown filename', line, func ? UTF8ToString(func) : 'unknown function']);
- }
- /** @constructor */
- function ExceptionInfo(excPtr) {
- this.excPtr = excPtr;
- this.ptr = excPtr - 24;
-
- this.set_type = function(type) {
- HEAPU32[(((this.ptr)+(4))>>2)] = type;
- };
-
- this.get_type = function() {
- return HEAPU32[(((this.ptr)+(4))>>2)];
- };
-
- this.set_destructor = function(destructor) {
- HEAPU32[(((this.ptr)+(8))>>2)] = destructor;
- };
-
- this.get_destructor = function() {
- return HEAPU32[(((this.ptr)+(8))>>2)];
- };
-
- this.set_refcount = function(refcount) {
- HEAP32[((this.ptr)>>2)] = refcount;
- };
-
- this.set_caught = function (caught) {
- caught = caught ? 1 : 0;
- HEAP8[(((this.ptr)+(12))>>0)] = caught;
- };
-
- this.get_caught = function () {
- return HEAP8[(((this.ptr)+(12))>>0)] != 0;
- };
-
- this.set_rethrown = function (rethrown) {
- rethrown = rethrown ? 1 : 0;
- HEAP8[(((this.ptr)+(13))>>0)] = rethrown;
- };
-
- this.get_rethrown = function () {
- return HEAP8[(((this.ptr)+(13))>>0)] != 0;
- };
-
- // Initialize native structure fields. Should be called once after allocated.
- this.init = function(type, destructor) {
- this.set_adjusted_ptr(0);
- this.set_type(type);
- this.set_destructor(destructor);
- this.set_refcount(0);
- this.set_caught(false);
- this.set_rethrown(false);
- }
-
- this.add_ref = function() {
- var value = HEAP32[((this.ptr)>>2)];
- HEAP32[((this.ptr)>>2)] = value + 1;
- };
-
- // Returns true if last reference released.
- this.release_ref = function() {
- var prev = HEAP32[((this.ptr)>>2)];
- HEAP32[((this.ptr)>>2)] = prev - 1;
- assert(prev > 0);
- return prev === 1;
- };
-
- this.set_adjusted_ptr = function(adjustedPtr) {
- HEAPU32[(((this.ptr)+(16))>>2)] = adjustedPtr;
- };
-
- this.get_adjusted_ptr = function() {
- return HEAPU32[(((this.ptr)+(16))>>2)];
- };
-
- // Get pointer which is expected to be received by catch clause in C++ code. It may be adjusted
- // when the pointer is casted to some of the exception object base classes (e.g. when virtual
- // inheritance is used). When a pointer is thrown this method should return the thrown pointer
- // itself.
- this.get_exception_ptr = function() {
- // Work around a fastcomp bug, this code is still included for some reason in a build without
- // exceptions support.
- var isPointer = ___cxa_is_pointer_type(this.get_type());
- if (isPointer) {
- return HEAPU32[((this.excPtr)>>2)];
- }
- var adjusted = this.get_adjusted_ptr();
- if (adjusted !== 0) return adjusted;
- return this.excPtr;
- };
- }
-
- var exceptionLast = 0;
-
- var uncaughtExceptionCount = 0;
- function ___cxa_throw(ptr, type, destructor) {
- var info = new ExceptionInfo(ptr);
- // Initialize ExceptionInfo content after it was allocated in __cxa_allocate_exception.
- info.init(type, destructor);
- exceptionLast = ptr;
- uncaughtExceptionCount++;
- throw ptr + " - Exception catching is disabled, this exception cannot be caught. Compile with -sNO_DISABLE_EXCEPTION_CATCHING or -sEXCEPTION_CATCHING_ALLOWED=[..] to catch.";
- }
- function getRandomDevice() {
- if (typeof crypto == 'object' && typeof crypto['getRandomValues'] == 'function') {
- // for modern web browsers
- var randomBuffer = new Uint8Array(1);
- return () => { crypto.getRandomValues(randomBuffer); return randomBuffer[0]; };
- } else
- if (ENVIRONMENT_IS_NODE) {
- // for nodejs with or without crypto support included
- try {
- var crypto_module = require('crypto');
- // nodejs has crypto support
- return () => crypto_module['randomBytes'](1)[0];
- } catch (e) {
- // nodejs doesn't have crypto support
- }
- }
- // we couldn't find a proper implementation, as Math.random() is not suitable for /dev/random, see emscripten-core/emscripten/pull/7096
- return () => abort("no cryptographic support found for randomDevice. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: function(array) { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };");
- }
-
- var PATH = {isAbs:(path) => path.charAt(0) === '/',splitPath:(filename) => {
- var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
- return splitPathRe.exec(filename).slice(1);
- },normalizeArray:(parts, allowAboveRoot) => {
- // if the path tries to go above the root, `up` ends up > 0
- var up = 0;
- for (var i = parts.length - 1; i >= 0; i--) {
- var last = parts[i];
- if (last === '.') {
- parts.splice(i, 1);
- } else if (last === '..') {
- parts.splice(i, 1);
- up++;
- } else if (up) {
- parts.splice(i, 1);
- up--;
- }
- }
- // if the path is allowed to go above the root, restore leading ..s
- if (allowAboveRoot) {
- for (; up; up--) {
- parts.unshift('..');
- }
- }
- return parts;
- },normalize:(path) => {
- var isAbsolute = PATH.isAbs(path),
- trailingSlash = path.substr(-1) === '/';
- // Normalize the path
- path = PATH.normalizeArray(path.split('/').filter((p) => !!p), !isAbsolute).join('/');
- if (!path && !isAbsolute) {
- path = '.';
- }
- if (path && trailingSlash) {
- path += '/';
- }
- return (isAbsolute ? '/' : '') + path;
- },dirname:(path) => {
- var result = PATH.splitPath(path),
- root = result[0],
- dir = result[1];
- if (!root && !dir) {
- // No dirname whatsoever
- return '.';
- }
- if (dir) {
- // It has a dirname, strip trailing slash
- dir = dir.substr(0, dir.length - 1);
- }
- return root + dir;
- },basename:(path) => {
- // EMSCRIPTEN return '/'' for '/', not an empty string
- if (path === '/') return '/';
- path = PATH.normalize(path);
- path = path.replace(/\/$/, "");
- var lastSlash = path.lastIndexOf('/');
- if (lastSlash === -1) return path;
- return path.substr(lastSlash+1);
- },join:function() {
- var paths = Array.prototype.slice.call(arguments);
- return PATH.normalize(paths.join('/'));
- },join2:(l, r) => {
- return PATH.normalize(l + '/' + r);
- }};
-
-
- var PATH_FS = {resolve:function() {
- var resolvedPath = '',
- resolvedAbsolute = false;
- for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
- var path = (i >= 0) ? arguments[i] : FS.cwd();
- // Skip empty and invalid entries
- if (typeof path != 'string') {
- throw new TypeError('Arguments to path.resolve must be strings');
- } else if (!path) {
- return ''; // an invalid portion invalidates the whole thing
- }
- resolvedPath = path + '/' + resolvedPath;
- resolvedAbsolute = PATH.isAbs(path);
- }
- // At this point the path should be resolved to a full absolute path, but
- // handle relative paths to be safe (might happen when process.cwd() fails)
- resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter((p) => !!p), !resolvedAbsolute).join('/');
- return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
- },relative:(from, to) => {
- from = PATH_FS.resolve(from).substr(1);
- to = PATH_FS.resolve(to).substr(1);
- function trim(arr) {
- var start = 0;
- for (; start < arr.length; start++) {
- if (arr[start] !== '') break;
- }
- var end = arr.length - 1;
- for (; end >= 0; end--) {
- if (arr[end] !== '') break;
- }
- if (start > end) return [];
- return arr.slice(start, end - start + 1);
- }
- var fromParts = trim(from.split('/'));
- var toParts = trim(to.split('/'));
- var length = Math.min(fromParts.length, toParts.length);
- var samePartsLength = length;
- for (var i = 0; i < length; i++) {
- if (fromParts[i] !== toParts[i]) {
- samePartsLength = i;
- break;
- }
- }
- var outputParts = [];
- for (var i = samePartsLength; i < fromParts.length; i++) {
- outputParts.push('..');
- }
- outputParts = outputParts.concat(toParts.slice(samePartsLength));
- return outputParts.join('/');
- }};
-
-
- /** @type {function(string, boolean=, number=)} */
- function intArrayFromString(stringy, dontAddNull, length) {
- var len = length > 0 ? length : lengthBytesUTF8(stringy)+1;
- var u8array = new Array(len);
- var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length);
- if (dontAddNull) u8array.length = numBytesWritten;
- return u8array;
- }
- var TTY = {ttys:[],init:function () {
- // https://github.com/emscripten-core/emscripten/pull/1555
- // if (ENVIRONMENT_IS_NODE) {
- // // currently, FS.init does not distinguish if process.stdin is a file or TTY
- // // device, it always assumes it's a TTY device. because of this, we're forcing
- // // process.stdin to UTF8 encoding to at least make stdin reading compatible
- // // with text files until FS.init can be refactored.
- // process['stdin']['setEncoding']('utf8');
- // }
- },shutdown:function() {
- // https://github.com/emscripten-core/emscripten/pull/1555
- // if (ENVIRONMENT_IS_NODE) {
- // // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)?
- // // isaacs: because now it's reading from the stream, you've expressed interest in it, so that read() kicks off a _read() which creates a ReadReq operation
- // // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists?
- // // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle
- // // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call
- // process['stdin']['pause']();
- // }
- },register:function(dev, ops) {
- TTY.ttys[dev] = { input: [], output: [], ops: ops };
- FS.registerDevice(dev, TTY.stream_ops);
- },stream_ops:{open:function(stream) {
- var tty = TTY.ttys[stream.node.rdev];
- if (!tty) {
- throw new FS.ErrnoError(43);
- }
- stream.tty = tty;
- stream.seekable = false;
- },close:function(stream) {
- // flush any pending line data
- stream.tty.ops.fsync(stream.tty);
- },fsync:function(stream) {
- stream.tty.ops.fsync(stream.tty);
- },read:function(stream, buffer, offset, length, pos /* ignored */) {
- if (!stream.tty || !stream.tty.ops.get_char) {
- throw new FS.ErrnoError(60);
- }
- var bytesRead = 0;
- for (var i = 0; i < length; i++) {
- var result;
- try {
- result = stream.tty.ops.get_char(stream.tty);
- } catch (e) {
- throw new FS.ErrnoError(29);
- }
- if (result === undefined && bytesRead === 0) {
- throw new FS.ErrnoError(6);
- }
- if (result === null || result === undefined) break;
- bytesRead++;
- buffer[offset+i] = result;
- }
- if (bytesRead) {
- stream.node.timestamp = Date.now();
- }
- return bytesRead;
- },write:function(stream, buffer, offset, length, pos) {
- if (!stream.tty || !stream.tty.ops.put_char) {
- throw new FS.ErrnoError(60);
- }
- try {
- for (var i = 0; i < length; i++) {
- stream.tty.ops.put_char(stream.tty, buffer[offset+i]);
- }
- } catch (e) {
- throw new FS.ErrnoError(29);
- }
- if (length) {
- stream.node.timestamp = Date.now();
- }
- return i;
- }},default_tty_ops:{get_char:function(tty) {
- if (!tty.input.length) {
- var result = null;
- if (ENVIRONMENT_IS_NODE) {
- // we will read data by chunks of BUFSIZE
- var BUFSIZE = 256;
- var buf = Buffer.alloc(BUFSIZE);
- var bytesRead = 0;
-
- try {
- bytesRead = fs.readSync(process.stdin.fd, buf, 0, BUFSIZE, -1);
- } catch(e) {
- // Cross-platform differences: on Windows, reading EOF throws an exception, but on other OSes,
- // reading EOF returns 0. Uniformize behavior by treating the EOF exception to return 0.
- if (e.toString().includes('EOF')) bytesRead = 0;
- else throw e;
- }
-
- if (bytesRead > 0) {
- result = buf.slice(0, bytesRead).toString('utf-8');
- } else {
- result = null;
- }
- } else
- if (typeof window != 'undefined' &&
- typeof window.prompt == 'function') {
- // Browser.
- result = window.prompt('Input: '); // returns null on cancel
- if (result !== null) {
- result += '\n';
- }
- } else if (typeof readline == 'function') {
- // Command line.
- result = readline();
- if (result !== null) {
- result += '\n';
- }
- }
- if (!result) {
- return null;
- }
- tty.input = intArrayFromString(result, true);
- }
- return tty.input.shift();
- },put_char:function(tty, val) {
- if (val === null || val === 10) {
- out(UTF8ArrayToString(tty.output, 0));
- tty.output = [];
- } else {
- if (val != 0) tty.output.push(val); // val == 0 would cut text output off in the middle.
- }
- },fsync:function(tty) {
- if (tty.output && tty.output.length > 0) {
- out(UTF8ArrayToString(tty.output, 0));
- tty.output = [];
- }
- }},default_tty1_ops:{put_char:function(tty, val) {
- if (val === null || val === 10) {
- err(UTF8ArrayToString(tty.output, 0));
- tty.output = [];
- } else {
- if (val != 0) tty.output.push(val);
- }
- },fsync:function(tty) {
- if (tty.output && tty.output.length > 0) {
- err(UTF8ArrayToString(tty.output, 0));
- tty.output = [];
- }
- }}};
-
-
- function zeroMemory(address, size) {
- HEAPU8.fill(0, address, address + size);
- return address;
- }
-
- function alignMemory(size, alignment) {
- assert(alignment, "alignment argument is required");
- return Math.ceil(size / alignment) * alignment;
- }
- function mmapAlloc(size) {
- abort('internal error: mmapAlloc called but `emscripten_builtin_memalign` native symbol not exported');
- }
- var MEMFS = {ops_table:null,mount:function(mount) {
- return MEMFS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
- },createNode:function(parent, name, mode, dev) {
- if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
- // no supported
- throw new FS.ErrnoError(63);
- }
- if (!MEMFS.ops_table) {
- MEMFS.ops_table = {
- dir: {
- node: {
- getattr: MEMFS.node_ops.getattr,
- setattr: MEMFS.node_ops.setattr,
- lookup: MEMFS.node_ops.lookup,
- mknod: MEMFS.node_ops.mknod,
- rename: MEMFS.node_ops.rename,
- unlink: MEMFS.node_ops.unlink,
- rmdir: MEMFS.node_ops.rmdir,
- readdir: MEMFS.node_ops.readdir,
- symlink: MEMFS.node_ops.symlink
- },
- stream: {
- llseek: MEMFS.stream_ops.llseek
- }
- },
- file: {
- node: {
- getattr: MEMFS.node_ops.getattr,
- setattr: MEMFS.node_ops.setattr
- },
- stream: {
- llseek: MEMFS.stream_ops.llseek,
- read: MEMFS.stream_ops.read,
- write: MEMFS.stream_ops.write,
- allocate: MEMFS.stream_ops.allocate,
- mmap: MEMFS.stream_ops.mmap,
- msync: MEMFS.stream_ops.msync
- }
- },
- link: {
- node: {
- getattr: MEMFS.node_ops.getattr,
- setattr: MEMFS.node_ops.setattr,
- readlink: MEMFS.node_ops.readlink
- },
- stream: {}
- },
- chrdev: {
- node: {
- getattr: MEMFS.node_ops.getattr,
- setattr: MEMFS.node_ops.setattr
- },
- stream: FS.chrdev_stream_ops
- }
- };
- }
- var node = FS.createNode(parent, name, mode, dev);
- if (FS.isDir(node.mode)) {
- node.node_ops = MEMFS.ops_table.dir.node;
- node.stream_ops = MEMFS.ops_table.dir.stream;
- node.contents = {};
- } else if (FS.isFile(node.mode)) {
- node.node_ops = MEMFS.ops_table.file.node;
- node.stream_ops = MEMFS.ops_table.file.stream;
- node.usedBytes = 0; // The actual number of bytes used in the typed array, as opposed to contents.length which gives the whole capacity.
- // When the byte data of the file is populated, this will point to either a typed array, or a normal JS array. Typed arrays are preferred
- // for performance, and used by default. However, typed arrays are not resizable like normal JS arrays are, so there is a small disk size
- // penalty involved for appending file writes that continuously grow a file similar to std::vector capacity vs used -scheme.
- node.contents = null;
- } else if (FS.isLink(node.mode)) {
- node.node_ops = MEMFS.ops_table.link.node;
- node.stream_ops = MEMFS.ops_table.link.stream;
- } else if (FS.isChrdev(node.mode)) {
- node.node_ops = MEMFS.ops_table.chrdev.node;
- node.stream_ops = MEMFS.ops_table.chrdev.stream;
- }
- node.timestamp = Date.now();
- // add the new node to the parent
- if (parent) {
- parent.contents[name] = node;
- parent.timestamp = node.timestamp;
- }
- return node;
- },getFileDataAsTypedArray:function(node) {
- if (!node.contents) return new Uint8Array(0);
- if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes); // Make sure to not return excess unused bytes.
- return new Uint8Array(node.contents);
- },expandFileStorage:function(node, newCapacity) {
- var prevCapacity = node.contents ? node.contents.length : 0;
- if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough.
- // Don't expand strictly to the given requested limit if it's only a very small increase, but instead geometrically grow capacity.
- // For small filesizes (<1MB), perform size*2 geometric increase, but for large sizes, do a much more conservative size*1.125 increase to
- // avoid overshooting the allocation cap by a very large margin.
- var CAPACITY_DOUBLING_MAX = 1024 * 1024;
- newCapacity = Math.max(newCapacity, (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125)) >>> 0);
- if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding.
- var oldContents = node.contents;
- node.contents = new Uint8Array(newCapacity); // Allocate new storage.
- if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0); // Copy old data over to the new storage.
- },resizeFileStorage:function(node, newSize) {
- if (node.usedBytes == newSize) return;
- if (newSize == 0) {
- node.contents = null; // Fully decommit when requesting a resize to zero.
- node.usedBytes = 0;
- } else {
- var oldContents = node.contents;
- node.contents = new Uint8Array(newSize); // Allocate new storage.
- if (oldContents) {
- node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); // Copy old data over to the new storage.
- }
- node.usedBytes = newSize;
- }
- },node_ops:{getattr:function(node) {
- var attr = {};
- // device numbers reuse inode numbers.
- attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
- attr.ino = node.id;
- attr.mode = node.mode;
- attr.nlink = 1;
- attr.uid = 0;
- attr.gid = 0;
- attr.rdev = node.rdev;
- if (FS.isDir(node.mode)) {
- attr.size = 4096;
- } else if (FS.isFile(node.mode)) {
- attr.size = node.usedBytes;
- } else if (FS.isLink(node.mode)) {
- attr.size = node.link.length;
- } else {
- attr.size = 0;
- }
- attr.atime = new Date(node.timestamp);
- attr.mtime = new Date(node.timestamp);
- attr.ctime = new Date(node.timestamp);
- // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),
- // but this is not required by the standard.
- attr.blksize = 4096;
- attr.blocks = Math.ceil(attr.size / attr.blksize);
- return attr;
- },setattr:function(node, attr) {
- if (attr.mode !== undefined) {
- node.mode = attr.mode;
- }
- if (attr.timestamp !== undefined) {
- node.timestamp = attr.timestamp;
- }
- if (attr.size !== undefined) {
- MEMFS.resizeFileStorage(node, attr.size);
- }
- },lookup:function(parent, name) {
- throw FS.genericErrors[44];
- },mknod:function(parent, name, mode, dev) {
- return MEMFS.createNode(parent, name, mode, dev);
- },rename:function(old_node, new_dir, new_name) {
- // if we're overwriting a directory at new_name, make sure it's empty.
- if (FS.isDir(old_node.mode)) {
- var new_node;
- try {
- new_node = FS.lookupNode(new_dir, new_name);
- } catch (e) {
- }
- if (new_node) {
- for (var i in new_node.contents) {
- throw new FS.ErrnoError(55);
- }
- }
- }
- // do the internal rewiring
- delete old_node.parent.contents[old_node.name];
- old_node.parent.timestamp = Date.now()
- old_node.name = new_name;
- new_dir.contents[new_name] = old_node;
- new_dir.timestamp = old_node.parent.timestamp;
- old_node.parent = new_dir;
- },unlink:function(parent, name) {
- delete parent.contents[name];
- parent.timestamp = Date.now();
- },rmdir:function(parent, name) {
- var node = FS.lookupNode(parent, name);
- for (var i in node.contents) {
- throw new FS.ErrnoError(55);
- }
- delete parent.contents[name];
- parent.timestamp = Date.now();
- },readdir:function(node) {
- var entries = ['.', '..'];
- for (var key in node.contents) {
- if (!node.contents.hasOwnProperty(key)) {
- continue;
- }
- entries.push(key);
- }
- return entries;
- },symlink:function(parent, newname, oldpath) {
- var node = MEMFS.createNode(parent, newname, 511 /* 0777 */ | 40960, 0);
- node.link = oldpath;
- return node;
- },readlink:function(node) {
- if (!FS.isLink(node.mode)) {
- throw new FS.ErrnoError(28);
- }
- return node.link;
- }},stream_ops:{read:function(stream, buffer, offset, length, position) {
- var contents = stream.node.contents;
- if (position >= stream.node.usedBytes) return 0;
- var size = Math.min(stream.node.usedBytes - position, length);
- assert(size >= 0);
- if (size > 8 && contents.subarray) { // non-trivial, and typed array
- buffer.set(contents.subarray(position, position + size), offset);
- } else {
- for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i];
- }
- return size;
- },write:function(stream, buffer, offset, length, position, canOwn) {
- // The data buffer should be a typed array view
- assert(!(buffer instanceof ArrayBuffer));
- // If the buffer is located in main memory (HEAP), and if
- // memory can grow, we can't hold on to references of the
- // memory buffer, as they may get invalidated. That means we
- // need to do copy its contents.
- if (buffer.buffer === HEAP8.buffer) {
- canOwn = false;
- }
-
- if (!length) return 0;
- var node = stream.node;
- node.timestamp = Date.now();
-
- if (buffer.subarray && (!node.contents || node.contents.subarray)) { // This write is from a typed array to a typed array?
- if (canOwn) {
- assert(position === 0, 'canOwn must imply no weird position inside the file');
- node.contents = buffer.subarray(offset, offset + length);
- node.usedBytes = length;
- return length;
- } else if (node.usedBytes === 0 && position === 0) { // If this is a simple first write to an empty file, do a fast set since we don't need to care about old data.
- node.contents = buffer.slice(offset, offset + length);
- node.usedBytes = length;
- return length;
- } else if (position + length <= node.usedBytes) { // Writing to an already allocated and used subrange of the file?
- node.contents.set(buffer.subarray(offset, offset + length), position);
- return length;
- }
- }
-
- // Appending to an existing file and we need to reallocate, or source data did not come as a typed array.
- MEMFS.expandFileStorage(node, position+length);
- if (node.contents.subarray && buffer.subarray) {
- // Use typed array write which is available.
- node.contents.set(buffer.subarray(offset, offset + length), position);
- } else {
- for (var i = 0; i < length; i++) {
- node.contents[position + i] = buffer[offset + i]; // Or fall back to manual write if not.
- }
- }
- node.usedBytes = Math.max(node.usedBytes, position + length);
- return length;
- },llseek:function(stream, offset, whence) {
- var position = offset;
- if (whence === 1) {
- position += stream.position;
- } else if (whence === 2) {
- if (FS.isFile(stream.node.mode)) {
- position += stream.node.usedBytes;
- }
- }
- if (position < 0) {
- throw new FS.ErrnoError(28);
- }
- return position;
- },allocate:function(stream, offset, length) {
- MEMFS.expandFileStorage(stream.node, offset + length);
- stream.node.usedBytes = Math.max(stream.node.usedBytes, offset + length);
- },mmap:function(stream, length, position, prot, flags) {
- if (!FS.isFile(stream.node.mode)) {
- throw new FS.ErrnoError(43);
- }
- var ptr;
- var allocated;
- var contents = stream.node.contents;
- // Only make a new copy when MAP_PRIVATE is specified.
- if (!(flags & 2) && contents.buffer === HEAP8.buffer) {
- // We can't emulate MAP_SHARED when the file is not backed by the
- // buffer we're mapping to (e.g. the HEAP buffer).
- allocated = false;
- ptr = contents.byteOffset;
- } else {
- // Try to avoid unnecessary slices.
- if (position > 0 || position + length < contents.length) {
- if (contents.subarray) {
- contents = contents.subarray(position, position + length);
- } else {
- contents = Array.prototype.slice.call(contents, position, position + length);
- }
- }
- allocated = true;
- ptr = mmapAlloc(length);
- if (!ptr) {
- throw new FS.ErrnoError(48);
- }
- HEAP8.set(contents, ptr);
- }
- return { ptr: ptr, allocated: allocated };
- },msync:function(stream, buffer, offset, length, mmapFlags) {
- MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false);
- // should we check if bytesWritten and length are the same?
- return 0;
- }}};
-
- /** @param {boolean=} noRunDep */
- function asyncLoad(url, onload, onerror, noRunDep) {
- var dep = !noRunDep ? getUniqueRunDependency('al ' + url) : '';
- readAsync(url, (arrayBuffer) => {
- assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).');
- onload(new Uint8Array(arrayBuffer));
- if (dep) removeRunDependency(dep);
- }, (event) => {
- if (onerror) {
- onerror();
- } else {
- throw 'Loading data file "' + url + '" failed.';
- }
- });
- if (dep) addRunDependency(dep);
- }
-
-
- var ERRNO_MESSAGES = {0:"Success",1:"Arg list too long",2:"Permission denied",3:"Address already in use",4:"Address not available",5:"Address family not supported by protocol family",6:"No more processes",7:"Socket already connected",8:"Bad file number",9:"Trying to read unreadable message",10:"Mount device busy",11:"Operation canceled",12:"No children",13:"Connection aborted",14:"Connection refused",15:"Connection reset by peer",16:"File locking deadlock error",17:"Destination address required",18:"Math arg out of domain of func",19:"Quota exceeded",20:"File exists",21:"Bad address",22:"File too large",23:"Host is unreachable",24:"Identifier removed",25:"Illegal byte sequence",26:"Connection already in progress",27:"Interrupted system call",28:"Invalid argument",29:"I/O error",30:"Socket is already connected",31:"Is a directory",32:"Too many symbolic links",33:"Too many open files",34:"Too many links",35:"Message too long",36:"Multihop attempted",37:"File or path name too long",38:"Network interface is not configured",39:"Connection reset by network",40:"Network is unreachable",41:"Too many open files in system",42:"No buffer space available",43:"No such device",44:"No such file or directory",45:"Exec format error",46:"No record locks available",47:"The link has been severed",48:"Not enough core",49:"No message of desired type",50:"Protocol not available",51:"No space left on device",52:"Function not implemented",53:"Socket is not connected",54:"Not a directory",55:"Directory not empty",56:"State not recoverable",57:"Socket operation on non-socket",59:"Not a typewriter",60:"No such device or address",61:"Value too large for defined data type",62:"Previous owner died",63:"Not super-user",64:"Broken pipe",65:"Protocol error",66:"Unknown protocol",67:"Protocol wrong type for socket",68:"Math result not representable",69:"Read only file system",70:"Illegal seek",71:"No such process",72:"Stale file handle",73:"Connection timed out",74:"Text file busy",75:"Cross-device link",100:"Device not a stream",101:"Bad font file fmt",102:"Invalid slot",103:"Invalid request code",104:"No anode",105:"Block device required",106:"Channel number out of range",107:"Level 3 halted",108:"Level 3 reset",109:"Link number out of range",110:"Protocol driver not attached",111:"No CSI structure available",112:"Level 2 halted",113:"Invalid exchange",114:"Invalid request descriptor",115:"Exchange full",116:"No data (for no delay io)",117:"Timer expired",118:"Out of streams resources",119:"Machine is not on the network",120:"Package not installed",121:"The object is remote",122:"Advertise error",123:"Srmount error",124:"Communication error on send",125:"Cross mount point (not really error)",126:"Given log. name not unique",127:"f.d. invalid for this operation",128:"Remote address changed",129:"Can access a needed shared lib",130:"Accessing a corrupted shared lib",131:".lib section in a.out corrupted",132:"Attempting to link in too many libs",133:"Attempting to exec a shared library",135:"Streams pipe error",136:"Too many users",137:"Socket type not supported",138:"Not supported",139:"Protocol family not supported",140:"Can't send after socket shutdown",141:"Too many references",142:"Host is down",148:"No medium (in tape drive)",156:"Level 2 not synchronized"};
-
- var ERRNO_CODES = {};
-
- function withStackSave(f) {
- var stack = stackSave();
- var ret = f();
- stackRestore(stack);
- return ret;
- }
- function demangle(func) {
- warnOnce('warning: build with -sDEMANGLE_SUPPORT to link in libcxxabi demangling');
- return func;
- }
- function demangleAll(text) {
- var regex =
- /\b_Z[\w\d_]+/g;
- return text.replace(regex,
- function(x) {
- var y = demangle(x);
- return x === y ? x : (y + ' [' + x + ']');
- });
- }
- var FS = {root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,lookupPath:(path, opts = {}) => {
- path = PATH_FS.resolve(path);
-
- if (!path) return { path: '', node: null };
-
- var defaults = {
- follow_mount: true,
- recurse_count: 0
- };
- opts = Object.assign(defaults, opts)
-
- if (opts.recurse_count > 8) { // max recursive lookup of 8
- throw new FS.ErrnoError(32);
- }
-
- // split the absolute path
- var parts = path.split('/').filter((p) => !!p);
-
- // start at the root
- var current = FS.root;
- var current_path = '/';
-
- for (var i = 0; i < parts.length; i++) {
- var islast = (i === parts.length-1);
- if (islast && opts.parent) {
- // stop resolving
- break;
- }
-
- current = FS.lookupNode(current, parts[i]);
- current_path = PATH.join2(current_path, parts[i]);
-
- // jump to the mount's root node if this is a mountpoint
- if (FS.isMountpoint(current)) {
- if (!islast || (islast && opts.follow_mount)) {
- current = current.mounted.root;
- }
- }
-
- // by default, lookupPath will not follow a symlink if it is the final path component.
- // setting opts.follow = true will override this behavior.
- if (!islast || opts.follow) {
- var count = 0;
- while (FS.isLink(current.mode)) {
- var link = FS.readlink(current_path);
- current_path = PATH_FS.resolve(PATH.dirname(current_path), link);
-
- var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count + 1 });
- current = lookup.node;
-
- if (count++ > 40) { // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
- throw new FS.ErrnoError(32);
- }
- }
- }
- }
-
- return { path: current_path, node: current };
- },getPath:(node) => {
- var path;
- while (true) {
- if (FS.isRoot(node)) {
- var mount = node.mount.mountpoint;
- if (!path) return mount;
- return mount[mount.length-1] !== '/' ? mount + '/' + path : mount + path;
- }
- path = path ? node.name + '/' + path : node.name;
- node = node.parent;
- }
- },hashName:(parentid, name) => {
- var hash = 0;
-
- for (var i = 0; i < name.length; i++) {
- hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
- }
- return ((parentid + hash) >>> 0) % FS.nameTable.length;
- },hashAddNode:(node) => {
- var hash = FS.hashName(node.parent.id, node.name);
- node.name_next = FS.nameTable[hash];
- FS.nameTable[hash] = node;
- },hashRemoveNode:(node) => {
- var hash = FS.hashName(node.parent.id, node.name);
- if (FS.nameTable[hash] === node) {
- FS.nameTable[hash] = node.name_next;
- } else {
- var current = FS.nameTable[hash];
- while (current) {
- if (current.name_next === node) {
- current.name_next = node.name_next;
- break;
- }
- current = current.name_next;
- }
- }
- },lookupNode:(parent, name) => {
- var errCode = FS.mayLookup(parent);
- if (errCode) {
- throw new FS.ErrnoError(errCode, parent);
- }
- var hash = FS.hashName(parent.id, name);
- for (var node = FS.nameTable[hash]; node; node = node.name_next) {
- var nodeName = node.name;
- if (node.parent.id === parent.id && nodeName === name) {
- return node;
- }
- }
- // if we failed to find it in the cache, call into the VFS
- return FS.lookup(parent, name);
- },createNode:(parent, name, mode, rdev) => {
- assert(typeof parent == 'object')
- var node = new FS.FSNode(parent, name, mode, rdev);
-
- FS.hashAddNode(node);
-
- return node;
- },destroyNode:(node) => {
- FS.hashRemoveNode(node);
- },isRoot:(node) => {
- return node === node.parent;
- },isMountpoint:(node) => {
- return !!node.mounted;
- },isFile:(mode) => {
- return (mode & 61440) === 32768;
- },isDir:(mode) => {
- return (mode & 61440) === 16384;
- },isLink:(mode) => {
- return (mode & 61440) === 40960;
- },isChrdev:(mode) => {
- return (mode & 61440) === 8192;
- },isBlkdev:(mode) => {
- return (mode & 61440) === 24576;
- },isFIFO:(mode) => {
- return (mode & 61440) === 4096;
- },isSocket:(mode) => {
- return (mode & 49152) === 49152;
- },flagModes:{"r":0,"r+":2,"w":577,"w+":578,"a":1089,"a+":1090},modeStringToFlags:(str) => {
- var flags = FS.flagModes[str];
- if (typeof flags == 'undefined') {
- throw new Error('Unknown file open mode: ' + str);
- }
- return flags;
- },flagsToPermissionString:(flag) => {
- var perms = ['r', 'w', 'rw'][flag & 3];
- if ((flag & 512)) {
- perms += 'w';
- }
- return perms;
- },nodePermissions:(node, perms) => {
- if (FS.ignorePermissions) {
- return 0;
- }
- // return 0 if any user, group or owner bits are set.
- if (perms.includes('r') && !(node.mode & 292)) {
- return 2;
- } else if (perms.includes('w') && !(node.mode & 146)) {
- return 2;
- } else if (perms.includes('x') && !(node.mode & 73)) {
- return 2;
- }
- return 0;
- },mayLookup:(dir) => {
- var errCode = FS.nodePermissions(dir, 'x');
- if (errCode) return errCode;
- if (!dir.node_ops.lookup) return 2;
- return 0;
- },mayCreate:(dir, name) => {
- try {
- var node = FS.lookupNode(dir, name);
- return 20;
- } catch (e) {
- }
- return FS.nodePermissions(dir, 'wx');
- },mayDelete:(dir, name, isdir) => {
- var node;
- try {
- node = FS.lookupNode(dir, name);
- } catch (e) {
- return e.errno;
- }
- var errCode = FS.nodePermissions(dir, 'wx');
- if (errCode) {
- return errCode;
- }
- if (isdir) {
- if (!FS.isDir(node.mode)) {
- return 54;
- }
- if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
- return 10;
- }
- } else {
- if (FS.isDir(node.mode)) {
- return 31;
- }
- }
- return 0;
- },mayOpen:(node, flags) => {
- if (!node) {
- return 44;
- }
- if (FS.isLink(node.mode)) {
- return 32;
- } else if (FS.isDir(node.mode)) {
- if (FS.flagsToPermissionString(flags) !== 'r' || // opening for write
- (flags & 512)) { // TODO: check for O_SEARCH? (== search for dir only)
- return 31;
- }
- }
- return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
- },MAX_OPEN_FDS:4096,nextfd:(fd_start = 0, fd_end = FS.MAX_OPEN_FDS) => {
- for (var fd = fd_start; fd <= fd_end; fd++) {
- if (!FS.streams[fd]) {
- return fd;
- }
- }
- throw new FS.ErrnoError(33);
- },getStream:(fd) => FS.streams[fd],createStream:(stream, fd_start, fd_end) => {
- if (!FS.FSStream) {
- FS.FSStream = /** @constructor */ function() {
- this.shared = { };
- };
- FS.FSStream.prototype = {};
- Object.defineProperties(FS.FSStream.prototype, {
- object: {
- /** @this {FS.FSStream} */
- get: function() { return this.node; },
- /** @this {FS.FSStream} */
- set: function(val) { this.node = val; }
- },
- isRead: {
- /** @this {FS.FSStream} */
- get: function() { return (this.flags & 2097155) !== 1; }
- },
- isWrite: {
- /** @this {FS.FSStream} */
- get: function() { return (this.flags & 2097155) !== 0; }
- },
- isAppend: {
- /** @this {FS.FSStream} */
- get: function() { return (this.flags & 1024); }
- },
- flags: {
- /** @this {FS.FSStream} */
- get: function() { return this.shared.flags; },
- /** @this {FS.FSStream} */
- set: function(val) { this.shared.flags = val; },
- },
- position : {
- /** @this {FS.FSStream} */
- get: function() { return this.shared.position; },
- /** @this {FS.FSStream} */
- set: function(val) { this.shared.position = val; },
- },
- });
- }
- // clone it, so we can return an instance of FSStream
- stream = Object.assign(new FS.FSStream(), stream);
- var fd = FS.nextfd(fd_start, fd_end);
- stream.fd = fd;
- FS.streams[fd] = stream;
- return stream;
- },closeStream:(fd) => {
- FS.streams[fd] = null;
- },chrdev_stream_ops:{open:(stream) => {
- var device = FS.getDevice(stream.node.rdev);
- // override node's stream ops with the device's
- stream.stream_ops = device.stream_ops;
- // forward the open call
- if (stream.stream_ops.open) {
- stream.stream_ops.open(stream);
- }
- },llseek:() => {
- throw new FS.ErrnoError(70);
- }},major:(dev) => ((dev) >> 8),minor:(dev) => ((dev) & 0xff),makedev:(ma, mi) => ((ma) << 8 | (mi)),registerDevice:(dev, ops) => {
- FS.devices[dev] = { stream_ops: ops };
- },getDevice:(dev) => FS.devices[dev],getMounts:(mount) => {
- var mounts = [];
- var check = [mount];
-
- while (check.length) {
- var m = check.pop();
-
- mounts.push(m);
-
- check.push.apply(check, m.mounts);
- }
-
- return mounts;
- },syncfs:(populate, callback) => {
- if (typeof populate == 'function') {
- callback = populate;
- populate = false;
- }
-
- FS.syncFSRequests++;
-
- if (FS.syncFSRequests > 1) {
- err('warning: ' + FS.syncFSRequests + ' FS.syncfs operations in flight at once, probably just doing extra work');
- }
-
- var mounts = FS.getMounts(FS.root.mount);
- var completed = 0;
-
- function doCallback(errCode) {
- assert(FS.syncFSRequests > 0);
- FS.syncFSRequests--;
- return callback(errCode);
- }
-
- function done(errCode) {
- if (errCode) {
- if (!done.errored) {
- done.errored = true;
- return doCallback(errCode);
- }
- return;
- }
- if (++completed >= mounts.length) {
- doCallback(null);
- }
- };
-
- // sync all mounts
- mounts.forEach((mount) => {
- if (!mount.type.syncfs) {
- return done(null);
- }
- mount.type.syncfs(mount, populate, done);
- });
- },mount:(type, opts, mountpoint) => {
- if (typeof type == 'string') {
- // The filesystem was not included, and instead we have an error
- // message stored in the variable.
- throw type;
- }
- var root = mountpoint === '/';
- var pseudo = !mountpoint;
- var node;
-
- if (root && FS.root) {
- throw new FS.ErrnoError(10);
- } else if (!root && !pseudo) {
- var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
-
- mountpoint = lookup.path; // use the absolute path
- node = lookup.node;
-
- if (FS.isMountpoint(node)) {
- throw new FS.ErrnoError(10);
- }
-
- if (!FS.isDir(node.mode)) {
- throw new FS.ErrnoError(54);
- }
- }
-
- var mount = {
- type: type,
- opts: opts,
- mountpoint: mountpoint,
- mounts: []
- };
-
- // create a root node for the fs
- var mountRoot = type.mount(mount);
- mountRoot.mount = mount;
- mount.root = mountRoot;
-
- if (root) {
- FS.root = mountRoot;
- } else if (node) {
- // set as a mountpoint
- node.mounted = mount;
-
- // add the new mount to the current mount's children
- if (node.mount) {
- node.mount.mounts.push(mount);
- }
- }
-
- return mountRoot;
- },unmount:(mountpoint) => {
- var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
-
- if (!FS.isMountpoint(lookup.node)) {
- throw new FS.ErrnoError(28);
- }
-
- // destroy the nodes for this mount, and all its child mounts
- var node = lookup.node;
- var mount = node.mounted;
- var mounts = FS.getMounts(mount);
-
- Object.keys(FS.nameTable).forEach((hash) => {
- var current = FS.nameTable[hash];
-
- while (current) {
- var next = current.name_next;
-
- if (mounts.includes(current.mount)) {
- FS.destroyNode(current);
- }
-
- current = next;
- }
- });
-
- // no longer a mountpoint
- node.mounted = null;
-
- // remove this mount from the child mounts
- var idx = node.mount.mounts.indexOf(mount);
- assert(idx !== -1);
- node.mount.mounts.splice(idx, 1);
- },lookup:(parent, name) => {
- return parent.node_ops.lookup(parent, name);
- },mknod:(path, mode, dev) => {
- var lookup = FS.lookupPath(path, { parent: true });
- var parent = lookup.node;
- var name = PATH.basename(path);
- if (!name || name === '.' || name === '..') {
- throw new FS.ErrnoError(28);
- }
- var errCode = FS.mayCreate(parent, name);
- if (errCode) {
- throw new FS.ErrnoError(errCode);
- }
- if (!parent.node_ops.mknod) {
- throw new FS.ErrnoError(63);
- }
- return parent.node_ops.mknod(parent, name, mode, dev);
- },create:(path, mode) => {
- mode = mode !== undefined ? mode : 438 /* 0666 */;
- mode &= 4095;
- mode |= 32768;
- return FS.mknod(path, mode, 0);
- },mkdir:(path, mode) => {
- mode = mode !== undefined ? mode : 511 /* 0777 */;
- mode &= 511 | 512;
- mode |= 16384;
- return FS.mknod(path, mode, 0);
- },mkdirTree:(path, mode) => {
- var dirs = path.split('/');
- var d = '';
- for (var i = 0; i < dirs.length; ++i) {
- if (!dirs[i]) continue;
- d += '/' + dirs[i];
- try {
- FS.mkdir(d, mode);
- } catch(e) {
- if (e.errno != 20) throw e;
- }
- }
- },mkdev:(path, mode, dev) => {
- if (typeof dev == 'undefined') {
- dev = mode;
- mode = 438 /* 0666 */;
- }
- mode |= 8192;
- return FS.mknod(path, mode, dev);
- },symlink:(oldpath, newpath) => {
- if (!PATH_FS.resolve(oldpath)) {
- throw new FS.ErrnoError(44);
- }
- var lookup = FS.lookupPath(newpath, { parent: true });
- var parent = lookup.node;
- if (!parent) {
- throw new FS.ErrnoError(44);
- }
- var newname = PATH.basename(newpath);
- var errCode = FS.mayCreate(parent, newname);
- if (errCode) {
- throw new FS.ErrnoError(errCode);
- }
- if (!parent.node_ops.symlink) {
- throw new FS.ErrnoError(63);
- }
- return parent.node_ops.symlink(parent, newname, oldpath);
- },rename:(old_path, new_path) => {
- var old_dirname = PATH.dirname(old_path);
- var new_dirname = PATH.dirname(new_path);
- var old_name = PATH.basename(old_path);
- var new_name = PATH.basename(new_path);
- // parents must exist
- var lookup, old_dir, new_dir;
-
- // let the errors from non existant directories percolate up
- lookup = FS.lookupPath(old_path, { parent: true });
- old_dir = lookup.node;
- lookup = FS.lookupPath(new_path, { parent: true });
- new_dir = lookup.node;
-
- if (!old_dir || !new_dir) throw new FS.ErrnoError(44);
- // need to be part of the same mount
- if (old_dir.mount !== new_dir.mount) {
- throw new FS.ErrnoError(75);
- }
- // source must exist
- var old_node = FS.lookupNode(old_dir, old_name);
- // old path should not be an ancestor of the new path
- var relative = PATH_FS.relative(old_path, new_dirname);
- if (relative.charAt(0) !== '.') {
- throw new FS.ErrnoError(28);
- }
- // new path should not be an ancestor of the old path
- relative = PATH_FS.relative(new_path, old_dirname);
- if (relative.charAt(0) !== '.') {
- throw new FS.ErrnoError(55);
- }
- // see if the new path already exists
- var new_node;
- try {
- new_node = FS.lookupNode(new_dir, new_name);
- } catch (e) {
- // not fatal
- }
- // early out if nothing needs to change
- if (old_node === new_node) {
- return;
- }
- // we'll need to delete the old entry
- var isdir = FS.isDir(old_node.mode);
- var errCode = FS.mayDelete(old_dir, old_name, isdir);
- if (errCode) {
- throw new FS.ErrnoError(errCode);
- }
- // need delete permissions if we'll be overwriting.
- // need create permissions if new doesn't already exist.
- errCode = new_node ?
- FS.mayDelete(new_dir, new_name, isdir) :
- FS.mayCreate(new_dir, new_name);
- if (errCode) {
- throw new FS.ErrnoError(errCode);
- }
- if (!old_dir.node_ops.rename) {
- throw new FS.ErrnoError(63);
- }
- if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) {
- throw new FS.ErrnoError(10);
- }
- // if we are going to change the parent, check write permissions
- if (new_dir !== old_dir) {
- errCode = FS.nodePermissions(old_dir, 'w');
- if (errCode) {
- throw new FS.ErrnoError(errCode);
- }
- }
- // remove the node from the lookup hash
- FS.hashRemoveNode(old_node);
- // do the underlying fs rename
- try {
- old_dir.node_ops.rename(old_node, new_dir, new_name);
- } catch (e) {
- throw e;
- } finally {
- // add the node back to the hash (in case node_ops.rename
- // changed its name)
- FS.hashAddNode(old_node);
- }
- },rmdir:(path) => {
- var lookup = FS.lookupPath(path, { parent: true });
- var parent = lookup.node;
- var name = PATH.basename(path);
- var node = FS.lookupNode(parent, name);
- var errCode = FS.mayDelete(parent, name, true);
- if (errCode) {
- throw new FS.ErrnoError(errCode);
- }
- if (!parent.node_ops.rmdir) {
- throw new FS.ErrnoError(63);
- }
- if (FS.isMountpoint(node)) {
- throw new FS.ErrnoError(10);
- }
- parent.node_ops.rmdir(parent, name);
- FS.destroyNode(node);
- },readdir:(path) => {
- var lookup = FS.lookupPath(path, { follow: true });
- var node = lookup.node;
- if (!node.node_ops.readdir) {
- throw new FS.ErrnoError(54);
- }
- return node.node_ops.readdir(node);
- },unlink:(path) => {
- var lookup = FS.lookupPath(path, { parent: true });
- var parent = lookup.node;
- if (!parent) {
- throw new FS.ErrnoError(44);
- }
- var name = PATH.basename(path);
- var node = FS.lookupNode(parent, name);
- var errCode = FS.mayDelete(parent, name, false);
- if (errCode) {
- // According to POSIX, we should map EISDIR to EPERM, but
- // we instead do what Linux does (and we must, as we use
- // the musl linux libc).
- throw new FS.ErrnoError(errCode);
- }
- if (!parent.node_ops.unlink) {
- throw new FS.ErrnoError(63);
- }
- if (FS.isMountpoint(node)) {
- throw new FS.ErrnoError(10);
- }
- parent.node_ops.unlink(parent, name);
- FS.destroyNode(node);
- },readlink:(path) => {
- var lookup = FS.lookupPath(path);
- var link = lookup.node;
- if (!link) {
- throw new FS.ErrnoError(44);
- }
- if (!link.node_ops.readlink) {
- throw new FS.ErrnoError(28);
- }
- return PATH_FS.resolve(FS.getPath(link.parent), link.node_ops.readlink(link));
- },stat:(path, dontFollow) => {
- var lookup = FS.lookupPath(path, { follow: !dontFollow });
- var node = lookup.node;
- if (!node) {
- throw new FS.ErrnoError(44);
- }
- if (!node.node_ops.getattr) {
- throw new FS.ErrnoError(63);
- }
- return node.node_ops.getattr(node);
- },lstat:(path) => {
- return FS.stat(path, true);
- },chmod:(path, mode, dontFollow) => {
- var node;
- if (typeof path == 'string') {
- var lookup = FS.lookupPath(path, { follow: !dontFollow });
- node = lookup.node;
- } else {
- node = path;
- }
- if (!node.node_ops.setattr) {
- throw new FS.ErrnoError(63);
- }
- node.node_ops.setattr(node, {
- mode: (mode & 4095) | (node.mode & ~4095),
- timestamp: Date.now()
- });
- },lchmod:(path, mode) => {
- FS.chmod(path, mode, true);
- },fchmod:(fd, mode) => {
- var stream = FS.getStream(fd);
- if (!stream) {
- throw new FS.ErrnoError(8);
- }
- FS.chmod(stream.node, mode);
- },chown:(path, uid, gid, dontFollow) => {
- var node;
- if (typeof path == 'string') {
- var lookup = FS.lookupPath(path, { follow: !dontFollow });
- node = lookup.node;
- } else {
- node = path;
- }
- if (!node.node_ops.setattr) {
- throw new FS.ErrnoError(63);
- }
- node.node_ops.setattr(node, {
- timestamp: Date.now()
- // we ignore the uid / gid for now
- });
- },lchown:(path, uid, gid) => {
- FS.chown(path, uid, gid, true);
- },fchown:(fd, uid, gid) => {
- var stream = FS.getStream(fd);
- if (!stream) {
- throw new FS.ErrnoError(8);
- }
- FS.chown(stream.node, uid, gid);
- },truncate:(path, len) => {
- if (len < 0) {
- throw new FS.ErrnoError(28);
- }
- var node;
- if (typeof path == 'string') {
- var lookup = FS.lookupPath(path, { follow: true });
- node = lookup.node;
- } else {
- node = path;
- }
- if (!node.node_ops.setattr) {
- throw new FS.ErrnoError(63);
- }
- if (FS.isDir(node.mode)) {
- throw new FS.ErrnoError(31);
- }
- if (!FS.isFile(node.mode)) {
- throw new FS.ErrnoError(28);
- }
- var errCode = FS.nodePermissions(node, 'w');
- if (errCode) {
- throw new FS.ErrnoError(errCode);
- }
- node.node_ops.setattr(node, {
- size: len,
- timestamp: Date.now()
- });
- },ftruncate:(fd, len) => {
- var stream = FS.getStream(fd);
- if (!stream) {
- throw new FS.ErrnoError(8);
- }
- if ((stream.flags & 2097155) === 0) {
- throw new FS.ErrnoError(28);
- }
- FS.truncate(stream.node, len);
- },utime:(path, atime, mtime) => {
- var lookup = FS.lookupPath(path, { follow: true });
- var node = lookup.node;
- node.node_ops.setattr(node, {
- timestamp: Math.max(atime, mtime)
- });
- },open:(path, flags, mode) => {
- if (path === "") {
- throw new FS.ErrnoError(44);
- }
- flags = typeof flags == 'string' ? FS.modeStringToFlags(flags) : flags;
- mode = typeof mode == 'undefined' ? 438 /* 0666 */ : mode;
- if ((flags & 64)) {
- mode = (mode & 4095) | 32768;
- } else {
- mode = 0;
- }
- var node;
- if (typeof path == 'object') {
- node = path;
- } else {
- path = PATH.normalize(path);
- try {
- var lookup = FS.lookupPath(path, {
- follow: !(flags & 131072)
- });
- node = lookup.node;
- } catch (e) {
- // ignore
- }
- }
- // perhaps we need to create the node
- var created = false;
- if ((flags & 64)) {
- if (node) {
- // if O_CREAT and O_EXCL are set, error out if the node already exists
- if ((flags & 128)) {
- throw new FS.ErrnoError(20);
- }
- } else {
- // node doesn't exist, try to create it
- node = FS.mknod(path, mode, 0);
- created = true;
- }
- }
- if (!node) {
- throw new FS.ErrnoError(44);
- }
- // can't truncate a device
- if (FS.isChrdev(node.mode)) {
- flags &= ~512;
- }
- // if asked only for a directory, then this must be one
- if ((flags & 65536) && !FS.isDir(node.mode)) {
- throw new FS.ErrnoError(54);
- }
- // check permissions, if this is not a file we just created now (it is ok to
- // create and write to a file with read-only permissions; it is read-only
- // for later use)
- if (!created) {
- var errCode = FS.mayOpen(node, flags);
- if (errCode) {
- throw new FS.ErrnoError(errCode);
- }
- }
- // do truncation if necessary
- if ((flags & 512) && !created) {
- FS.truncate(node, 0);
- }
- // we've already handled these, don't pass down to the underlying vfs
- flags &= ~(128 | 512 | 131072);
-
- // register the stream with the filesystem
- var stream = FS.createStream({
- node: node,
- path: FS.getPath(node), // we want the absolute path to the node
- flags: flags,
- seekable: true,
- position: 0,
- stream_ops: node.stream_ops,
- // used by the file family libc calls (fopen, fwrite, ferror, etc.)
- ungotten: [],
- error: false
- });
- // call the new stream's open function
- if (stream.stream_ops.open) {
- stream.stream_ops.open(stream);
- }
- if (Module['logReadFiles'] && !(flags & 1)) {
- if (!FS.readFiles) FS.readFiles = {};
- if (!(path in FS.readFiles)) {
- FS.readFiles[path] = 1;
- }
- }
- return stream;
- },close:(stream) => {
- if (FS.isClosed(stream)) {
- throw new FS.ErrnoError(8);
- }
- if (stream.getdents) stream.getdents = null; // free readdir state
- try {
- if (stream.stream_ops.close) {
- stream.stream_ops.close(stream);
- }
- } catch (e) {
- throw e;
- } finally {
- FS.closeStream(stream.fd);
- }
- stream.fd = null;
- },isClosed:(stream) => {
- return stream.fd === null;
- },llseek:(stream, offset, whence) => {
- if (FS.isClosed(stream)) {
- throw new FS.ErrnoError(8);
- }
- if (!stream.seekable || !stream.stream_ops.llseek) {
- throw new FS.ErrnoError(70);
- }
- if (whence != 0 && whence != 1 && whence != 2) {
- throw new FS.ErrnoError(28);
- }
- stream.position = stream.stream_ops.llseek(stream, offset, whence);
- stream.ungotten = [];
- return stream.position;
- },read:(stream, buffer, offset, length, position) => {
- if (length < 0 || position < 0) {
- throw new FS.ErrnoError(28);
- }
- if (FS.isClosed(stream)) {
- throw new FS.ErrnoError(8);
- }
- if ((stream.flags & 2097155) === 1) {
- throw new FS.ErrnoError(8);
- }
- if (FS.isDir(stream.node.mode)) {
- throw new FS.ErrnoError(31);
- }
- if (!stream.stream_ops.read) {
- throw new FS.ErrnoError(28);
- }
- var seeking = typeof position != 'undefined';
- if (!seeking) {
- position = stream.position;
- } else if (!stream.seekable) {
- throw new FS.ErrnoError(70);
- }
- var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
- if (!seeking) stream.position += bytesRead;
- return bytesRead;
- },write:(stream, buffer, offset, length, position, canOwn) => {
- if (length < 0 || position < 0) {
- throw new FS.ErrnoError(28);
- }
- if (FS.isClosed(stream)) {
- throw new FS.ErrnoError(8);
- }
- if ((stream.flags & 2097155) === 0) {
- throw new FS.ErrnoError(8);
- }
- if (FS.isDir(stream.node.mode)) {
- throw new FS.ErrnoError(31);
- }
- if (!stream.stream_ops.write) {
- throw new FS.ErrnoError(28);
- }
- if (stream.seekable && stream.flags & 1024) {
- // seek to the end before writing in append mode
- FS.llseek(stream, 0, 2);
- }
- var seeking = typeof position != 'undefined';
- if (!seeking) {
- position = stream.position;
- } else if (!stream.seekable) {
- throw new FS.ErrnoError(70);
- }
- var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
- if (!seeking) stream.position += bytesWritten;
- return bytesWritten;
- },allocate:(stream, offset, length) => {
- if (FS.isClosed(stream)) {
- throw new FS.ErrnoError(8);
- }
- if (offset < 0 || length <= 0) {
- throw new FS.ErrnoError(28);
- }
- if ((stream.flags & 2097155) === 0) {
- throw new FS.ErrnoError(8);
- }
- if (!FS.isFile(stream.node.mode) && !FS.isDir(stream.node.mode)) {
- throw new FS.ErrnoError(43);
- }
- if (!stream.stream_ops.allocate) {
- throw new FS.ErrnoError(138);
- }
- stream.stream_ops.allocate(stream, offset, length);
- },mmap:(stream, length, position, prot, flags) => {
- // User requests writing to file (prot & PROT_WRITE != 0).
- // Checking if we have permissions to write to the file unless
- // MAP_PRIVATE flag is set. According to POSIX spec it is possible
- // to write to file opened in read-only mode with MAP_PRIVATE flag,
- // as all modifications will be visible only in the memory of
- // the current process.
- if ((prot & 2) !== 0
- && (flags & 2) === 0
- && (stream.flags & 2097155) !== 2) {
- throw new FS.ErrnoError(2);
- }
- if ((stream.flags & 2097155) === 1) {
- throw new FS.ErrnoError(2);
- }
- if (!stream.stream_ops.mmap) {
- throw new FS.ErrnoError(43);
- }
- return stream.stream_ops.mmap(stream, length, position, prot, flags);
- },msync:(stream, buffer, offset, length, mmapFlags) => {
- if (!stream.stream_ops.msync) {
- return 0;
- }
- return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags);
- },munmap:(stream) => 0,ioctl:(stream, cmd, arg) => {
- if (!stream.stream_ops.ioctl) {
- throw new FS.ErrnoError(59);
- }
- return stream.stream_ops.ioctl(stream, cmd, arg);
- },readFile:(path, opts = {}) => {
- opts.flags = opts.flags || 0;
- opts.encoding = opts.encoding || 'binary';
- if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
- throw new Error('Invalid encoding type "' + opts.encoding + '"');
- }
- var ret;
- var stream = FS.open(path, opts.flags);
- var stat = FS.stat(path);
- var length = stat.size;
- var buf = new Uint8Array(length);
- FS.read(stream, buf, 0, length, 0);
- if (opts.encoding === 'utf8') {
- ret = UTF8ArrayToString(buf, 0);
- } else if (opts.encoding === 'binary') {
- ret = buf;
- }
- FS.close(stream);
- return ret;
- },writeFile:(path, data, opts = {}) => {
- opts.flags = opts.flags || 577;
- var stream = FS.open(path, opts.flags, opts.mode);
- if (typeof data == 'string') {
- var buf = new Uint8Array(lengthBytesUTF8(data)+1);
- var actualNumBytes = stringToUTF8Array(data, buf, 0, buf.length);
- FS.write(stream, buf, 0, actualNumBytes, undefined, opts.canOwn);
- } else if (ArrayBuffer.isView(data)) {
- FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn);
- } else {
- throw new Error('Unsupported data type');
- }
- FS.close(stream);
- },cwd:() => FS.currentPath,chdir:(path) => {
- var lookup = FS.lookupPath(path, { follow: true });
- if (lookup.node === null) {
- throw new FS.ErrnoError(44);
- }
- if (!FS.isDir(lookup.node.mode)) {
- throw new FS.ErrnoError(54);
- }
- var errCode = FS.nodePermissions(lookup.node, 'x');
- if (errCode) {
- throw new FS.ErrnoError(errCode);
- }
- FS.currentPath = lookup.path;
- },createDefaultDirectories:() => {
- FS.mkdir('/tmp');
- FS.mkdir('/home');
- FS.mkdir('/home/web_user');
- },createDefaultDevices:() => {
- // create /dev
- FS.mkdir('/dev');
- // setup /dev/null
- FS.registerDevice(FS.makedev(1, 3), {
- read: () => 0,
- write: (stream, buffer, offset, length, pos) => length,
- });
- FS.mkdev('/dev/null', FS.makedev(1, 3));
- // setup /dev/tty and /dev/tty1
- // stderr needs to print output using err() rather than out()
- // so we register a second tty just for it.
- TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
- TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
- FS.mkdev('/dev/tty', FS.makedev(5, 0));
- FS.mkdev('/dev/tty1', FS.makedev(6, 0));
- // setup /dev/[u]random
- var random_device = getRandomDevice();
- FS.createDevice('/dev', 'random', random_device);
- FS.createDevice('/dev', 'urandom', random_device);
- // we're not going to emulate the actual shm device,
- // just create the tmp dirs that reside in it commonly
- FS.mkdir('/dev/shm');
- FS.mkdir('/dev/shm/tmp');
- },createSpecialDirectories:() => {
- // create /proc/self/fd which allows /proc/self/fd/6 => readlink gives the
- // name of the stream for fd 6 (see test_unistd_ttyname)
- FS.mkdir('/proc');
- var proc_self = FS.mkdir('/proc/self');
- FS.mkdir('/proc/self/fd');
- FS.mount({
- mount: () => {
- var node = FS.createNode(proc_self, 'fd', 16384 | 511 /* 0777 */, 73);
- node.node_ops = {
- lookup: (parent, name) => {
- var fd = +name;
- var stream = FS.getStream(fd);
- if (!stream) throw new FS.ErrnoError(8);
- var ret = {
- parent: null,
- mount: { mountpoint: 'fake' },
- node_ops: { readlink: () => stream.path },
- };
- ret.parent = ret; // make it look like a simple root node
- return ret;
- }
- };
- return node;
- }
- }, {}, '/proc/self/fd');
- },createStandardStreams:() => {
- // TODO deprecate the old functionality of a single
- // input / output callback and that utilizes FS.createDevice
- // and instead require a unique set of stream ops
-
- // by default, we symlink the standard streams to the
- // default tty devices. however, if the standard streams
- // have been overwritten we create a unique device for
- // them instead.
- if (Module['stdin']) {
- FS.createDevice('/dev', 'stdin', Module['stdin']);
- } else {
- FS.symlink('/dev/tty', '/dev/stdin');
- }
- if (Module['stdout']) {
- FS.createDevice('/dev', 'stdout', null, Module['stdout']);
- } else {
- FS.symlink('/dev/tty', '/dev/stdout');
- }
- if (Module['stderr']) {
- FS.createDevice('/dev', 'stderr', null, Module['stderr']);
- } else {
- FS.symlink('/dev/tty1', '/dev/stderr');
- }
-
- // open default streams for the stdin, stdout and stderr devices
- var stdin = FS.open('/dev/stdin', 0);
- var stdout = FS.open('/dev/stdout', 1);
- var stderr = FS.open('/dev/stderr', 1);
- assert(stdin.fd === 0, 'invalid handle for stdin (' + stdin.fd + ')');
- assert(stdout.fd === 1, 'invalid handle for stdout (' + stdout.fd + ')');
- assert(stderr.fd === 2, 'invalid handle for stderr (' + stderr.fd + ')');
- },ensureErrnoError:() => {
- if (FS.ErrnoError) return;
- FS.ErrnoError = /** @this{Object} */ function ErrnoError(errno, node) {
- this.node = node;
- this.setErrno = /** @this{Object} */ function(errno) {
- this.errno = errno;
- for (var key in ERRNO_CODES) {
- if (ERRNO_CODES[key] === errno) {
- this.code = key;
- break;
- }
- }
- };
- this.setErrno(errno);
- this.message = ERRNO_MESSAGES[errno];
-
- // Try to get a maximally helpful stack trace. On Node.js, getting Error.stack
- // now ensures it shows what we want.
- if (this.stack) {
- // Define the stack property for Node.js 4, which otherwise errors on the next line.
- Object.defineProperty(this, "stack", { value: (new Error).stack, writable: true });
- this.stack = demangleAll(this.stack);
- }
- };
- FS.ErrnoError.prototype = new Error();
- FS.ErrnoError.prototype.constructor = FS.ErrnoError;
- // Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info)
- [44].forEach((code) => {
- FS.genericErrors[code] = new FS.ErrnoError(code);
- FS.genericErrors[code].stack = '<generic error, no stack>';
- });
- },staticInit:() => {
- FS.ensureErrnoError();
-
- FS.nameTable = new Array(4096);
-
- FS.mount(MEMFS, {}, '/');
-
- FS.createDefaultDirectories();
- FS.createDefaultDevices();
- FS.createSpecialDirectories();
-
- FS.filesystems = {
- 'MEMFS': MEMFS,
- };
- },init:(input, output, error) => {
- assert(!FS.init.initialized, 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)');
- FS.init.initialized = true;
-
- FS.ensureErrnoError();
-
- // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
- Module['stdin'] = input || Module['stdin'];
- Module['stdout'] = output || Module['stdout'];
- Module['stderr'] = error || Module['stderr'];
-
- FS.createStandardStreams();
- },quit:() => {
- FS.init.initialized = false;
- // force-flush all streams, so we get musl std streams printed out
- _fflush(0);
- // close all of our streams
- for (var i = 0; i < FS.streams.length; i++) {
- var stream = FS.streams[i];
- if (!stream) {
- continue;
- }
- FS.close(stream);
- }
- },getMode:(canRead, canWrite) => {
- var mode = 0;
- if (canRead) mode |= 292 | 73;
- if (canWrite) mode |= 146;
- return mode;
- },findObject:(path, dontResolveLastLink) => {
- var ret = FS.analyzePath(path, dontResolveLastLink);
- if (!ret.exists) {
- return null;
- }
- return ret.object;
- },analyzePath:(path, dontResolveLastLink) => {
- // operate from within the context of the symlink's target
- try {
- var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
- path = lookup.path;
- } catch (e) {
- }
- var ret = {
- isRoot: false, exists: false, error: 0, name: null, path: null, object: null,
- parentExists: false, parentPath: null, parentObject: null
- };
- try {
- var lookup = FS.lookupPath(path, { parent: true });
- ret.parentExists = true;
- ret.parentPath = lookup.path;
- ret.parentObject = lookup.node;
- ret.name = PATH.basename(path);
- lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
- ret.exists = true;
- ret.path = lookup.path;
- ret.object = lookup.node;
- ret.name = lookup.node.name;
- ret.isRoot = lookup.path === '/';
- } catch (e) {
- ret.error = e.errno;
- };
- return ret;
- },createPath:(parent, path, canRead, canWrite) => {
- parent = typeof parent == 'string' ? parent : FS.getPath(parent);
- var parts = path.split('/').reverse();
- while (parts.length) {
- var part = parts.pop();
- if (!part) continue;
- var current = PATH.join2(parent, part);
- try {
- FS.mkdir(current);
- } catch (e) {
- // ignore EEXIST
- }
- parent = current;
- }
- return current;
- },createFile:(parent, name, properties, canRead, canWrite) => {
- var path = PATH.join2(typeof parent == 'string' ? parent : FS.getPath(parent), name);
- var mode = FS.getMode(canRead, canWrite);
- return FS.create(path, mode);
- },createDataFile:(parent, name, data, canRead, canWrite, canOwn) => {
- var path = name;
- if (parent) {
- parent = typeof parent == 'string' ? parent : FS.getPath(parent);
- path = name ? PATH.join2(parent, name) : parent;
- }
- var mode = FS.getMode(canRead, canWrite);
- var node = FS.create(path, mode);
- if (data) {
- if (typeof data == 'string') {
- var arr = new Array(data.length);
- for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
- data = arr;
- }
- // make sure we can write to the file
- FS.chmod(node, mode | 146);
- var stream = FS.open(node, 577);
- FS.write(stream, data, 0, data.length, 0, canOwn);
- FS.close(stream);
- FS.chmod(node, mode);
- }
- return node;
- },createDevice:(parent, name, input, output) => {
- var path = PATH.join2(typeof parent == 'string' ? parent : FS.getPath(parent), name);
- var mode = FS.getMode(!!input, !!output);
- if (!FS.createDevice.major) FS.createDevice.major = 64;
- var dev = FS.makedev(FS.createDevice.major++, 0);
- // Create a fake device that a set of stream ops to emulate
- // the old behavior.
- FS.registerDevice(dev, {
- open: (stream) => {
- stream.seekable = false;
- },
- close: (stream) => {
- // flush any pending line data
- if (output && output.buffer && output.buffer.length) {
- output(10);
- }
- },
- read: (stream, buffer, offset, length, pos /* ignored */) => {
- var bytesRead = 0;
- for (var i = 0; i < length; i++) {
- var result;
- try {
- result = input();
- } catch (e) {
- throw new FS.ErrnoError(29);
- }
- if (result === undefined && bytesRead === 0) {
- throw new FS.ErrnoError(6);
- }
- if (result === null || result === undefined) break;
- bytesRead++;
- buffer[offset+i] = result;
- }
- if (bytesRead) {
- stream.node.timestamp = Date.now();
- }
- return bytesRead;
- },
- write: (stream, buffer, offset, length, pos) => {
- for (var i = 0; i < length; i++) {
- try {
- output(buffer[offset+i]);
- } catch (e) {
- throw new FS.ErrnoError(29);
- }
- }
- if (length) {
- stream.node.timestamp = Date.now();
- }
- return i;
- }
- });
- return FS.mkdev(path, mode, dev);
- },forceLoadFile:(obj) => {
- if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
- if (typeof XMLHttpRequest != 'undefined') {
- throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");
- } else if (read_) {
- // Command-line.
- try {
- // WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as
- // read() will try to parse UTF8.
- obj.contents = intArrayFromString(read_(obj.url), true);
- obj.usedBytes = obj.contents.length;
- } catch (e) {
- throw new FS.ErrnoError(29);
- }
- } else {
- throw new Error('Cannot load without read() or XMLHttpRequest.');
- }
- },createLazyFile:(parent, name, url, canRead, canWrite) => {
- // Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse.
- /** @constructor */
- function LazyUint8Array() {
- this.lengthKnown = false;
- this.chunks = []; // Loaded chunks. Index is the chunk number
- }
- LazyUint8Array.prototype.get = /** @this{Object} */ function LazyUint8Array_get(idx) {
- if (idx > this.length-1 || idx < 0) {
- return undefined;
- }
- var chunkOffset = idx % this.chunkSize;
- var chunkNum = (idx / this.chunkSize)|0;
- return this.getter(chunkNum)[chunkOffset];
- };
- LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) {
- this.getter = getter;
- };
- LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() {
- // Find length
- var xhr = new XMLHttpRequest();
- xhr.open('HEAD', url, false);
- xhr.send(null);
- if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
- var datalength = Number(xhr.getResponseHeader("Content-length"));
- var header;
- var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
- var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip";
-
- var chunkSize = 1024*1024; // Chunk size in bytes
-
- if (!hasByteServing) chunkSize = datalength;
-
- // Function to get a range from the remote URL.
- var doXHR = (from, to) => {
- if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!");
- if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!");
-
- // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
- var xhr = new XMLHttpRequest();
- xhr.open('GET', url, false);
- if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
-
- // Some hints to the browser that we want binary data.
- xhr.responseType = 'arraybuffer';
- if (xhr.overrideMimeType) {
- xhr.overrideMimeType('text/plain; charset=x-user-defined');
- }
-
- xhr.send(null);
- if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
- if (xhr.response !== undefined) {
- return new Uint8Array(/** @type{Array<number>} */(xhr.response || []));
- }
- return intArrayFromString(xhr.responseText || '', true);
- };
- var lazyArray = this;
- lazyArray.setDataGetter((chunkNum) => {
- var start = chunkNum * chunkSize;
- var end = (chunkNum+1) * chunkSize - 1; // including this byte
- end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block
- if (typeof lazyArray.chunks[chunkNum] == 'undefined') {
- lazyArray.chunks[chunkNum] = doXHR(start, end);
- }
- if (typeof lazyArray.chunks[chunkNum] == 'undefined') throw new Error('doXHR failed!');
- return lazyArray.chunks[chunkNum];
- });
-
- if (usesGzip || !datalength) {
- // if the server uses gzip or doesn't supply the length, we have to download the whole file to get the (uncompressed) length
- chunkSize = datalength = 1; // this will force getter(0)/doXHR do download the whole file
- datalength = this.getter(0).length;
- chunkSize = datalength;
- out("LazyFiles on gzip forces download of the whole file when length is accessed");
- }
-
- this._length = datalength;
- this._chunkSize = chunkSize;
- this.lengthKnown = true;
- };
- if (typeof XMLHttpRequest != 'undefined') {
- if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc';
- var lazyArray = new LazyUint8Array();
- Object.defineProperties(lazyArray, {
- length: {
- get: /** @this{Object} */ function() {
- if (!this.lengthKnown) {
- this.cacheLength();
- }
- return this._length;
- }
- },
- chunkSize: {
- get: /** @this{Object} */ function() {
- if (!this.lengthKnown) {
- this.cacheLength();
- }
- return this._chunkSize;
- }
- }
- });
-
- var properties = { isDevice: false, contents: lazyArray };
- } else {
- var properties = { isDevice: false, url: url };
- }
-
- var node = FS.createFile(parent, name, properties, canRead, canWrite);
- // This is a total hack, but I want to get this lazy file code out of the
- // core of MEMFS. If we want to keep this lazy file concept I feel it should
- // be its own thin LAZYFS proxying calls to MEMFS.
- if (properties.contents) {
- node.contents = properties.contents;
- } else if (properties.url) {
- node.contents = null;
- node.url = properties.url;
- }
- // Add a function that defers querying the file size until it is asked the first time.
- Object.defineProperties(node, {
- usedBytes: {
- get: /** @this {FSNode} */ function() { return this.contents.length; }
- }
- });
- // override each stream op with one that tries to force load the lazy file first
- var stream_ops = {};
- var keys = Object.keys(node.stream_ops);
- keys.forEach((key) => {
- var fn = node.stream_ops[key];
- stream_ops[key] = function forceLoadLazyFile() {
- FS.forceLoadFile(node);
- return fn.apply(null, arguments);
- };
- });
- function writeChunks(stream, buffer, offset, length, position) {
- var contents = stream.node.contents;
- if (position >= contents.length)
- return 0;
- var size = Math.min(contents.length - position, length);
- assert(size >= 0);
- if (contents.slice) { // normal array
- for (var i = 0; i < size; i++) {
- buffer[offset + i] = contents[position + i];
- }
- } else {
- for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR
- buffer[offset + i] = contents.get(position + i);
- }
- }
- return size;
- }
- // use a custom read function
- stream_ops.read = (stream, buffer, offset, length, position) => {
- FS.forceLoadFile(node);
- return writeChunks(stream, buffer, offset, length, position)
- };
- // use a custom mmap function
- stream_ops.mmap = (stream, length, position, prot, flags) => {
- FS.forceLoadFile(node);
- var ptr = mmapAlloc(length);
- if (!ptr) {
- throw new FS.ErrnoError(48);
- }
- writeChunks(stream, HEAP8, ptr, length, position);
- return { ptr: ptr, allocated: true };
- };
- node.stream_ops = stream_ops;
- return node;
- },createPreloadedFile:(parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) => {
- // TODO we should allow people to just pass in a complete filename instead
- // of parent and name being that we just join them anyways
- var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent;
- var dep = getUniqueRunDependency('cp ' + fullname); // might have several active requests for the same fullname
- function processData(byteArray) {
- function finish(byteArray) {
- if (preFinish) preFinish();
- if (!dontCreateFile) {
- FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
- }
- if (onload) onload();
- removeRunDependency(dep);
- }
- if (Browser.handledByPreloadPlugin(byteArray, fullname, finish, () => {
- if (onerror) onerror();
- removeRunDependency(dep);
- })) {
- return;
- }
- finish(byteArray);
- }
- addRunDependency(dep);
- if (typeof url == 'string') {
- asyncLoad(url, (byteArray) => processData(byteArray), onerror);
- } else {
- processData(url);
- }
- },indexedDB:() => {
- return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
- },DB_NAME:() => {
- return 'EM_FS_' + window.location.pathname;
- },DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:(paths, onload, onerror) => {
- onload = onload || (() => {});
- onerror = onerror || (() => {});
- var indexedDB = FS.indexedDB();
- try {
- var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
- } catch (e) {
- return onerror(e);
- }
- openRequest.onupgradeneeded = () => {
- out('creating db');
- var db = openRequest.result;
- db.createObjectStore(FS.DB_STORE_NAME);
- };
- openRequest.onsuccess = () => {
- var db = openRequest.result;
- var transaction = db.transaction([FS.DB_STORE_NAME], 'readwrite');
- var files = transaction.objectStore(FS.DB_STORE_NAME);
- var ok = 0, fail = 0, total = paths.length;
- function finish() {
- if (fail == 0) onload(); else onerror();
- }
- paths.forEach((path) => {
- var putRequest = files.put(FS.analyzePath(path).object.contents, path);
- putRequest.onsuccess = () => { ok++; if (ok + fail == total) finish() };
- putRequest.onerror = () => { fail++; if (ok + fail == total) finish() };
- });
- transaction.onerror = onerror;
- };
- openRequest.onerror = onerror;
- },loadFilesFromDB:(paths, onload, onerror) => {
- onload = onload || (() => {});
- onerror = onerror || (() => {});
- var indexedDB = FS.indexedDB();
- try {
- var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
- } catch (e) {
- return onerror(e);
- }
- openRequest.onupgradeneeded = onerror; // no database to load from
- openRequest.onsuccess = () => {
- var db = openRequest.result;
- try {
- var transaction = db.transaction([FS.DB_STORE_NAME], 'readonly');
- } catch(e) {
- onerror(e);
- return;
- }
- var files = transaction.objectStore(FS.DB_STORE_NAME);
- var ok = 0, fail = 0, total = paths.length;
- function finish() {
- if (fail == 0) onload(); else onerror();
- }
- paths.forEach((path) => {
- var getRequest = files.get(path);
- getRequest.onsuccess = () => {
- if (FS.analyzePath(path).exists) {
- FS.unlink(path);
- }
- FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true);
- ok++;
- if (ok + fail == total) finish();
- };
- getRequest.onerror = () => { fail++; if (ok + fail == total) finish() };
- });
- transaction.onerror = onerror;
- };
- openRequest.onerror = onerror;
- },absolutePath:() => {
- abort('FS.absolutePath has been removed; use PATH_FS.resolve instead');
- },createFolder:() => {
- abort('FS.createFolder has been removed; use FS.mkdir instead');
- },createLink:() => {
- abort('FS.createLink has been removed; use FS.symlink instead');
- },joinPath:() => {
- abort('FS.joinPath has been removed; use PATH.join instead');
- },mmapAlloc:() => {
- abort('FS.mmapAlloc has been replaced by the top level function mmapAlloc');
- },standardizePath:() => {
- abort('FS.standardizePath has been removed; use PATH.normalize instead');
- }};
- var SOCKFS = {mount:function(mount) {
- // If Module['websocket'] has already been defined (e.g. for configuring
- // the subprotocol/url) use that, if not initialise it to a new object.
- Module['websocket'] = (Module['websocket'] &&
- ('object' === typeof Module['websocket'])) ? Module['websocket'] : {};
-
- // Add the Event registration mechanism to the exported websocket configuration
- // object so we can register network callbacks from native JavaScript too.
- // For more documentation see system/include/emscripten/emscripten.h
- Module['websocket']._callbacks = {};
- Module['websocket']['on'] = /** @this{Object} */ function(event, callback) {
- if ('function' === typeof callback) {
- this._callbacks[event] = callback;
- }
- return this;
- };
-
- Module['websocket'].emit = /** @this{Object} */ function(event, param) {
- if ('function' === typeof this._callbacks[event]) {
- this._callbacks[event].call(this, param);
- }
- };
-
- // If debug is enabled register simple default logging callbacks for each Event.
-
- return FS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
- },createSocket:function(family, type, protocol) {
- type &= ~526336; // Some applications may pass it; it makes no sense for a single process.
- var streaming = type == 1;
- if (streaming && protocol && protocol != 6) {
- throw new FS.ErrnoError(66); // if SOCK_STREAM, must be tcp or 0.
- }
-
- // create our internal socket structure
- var sock = {
- family: family,
- type: type,
- protocol: protocol,
- server: null,
- error: null, // Used in getsockopt for SOL_SOCKET/SO_ERROR test
- peers: {},
- pending: [],
- recv_queue: [],
- sock_ops: SOCKFS.websocket_sock_ops
- };
-
- // create the filesystem node to store the socket structure
- var name = SOCKFS.nextname();
- var node = FS.createNode(SOCKFS.root, name, 49152, 0);
- node.sock = sock;
-
- // and the wrapping stream that enables library functions such
- // as read and write to indirectly interact with the socket
- var stream = FS.createStream({
- path: name,
- node: node,
- flags: 2,
- seekable: false,
- stream_ops: SOCKFS.stream_ops
- });
-
- // map the new stream to the socket structure (sockets have a 1:1
- // relationship with a stream)
- sock.stream = stream;
-
- return sock;
- },getSocket:function(fd) {
- var stream = FS.getStream(fd);
- if (!stream || !FS.isSocket(stream.node.mode)) {
- return null;
- }
- return stream.node.sock;
- },stream_ops:{poll:function(stream) {
- var sock = stream.node.sock;
- return sock.sock_ops.poll(sock);
- },ioctl:function(stream, request, varargs) {
- var sock = stream.node.sock;
- return sock.sock_ops.ioctl(sock, request, varargs);
- },read:function(stream, buffer, offset, length, position /* ignored */) {
- var sock = stream.node.sock;
- var msg = sock.sock_ops.recvmsg(sock, length);
- if (!msg) {
- // socket is closed
- return 0;
- }
- buffer.set(msg.buffer, offset);
- return msg.buffer.length;
- },write:function(stream, buffer, offset, length, position /* ignored */) {
- var sock = stream.node.sock;
- return sock.sock_ops.sendmsg(sock, buffer, offset, length);
- },close:function(stream) {
- var sock = stream.node.sock;
- sock.sock_ops.close(sock);
- }},nextname:function() {
- if (!SOCKFS.nextname.current) {
- SOCKFS.nextname.current = 0;
- }
- return 'socket[' + (SOCKFS.nextname.current++) + ']';
- },websocket_sock_ops:{createPeer:function(sock, addr, port) {
- var ws;
-
- if (typeof addr == 'object') {
- ws = addr;
- addr = null;
- port = null;
- }
-
- if (ws) {
- // for sockets that've already connected (e.g. we're the server)
- // we can inspect the _socket property for the address
- if (ws._socket) {
- addr = ws._socket.remoteAddress;
- port = ws._socket.remotePort;
- }
- // if we're just now initializing a connection to the remote,
- // inspect the url property
- else {
- var result = /ws[s]?:\/\/([^:]+):(\d+)/.exec(ws.url);
- if (!result) {
- throw new Error('WebSocket URL must be in the format ws(s)://address:port');
- }
- addr = result[1];
- port = parseInt(result[2], 10);
- }
- } else {
- // create the actual websocket object and connect
- try {
- // runtimeConfig gets set to true if WebSocket runtime configuration is available.
- var runtimeConfig = (Module['websocket'] && ('object' === typeof Module['websocket']));
-
- // The default value is 'ws://' the replace is needed because the compiler replaces '//' comments with '#'
- // comments without checking context, so we'd end up with ws:#, the replace swaps the '#' for '//' again.
- var url = 'ws:#'.replace('#', '//');
-
- if (runtimeConfig) {
- if ('string' === typeof Module['websocket']['url']) {
- url = Module['websocket']['url']; // Fetch runtime WebSocket URL config.
- }
- }
-
- if (url === 'ws://' || url === 'wss://') { // Is the supplied URL config just a prefix, if so complete it.
- var parts = addr.split('/');
- url = url + parts[0] + ":" + port + "/" + parts.slice(1).join('/');
- }
-
- // Make the WebSocket subprotocol (Sec-WebSocket-Protocol) default to binary if no configuration is set.
- var subProtocols = 'binary'; // The default value is 'binary'
-
- if (runtimeConfig) {
- if ('string' === typeof Module['websocket']['subprotocol']) {
- subProtocols = Module['websocket']['subprotocol']; // Fetch runtime WebSocket subprotocol config.
- }
- }
-
- // The default WebSocket options
- var opts = undefined;
-
- if (subProtocols !== 'null') {
- // The regex trims the string (removes spaces at the beginning and end, then splits the string by
- // <any space>,<any space> into an Array. Whitespace removal is important for Websockify and ws.
- subProtocols = subProtocols.replace(/^ +| +$/g,"").split(/ *, */);
-
- opts = subProtocols;
- }
-
- // some webservers (azure) does not support subprotocol header
- if (runtimeConfig && null === Module['websocket']['subprotocol']) {
- subProtocols = 'null';
- opts = undefined;
- }
-
- // If node we use the ws library.
- var WebSocketConstructor;
- if (ENVIRONMENT_IS_NODE) {
- WebSocketConstructor = /** @type{(typeof WebSocket)} */(require('ws'));
- } else
- {
- WebSocketConstructor = WebSocket;
- }
- ws = new WebSocketConstructor(url, opts);
- ws.binaryType = 'arraybuffer';
- } catch (e) {
- throw new FS.ErrnoError(23);
- }
- }
-
- var peer = {
- addr: addr,
- port: port,
- socket: ws,
- dgram_send_queue: []
- };
-
- SOCKFS.websocket_sock_ops.addPeer(sock, peer);
- SOCKFS.websocket_sock_ops.handlePeerEvents(sock, peer);
-
- // if this is a bound dgram socket, send the port number first to allow
- // us to override the ephemeral port reported to us by remotePort on the
- // remote end.
- if (sock.type === 2 && typeof sock.sport != 'undefined') {
- peer.dgram_send_queue.push(new Uint8Array([
- 255, 255, 255, 255,
- 'p'.charCodeAt(0), 'o'.charCodeAt(0), 'r'.charCodeAt(0), 't'.charCodeAt(0),
- ((sock.sport & 0xff00) >> 8) , (sock.sport & 0xff)
- ]));
- }
-
- return peer;
- },getPeer:function(sock, addr, port) {
- return sock.peers[addr + ':' + port];
- },addPeer:function(sock, peer) {
- sock.peers[peer.addr + ':' + peer.port] = peer;
- },removePeer:function(sock, peer) {
- delete sock.peers[peer.addr + ':' + peer.port];
- },handlePeerEvents:function(sock, peer) {
- var first = true;
-
- var handleOpen = function () {
-
- Module['websocket'].emit('open', sock.stream.fd);
-
- try {
- var queued = peer.dgram_send_queue.shift();
- while (queued) {
- peer.socket.send(queued);
- queued = peer.dgram_send_queue.shift();
- }
- } catch (e) {
- // not much we can do here in the way of proper error handling as we've already
- // lied and said this data was sent. shut it down.
- peer.socket.close();
- }
- };
-
- function handleMessage(data) {
- if (typeof data == 'string') {
- var encoder = new TextEncoder(); // should be utf-8
- data = encoder.encode(data); // make a typed array from the string
- } else {
- assert(data.byteLength !== undefined); // must receive an ArrayBuffer
- if (data.byteLength == 0) {
- // An empty ArrayBuffer will emit a pseudo disconnect event
- // as recv/recvmsg will return zero which indicates that a socket
- // has performed a shutdown although the connection has not been disconnected yet.
- return;
- }
- data = new Uint8Array(data); // make a typed array view on the array buffer
- }
-
- // if this is the port message, override the peer's port with it
- var wasfirst = first;
- first = false;
- if (wasfirst &&
- data.length === 10 &&
- data[0] === 255 && data[1] === 255 && data[2] === 255 && data[3] === 255 &&
- data[4] === 'p'.charCodeAt(0) && data[5] === 'o'.charCodeAt(0) && data[6] === 'r'.charCodeAt(0) && data[7] === 't'.charCodeAt(0)) {
- // update the peer's port and it's key in the peer map
- var newport = ((data[8] << 8) | data[9]);
- SOCKFS.websocket_sock_ops.removePeer(sock, peer);
- peer.port = newport;
- SOCKFS.websocket_sock_ops.addPeer(sock, peer);
- return;
- }
-
- sock.recv_queue.push({ addr: peer.addr, port: peer.port, data: data });
- Module['websocket'].emit('message', sock.stream.fd);
- };
-
- if (ENVIRONMENT_IS_NODE) {
- peer.socket.on('open', handleOpen);
- peer.socket.on('message', function(data, isBinary) {
- if (!isBinary) {
- return;
- }
- handleMessage((new Uint8Array(data)).buffer); // copy from node Buffer -> ArrayBuffer
- });
- peer.socket.on('close', function() {
- Module['websocket'].emit('close', sock.stream.fd);
- });
- peer.socket.on('error', function(error) {
- // Although the ws library may pass errors that may be more descriptive than
- // ECONNREFUSED they are not necessarily the expected error code e.g.
- // ENOTFOUND on getaddrinfo seems to be node.js specific, so using ECONNREFUSED
- // is still probably the most useful thing to do.
- sock.error = 14; // Used in getsockopt for SOL_SOCKET/SO_ERROR test.
- Module['websocket'].emit('error', [sock.stream.fd, sock.error, 'ECONNREFUSED: Connection refused']);
- // don't throw
- });
- } else {
- peer.socket.onopen = handleOpen;
- peer.socket.onclose = function() {
- Module['websocket'].emit('close', sock.stream.fd);
- };
- peer.socket.onmessage = function peer_socket_onmessage(event) {
- handleMessage(event.data);
- };
- peer.socket.onerror = function(error) {
- // The WebSocket spec only allows a 'simple event' to be thrown on error,
- // so we only really know as much as ECONNREFUSED.
- sock.error = 14; // Used in getsockopt for SOL_SOCKET/SO_ERROR test.
- Module['websocket'].emit('error', [sock.stream.fd, sock.error, 'ECONNREFUSED: Connection refused']);
- };
- }
- },poll:function(sock) {
- if (sock.type === 1 && sock.server) {
- // listen sockets should only say they're available for reading
- // if there are pending clients.
- return sock.pending.length ? (64 | 1) : 0;
- }
-
- var mask = 0;
- var dest = sock.type === 1 ? // we only care about the socket state for connection-based sockets
- SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport) :
- null;
-
- if (sock.recv_queue.length ||
- !dest || // connection-less sockets are always ready to read
- (dest && dest.socket.readyState === dest.socket.CLOSING) ||
- (dest && dest.socket.readyState === dest.socket.CLOSED)) { // let recv return 0 once closed
- mask |= (64 | 1);
- }
-
- if (!dest || // connection-less sockets are always ready to write
- (dest && dest.socket.readyState === dest.socket.OPEN)) {
- mask |= 4;
- }
-
- if ((dest && dest.socket.readyState === dest.socket.CLOSING) ||
- (dest && dest.socket.readyState === dest.socket.CLOSED)) {
- mask |= 16;
- }
-
- return mask;
- },ioctl:function(sock, request, arg) {
- switch (request) {
- case 21531:
- var bytes = 0;
- if (sock.recv_queue.length) {
- bytes = sock.recv_queue[0].data.length;
- }
- HEAP32[((arg)>>2)] = bytes;
- return 0;
- default:
- return 28;
- }
- },close:function(sock) {
- // if we've spawned a listen server, close it
- if (sock.server) {
- try {
- sock.server.close();
- } catch (e) {
- }
- sock.server = null;
- }
- // close any peer connections
- var peers = Object.keys(sock.peers);
- for (var i = 0; i < peers.length; i++) {
- var peer = sock.peers[peers[i]];
- try {
- peer.socket.close();
- } catch (e) {
- }
- SOCKFS.websocket_sock_ops.removePeer(sock, peer);
- }
- return 0;
- },bind:function(sock, addr, port) {
- if (typeof sock.saddr != 'undefined' || typeof sock.sport != 'undefined') {
- throw new FS.ErrnoError(28); // already bound
- }
- sock.saddr = addr;
- sock.sport = port;
- // in order to emulate dgram sockets, we need to launch a listen server when
- // binding on a connection-less socket
- // note: this is only required on the server side
- if (sock.type === 2) {
- // close the existing server if it exists
- if (sock.server) {
- sock.server.close();
- sock.server = null;
- }
- // swallow error operation not supported error that occurs when binding in the
- // browser where this isn't supported
- try {
- sock.sock_ops.listen(sock, 0);
- } catch (e) {
- if (!(e instanceof FS.ErrnoError)) throw e;
- if (e.errno !== 138) throw e;
- }
- }
- },connect:function(sock, addr, port) {
- if (sock.server) {
- throw new FS.ErrnoError(138);
- }
-
- // TODO autobind
- // if (!sock.addr && sock.type == 2) {
- // }
-
- // early out if we're already connected / in the middle of connecting
- if (typeof sock.daddr != 'undefined' && typeof sock.dport != 'undefined') {
- var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
- if (dest) {
- if (dest.socket.readyState === dest.socket.CONNECTING) {
- throw new FS.ErrnoError(7);
- } else {
- throw new FS.ErrnoError(30);
- }
- }
- }
-
- // add the socket to our peer list and set our
- // destination address / port to match
- var peer = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
- sock.daddr = peer.addr;
- sock.dport = peer.port;
-
- // always "fail" in non-blocking mode
- throw new FS.ErrnoError(26);
- },listen:function(sock, backlog) {
- if (!ENVIRONMENT_IS_NODE) {
- throw new FS.ErrnoError(138);
- }
- if (sock.server) {
- throw new FS.ErrnoError(28); // already listening
- }
- var WebSocketServer = require('ws').Server;
- var host = sock.saddr;
- sock.server = new WebSocketServer({
- host: host,
- port: sock.sport
- // TODO support backlog
- });
- Module['websocket'].emit('listen', sock.stream.fd); // Send Event with listen fd.
-
- sock.server.on('connection', function(ws) {
- if (sock.type === 1) {
- var newsock = SOCKFS.createSocket(sock.family, sock.type, sock.protocol);
-
- // create a peer on the new socket
- var peer = SOCKFS.websocket_sock_ops.createPeer(newsock, ws);
- newsock.daddr = peer.addr;
- newsock.dport = peer.port;
-
- // push to queue for accept to pick up
- sock.pending.push(newsock);
- Module['websocket'].emit('connection', newsock.stream.fd);
- } else {
- // create a peer on the listen socket so calling sendto
- // with the listen socket and an address will resolve
- // to the correct client
- SOCKFS.websocket_sock_ops.createPeer(sock, ws);
- Module['websocket'].emit('connection', sock.stream.fd);
- }
- });
- sock.server.on('close', function() {
- Module['websocket'].emit('close', sock.stream.fd);
- sock.server = null;
- });
- sock.server.on('error', function(error) {
- // Although the ws library may pass errors that may be more descriptive than
- // ECONNREFUSED they are not necessarily the expected error code e.g.
- // ENOTFOUND on getaddrinfo seems to be node.js specific, so using EHOSTUNREACH
- // is still probably the most useful thing to do. This error shouldn't
- // occur in a well written app as errors should get trapped in the compiled
- // app's own getaddrinfo call.
- sock.error = 23; // Used in getsockopt for SOL_SOCKET/SO_ERROR test.
- Module['websocket'].emit('error', [sock.stream.fd, sock.error, 'EHOSTUNREACH: Host is unreachable']);
- // don't throw
- });
- },accept:function(listensock) {
- if (!listensock.server || !listensock.pending.length) {
- throw new FS.ErrnoError(28);
- }
- var newsock = listensock.pending.shift();
- newsock.stream.flags = listensock.stream.flags;
- return newsock;
- },getname:function(sock, peer) {
- var addr, port;
- if (peer) {
- if (sock.daddr === undefined || sock.dport === undefined) {
- throw new FS.ErrnoError(53);
- }
- addr = sock.daddr;
- port = sock.dport;
- } else {
- // TODO saddr and sport will be set for bind()'d UDP sockets, but what
- // should we be returning for TCP sockets that've been connect()'d?
- addr = sock.saddr || 0;
- port = sock.sport || 0;
- }
- return { addr: addr, port: port };
- },sendmsg:function(sock, buffer, offset, length, addr, port) {
- if (sock.type === 2) {
- // connection-less sockets will honor the message address,
- // and otherwise fall back to the bound destination address
- if (addr === undefined || port === undefined) {
- addr = sock.daddr;
- port = sock.dport;
- }
- // if there was no address to fall back to, error out
- if (addr === undefined || port === undefined) {
- throw new FS.ErrnoError(17);
- }
- } else {
- // connection-based sockets will only use the bound
- addr = sock.daddr;
- port = sock.dport;
- }
-
- // find the peer for the destination address
- var dest = SOCKFS.websocket_sock_ops.getPeer(sock, addr, port);
-
- // early out if not connected with a connection-based socket
- if (sock.type === 1) {
- if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
- throw new FS.ErrnoError(53);
- } else if (dest.socket.readyState === dest.socket.CONNECTING) {
- throw new FS.ErrnoError(6);
- }
- }
-
- // create a copy of the incoming data to send, as the WebSocket API
- // doesn't work entirely with an ArrayBufferView, it'll just send
- // the entire underlying buffer
- if (ArrayBuffer.isView(buffer)) {
- offset += buffer.byteOffset;
- buffer = buffer.buffer;
- }
-
- var data;
- data = buffer.slice(offset, offset + length);
-
- // if we're emulating a connection-less dgram socket and don't have
- // a cached connection, queue the buffer to send upon connect and
- // lie, saying the data was sent now.
- if (sock.type === 2) {
- if (!dest || dest.socket.readyState !== dest.socket.OPEN) {
- // if we're not connected, open a new connection
- if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
- dest = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
- }
- dest.dgram_send_queue.push(data);
- return length;
- }
- }
-
- try {
- // send the actual data
- dest.socket.send(data);
- return length;
- } catch (e) {
- throw new FS.ErrnoError(28);
- }
- },recvmsg:function(sock, length) {
- // http://pubs.opengroup.org/onlinepubs/7908799/xns/recvmsg.html
- if (sock.type === 1 && sock.server) {
- // tcp servers should not be recv()'ing on the listen socket
- throw new FS.ErrnoError(53);
- }
-
- var queued = sock.recv_queue.shift();
- if (!queued) {
- if (sock.type === 1) {
- var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
-
- if (!dest) {
- // if we have a destination address but are not connected, error out
- throw new FS.ErrnoError(53);
- }
- if (dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
- // return null if the socket has closed
- return null;
- }
- // else, our socket is in a valid state but truly has nothing available
- throw new FS.ErrnoError(6);
- }
- throw new FS.ErrnoError(6);
- }
-
- // queued.data will be an ArrayBuffer if it's unadulterated, but if it's
- // requeued TCP data it'll be an ArrayBufferView
- var queuedLength = queued.data.byteLength || queued.data.length;
- var queuedOffset = queued.data.byteOffset || 0;
- var queuedBuffer = queued.data.buffer || queued.data;
- var bytesRead = Math.min(length, queuedLength);
- var res = {
- buffer: new Uint8Array(queuedBuffer, queuedOffset, bytesRead),
- addr: queued.addr,
- port: queued.port
- };
-
- // push back any unread data for TCP connections
- if (sock.type === 1 && bytesRead < queuedLength) {
- var bytesRemaining = queuedLength - bytesRead;
- queued.data = new Uint8Array(queuedBuffer, queuedOffset + bytesRead, bytesRemaining);
- sock.recv_queue.unshift(queued);
- }
-
- return res;
- }}};
-
- function getSocketFromFD(fd) {
- var socket = SOCKFS.getSocket(fd);
- if (!socket) throw new FS.ErrnoError(8);
- return socket;
- }
-
- function setErrNo(value) {
- HEAP32[((___errno_location())>>2)] = value;
- return value;
- }
- var Sockets = {BUFFER_SIZE:10240,MAX_BUFFER_SIZE:10485760,nextFd:1,fds:{},nextport:1,maxport:65535,peer:null,connections:{},portmap:{},localAddr:4261412874,addrPool:[33554442,50331658,67108874,83886090,100663306,117440522,134217738,150994954,167772170,184549386,201326602,218103818,234881034]};
-
- function inetNtop4(addr) {
- return (addr & 0xff) + '.' + ((addr >> 8) & 0xff) + '.' + ((addr >> 16) & 0xff) + '.' + ((addr >> 24) & 0xff)
- }
-
-
- function inetNtop6(ints) {
- // ref: http://www.ietf.org/rfc/rfc2373.txt - section 2.5.4
- // Format for IPv4 compatible and mapped 128-bit IPv6 Addresses
- // 128-bits are split into eight 16-bit words
- // stored in network byte order (big-endian)
- // | 80 bits | 16 | 32 bits |
- // +-----------------------------------------------------------------+
- // | 10 bytes | 2 | 4 bytes |
- // +--------------------------------------+--------------------------+
- // + 5 words | 1 | 2 words |
- // +--------------------------------------+--------------------------+
- // |0000..............................0000|0000| IPv4 ADDRESS | (compatible)
- // +--------------------------------------+----+---------------------+
- // |0000..............................0000|FFFF| IPv4 ADDRESS | (mapped)
- // +--------------------------------------+----+---------------------+
- var str = "";
- var word = 0;
- var longest = 0;
- var lastzero = 0;
- var zstart = 0;
- var len = 0;
- var i = 0;
- var parts = [
- ints[0] & 0xffff,
- (ints[0] >> 16),
- ints[1] & 0xffff,
- (ints[1] >> 16),
- ints[2] & 0xffff,
- (ints[2] >> 16),
- ints[3] & 0xffff,
- (ints[3] >> 16)
- ];
-
- // Handle IPv4-compatible, IPv4-mapped, loopback and any/unspecified addresses
-
- var hasipv4 = true;
- var v4part = "";
- // check if the 10 high-order bytes are all zeros (first 5 words)
- for (i = 0; i < 5; i++) {
- if (parts[i] !== 0) { hasipv4 = false; break; }
- }
-
- if (hasipv4) {
- // low-order 32-bits store an IPv4 address (bytes 13 to 16) (last 2 words)
- v4part = inetNtop4(parts[6] | (parts[7] << 16));
- // IPv4-mapped IPv6 address if 16-bit value (bytes 11 and 12) == 0xFFFF (6th word)
- if (parts[5] === -1) {
- str = "::ffff:";
- str += v4part;
- return str;
- }
- // IPv4-compatible IPv6 address if 16-bit value (bytes 11 and 12) == 0x0000 (6th word)
- if (parts[5] === 0) {
- str = "::";
- //special case IPv6 addresses
- if (v4part === "0.0.0.0") v4part = ""; // any/unspecified address
- if (v4part === "0.0.0.1") v4part = "1";// loopback address
- str += v4part;
- return str;
- }
- }
-
- // Handle all other IPv6 addresses
-
- // first run to find the longest contiguous zero words
- for (word = 0; word < 8; word++) {
- if (parts[word] === 0) {
- if (word - lastzero > 1) {
- len = 0;
- }
- lastzero = word;
- len++;
- }
- if (len > longest) {
- longest = len;
- zstart = word - longest + 1;
- }
- }
-
- for (word = 0; word < 8; word++) {
- if (longest > 1) {
- // compress contiguous zeros - to produce "::"
- if (parts[word] === 0 && word >= zstart && word < (zstart + longest) ) {
- if (word === zstart) {
- str += ":";
- if (zstart === 0) str += ":"; //leading zeros case
- }
- continue;
- }
- }
- // converts 16-bit words from big-endian to little-endian before converting to hex string
- str += Number(_ntohs(parts[word] & 0xffff)).toString(16);
- str += word < 7 ? ":" : "";
- }
- return str;
- }
-
- function readSockaddr(sa, salen) {
- // family / port offsets are common to both sockaddr_in and sockaddr_in6
- var family = HEAP16[((sa)>>1)];
- var port = _ntohs(HEAPU16[(((sa)+(2))>>1)]);
- var addr;
-
- switch (family) {
- case 2:
- if (salen !== 16) {
- return { errno: 28 };
- }
- addr = HEAP32[(((sa)+(4))>>2)];
- addr = inetNtop4(addr);
- break;
- case 10:
- if (salen !== 28) {
- return { errno: 28 };
- }
- addr = [
- HEAP32[(((sa)+(8))>>2)],
- HEAP32[(((sa)+(12))>>2)],
- HEAP32[(((sa)+(16))>>2)],
- HEAP32[(((sa)+(20))>>2)]
- ];
- addr = inetNtop6(addr);
- break;
- default:
- return { errno: 5 };
- }
-
- return { family: family, addr: addr, port: port };
- }
-
-
- function inetPton4(str) {
- var b = str.split('.');
- for (var i = 0; i < 4; i++) {
- var tmp = Number(b[i]);
- if (isNaN(tmp)) return null;
- b[i] = tmp;
- }
- return (b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24)) >>> 0;
- }
-
-
- /** @suppress {checkTypes} */
- function jstoi_q(str) {
- return parseInt(str);
- }
- function inetPton6(str) {
- var words;
- var w, offset, z, i;
- /* http://home.deds.nl/~aeron/regex/ */
- var valid6regx = /^((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\3)::|:\b|$))|(?!\2\3)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})$/i
- var parts = [];
- if (!valid6regx.test(str)) {
- return null;
- }
- if (str === "::") {
- return [0, 0, 0, 0, 0, 0, 0, 0];
- }
- // Z placeholder to keep track of zeros when splitting the string on ":"
- if (str.startsWith("::")) {
- str = str.replace("::", "Z:"); // leading zeros case
- } else {
- str = str.replace("::", ":Z:");
- }
-
- if (str.indexOf(".") > 0) {
- // parse IPv4 embedded stress
- str = str.replace(new RegExp('[.]', 'g'), ":");
- words = str.split(":");
- words[words.length-4] = jstoi_q(words[words.length-4]) + jstoi_q(words[words.length-3])*256;
- words[words.length-3] = jstoi_q(words[words.length-2]) + jstoi_q(words[words.length-1])*256;
- words = words.slice(0, words.length-2);
- } else {
- words = str.split(":");
- }
-
- offset = 0; z = 0;
- for (w=0; w < words.length; w++) {
- if (typeof words[w] == 'string') {
- if (words[w] === 'Z') {
- // compressed zeros - write appropriate number of zero words
- for (z = 0; z < (8 - words.length+1); z++) {
- parts[w+z] = 0;
- }
- offset = z-1;
- } else {
- // parse hex to field to 16-bit value and write it in network byte-order
- parts[w+offset] = _htons(parseInt(words[w],16));
- }
- } else {
- // parsed IPv4 words
- parts[w+offset] = words[w];
- }
- }
- return [
- (parts[1] << 16) | parts[0],
- (parts[3] << 16) | parts[2],
- (parts[5] << 16) | parts[4],
- (parts[7] << 16) | parts[6]
- ];
- }
- var DNS = {address_map:{id:1,addrs:{},names:{}},lookup_name:function (name) {
- // If the name is already a valid ipv4 / ipv6 address, don't generate a fake one.
- var res = inetPton4(name);
- if (res !== null) {
- return name;
- }
- res = inetPton6(name);
- if (res !== null) {
- return name;
- }
-
- // See if this name is already mapped.
- var addr;
-
- if (DNS.address_map.addrs[name]) {
- addr = DNS.address_map.addrs[name];
- } else {
- var id = DNS.address_map.id++;
- assert(id < 65535, 'exceeded max address mappings of 65535');
-
- addr = '172.29.' + (id & 0xff) + '.' + (id & 0xff00);
-
- DNS.address_map.names[addr] = name;
- DNS.address_map.addrs[name] = addr;
- }
-
- return addr;
- },lookup_addr:function (addr) {
- if (DNS.address_map.names[addr]) {
- return DNS.address_map.names[addr];
- }
-
- return null;
- }};
- /** @param {boolean=} allowNull */
- function getSocketAddress(addrp, addrlen, allowNull) {
- if (allowNull && addrp === 0) return null;
- var info = readSockaddr(addrp, addrlen);
- if (info.errno) throw new FS.ErrnoError(info.errno);
- info.addr = DNS.lookup_addr(info.addr) || info.addr;
- return info;
- }
-
-
- var SYSCALLS = {DEFAULT_POLLMASK:5,calculateAt:function(dirfd, path, allowEmpty) {
- if (PATH.isAbs(path)) {
- return path;
- }
- // relative path
- var dir;
- if (dirfd === -100) {
- dir = FS.cwd();
- } else {
- var dirstream = SYSCALLS.getStreamFromFD(dirfd);
- dir = dirstream.path;
- }
- if (path.length == 0) {
- if (!allowEmpty) {
- throw new FS.ErrnoError(44);;
- }
- return dir;
- }
- return PATH.join2(dir, path);
- },doStat:function(func, path, buf) {
- try {
- var stat = func(path);
- } catch (e) {
- if (e && e.node && PATH.normalize(path) !== PATH.normalize(FS.getPath(e.node))) {
- // an error occurred while trying to look up the path; we should just report ENOTDIR
- return -54;
- }
- throw e;
- }
- HEAP32[((buf)>>2)] = stat.dev;
- HEAP32[(((buf)+(8))>>2)] = stat.ino;
- HEAP32[(((buf)+(12))>>2)] = stat.mode;
- HEAPU32[(((buf)+(16))>>2)] = stat.nlink;
- HEAP32[(((buf)+(20))>>2)] = stat.uid;
- HEAP32[(((buf)+(24))>>2)] = stat.gid;
- HEAP32[(((buf)+(28))>>2)] = stat.rdev;
- (tempI64 = [stat.size>>>0,(tempDouble=stat.size,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((buf)+(40))>>2)] = tempI64[0],HEAP32[(((buf)+(44))>>2)] = tempI64[1]);
- HEAP32[(((buf)+(48))>>2)] = 4096;
- HEAP32[(((buf)+(52))>>2)] = stat.blocks;
- var atime = stat.atime.getTime();
- var mtime = stat.mtime.getTime();
- var ctime = stat.ctime.getTime();
- (tempI64 = [Math.floor(atime / 1000)>>>0,(tempDouble=Math.floor(atime / 1000),(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((buf)+(56))>>2)] = tempI64[0],HEAP32[(((buf)+(60))>>2)] = tempI64[1]);
- HEAPU32[(((buf)+(64))>>2)] = (atime % 1000) * 1000;
- (tempI64 = [Math.floor(mtime / 1000)>>>0,(tempDouble=Math.floor(mtime / 1000),(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((buf)+(72))>>2)] = tempI64[0],HEAP32[(((buf)+(76))>>2)] = tempI64[1]);
- HEAPU32[(((buf)+(80))>>2)] = (mtime % 1000) * 1000;
- (tempI64 = [Math.floor(ctime / 1000)>>>0,(tempDouble=Math.floor(ctime / 1000),(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((buf)+(88))>>2)] = tempI64[0],HEAP32[(((buf)+(92))>>2)] = tempI64[1]);
- HEAPU32[(((buf)+(96))>>2)] = (ctime % 1000) * 1000;
- (tempI64 = [stat.ino>>>0,(tempDouble=stat.ino,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((buf)+(104))>>2)] = tempI64[0],HEAP32[(((buf)+(108))>>2)] = tempI64[1]);
- return 0;
- },doMsync:function(addr, stream, len, flags, offset) {
- if (!FS.isFile(stream.node.mode)) {
- throw new FS.ErrnoError(43);
- }
- if (flags & 2) {
- // MAP_PRIVATE calls need not to be synced back to underlying fs
- return 0;
- }
- var buffer = HEAPU8.slice(addr, addr + len);
- FS.msync(stream, buffer, offset, len, flags);
- },varargs:undefined,get:function() {
- assert(SYSCALLS.varargs != undefined);
- SYSCALLS.varargs += 4;
- var ret = HEAP32[(((SYSCALLS.varargs)-(4))>>2)];
- return ret;
- },getStr:function(ptr) {
- var ret = UTF8ToString(ptr);
- return ret;
- },getStreamFromFD:function(fd) {
- var stream = FS.getStream(fd);
- if (!stream) throw new FS.ErrnoError(8);
- return stream;
- }};
- function ___syscall_connect(fd, addr, addrlen) {
- try {
-
- var sock = getSocketFromFD(fd);
- var info = getSocketAddress(addr, addrlen);
- sock.sock_ops.connect(sock, info.addr, info.port);
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
- return -e.errno;
- }
- }
- function ___syscall_faccessat(dirfd, path, amode, flags) {
- try {
-
- path = SYSCALLS.getStr(path);
- assert(flags === 0);
- path = SYSCALLS.calculateAt(dirfd, path);
- if (amode & ~7) {
- // need a valid mode
- return -28;
- }
- var lookup = FS.lookupPath(path, { follow: true });
- var node = lookup.node;
- if (!node) {
- return -44;
- }
- var perms = '';
- if (amode & 4) perms += 'r';
- if (amode & 2) perms += 'w';
- if (amode & 1) perms += 'x';
- if (perms /* otherwise, they've just passed F_OK */ && FS.nodePermissions(node, perms)) {
- return -2;
- }
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
- return -e.errno;
- }
- }
-
- function ___syscall_fcntl64(fd, cmd, varargs) {
- SYSCALLS.varargs = varargs;
- try {
-
- var stream = SYSCALLS.getStreamFromFD(fd);
- switch (cmd) {
- case 0: {
- var arg = SYSCALLS.get();
- if (arg < 0) {
- return -28;
- }
- var newStream;
- newStream = FS.createStream(stream, arg);
- return newStream.fd;
- }
- case 1:
- case 2:
- return 0; // FD_CLOEXEC makes no sense for a single process.
- case 3:
- return stream.flags;
- case 4: {
- var arg = SYSCALLS.get();
- stream.flags |= arg;
- return 0;
- }
- case 5:
- /* case 5: Currently in musl F_GETLK64 has same value as F_GETLK, so omitted to avoid duplicate case blocks. If that changes, uncomment this */ {
-
- var arg = SYSCALLS.get();
- var offset = 0;
- // We're always unlocked.
- HEAP16[(((arg)+(offset))>>1)] = 2;
- return 0;
- }
- case 6:
- case 7:
- /* case 6: Currently in musl F_SETLK64 has same value as F_SETLK, so omitted to avoid duplicate case blocks. If that changes, uncomment this */
- /* case 7: Currently in musl F_SETLKW64 has same value as F_SETLKW, so omitted to avoid duplicate case blocks. If that changes, uncomment this */
-
-
- return 0; // Pretend that the locking is successful.
- case 16:
- case 8:
- return -28; // These are for sockets. We don't have them fully implemented yet.
- case 9:
- // musl trusts getown return values, due to a bug where they must be, as they overlap with errors. just return -1 here, so fcntl() returns that, and we set errno ourselves.
- setErrNo(28);
- return -1;
- default: {
- return -28;
- }
- }
- } catch (e) {
- if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
- return -e.errno;
- }
- }
- function ___syscall_fstat64(fd, buf) {
- try {
-
- var stream = SYSCALLS.getStreamFromFD(fd);
- return SYSCALLS.doStat(FS.stat, stream.path, buf);
- } catch (e) {
- if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
- return -e.errno;
- }
- }
- function convertI32PairToI53Checked(lo, hi) {
- assert(lo == (lo >>> 0) || lo == (lo|0)); // lo should either be a i32 or a u32
- assert(hi === (hi|0)); // hi should be a i32
- return ((hi + 0x200000) >>> 0 < 0x400001 - !!lo) ? (lo >>> 0) + hi * 4294967296 : NaN;
- }
-
-
-
-
- function ___syscall_ftruncate64(fd, length_low, length_high) {
- try {
-
- var length = convertI32PairToI53Checked(length_low, length_high); if (isNaN(length)) return -61;
- FS.ftruncate(fd, length);
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
- return -e.errno;
- }
- }
- function ___syscall_ioctl(fd, op, varargs) {
- SYSCALLS.varargs = varargs;
- try {
-
- var stream = SYSCALLS.getStreamFromFD(fd);
- switch (op) {
- case 21509:
- case 21505: {
- if (!stream.tty) return -59;
- return 0;
- }
- case 21510:
- case 21511:
- case 21512:
- case 21506:
- case 21507:
- case 21508: {
- if (!stream.tty) return -59;
- return 0; // no-op, not actually adjusting terminal settings
- }
- case 21519: {
- if (!stream.tty) return -59;
- var argp = SYSCALLS.get();
- HEAP32[((argp)>>2)] = 0;
- return 0;
- }
- case 21520: {
- if (!stream.tty) return -59;
- return -28; // not supported
- }
- case 21531: {
- var argp = SYSCALLS.get();
- return FS.ioctl(stream, op, argp);
- }
- case 21523: {
- // TODO: in theory we should write to the winsize struct that gets
- // passed in, but for now musl doesn't read anything on it
- if (!stream.tty) return -59;
- return 0;
- }
- case 21524: {
- // TODO: technically, this ioctl call should change the window size.
- // but, since emscripten doesn't have any concept of a terminal window
- // yet, we'll just silently throw it away as we do TIOCGWINSZ
- if (!stream.tty) return -59;
- return 0;
- }
- default: return -28; // not supported
- }
- } catch (e) {
- if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
- return -e.errno;
- }
- }
- function ___syscall_lstat64(path, buf) {
- try {
-
- path = SYSCALLS.getStr(path);
- return SYSCALLS.doStat(FS.lstat, path, buf);
- } catch (e) {
- if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
- return -e.errno;
- }
- }
- function ___syscall_newfstatat(dirfd, path, buf, flags) {
- try {
-
- path = SYSCALLS.getStr(path);
- var nofollow = flags & 256;
- var allowEmpty = flags & 4096;
- flags = flags & (~6400);
- assert(!flags, 'unknown flags in __syscall_newfstatat: ' + flags);
- path = SYSCALLS.calculateAt(dirfd, path, allowEmpty);
- return SYSCALLS.doStat(nofollow ? FS.lstat : FS.stat, path, buf);
- } catch (e) {
- if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
- return -e.errno;
- }
- }
- function ___syscall_openat(dirfd, path, flags, varargs) {
- SYSCALLS.varargs = varargs;
- try {
-
- path = SYSCALLS.getStr(path);
- path = SYSCALLS.calculateAt(dirfd, path);
- var mode = varargs ? SYSCALLS.get() : 0;
- return FS.open(path, flags, mode).fd;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
- return -e.errno;
- }
- }
-
- function ___syscall_socket(domain, type, protocol) {
- try {
-
- var sock = SOCKFS.createSocket(domain, type, protocol);
- assert(sock.stream.fd < 64); // XXX ? select() assumes socket fd values are in 0..63
- return sock.stream.fd;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
- return -e.errno;
- }
- }
- function ___syscall_stat64(path, buf) {
- try {
-
- path = SYSCALLS.getStr(path);
- return SYSCALLS.doStat(FS.stat, path, buf);
- } catch (e) {
- if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
- return -e.errno;
- }
- }
- var tupleRegistrations = {};
-
- function runDestructors(destructors) {
- while (destructors.length) {
- var ptr = destructors.pop();
- var del = destructors.pop();
- del(ptr);
- }
- }
-
- function simpleReadValueFromPointer(pointer) {
- return this['fromWireType'](HEAP32[((pointer)>>2)]);
- }
-
- var awaitingDependencies = {};
-
- var registeredTypes = {};
-
- var typeDependencies = {};
-
- var char_0 = 48;
-
- var char_9 = 57;
- function makeLegalFunctionName(name) {
- if (undefined === name) {
- return '_unknown';
- }
- name = name.replace(/[^a-zA-Z0-9_]/g, '$');
- var f = name.charCodeAt(0);
- if (f >= char_0 && f <= char_9) {
- return '_' + name;
- }
- return name;
- }
- function createNamedFunction(name, body) {
- name = makeLegalFunctionName(name);
- /*jshint evil:true*/
- return new Function(
- "body",
- "return function " + name + "() {\n" +
- " \"use strict\";" +
- " return body.apply(this, arguments);\n" +
- "};\n"
- )(body);
- }
- function extendError(baseErrorType, errorName) {
- var errorClass = createNamedFunction(errorName, function(message) {
- this.name = errorName;
- this.message = message;
-
- var stack = (new Error(message)).stack;
- if (stack !== undefined) {
- this.stack = this.toString() + '\n' +
- stack.replace(/^Error(:[^\n]*)?\n/, '');
- }
- });
- errorClass.prototype = Object.create(baseErrorType.prototype);
- errorClass.prototype.constructor = errorClass;
- errorClass.prototype.toString = function() {
- if (this.message === undefined) {
- return this.name;
- } else {
- return this.name + ': ' + this.message;
- }
- };
-
- return errorClass;
- }
- var InternalError = undefined;
- function throwInternalError(message) {
- throw new InternalError(message);
- }
- function whenDependentTypesAreResolved(myTypes, dependentTypes, getTypeConverters) {
- myTypes.forEach(function(type) {
- typeDependencies[type] = dependentTypes;
- });
-
- function onComplete(typeConverters) {
- var myTypeConverters = getTypeConverters(typeConverters);
- if (myTypeConverters.length !== myTypes.length) {
- throwInternalError('Mismatched type converter count');
- }
- for (var i = 0; i < myTypes.length; ++i) {
- registerType(myTypes[i], myTypeConverters[i]);
- }
- }
-
- var typeConverters = new Array(dependentTypes.length);
- var unregisteredTypes = [];
- var registered = 0;
- dependentTypes.forEach((dt, i) => {
- if (registeredTypes.hasOwnProperty(dt)) {
- typeConverters[i] = registeredTypes[dt];
- } else {
- unregisteredTypes.push(dt);
- if (!awaitingDependencies.hasOwnProperty(dt)) {
- awaitingDependencies[dt] = [];
- }
- awaitingDependencies[dt].push(() => {
- typeConverters[i] = registeredTypes[dt];
- ++registered;
- if (registered === unregisteredTypes.length) {
- onComplete(typeConverters);
- }
- });
- }
- });
- if (0 === unregisteredTypes.length) {
- onComplete(typeConverters);
- }
- }
- function __embind_finalize_value_array(rawTupleType) {
- var reg = tupleRegistrations[rawTupleType];
- delete tupleRegistrations[rawTupleType];
- var elements = reg.elements;
- var elementsLength = elements.length;
- var elementTypes = elements.map(function(elt) { return elt.getterReturnType; }).
- concat(elements.map(function(elt) { return elt.setterArgumentType; }));
-
- var rawConstructor = reg.rawConstructor;
- var rawDestructor = reg.rawDestructor;
-
- whenDependentTypesAreResolved([rawTupleType], elementTypes, function(elementTypes) {
- elements.forEach((elt, i) => {
- var getterReturnType = elementTypes[i];
- var getter = elt.getter;
- var getterContext = elt.getterContext;
- var setterArgumentType = elementTypes[i + elementsLength];
- var setter = elt.setter;
- var setterContext = elt.setterContext;
- elt.read = (ptr) => {
- return getterReturnType['fromWireType'](getter(getterContext, ptr));
- };
- elt.write = (ptr, o) => {
- var destructors = [];
- setter(setterContext, ptr, setterArgumentType['toWireType'](destructors, o));
- runDestructors(destructors);
- };
- });
-
- return [{
- name: reg.name,
- 'fromWireType': function(ptr) {
- var rv = new Array(elementsLength);
- for (var i = 0; i < elementsLength; ++i) {
- rv[i] = elements[i].read(ptr);
- }
- rawDestructor(ptr);
- return rv;
- },
- 'toWireType': function(destructors, o) {
- if (elementsLength !== o.length) {
- throw new TypeError("Incorrect number of tuple elements for " + reg.name + ": expected=" + elementsLength + ", actual=" + o.length);
- }
- var ptr = rawConstructor();
- for (var i = 0; i < elementsLength; ++i) {
- elements[i].write(ptr, o[i]);
- }
- if (destructors !== null) {
- destructors.push(rawDestructor, ptr);
- }
- return ptr;
- },
- 'argPackAdvance': 8,
- 'readValueFromPointer': simpleReadValueFromPointer,
- destructorFunction: rawDestructor,
- }];
- });
- }
- var structRegistrations = {};
-
-
-
- function __embind_finalize_value_object(structType) {
- var reg = structRegistrations[structType];
- delete structRegistrations[structType];
-
- var rawConstructor = reg.rawConstructor;
- var rawDestructor = reg.rawDestructor;
- var fieldRecords = reg.fields;
- var fieldTypes = fieldRecords.map((field) => field.getterReturnType).
- concat(fieldRecords.map((field) => field.setterArgumentType));
- whenDependentTypesAreResolved([structType], fieldTypes, (fieldTypes) => {
- var fields = {};
- fieldRecords.forEach((field, i) => {
- var fieldName = field.fieldName;
- var getterReturnType = fieldTypes[i];
- var getter = field.getter;
- var getterContext = field.getterContext;
- var setterArgumentType = fieldTypes[i + fieldRecords.length];
- var setter = field.setter;
- var setterContext = field.setterContext;
- fields[fieldName] = {
- read: (ptr) => {
- return getterReturnType['fromWireType'](
- getter(getterContext, ptr));
- },
- write: (ptr, o) => {
- var destructors = [];
- setter(setterContext, ptr, setterArgumentType['toWireType'](destructors, o));
- runDestructors(destructors);
- }
- };
- });
-
- return [{
- name: reg.name,
- 'fromWireType': function(ptr) {
- var rv = {};
- for (var i in fields) {
- rv[i] = fields[i].read(ptr);
- }
- rawDestructor(ptr);
- return rv;
- },
- 'toWireType': function(destructors, o) {
- // todo: Here we have an opportunity for -O3 level "unsafe" optimizations:
- // assume all fields are present without checking.
- for (var fieldName in fields) {
- if (!(fieldName in o)) {
- throw new TypeError('Missing field: "' + fieldName + '"');
- }
- }
- var ptr = rawConstructor();
- for (fieldName in fields) {
- fields[fieldName].write(ptr, o[fieldName]);
- }
- if (destructors !== null) {
- destructors.push(rawDestructor, ptr);
- }
- return ptr;
- },
- 'argPackAdvance': 8,
- 'readValueFromPointer': simpleReadValueFromPointer,
- destructorFunction: rawDestructor,
- }];
- });
- }
- function __embind_register_bigint(primitiveType, name, size, minRange, maxRange) {}
- function getShiftFromSize(size) {
- switch (size) {
- case 1: return 0;
- case 2: return 1;
- case 4: return 2;
- case 8: return 3;
- default:
- throw new TypeError('Unknown type size: ' + size);
- }
- }
-
- function embind_init_charCodes() {
- var codes = new Array(256);
- for (var i = 0; i < 256; ++i) {
- codes[i] = String.fromCharCode(i);
- }
- embind_charCodes = codes;
- }
- var embind_charCodes = undefined;
- function readLatin1String(ptr) {
- var ret = "";
- var c = ptr;
- while (HEAPU8[c]) {
- ret += embind_charCodes[HEAPU8[c++]];
- }
- return ret;
- }
-
-
-
-
- var BindingError = undefined;
- function throwBindingError(message) {
- throw new BindingError(message);
- }
-
- /** @param {Object=} options */
- function registerType(rawType, registeredInstance, options = {}) {
- if (!('argPackAdvance' in registeredInstance)) {
- throw new TypeError('registerType registeredInstance requires argPackAdvance');
- }
-
- var name = registeredInstance.name;
- if (!rawType) {
- throwBindingError('type "' + name + '" must have a positive integer typeid pointer');
- }
- if (registeredTypes.hasOwnProperty(rawType)) {
- if (options.ignoreDuplicateRegistrations) {
- return;
- } else {
- throwBindingError("Cannot register type '" + name + "' twice");
- }
- }
-
- registeredTypes[rawType] = registeredInstance;
- delete typeDependencies[rawType];
-
- if (awaitingDependencies.hasOwnProperty(rawType)) {
- var callbacks = awaitingDependencies[rawType];
- delete awaitingDependencies[rawType];
- callbacks.forEach((cb) => cb());
- }
- }
- function __embind_register_bool(rawType, name, size, trueValue, falseValue) {
- var shift = getShiftFromSize(size);
-
- name = readLatin1String(name);
- registerType(rawType, {
- name: name,
- 'fromWireType': function(wt) {
- // ambiguous emscripten ABI: sometimes return values are
- // true or false, and sometimes integers (0 or 1)
- return !!wt;
- },
- 'toWireType': function(destructors, o) {
- return o ? trueValue : falseValue;
- },
- 'argPackAdvance': 8,
- 'readValueFromPointer': function(pointer) {
- // TODO: if heap is fixed (like in asm.js) this could be executed outside
- var heap;
- if (size === 1) {
- heap = HEAP8;
- } else if (size === 2) {
- heap = HEAP16;
- } else if (size === 4) {
- heap = HEAP32;
- } else {
- throw new TypeError("Unknown boolean type size: " + name);
- }
- return this['fromWireType'](heap[pointer >> shift]);
- },
- destructorFunction: null, // This type does not need a destructor
- });
- }
-
- function ClassHandle_isAliasOf(other) {
- if (!(this instanceof ClassHandle)) {
- return false;
- }
- if (!(other instanceof ClassHandle)) {
- return false;
- }
-
- var leftClass = this.$$.ptrType.registeredClass;
- var left = this.$$.ptr;
- var rightClass = other.$$.ptrType.registeredClass;
- var right = other.$$.ptr;
-
- while (leftClass.baseClass) {
- left = leftClass.upcast(left);
- leftClass = leftClass.baseClass;
- }
-
- while (rightClass.baseClass) {
- right = rightClass.upcast(right);
- rightClass = rightClass.baseClass;
- }
-
- return leftClass === rightClass && left === right;
- }
-
- function shallowCopyInternalPointer(o) {
- return {
- count: o.count,
- deleteScheduled: o.deleteScheduled,
- preservePointerOnDelete: o.preservePointerOnDelete,
- ptr: o.ptr,
- ptrType: o.ptrType,
- smartPtr: o.smartPtr,
- smartPtrType: o.smartPtrType,
- };
- }
-
- function throwInstanceAlreadyDeleted(obj) {
- function getInstanceTypeName(handle) {
- return handle.$$.ptrType.registeredClass.name;
- }
- throwBindingError(getInstanceTypeName(obj) + ' instance already deleted');
- }
-
- var finalizationRegistry = false;
-
- function detachFinalizer(handle) {}
-
- function runDestructor($$) {
- if ($$.smartPtr) {
- $$.smartPtrType.rawDestructor($$.smartPtr);
- } else {
- $$.ptrType.registeredClass.rawDestructor($$.ptr);
- }
- }
- function releaseClassHandle($$) {
- $$.count.value -= 1;
- var toDelete = 0 === $$.count.value;
- if (toDelete) {
- runDestructor($$);
- }
- }
-
- function downcastPointer(ptr, ptrClass, desiredClass) {
- if (ptrClass === desiredClass) {
- return ptr;
- }
- if (undefined === desiredClass.baseClass) {
- return null; // no conversion
- }
-
- var rv = downcastPointer(ptr, ptrClass, desiredClass.baseClass);
- if (rv === null) {
- return null;
- }
- return desiredClass.downcast(rv);
- }
-
- var registeredPointers = {};
-
- function getInheritedInstanceCount() {
- return Object.keys(registeredInstances).length;
- }
-
- function getLiveInheritedInstances() {
- var rv = [];
- for (var k in registeredInstances) {
- if (registeredInstances.hasOwnProperty(k)) {
- rv.push(registeredInstances[k]);
- }
- }
- return rv;
- }
-
- var deletionQueue = [];
- function flushPendingDeletes() {
- while (deletionQueue.length) {
- var obj = deletionQueue.pop();
- obj.$$.deleteScheduled = false;
- obj['delete']();
- }
- }
-
- var delayFunction = undefined;
-
-
- function setDelayFunction(fn) {
- delayFunction = fn;
- if (deletionQueue.length && delayFunction) {
- delayFunction(flushPendingDeletes);
- }
- }
- function init_embind() {
- Module['getInheritedInstanceCount'] = getInheritedInstanceCount;
- Module['getLiveInheritedInstances'] = getLiveInheritedInstances;
- Module['flushPendingDeletes'] = flushPendingDeletes;
- Module['setDelayFunction'] = setDelayFunction;
- }
- var registeredInstances = {};
-
- function getBasestPointer(class_, ptr) {
- if (ptr === undefined) {
- throwBindingError('ptr should not be undefined');
- }
- while (class_.baseClass) {
- ptr = class_.upcast(ptr);
- class_ = class_.baseClass;
- }
- return ptr;
- }
- function getInheritedInstance(class_, ptr) {
- ptr = getBasestPointer(class_, ptr);
- return registeredInstances[ptr];
- }
-
-
- function makeClassHandle(prototype, record) {
- if (!record.ptrType || !record.ptr) {
- throwInternalError('makeClassHandle requires ptr and ptrType');
- }
- var hasSmartPtrType = !!record.smartPtrType;
- var hasSmartPtr = !!record.smartPtr;
- if (hasSmartPtrType !== hasSmartPtr) {
- throwInternalError('Both smartPtrType and smartPtr must be specified');
- }
- record.count = { value: 1 };
- return attachFinalizer(Object.create(prototype, {
- $$: {
- value: record,
- },
- }));
- }
- function RegisteredPointer_fromWireType(ptr) {
- // ptr is a raw pointer (or a raw smartpointer)
-
- // rawPointer is a maybe-null raw pointer
- var rawPointer = this.getPointee(ptr);
- if (!rawPointer) {
- this.destructor(ptr);
- return null;
- }
-
- var registeredInstance = getInheritedInstance(this.registeredClass, rawPointer);
- if (undefined !== registeredInstance) {
- // JS object has been neutered, time to repopulate it
- if (0 === registeredInstance.$$.count.value) {
- registeredInstance.$$.ptr = rawPointer;
- registeredInstance.$$.smartPtr = ptr;
- return registeredInstance['clone']();
- } else {
- // else, just increment reference count on existing object
- // it already has a reference to the smart pointer
- var rv = registeredInstance['clone']();
- this.destructor(ptr);
- return rv;
- }
- }
-
- function makeDefaultHandle() {
- if (this.isSmartPointer) {
- return makeClassHandle(this.registeredClass.instancePrototype, {
- ptrType: this.pointeeType,
- ptr: rawPointer,
- smartPtrType: this,
- smartPtr: ptr,
- });
- } else {
- return makeClassHandle(this.registeredClass.instancePrototype, {
- ptrType: this,
- ptr: ptr,
- });
- }
- }
-
- var actualType = this.registeredClass.getActualType(rawPointer);
- var registeredPointerRecord = registeredPointers[actualType];
- if (!registeredPointerRecord) {
- return makeDefaultHandle.call(this);
- }
-
- var toType;
- if (this.isConst) {
- toType = registeredPointerRecord.constPointerType;
- } else {
- toType = registeredPointerRecord.pointerType;
- }
- var dp = downcastPointer(
- rawPointer,
- this.registeredClass,
- toType.registeredClass);
- if (dp === null) {
- return makeDefaultHandle.call(this);
- }
- if (this.isSmartPointer) {
- return makeClassHandle(toType.registeredClass.instancePrototype, {
- ptrType: toType,
- ptr: dp,
- smartPtrType: this,
- smartPtr: ptr,
- });
- } else {
- return makeClassHandle(toType.registeredClass.instancePrototype, {
- ptrType: toType,
- ptr: dp,
- });
- }
- }
- function attachFinalizer(handle) {
- if ('undefined' === typeof FinalizationRegistry) {
- attachFinalizer = (handle) => handle;
- return handle;
- }
- // If the running environment has a FinalizationRegistry (see
- // https://github.com/tc39/proposal-weakrefs), then attach finalizers
- // for class handles. We check for the presence of FinalizationRegistry
- // at run-time, not build-time.
- finalizationRegistry = new FinalizationRegistry((info) => {
- console.warn(info.leakWarning.stack.replace(/^Error: /, ''));
- releaseClassHandle(info.$$);
- });
- attachFinalizer = (handle) => {
- var $$ = handle.$$;
- var hasSmartPtr = !!$$.smartPtr;
- if (hasSmartPtr) {
- // We should not call the destructor on raw pointers in case other code expects the pointee to live
- var info = { $$: $$ };
- // Create a warning as an Error instance in advance so that we can store
- // the current stacktrace and point to it when / if a leak is detected.
- // This is more useful than the empty stacktrace of `FinalizationRegistry`
- // callback.
- var cls = $$.ptrType.registeredClass;
- info.leakWarning = new Error("Embind found a leaked C++ instance " + cls.name + " <" + ptrToString($$.ptr) + ">.\n" +
- "We'll free it automatically in this case, but this functionality is not reliable across various environments.\n" +
- "Make sure to invoke .delete() manually once you're done with the instance instead.\n" +
- "Originally allocated"); // `.stack` will add "at ..." after this sentence
- if ('captureStackTrace' in Error) {
- Error.captureStackTrace(info.leakWarning, RegisteredPointer_fromWireType);
- }
- finalizationRegistry.register(handle, info, handle);
- }
- return handle;
- };
- detachFinalizer = (handle) => finalizationRegistry.unregister(handle);
- return attachFinalizer(handle);
- }
- function ClassHandle_clone() {
- if (!this.$$.ptr) {
- throwInstanceAlreadyDeleted(this);
- }
-
- if (this.$$.preservePointerOnDelete) {
- this.$$.count.value += 1;
- return this;
- } else {
- var clone = attachFinalizer(Object.create(Object.getPrototypeOf(this), {
- $$: {
- value: shallowCopyInternalPointer(this.$$),
- }
- }));
-
- clone.$$.count.value += 1;
- clone.$$.deleteScheduled = false;
- return clone;
- }
- }
-
-
-
-
- function ClassHandle_delete() {
- if (!this.$$.ptr) {
- throwInstanceAlreadyDeleted(this);
- }
-
- if (this.$$.deleteScheduled && !this.$$.preservePointerOnDelete) {
- throwBindingError('Object already scheduled for deletion');
- }
-
- detachFinalizer(this);
- releaseClassHandle(this.$$);
-
- if (!this.$$.preservePointerOnDelete) {
- this.$$.smartPtr = undefined;
- this.$$.ptr = undefined;
- }
- }
-
- function ClassHandle_isDeleted() {
- return !this.$$.ptr;
- }
-
-
-
- function ClassHandle_deleteLater() {
- if (!this.$$.ptr) {
- throwInstanceAlreadyDeleted(this);
- }
- if (this.$$.deleteScheduled && !this.$$.preservePointerOnDelete) {
- throwBindingError('Object already scheduled for deletion');
- }
- deletionQueue.push(this);
- if (deletionQueue.length === 1 && delayFunction) {
- delayFunction(flushPendingDeletes);
- }
- this.$$.deleteScheduled = true;
- return this;
- }
- function init_ClassHandle() {
- ClassHandle.prototype['isAliasOf'] = ClassHandle_isAliasOf;
- ClassHandle.prototype['clone'] = ClassHandle_clone;
- ClassHandle.prototype['delete'] = ClassHandle_delete;
- ClassHandle.prototype['isDeleted'] = ClassHandle_isDeleted;
- ClassHandle.prototype['deleteLater'] = ClassHandle_deleteLater;
- }
- function ClassHandle() {
- }
-
-
-
- function ensureOverloadTable(proto, methodName, humanName) {
- if (undefined === proto[methodName].overloadTable) {
- var prevFunc = proto[methodName];
- // Inject an overload resolver function that routes to the appropriate overload based on the number of arguments.
- proto[methodName] = function() {
- // TODO This check can be removed in -O3 level "unsafe" optimizations.
- if (!proto[methodName].overloadTable.hasOwnProperty(arguments.length)) {
- throwBindingError("Function '" + humanName + "' called with an invalid number of arguments (" + arguments.length + ") - expects one of (" + proto[methodName].overloadTable + ")!");
- }
- return proto[methodName].overloadTable[arguments.length].apply(this, arguments);
- };
- // Move the previous function into the overload table.
- proto[methodName].overloadTable = [];
- proto[methodName].overloadTable[prevFunc.argCount] = prevFunc;
- }
- }
-
- /** @param {number=} numArguments */
- function exposePublicSymbol(name, value, numArguments) {
- if (Module.hasOwnProperty(name)) {
- if (undefined === numArguments || (undefined !== Module[name].overloadTable && undefined !== Module[name].overloadTable[numArguments])) {
- throwBindingError("Cannot register public name '" + name + "' twice");
- }
-
- // We are exposing a function with the same name as an existing function. Create an overload table and a function selector
- // that routes between the two.
- ensureOverloadTable(Module, name, name);
- if (Module.hasOwnProperty(numArguments)) {
- throwBindingError("Cannot register multiple overloads of a function with the same number of arguments (" + numArguments + ")!");
- }
- // Add the new function into the overload table.
- Module[name].overloadTable[numArguments] = value;
- }
- else {
- Module[name] = value;
- if (undefined !== numArguments) {
- Module[name].numArguments = numArguments;
- }
- }
- }
-
-
-
- /** @constructor */
- function RegisteredClass(name,
- constructor,
- instancePrototype,
- rawDestructor,
- baseClass,
- getActualType,
- upcast,
- downcast) {
- this.name = name;
- this.constructor = constructor;
- this.instancePrototype = instancePrototype;
- this.rawDestructor = rawDestructor;
- this.baseClass = baseClass;
- this.getActualType = getActualType;
- this.upcast = upcast;
- this.downcast = downcast;
- this.pureVirtualFunctions = [];
- }
-
-
- function upcastPointer(ptr, ptrClass, desiredClass) {
- while (ptrClass !== desiredClass) {
- if (!ptrClass.upcast) {
- throwBindingError("Expected null or instance of " + desiredClass.name + ", got an instance of " + ptrClass.name);
- }
- ptr = ptrClass.upcast(ptr);
- ptrClass = ptrClass.baseClass;
- }
- return ptr;
- }
- function constNoSmartPtrRawPointerToWireType(destructors, handle) {
- if (handle === null) {
- if (this.isReference) {
- throwBindingError('null is not a valid ' + this.name);
- }
- return 0;
- }
-
- if (!handle.$$) {
- throwBindingError('Cannot pass "' + embindRepr(handle) + '" as a ' + this.name);
- }
- if (!handle.$$.ptr) {
- throwBindingError('Cannot pass deleted object as a pointer of type ' + this.name);
- }
- var handleClass = handle.$$.ptrType.registeredClass;
- var ptr = upcastPointer(handle.$$.ptr, handleClass, this.registeredClass);
- return ptr;
- }
-
-
- function genericPointerToWireType(destructors, handle) {
- var ptr;
- if (handle === null) {
- if (this.isReference) {
- throwBindingError('null is not a valid ' + this.name);
- }
-
- if (this.isSmartPointer) {
- ptr = this.rawConstructor();
- if (destructors !== null) {
- destructors.push(this.rawDestructor, ptr);
- }
- return ptr;
- } else {
- return 0;
- }
- }
-
- if (!handle.$$) {
- throwBindingError('Cannot pass "' + embindRepr(handle) + '" as a ' + this.name);
- }
- if (!handle.$$.ptr) {
- throwBindingError('Cannot pass deleted object as a pointer of type ' + this.name);
- }
- if (!this.isConst && handle.$$.ptrType.isConst) {
- throwBindingError('Cannot convert argument of type ' + (handle.$$.smartPtrType ? handle.$$.smartPtrType.name : handle.$$.ptrType.name) + ' to parameter type ' + this.name);
- }
- var handleClass = handle.$$.ptrType.registeredClass;
- ptr = upcastPointer(handle.$$.ptr, handleClass, this.registeredClass);
-
- if (this.isSmartPointer) {
- // TODO: this is not strictly true
- // We could support BY_EMVAL conversions from raw pointers to smart pointers
- // because the smart pointer can hold a reference to the handle
- if (undefined === handle.$$.smartPtr) {
- throwBindingError('Passing raw pointer to smart pointer is illegal');
- }
-
- switch (this.sharingPolicy) {
- case 0: // NONE
- // no upcasting
- if (handle.$$.smartPtrType === this) {
- ptr = handle.$$.smartPtr;
- } else {
- throwBindingError('Cannot convert argument of type ' + (handle.$$.smartPtrType ? handle.$$.smartPtrType.name : handle.$$.ptrType.name) + ' to parameter type ' + this.name);
- }
- break;
-
- case 1: // INTRUSIVE
- ptr = handle.$$.smartPtr;
- break;
-
- case 2: // BY_EMVAL
- if (handle.$$.smartPtrType === this) {
- ptr = handle.$$.smartPtr;
- } else {
- var clonedHandle = handle['clone']();
- ptr = this.rawShare(
- ptr,
- Emval.toHandle(function() {
- clonedHandle['delete']();
- })
- );
- if (destructors !== null) {
- destructors.push(this.rawDestructor, ptr);
- }
- }
- break;
-
- default:
- throwBindingError('Unsupporting sharing policy');
- }
- }
- return ptr;
- }
-
-
- function nonConstNoSmartPtrRawPointerToWireType(destructors, handle) {
- if (handle === null) {
- if (this.isReference) {
- throwBindingError('null is not a valid ' + this.name);
- }
- return 0;
- }
-
- if (!handle.$$) {
- throwBindingError('Cannot pass "' + embindRepr(handle) + '" as a ' + this.name);
- }
- if (!handle.$$.ptr) {
- throwBindingError('Cannot pass deleted object as a pointer of type ' + this.name);
- }
- if (handle.$$.ptrType.isConst) {
- throwBindingError('Cannot convert argument of type ' + handle.$$.ptrType.name + ' to parameter type ' + this.name);
- }
- var handleClass = handle.$$.ptrType.registeredClass;
- var ptr = upcastPointer(handle.$$.ptr, handleClass, this.registeredClass);
- return ptr;
- }
-
-
- function RegisteredPointer_getPointee(ptr) {
- if (this.rawGetPointee) {
- ptr = this.rawGetPointee(ptr);
- }
- return ptr;
- }
-
- function RegisteredPointer_destructor(ptr) {
- if (this.rawDestructor) {
- this.rawDestructor(ptr);
- }
- }
-
- function RegisteredPointer_deleteObject(handle) {
- if (handle !== null) {
- handle['delete']();
- }
- }
-
- function init_RegisteredPointer() {
- RegisteredPointer.prototype.getPointee = RegisteredPointer_getPointee;
- RegisteredPointer.prototype.destructor = RegisteredPointer_destructor;
- RegisteredPointer.prototype['argPackAdvance'] = 8;
- RegisteredPointer.prototype['readValueFromPointer'] = simpleReadValueFromPointer;
- RegisteredPointer.prototype['deleteObject'] = RegisteredPointer_deleteObject;
- RegisteredPointer.prototype['fromWireType'] = RegisteredPointer_fromWireType;
- }
- /** @constructor
- @param {*=} pointeeType,
- @param {*=} sharingPolicy,
- @param {*=} rawGetPointee,
- @param {*=} rawConstructor,
- @param {*=} rawShare,
- @param {*=} rawDestructor,
- */
- function RegisteredPointer(
- name,
- registeredClass,
- isReference,
- isConst,
-
- // smart pointer properties
- isSmartPointer,
- pointeeType,
- sharingPolicy,
- rawGetPointee,
- rawConstructor,
- rawShare,
- rawDestructor
- ) {
- this.name = name;
- this.registeredClass = registeredClass;
- this.isReference = isReference;
- this.isConst = isConst;
-
- // smart pointer properties
- this.isSmartPointer = isSmartPointer;
- this.pointeeType = pointeeType;
- this.sharingPolicy = sharingPolicy;
- this.rawGetPointee = rawGetPointee;
- this.rawConstructor = rawConstructor;
- this.rawShare = rawShare;
- this.rawDestructor = rawDestructor;
-
- if (!isSmartPointer && registeredClass.baseClass === undefined) {
- if (isConst) {
- this['toWireType'] = constNoSmartPtrRawPointerToWireType;
- this.destructorFunction = null;
- } else {
- this['toWireType'] = nonConstNoSmartPtrRawPointerToWireType;
- this.destructorFunction = null;
- }
- } else {
- this['toWireType'] = genericPointerToWireType;
- // Here we must leave this.destructorFunction undefined, since whether genericPointerToWireType returns
- // a pointer that needs to be freed up is runtime-dependent, and cannot be evaluated at registration time.
- // TODO: Create an alternative mechanism that allows removing the use of var destructors = []; array in
- // craftInvokerFunction altogether.
- }
- }
-
- /** @param {number=} numArguments */
- function replacePublicSymbol(name, value, numArguments) {
- if (!Module.hasOwnProperty(name)) {
- throwInternalError('Replacing nonexistant public symbol');
- }
- // If there's an overload table for this symbol, replace the symbol in the overload table instead.
- if (undefined !== Module[name].overloadTable && undefined !== numArguments) {
- Module[name].overloadTable[numArguments] = value;
- }
- else {
- Module[name] = value;
- Module[name].argCount = numArguments;
- }
- }
-
-
-
- function dynCallLegacy(sig, ptr, args) {
- assert(('dynCall_' + sig) in Module, 'bad function pointer type - dynCall function not found for sig \'' + sig + '\'');
- if (args && args.length) {
- // j (64-bit integer) must be passed in as two numbers [low 32, high 32].
- assert(args.length === sig.substring(1).replace(/j/g, '--').length);
- } else {
- assert(sig.length == 1);
- }
- var f = Module['dynCall_' + sig];
- return args && args.length ? f.apply(null, [ptr].concat(args)) : f.call(null, ptr);
- }
-
- var wasmTableMirror = [];
-
- function getWasmTableEntry(funcPtr) {
- var func = wasmTableMirror[funcPtr];
- if (!func) {
- if (funcPtr >= wasmTableMirror.length) wasmTableMirror.length = funcPtr + 1;
- wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr);
- }
- assert(wasmTable.get(funcPtr) == func, "JavaScript-side Wasm function table mirror is out of date!");
- return func;
- }
-
- /** @param {Object=} args */
- function dynCall(sig, ptr, args) {
- // Without WASM_BIGINT support we cannot directly call function with i64 as
- // part of thier signature, so we rely the dynCall functions generated by
- // wasm-emscripten-finalize
- if (sig.includes('j')) {
- return dynCallLegacy(sig, ptr, args);
- }
- assert(getWasmTableEntry(ptr), 'missing table entry in dynCall: ' + ptr);
- var rtn = getWasmTableEntry(ptr).apply(null, args);
- return rtn;
- }
-
- function getDynCaller(sig, ptr) {
- assert(sig.includes('j') || sig.includes('p'), 'getDynCaller should only be called with i64 sigs')
- var argCache = [];
- return function() {
- argCache.length = 0;
- Object.assign(argCache, arguments);
- return dynCall(sig, ptr, argCache);
- };
- }
-
-
- function embind__requireFunction(signature, rawFunction) {
- signature = readLatin1String(signature);
-
- function makeDynCaller() {
- if (signature.includes('j')) {
- return getDynCaller(signature, rawFunction);
- }
- return getWasmTableEntry(rawFunction);
- }
-
- var fp = makeDynCaller();
- if (typeof fp != "function") {
- throwBindingError("unknown function pointer with signature " + signature + ": " + rawFunction);
- }
- return fp;
- }
-
-
-
- var UnboundTypeError = undefined;
-
-
- function getTypeName(type) {
- var ptr = ___getTypeName(type);
- var rv = readLatin1String(ptr);
- _free(ptr);
- return rv;
- }
- function throwUnboundTypeError(message, types) {
- var unboundTypes = [];
- var seen = {};
- function visit(type) {
- if (seen[type]) {
- return;
- }
- if (registeredTypes[type]) {
- return;
- }
- if (typeDependencies[type]) {
- typeDependencies[type].forEach(visit);
- return;
- }
- unboundTypes.push(type);
- seen[type] = true;
- }
- types.forEach(visit);
-
- throw new UnboundTypeError(message + ': ' + unboundTypes.map(getTypeName).join([', ']));
- }
-
- function __embind_register_class(rawType,
- rawPointerType,
- rawConstPointerType,
- baseClassRawType,
- getActualTypeSignature,
- getActualType,
- upcastSignature,
- upcast,
- downcastSignature,
- downcast,
- name,
- destructorSignature,
- rawDestructor) {
- name = readLatin1String(name);
- getActualType = embind__requireFunction(getActualTypeSignature, getActualType);
- if (upcast) {
- upcast = embind__requireFunction(upcastSignature, upcast);
- }
- if (downcast) {
- downcast = embind__requireFunction(downcastSignature, downcast);
- }
- rawDestructor = embind__requireFunction(destructorSignature, rawDestructor);
- var legalFunctionName = makeLegalFunctionName(name);
-
- exposePublicSymbol(legalFunctionName, function() {
- // this code cannot run if baseClassRawType is zero
- throwUnboundTypeError('Cannot construct ' + name + ' due to unbound types', [baseClassRawType]);
- });
-
- whenDependentTypesAreResolved(
- [rawType, rawPointerType, rawConstPointerType],
- baseClassRawType ? [baseClassRawType] : [],
- function(base) {
- base = base[0];
-
- var baseClass;
- var basePrototype;
- if (baseClassRawType) {
- baseClass = base.registeredClass;
- basePrototype = baseClass.instancePrototype;
- } else {
- basePrototype = ClassHandle.prototype;
- }
-
- var constructor = createNamedFunction(legalFunctionName, function() {
- if (Object.getPrototypeOf(this) !== instancePrototype) {
- throw new BindingError("Use 'new' to construct " + name);
- }
- if (undefined === registeredClass.constructor_body) {
- throw new BindingError(name + " has no accessible constructor");
- }
- var body = registeredClass.constructor_body[arguments.length];
- if (undefined === body) {
- throw new BindingError("Tried to invoke ctor of " + name + " with invalid number of parameters (" + arguments.length + ") - expected (" + Object.keys(registeredClass.constructor_body).toString() + ") parameters instead!");
- }
- return body.apply(this, arguments);
- });
-
- var instancePrototype = Object.create(basePrototype, {
- constructor: { value: constructor },
- });
-
- constructor.prototype = instancePrototype;
-
- var registeredClass = new RegisteredClass(name,
- constructor,
- instancePrototype,
- rawDestructor,
- baseClass,
- getActualType,
- upcast,
- downcast);
-
- var referenceConverter = new RegisteredPointer(name,
- registeredClass,
- true,
- false,
- false);
-
- var pointerConverter = new RegisteredPointer(name + '*',
- registeredClass,
- false,
- false,
- false);
-
- var constPointerConverter = new RegisteredPointer(name + ' const*',
- registeredClass,
- false,
- true,
- false);
-
- registeredPointers[rawType] = {
- pointerType: pointerConverter,
- constPointerType: constPointerConverter
- };
-
- replacePublicSymbol(legalFunctionName, constructor);
-
- return [referenceConverter, pointerConverter, constPointerConverter];
- }
- );
- }
-
- function new_(constructor, argumentList) {
- if (!(constructor instanceof Function)) {
- throw new TypeError('new_ called with constructor type ' + typeof(constructor) + " which is not a function");
- }
- /*
- * Previously, the following line was just:
- * function dummy() {};
- * Unfortunately, Chrome was preserving 'dummy' as the object's name, even
- * though at creation, the 'dummy' has the correct constructor name. Thus,
- * objects created with IMVU.new would show up in the debugger as 'dummy',
- * which isn't very helpful. Using IMVU.createNamedFunction addresses the
- * issue. Doublely-unfortunately, there's no way to write a test for this
- * behavior. -NRD 2013.02.22
- */
- var dummy = createNamedFunction(constructor.name || 'unknownFunctionName', function(){});
- dummy.prototype = constructor.prototype;
- var obj = new dummy;
-
- var r = constructor.apply(obj, argumentList);
- return (r instanceof Object) ? r : obj;
- }
-
-
- function craftInvokerFunction(humanName, argTypes, classType, cppInvokerFunc, cppTargetFunc) {
- // humanName: a human-readable string name for the function to be generated.
- // argTypes: An array that contains the embind type objects for all types in the function signature.
- // argTypes[0] is the type object for the function return value.
- // argTypes[1] is the type object for function this object/class type, or null if not crafting an invoker for a class method.
- // argTypes[2...] are the actual function parameters.
- // classType: The embind type object for the class to be bound, or null if this is not a method of a class.
- // cppInvokerFunc: JS Function object to the C++-side function that interops into C++ code.
- // cppTargetFunc: Function pointer (an integer to FUNCTION_TABLE) to the target C++ function the cppInvokerFunc will end up calling.
- var argCount = argTypes.length;
-
- if (argCount < 2) {
- throwBindingError("argTypes array size mismatch! Must at least get return value and 'this' types!");
- }
-
- var isClassMethodFunc = (argTypes[1] !== null && classType !== null);
-
- // Free functions with signature "void function()" do not need an invoker that marshalls between wire types.
- // TODO: This omits argument count check - enable only at -O3 or similar.
- // if (ENABLE_UNSAFE_OPTS && argCount == 2 && argTypes[0].name == "void" && !isClassMethodFunc) {
- // return FUNCTION_TABLE[fn];
- // }
-
- // Determine if we need to use a dynamic stack to store the destructors for the function parameters.
- // TODO: Remove this completely once all function invokers are being dynamically generated.
- var needsDestructorStack = false;
-
- for (var i = 1; i < argTypes.length; ++i) { // Skip return value at index 0 - it's not deleted here.
- if (argTypes[i] !== null && argTypes[i].destructorFunction === undefined) { // The type does not define a destructor function - must use dynamic stack
- needsDestructorStack = true;
- break;
- }
- }
-
- var returns = (argTypes[0].name !== "void");
-
- var argsList = "";
- var argsListWired = "";
- for (var i = 0; i < argCount - 2; ++i) {
- argsList += (i!==0?", ":"")+"arg"+i;
- argsListWired += (i!==0?", ":"")+"arg"+i+"Wired";
- }
-
- var invokerFnBody =
- "return function "+makeLegalFunctionName(humanName)+"("+argsList+") {\n" +
- "if (arguments.length !== "+(argCount - 2)+") {\n" +
- "throwBindingError('function "+humanName+" called with ' + arguments.length + ' arguments, expected "+(argCount - 2)+" args!');\n" +
- "}\n";
-
- if (needsDestructorStack) {
- invokerFnBody += "var destructors = [];\n";
- }
-
- var dtorStack = needsDestructorStack ? "destructors" : "null";
- var args1 = ["throwBindingError", "invoker", "fn", "runDestructors", "retType", "classParam"];
- var args2 = [throwBindingError, cppInvokerFunc, cppTargetFunc, runDestructors, argTypes[0], argTypes[1]];
-
- if (isClassMethodFunc) {
- invokerFnBody += "var thisWired = classParam.toWireType("+dtorStack+", this);\n";
- }
-
- for (var i = 0; i < argCount - 2; ++i) {
- invokerFnBody += "var arg"+i+"Wired = argType"+i+".toWireType("+dtorStack+", arg"+i+"); // "+argTypes[i+2].name+"\n";
- args1.push("argType"+i);
- args2.push(argTypes[i+2]);
- }
-
- if (isClassMethodFunc) {
- argsListWired = "thisWired" + (argsListWired.length > 0 ? ", " : "") + argsListWired;
- }
-
- invokerFnBody +=
- (returns?"var rv = ":"") + "invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";
-
- if (needsDestructorStack) {
- invokerFnBody += "runDestructors(destructors);\n";
- } else {
- for (var i = isClassMethodFunc?1:2; i < argTypes.length; ++i) { // Skip return value at index 0 - it's not deleted here. Also skip class type if not a method.
- var paramName = (i === 1 ? "thisWired" : ("arg"+(i - 2)+"Wired"));
- if (argTypes[i].destructorFunction !== null) {
- invokerFnBody += paramName+"_dtor("+paramName+"); // "+argTypes[i].name+"\n";
- args1.push(paramName+"_dtor");
- args2.push(argTypes[i].destructorFunction);
- }
- }
- }
-
- if (returns) {
- invokerFnBody += "var ret = retType.fromWireType(rv);\n" +
- "return ret;\n";
- } else {
- }
-
- invokerFnBody += "}\n";
-
- args1.push(invokerFnBody);
-
- var invokerFunction = new_(Function, args1).apply(null, args2);
- return invokerFunction;
- }
-
-
- function heap32VectorToArray(count, firstElement) {
- var array = [];
- for (var i = 0; i < count; i++) {
- // TODO(https://github.com/emscripten-core/emscripten/issues/17310):
- // Find a way to hoist the `>> 2` or `>> 3` out of this loop.
- array.push(HEAPU32[(((firstElement)+(i * 4))>>2)]);
- }
- return array;
- }
-
-
-
-
- function __embind_register_class_class_function(rawClassType,
- methodName,
- argCount,
- rawArgTypesAddr,
- invokerSignature,
- rawInvoker,
- fn) {
- var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr);
- methodName = readLatin1String(methodName);
- rawInvoker = embind__requireFunction(invokerSignature, rawInvoker);
- whenDependentTypesAreResolved([], [rawClassType], function(classType) {
- classType = classType[0];
- var humanName = classType.name + '.' + methodName;
-
- function unboundTypesHandler() {
- throwUnboundTypeError('Cannot call ' + humanName + ' due to unbound types', rawArgTypes);
- }
-
- if (methodName.startsWith("@@")) {
- methodName = Symbol[methodName.substring(2)];
- }
-
- var proto = classType.registeredClass.constructor;
- if (undefined === proto[methodName]) {
- // This is the first function to be registered with this name.
- unboundTypesHandler.argCount = argCount-1;
- proto[methodName] = unboundTypesHandler;
- } else {
- // There was an existing function with the same name registered. Set up
- // a function overload routing table.
- ensureOverloadTable(proto, methodName, humanName);
- proto[methodName].overloadTable[argCount-1] = unboundTypesHandler;
- }
-
- whenDependentTypesAreResolved([], rawArgTypes, function(argTypes) {
- // Replace the initial unbound-types-handler stub with the proper
- // function. If multiple overloads are registered, the function handlers
- // go into an overload table.
- var invokerArgsArray = [argTypes[0] /* return value */, null /* no class 'this'*/].concat(argTypes.slice(1) /* actual params */);
- var func = craftInvokerFunction(humanName, invokerArgsArray, null /* no class 'this'*/, rawInvoker, fn);
- if (undefined === proto[methodName].overloadTable) {
- func.argCount = argCount-1;
- proto[methodName] = func;
- } else {
- proto[methodName].overloadTable[argCount-1] = func;
- }
- return [];
- });
- return [];
- });
- }
-
-
-
-
-
-
- function __embind_register_class_constructor(
- rawClassType,
- argCount,
- rawArgTypesAddr,
- invokerSignature,
- invoker,
- rawConstructor
- ) {
- assert(argCount > 0);
- var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr);
- invoker = embind__requireFunction(invokerSignature, invoker);
- var args = [rawConstructor];
- var destructors = [];
-
- whenDependentTypesAreResolved([], [rawClassType], function(classType) {
- classType = classType[0];
- var humanName = 'constructor ' + classType.name;
-
- if (undefined === classType.registeredClass.constructor_body) {
- classType.registeredClass.constructor_body = [];
- }
- if (undefined !== classType.registeredClass.constructor_body[argCount - 1]) {
- throw new BindingError("Cannot register multiple constructors with identical number of parameters (" + (argCount-1) + ") for class '" + classType.name + "'! Overload resolution is currently only performed using the parameter count, not actual type info!");
- }
- classType.registeredClass.constructor_body[argCount - 1] = () => {
- throwUnboundTypeError('Cannot construct ' + classType.name + ' due to unbound types', rawArgTypes);
- };
-
- whenDependentTypesAreResolved([], rawArgTypes, function(argTypes) {
- // Insert empty slot for context type (argTypes[1]).
- argTypes.splice(1, 0, null);
- classType.registeredClass.constructor_body[argCount - 1] = craftInvokerFunction(humanName, argTypes, null, invoker, rawConstructor);
- return [];
- });
- return [];
- });
- }
-
-
-
-
-
- function __embind_register_class_function(rawClassType,
- methodName,
- argCount,
- rawArgTypesAddr, // [ReturnType, ThisType, Args...]
- invokerSignature,
- rawInvoker,
- context,
- isPureVirtual) {
- var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr);
- methodName = readLatin1String(methodName);
- rawInvoker = embind__requireFunction(invokerSignature, rawInvoker);
-
- whenDependentTypesAreResolved([], [rawClassType], function(classType) {
- classType = classType[0];
- var humanName = classType.name + '.' + methodName;
-
- if (methodName.startsWith("@@")) {
- methodName = Symbol[methodName.substring(2)];
- }
-
- if (isPureVirtual) {
- classType.registeredClass.pureVirtualFunctions.push(methodName);
- }
-
- function unboundTypesHandler() {
- throwUnboundTypeError('Cannot call ' + humanName + ' due to unbound types', rawArgTypes);
- }
-
- var proto = classType.registeredClass.instancePrototype;
- var method = proto[methodName];
- if (undefined === method || (undefined === method.overloadTable && method.className !== classType.name && method.argCount === argCount - 2)) {
- // This is the first overload to be registered, OR we are replacing a
- // function in the base class with a function in the derived class.
- unboundTypesHandler.argCount = argCount - 2;
- unboundTypesHandler.className = classType.name;
- proto[methodName] = unboundTypesHandler;
- } else {
- // There was an existing function with the same name registered. Set up
- // a function overload routing table.
- ensureOverloadTable(proto, methodName, humanName);
- proto[methodName].overloadTable[argCount - 2] = unboundTypesHandler;
- }
-
- whenDependentTypesAreResolved([], rawArgTypes, function(argTypes) {
- var memberFunction = craftInvokerFunction(humanName, argTypes, classType, rawInvoker, context);
-
- // Replace the initial unbound-handler-stub function with the appropriate member function, now that all types
- // are resolved. If multiple overloads are registered for this function, the function goes into an overload table.
- if (undefined === proto[methodName].overloadTable) {
- // Set argCount in case an overload is registered later
- memberFunction.argCount = argCount - 2;
- proto[methodName] = memberFunction;
- } else {
- proto[methodName].overloadTable[argCount - 2] = memberFunction;
- }
-
- return [];
- });
- return [];
- });
- }
-
-
-
-
-
-
-
- function validateThis(this_, classType, humanName) {
- if (!(this_ instanceof Object)) {
- throwBindingError(humanName + ' with invalid "this": ' + this_);
- }
- if (!(this_ instanceof classType.registeredClass.constructor)) {
- throwBindingError(humanName + ' incompatible with "this" of type ' + this_.constructor.name);
- }
- if (!this_.$$.ptr) {
- throwBindingError('cannot call emscripten binding method ' + humanName + ' on deleted object');
- }
-
- // todo: kill this
- return upcastPointer(this_.$$.ptr,
- this_.$$.ptrType.registeredClass,
- classType.registeredClass);
- }
- function __embind_register_class_property(classType,
- fieldName,
- getterReturnType,
- getterSignature,
- getter,
- getterContext,
- setterArgumentType,
- setterSignature,
- setter,
- setterContext) {
- fieldName = readLatin1String(fieldName);
- getter = embind__requireFunction(getterSignature, getter);
-
- whenDependentTypesAreResolved([], [classType], function(classType) {
- classType = classType[0];
- var humanName = classType.name + '.' + fieldName;
- var desc = {
- get: function() {
- throwUnboundTypeError('Cannot access ' + humanName + ' due to unbound types', [getterReturnType, setterArgumentType]);
- },
- enumerable: true,
- configurable: true
- };
- if (setter) {
- desc.set = () => {
- throwUnboundTypeError('Cannot access ' + humanName + ' due to unbound types', [getterReturnType, setterArgumentType]);
- };
- } else {
- desc.set = (v) => {
- throwBindingError(humanName + ' is a read-only property');
- };
- }
-
- Object.defineProperty(classType.registeredClass.instancePrototype, fieldName, desc);
-
- whenDependentTypesAreResolved(
- [],
- (setter ? [getterReturnType, setterArgumentType] : [getterReturnType]),
- function(types) {
- var getterReturnType = types[0];
- var desc = {
- get: function() {
- var ptr = validateThis(this, classType, humanName + ' getter');
- return getterReturnType['fromWireType'](getter(getterContext, ptr));
- },
- enumerable: true
- };
-
- if (setter) {
- setter = embind__requireFunction(setterSignature, setter);
- var setterArgumentType = types[1];
- desc.set = function(v) {
- var ptr = validateThis(this, classType, humanName + ' setter');
- var destructors = [];
- setter(setterContext, ptr, setterArgumentType['toWireType'](destructors, v));
- runDestructors(destructors);
- };
- }
-
- Object.defineProperty(classType.registeredClass.instancePrototype, fieldName, desc);
- return [];
- });
-
- return [];
- });
- }
- var emval_free_list = [];
-
- var emval_handle_array = [{},{value:undefined},{value:null},{value:true},{value:false}];
- function __emval_decref(handle) {
- if (handle > 4 && 0 === --emval_handle_array[handle].refcount) {
- emval_handle_array[handle] = undefined;
- emval_free_list.push(handle);
- }
- }
-
-
-
-
- function count_emval_handles() {
- var count = 0;
- for (var i = 5; i < emval_handle_array.length; ++i) {
- if (emval_handle_array[i] !== undefined) {
- ++count;
- }
- }
- return count;
- }
-
- function get_first_emval() {
- for (var i = 5; i < emval_handle_array.length; ++i) {
- if (emval_handle_array[i] !== undefined) {
- return emval_handle_array[i];
- }
- }
- return null;
- }
- function init_emval() {
- Module['count_emval_handles'] = count_emval_handles;
- Module['get_first_emval'] = get_first_emval;
- }
- var Emval = {toValue:(handle) => {
- if (!handle) {
- throwBindingError('Cannot use deleted val. handle = ' + handle);
- }
- return emval_handle_array[handle].value;
- },toHandle:(value) => {
- switch (value) {
- case undefined: return 1;
- case null: return 2;
- case true: return 3;
- case false: return 4;
- default:{
- var handle = emval_free_list.length ?
- emval_free_list.pop() :
- emval_handle_array.length;
-
- emval_handle_array[handle] = {refcount: 1, value: value};
- return handle;
- }
- }
- }};
-
-
-
- function __embind_register_emval(rawType, name) {
- name = readLatin1String(name);
- registerType(rawType, {
- name: name,
- 'fromWireType': function(handle) {
- var rv = Emval.toValue(handle);
- __emval_decref(handle);
- return rv;
- },
- 'toWireType': function(destructors, value) {
- return Emval.toHandle(value);
- },
- 'argPackAdvance': 8,
- 'readValueFromPointer': simpleReadValueFromPointer,
- destructorFunction: null, // This type does not need a destructor
-
- // TODO: do we need a deleteObject here? write a test where
- // emval is passed into JS via an interface
- });
- }
-
-
- function enumReadValueFromPointer(name, shift, signed) {
- switch (shift) {
- case 0: return function(pointer) {
- var heap = signed ? HEAP8 : HEAPU8;
- return this['fromWireType'](heap[pointer]);
- };
- case 1: return function(pointer) {
- var heap = signed ? HEAP16 : HEAPU16;
- return this['fromWireType'](heap[pointer >> 1]);
- };
- case 2: return function(pointer) {
- var heap = signed ? HEAP32 : HEAPU32;
- return this['fromWireType'](heap[pointer >> 2]);
- };
- default:
- throw new TypeError("Unknown integer type: " + name);
- }
- }
-
-
- function __embind_register_enum(rawType, name, size, isSigned) {
- var shift = getShiftFromSize(size);
- name = readLatin1String(name);
-
- function ctor() {}
- ctor.values = {};
-
- registerType(rawType, {
- name: name,
- constructor: ctor,
- 'fromWireType': function(c) {
- return this.constructor.values[c];
- },
- 'toWireType': function(destructors, c) {
- return c.value;
- },
- 'argPackAdvance': 8,
- 'readValueFromPointer': enumReadValueFromPointer(name, shift, isSigned),
- destructorFunction: null,
- });
- exposePublicSymbol(name, ctor);
- }
-
-
-
-
- function requireRegisteredType(rawType, humanName) {
- var impl = registeredTypes[rawType];
- if (undefined === impl) {
- throwBindingError(humanName + " has unknown type " + getTypeName(rawType));
- }
- return impl;
- }
- function __embind_register_enum_value(rawEnumType, name, enumValue) {
- var enumType = requireRegisteredType(rawEnumType, 'enum');
- name = readLatin1String(name);
-
- var Enum = enumType.constructor;
-
- var Value = Object.create(enumType.constructor.prototype, {
- value: {value: enumValue},
- constructor: {value: createNamedFunction(enumType.name + '_' + name, function() {})},
- });
- Enum.values[enumValue] = Value;
- Enum[name] = Value;
- }
- function embindRepr(v) {
- if (v === null) {
- return 'null';
- }
- var t = typeof v;
- if (t === 'object' || t === 'array' || t === 'function') {
- return v.toString();
- } else {
- return '' + v;
- }
- }
-
- function floatReadValueFromPointer(name, shift) {
- switch (shift) {
- case 2: return function(pointer) {
- return this['fromWireType'](HEAPF32[pointer >> 2]);
- };
- case 3: return function(pointer) {
- return this['fromWireType'](HEAPF64[pointer >> 3]);
- };
- default:
- throw new TypeError("Unknown float type: " + name);
- }
- }
-
-
-
- function __embind_register_float(rawType, name, size) {
- var shift = getShiftFromSize(size);
- name = readLatin1String(name);
- registerType(rawType, {
- name: name,
- 'fromWireType': function(value) {
- return value;
- },
- 'toWireType': function(destructors, value) {
- if (typeof value != "number" && typeof value != "boolean") {
- throw new TypeError('Cannot convert "' + embindRepr(value) + '" to ' + this.name);
- }
- // The VM will perform JS to Wasm value conversion, according to the spec:
- // https://www.w3.org/TR/wasm-js-api-1/#towebassemblyvalue
- return value;
- },
- 'argPackAdvance': 8,
- 'readValueFromPointer': floatReadValueFromPointer(name, shift),
- destructorFunction: null, // This type does not need a destructor
- });
- }
-
-
- function integerReadValueFromPointer(name, shift, signed) {
- // integers are quite common, so generate very specialized functions
- switch (shift) {
- case 0: return signed ?
- function readS8FromPointer(pointer) { return HEAP8[pointer]; } :
- function readU8FromPointer(pointer) { return HEAPU8[pointer]; };
- case 1: return signed ?
- function readS16FromPointer(pointer) { return HEAP16[pointer >> 1]; } :
- function readU16FromPointer(pointer) { return HEAPU16[pointer >> 1]; };
- case 2: return signed ?
- function readS32FromPointer(pointer) { return HEAP32[pointer >> 2]; } :
- function readU32FromPointer(pointer) { return HEAPU32[pointer >> 2]; };
- default:
- throw new TypeError("Unknown integer type: " + name);
- }
- }
-
-
- function __embind_register_integer(primitiveType, name, size, minRange, maxRange) {
- name = readLatin1String(name);
- // LLVM doesn't have signed and unsigned 32-bit types, so u32 literals come
- // out as 'i32 -1'. Always treat those as max u32.
- if (maxRange === -1) {
- maxRange = 4294967295;
- }
-
- var shift = getShiftFromSize(size);
-
- var fromWireType = (value) => value;
-
- if (minRange === 0) {
- var bitshift = 32 - 8*size;
- fromWireType = (value) => (value << bitshift) >>> bitshift;
- }
-
- var isUnsignedType = (name.includes('unsigned'));
- var checkAssertions = (value, toTypeName) => {
- if (typeof value != "number" && typeof value != "boolean") {
- throw new TypeError('Cannot convert "' + embindRepr(value) + '" to ' + toTypeName);
- }
- if (value < minRange || value > maxRange) {
- throw new TypeError('Passing a number "' + embindRepr(value) + '" from JS side to C/C++ side to an argument of type "' + name + '", which is outside the valid range [' + minRange + ', ' + maxRange + ']!');
- }
- }
- var toWireType;
- if (isUnsignedType) {
- toWireType = function(destructors, value) {
- checkAssertions(value, this.name);
- return value >>> 0;
- }
- } else {
- toWireType = function(destructors, value) {
- checkAssertions(value, this.name);
- // The VM will perform JS to Wasm value conversion, according to the spec:
- // https://www.w3.org/TR/wasm-js-api-1/#towebassemblyvalue
- return value;
- }
- }
- registerType(primitiveType, {
- name: name,
- 'fromWireType': fromWireType,
- 'toWireType': toWireType,
- 'argPackAdvance': 8,
- 'readValueFromPointer': integerReadValueFromPointer(name, shift, minRange !== 0),
- destructorFunction: null, // This type does not need a destructor
- });
- }
-
- function __embind_register_memory_view(rawType, dataTypeIndex, name) {
- var typeMapping = [
- Int8Array,
- Uint8Array,
- Int16Array,
- Uint16Array,
- Int32Array,
- Uint32Array,
- Float32Array,
- Float64Array,
- ];
-
- var TA = typeMapping[dataTypeIndex];
-
- function decodeMemoryView(handle) {
- handle = handle >> 2;
- var heap = HEAPU32;
- var size = heap[handle]; // in elements
- var data = heap[handle + 1]; // byte offset into emscripten heap
- return new TA(heap.buffer, data, size);
- }
-
- name = readLatin1String(name);
- registerType(rawType, {
- name: name,
- 'fromWireType': decodeMemoryView,
- 'argPackAdvance': 8,
- 'readValueFromPointer': decodeMemoryView,
- }, {
- ignoreDuplicateRegistrations: true,
- });
- }
-
-
-
- function __embind_register_std_string(rawType, name) {
- name = readLatin1String(name);
- var stdStringIsUTF8
- //process only std::string bindings with UTF8 support, in contrast to e.g. std::basic_string<unsigned char>
- = (name === "std::string");
-
- registerType(rawType, {
- name: name,
- 'fromWireType': function(value) {
- var length = HEAPU32[((value)>>2)];
- var payload = value + 4;
-
- var str;
- if (stdStringIsUTF8) {
- var decodeStartPtr = payload;
- // Looping here to support possible embedded '0' bytes
- for (var i = 0; i <= length; ++i) {
- var currentBytePtr = payload + i;
- if (i == length || HEAPU8[currentBytePtr] == 0) {
- var maxRead = currentBytePtr - decodeStartPtr;
- var stringSegment = UTF8ToString(decodeStartPtr, maxRead);
- if (str === undefined) {
- str = stringSegment;
- } else {
- str += String.fromCharCode(0);
- str += stringSegment;
- }
- decodeStartPtr = currentBytePtr + 1;
- }
- }
- } else {
- var a = new Array(length);
- for (var i = 0; i < length; ++i) {
- a[i] = String.fromCharCode(HEAPU8[payload + i]);
- }
- str = a.join('');
- }
-
- _free(value);
-
- return str;
- },
- 'toWireType': function(destructors, value) {
- if (value instanceof ArrayBuffer) {
- value = new Uint8Array(value);
- }
-
- var length;
- var valueIsOfTypeString = (typeof value == 'string');
-
- if (!(valueIsOfTypeString || value instanceof Uint8Array || value instanceof Uint8ClampedArray || value instanceof Int8Array)) {
- throwBindingError('Cannot pass non-string to std::string');
- }
- if (stdStringIsUTF8 && valueIsOfTypeString) {
- length = lengthBytesUTF8(value);
- } else {
- length = value.length;
- }
-
- // assumes 4-byte alignment
- var base = _malloc(4 + length + 1);
- var ptr = base + 4;
- HEAPU32[((base)>>2)] = length;
- if (stdStringIsUTF8 && valueIsOfTypeString) {
- stringToUTF8(value, ptr, length + 1);
- } else {
- if (valueIsOfTypeString) {
- for (var i = 0; i < length; ++i) {
- var charCode = value.charCodeAt(i);
- if (charCode > 255) {
- _free(ptr);
- throwBindingError('String has UTF-16 code units that do not fit in 8 bits');
- }
- HEAPU8[ptr + i] = charCode;
- }
- } else {
- for (var i = 0; i < length; ++i) {
- HEAPU8[ptr + i] = value[i];
- }
- }
- }
-
- if (destructors !== null) {
- destructors.push(_free, base);
- }
- return base;
- },
- 'argPackAdvance': 8,
- 'readValueFromPointer': simpleReadValueFromPointer,
- destructorFunction: function(ptr) { _free(ptr); },
- });
- }
-
-
-
- var UTF16Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf-16le') : undefined;;
- function UTF16ToString(ptr, maxBytesToRead) {
- assert(ptr % 2 == 0, 'Pointer passed to UTF16ToString must be aligned to two bytes!');
- var endPtr = ptr;
- // TextDecoder needs to know the byte length in advance, it doesn't stop on
- // null terminator by itself.
- // Also, use the length info to avoid running tiny strings through
- // TextDecoder, since .subarray() allocates garbage.
- var idx = endPtr >> 1;
- var maxIdx = idx + maxBytesToRead / 2;
- // If maxBytesToRead is not passed explicitly, it will be undefined, and this
- // will always evaluate to true. This saves on code size.
- while (!(idx >= maxIdx) && HEAPU16[idx]) ++idx;
- endPtr = idx << 1;
-
- if (endPtr - ptr > 32 && UTF16Decoder)
- return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr));
-
- // Fallback: decode without UTF16Decoder
- var str = '';
-
- // If maxBytesToRead is not passed explicitly, it will be undefined, and the
- // for-loop's condition will always evaluate to true. The loop is then
- // terminated on the first null char.
- for (var i = 0; !(i >= maxBytesToRead / 2); ++i) {
- var codeUnit = HEAP16[(((ptr)+(i*2))>>1)];
- if (codeUnit == 0) break;
- // fromCharCode constructs a character from a UTF-16 code unit, so we can
- // pass the UTF16 string right through.
- str += String.fromCharCode(codeUnit);
- }
-
- return str;
- }
-
- function stringToUTF16(str, outPtr, maxBytesToWrite) {
- assert(outPtr % 2 == 0, 'Pointer passed to stringToUTF16 must be aligned to two bytes!');
- assert(typeof maxBytesToWrite == 'number', 'stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!');
- // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed.
- if (maxBytesToWrite === undefined) {
- maxBytesToWrite = 0x7FFFFFFF;
- }
- if (maxBytesToWrite < 2) return 0;
- maxBytesToWrite -= 2; // Null terminator.
- var startPtr = outPtr;
- var numCharsToWrite = (maxBytesToWrite < str.length*2) ? (maxBytesToWrite / 2) : str.length;
- for (var i = 0; i < numCharsToWrite; ++i) {
- // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP.
- var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
- HEAP16[((outPtr)>>1)] = codeUnit;
- outPtr += 2;
- }
- // Null-terminate the pointer to the HEAP.
- HEAP16[((outPtr)>>1)] = 0;
- return outPtr - startPtr;
- }
-
- function lengthBytesUTF16(str) {
- return str.length*2;
- }
-
- function UTF32ToString(ptr, maxBytesToRead) {
- assert(ptr % 4 == 0, 'Pointer passed to UTF32ToString must be aligned to four bytes!');
- var i = 0;
-
- var str = '';
- // If maxBytesToRead is not passed explicitly, it will be undefined, and this
- // will always evaluate to true. This saves on code size.
- while (!(i >= maxBytesToRead / 4)) {
- var utf32 = HEAP32[(((ptr)+(i*4))>>2)];
- if (utf32 == 0) break;
- ++i;
- // Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing.
- // See http://unicode.org/faq/utf_bom.html#utf16-3
- if (utf32 >= 0x10000) {
- var ch = utf32 - 0x10000;
- str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
- } else {
- str += String.fromCharCode(utf32);
- }
- }
- return str;
- }
-
- function stringToUTF32(str, outPtr, maxBytesToWrite) {
- assert(outPtr % 4 == 0, 'Pointer passed to stringToUTF32 must be aligned to four bytes!');
- assert(typeof maxBytesToWrite == 'number', 'stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!');
- // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed.
- if (maxBytesToWrite === undefined) {
- maxBytesToWrite = 0x7FFFFFFF;
- }
- if (maxBytesToWrite < 4) return 0;
- var startPtr = outPtr;
- var endPtr = startPtr + maxBytesToWrite - 4;
- for (var i = 0; i < str.length; ++i) {
- // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.
- // See http://unicode.org/faq/utf_bom.html#utf16-3
- var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
- if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) {
- var trailSurrogate = str.charCodeAt(++i);
- codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF);
- }
- HEAP32[((outPtr)>>2)] = codeUnit;
- outPtr += 4;
- if (outPtr + 4 > endPtr) break;
- }
- // Null-terminate the pointer to the HEAP.
- HEAP32[((outPtr)>>2)] = 0;
- return outPtr - startPtr;
- }
-
- function lengthBytesUTF32(str) {
- var len = 0;
- for (var i = 0; i < str.length; ++i) {
- // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.
- // See http://unicode.org/faq/utf_bom.html#utf16-3
- var codeUnit = str.charCodeAt(i);
- if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) ++i; // possibly a lead surrogate, so skip over the tail surrogate.
- len += 4;
- }
-
- return len;
- }
- function __embind_register_std_wstring(rawType, charSize, name) {
- name = readLatin1String(name);
- var decodeString, encodeString, getHeap, lengthBytesUTF, shift;
- if (charSize === 2) {
- decodeString = UTF16ToString;
- encodeString = stringToUTF16;
- lengthBytesUTF = lengthBytesUTF16;
- getHeap = () => HEAPU16;
- shift = 1;
- } else if (charSize === 4) {
- decodeString = UTF32ToString;
- encodeString = stringToUTF32;
- lengthBytesUTF = lengthBytesUTF32;
- getHeap = () => HEAPU32;
- shift = 2;
- }
- registerType(rawType, {
- name: name,
- 'fromWireType': function(value) {
- // Code mostly taken from _embind_register_std_string fromWireType
- var length = HEAPU32[value >> 2];
- var HEAP = getHeap();
- var str;
-
- var decodeStartPtr = value + 4;
- // Looping here to support possible embedded '0' bytes
- for (var i = 0; i <= length; ++i) {
- var currentBytePtr = value + 4 + i * charSize;
- if (i == length || HEAP[currentBytePtr >> shift] == 0) {
- var maxReadBytes = currentBytePtr - decodeStartPtr;
- var stringSegment = decodeString(decodeStartPtr, maxReadBytes);
- if (str === undefined) {
- str = stringSegment;
- } else {
- str += String.fromCharCode(0);
- str += stringSegment;
- }
- decodeStartPtr = currentBytePtr + charSize;
- }
- }
-
- _free(value);
-
- return str;
- },
- 'toWireType': function(destructors, value) {
- if (!(typeof value == 'string')) {
- throwBindingError('Cannot pass non-string to C++ string type ' + name);
- }
-
- // assumes 4-byte alignment
- var length = lengthBytesUTF(value);
- var ptr = _malloc(4 + length + charSize);
- HEAPU32[ptr >> 2] = length >> shift;
-
- encodeString(value, ptr + 4, length + charSize);
-
- if (destructors !== null) {
- destructors.push(_free, ptr);
- }
- return ptr;
- },
- 'argPackAdvance': 8,
- 'readValueFromPointer': simpleReadValueFromPointer,
- destructorFunction: function(ptr) { _free(ptr); },
- });
- }
-
-
- function __embind_register_value_array(
- rawType,
- name,
- constructorSignature,
- rawConstructor,
- destructorSignature,
- rawDestructor
- ) {
- tupleRegistrations[rawType] = {
- name: readLatin1String(name),
- rawConstructor: embind__requireFunction(constructorSignature, rawConstructor),
- rawDestructor: embind__requireFunction(destructorSignature, rawDestructor),
- elements: [],
- };
- }
-
- function __embind_register_value_array_element(
- rawTupleType,
- getterReturnType,
- getterSignature,
- getter,
- getterContext,
- setterArgumentType,
- setterSignature,
- setter,
- setterContext
- ) {
- tupleRegistrations[rawTupleType].elements.push({
- getterReturnType: getterReturnType,
- getter: embind__requireFunction(getterSignature, getter),
- getterContext: getterContext,
- setterArgumentType: setterArgumentType,
- setter: embind__requireFunction(setterSignature, setter),
- setterContext: setterContext,
- });
- }
-
-
- function __embind_register_value_object(
- rawType,
- name,
- constructorSignature,
- rawConstructor,
- destructorSignature,
- rawDestructor
- ) {
- structRegistrations[rawType] = {
- name: readLatin1String(name),
- rawConstructor: embind__requireFunction(constructorSignature, rawConstructor),
- rawDestructor: embind__requireFunction(destructorSignature, rawDestructor),
- fields: [],
- };
- }
-
-
- function __embind_register_value_object_field(
- structType,
- fieldName,
- getterReturnType,
- getterSignature,
- getter,
- getterContext,
- setterArgumentType,
- setterSignature,
- setter,
- setterContext
- ) {
- structRegistrations[structType].fields.push({
- fieldName: readLatin1String(fieldName),
- getterReturnType: getterReturnType,
- getter: embind__requireFunction(getterSignature, getter),
- getterContext: getterContext,
- setterArgumentType: setterArgumentType,
- setter: embind__requireFunction(setterSignature, setter),
- setterContext: setterContext,
- });
- }
-
- function __embind_register_void(rawType, name) {
- name = readLatin1String(name);
- registerType(rawType, {
- isVoid: true, // void return values can be optimized out sometimes
- name: name,
- 'argPackAdvance': 0,
- 'fromWireType': function() {
- return undefined;
- },
- 'toWireType': function(destructors, o) {
- // TODO: assert if anything else is given?
- return undefined;
- },
- });
- }
- var nowIsMonotonic = true;;
- function __emscripten_get_now_is_monotonic() {
- return nowIsMonotonic;
- }
-
- function __emval_as(handle, returnType, destructorsRef) {
- handle = Emval.toValue(handle);
- returnType = requireRegisteredType(returnType, 'emval::as');
- var destructors = [];
- var rd = Emval.toHandle(destructors);
- HEAPU32[((destructorsRef)>>2)] = rd;
- return returnType['toWireType'](destructors, handle);
- }
- function emval_allocateDestructors(destructorsRef) {
- var destructors = [];
- HEAPU32[((destructorsRef)>>2)] = Emval.toHandle(destructors);
- return destructors;
- }
-
- var emval_symbols = {};
-
- function getStringOrSymbol(address) {
- var symbol = emval_symbols[address];
- if (symbol === undefined) {
- return readLatin1String(address);
- }
- return symbol;
- }
-
- var emval_methodCallers = [];
-
- function __emval_call_method(caller, handle, methodName, destructorsRef, args) {
- caller = emval_methodCallers[caller];
- handle = Emval.toValue(handle);
- methodName = getStringOrSymbol(methodName);
- return caller(handle, methodName, emval_allocateDestructors(destructorsRef), args);
- }
-
-
-
- function __emval_call_void_method(caller, handle, methodName, args) {
- caller = emval_methodCallers[caller];
- handle = Emval.toValue(handle);
- methodName = getStringOrSymbol(methodName);
- caller(handle, methodName, null, args);
- }
- function __emval_equals(first, second) {
- first = Emval.toValue(first);
- second = Emval.toValue(second);
- return first == second;
- }
-
-
- function emval_get_global() {
- if (typeof globalThis == 'object') {
- return globalThis;
- }
- return (function(){
- return Function;
- })()('return this')();
- }
- function __emval_get_global(name) {
- if (name===0) {
- return Emval.toHandle(emval_get_global());
- } else {
- name = getStringOrSymbol(name);
- return Emval.toHandle(emval_get_global()[name]);
- }
- }
- function emval_addMethodCaller(caller) {
- var id = emval_methodCallers.length;
- emval_methodCallers.push(caller);
- return id;
- }
-
- function emval_lookupTypes(argCount, argTypes) {
- var a = new Array(argCount);
- for (var i = 0; i < argCount; ++i) {
- a[i] = requireRegisteredType(HEAPU32[(((argTypes)+(i * POINTER_SIZE))>>2)],
- "parameter " + i);
- }
- return a;
- }
-
-
-
- var emval_registeredMethods = [];
- function __emval_get_method_caller(argCount, argTypes) {
- var types = emval_lookupTypes(argCount, argTypes);
- var retType = types[0];
- var signatureName = retType.name + "_$" + types.slice(1).map(function (t) { return t.name; }).join("_") + "$";
- var returnId = emval_registeredMethods[signatureName];
- if (returnId !== undefined) {
- return returnId;
- }
-
- var params = ["retType"];
- var args = [retType];
-
- var argsList = ""; // 'arg0, arg1, arg2, ... , argN'
- for (var i = 0; i < argCount - 1; ++i) {
- argsList += (i !== 0 ? ", " : "") + "arg" + i;
- params.push("argType" + i);
- args.push(types[1 + i]);
- }
-
- var functionName = makeLegalFunctionName("methodCaller_" + signatureName);
- var functionBody =
- "return function " + functionName + "(handle, name, destructors, args) {\n";
-
- var offset = 0;
- for (var i = 0; i < argCount - 1; ++i) {
- functionBody +=
- " var arg" + i + " = argType" + i + ".readValueFromPointer(args" + (offset ? ("+"+offset) : "") + ");\n";
- offset += types[i + 1]['argPackAdvance'];
- }
- functionBody +=
- " var rv = handle[name](" + argsList + ");\n";
- for (var i = 0; i < argCount - 1; ++i) {
- if (types[i + 1]['deleteObject']) {
- functionBody +=
- " argType" + i + ".deleteObject(arg" + i + ");\n";
- }
- }
- if (!retType.isVoid) {
- functionBody +=
- " return retType.toWireType(destructors, rv);\n";
- }
- functionBody +=
- "};\n";
-
- params.push(functionBody);
- var invokerFunction = new_(Function, params).apply(null, args);
- returnId = emval_addMethodCaller(invokerFunction);
- emval_registeredMethods[signatureName] = returnId;
- return returnId;
- }
-
- function __emval_get_module_property(name) {
- name = getStringOrSymbol(name);
- return Emval.toHandle(Module[name]);
- }
- function __emval_get_property(handle, key) {
- handle = Emval.toValue(handle);
- key = Emval.toValue(key);
- return Emval.toHandle(handle[key]);
- }
- function __emval_incref(handle) {
- if (handle > 4) {
- emval_handle_array[handle].refcount += 1;
- }
- }
- function __emval_instanceof(object, constructor) {
- object = Emval.toValue(object);
- constructor = Emval.toValue(constructor);
- return object instanceof constructor;
- }
- function __emval_is_number(handle) {
- handle = Emval.toValue(handle);
- return typeof handle == 'number';
- }
- function __emval_is_string(handle) {
- handle = Emval.toValue(handle);
- return typeof handle == 'string';
- }
-
- function craftEmvalAllocator(argCount) {
- /*This function returns a new function that looks like this:
- function emval_allocator_3(constructor, argTypes, args) {
- var argType0 = requireRegisteredType(HEAP32[(argTypes >> 2)], "parameter 0");
- var arg0 = argType0['readValueFromPointer'](args);
- var argType1 = requireRegisteredType(HEAP32[(argTypes >> 2) + 1], "parameter 1");
- var arg1 = argType1['readValueFromPointer'](args + 8);
- var argType2 = requireRegisteredType(HEAP32[(argTypes >> 2) + 2], "parameter 2");
- var arg2 = argType2['readValueFromPointer'](args + 16);
- var obj = new constructor(arg0, arg1, arg2);
- return Emval.toHandle(obj);
- } */
- var argsList = "";
- for (var i = 0; i < argCount; ++i) {
- argsList += (i!==0?", ":"")+"arg"+i; // 'arg0, arg1, ..., argn'
- }
-
- // The body of the generated function does not have access to enclosing
- // scope where HEAPU64/HEAPU32/etc are defined, and we cannot pass them
- // directly as arguments (like we do the Module object) since memory
- // growth can cause them to be re-bound.
- var getMemory = () => HEAPU32;
-
- var functionBody =
- "return function emval_allocator_"+argCount+"(constructor, argTypes, args) {\n" +
- " var HEAPU32 = getMemory();\n";
-
- for (var i = 0; i < argCount; ++i) {
- functionBody +=
- "var argType"+i+" = requireRegisteredType(HEAPU32[((argTypes)>>2)], 'parameter "+i+"');\n" +
- "var arg"+i+" = argType"+i+".readValueFromPointer(args);\n" +
- "args += argType"+i+"['argPackAdvance'];\n" +
- "argTypes += 4;\n";
- }
- functionBody +=
- "var obj = new constructor("+argsList+");\n" +
- "return valueToHandle(obj);\n" +
- "}\n";
-
- /*jshint evil:true*/
- return (new Function("requireRegisteredType", "Module", "valueToHandle", "getMemory" , functionBody))(
- requireRegisteredType, Module, Emval.toHandle, getMemory);
- }
-
- var emval_newers = {};
-
- function __emval_new(handle, argCount, argTypes, args) {
- handle = Emval.toValue(handle);
-
- var newer = emval_newers[argCount];
- if (!newer) {
- newer = craftEmvalAllocator(argCount);
- emval_newers[argCount] = newer;
- }
-
- return newer(handle, argTypes, args);
- }
- function __emval_new_array() {
- return Emval.toHandle([]);
- }
-
- function __emval_new_cstring(v) {
- return Emval.toHandle(getStringOrSymbol(v));
- }
- function __emval_new_object() {
- return Emval.toHandle({});
- }
-
-
- function __emval_run_destructors(handle) {
- var destructors = Emval.toValue(handle);
- runDestructors(destructors);
- __emval_decref(handle);
- }
- function __emval_set_property(handle, key, value) {
- handle = Emval.toValue(handle);
- key = Emval.toValue(key);
- value = Emval.toValue(value);
- handle[key] = value;
- }
-
- function __emval_take_value(type, arg) {
- type = requireRegisteredType(type, '_emval_take_value');
- var v = type['readValueFromPointer'](arg);
- return Emval.toHandle(v);
- }
- function readI53FromI64(ptr) {
- return HEAPU32[ptr>>2] + HEAP32[ptr+4>>2] * 4294967296;
- }
- function __gmtime_js(time, tmPtr) {
- var date = new Date(readI53FromI64(time)*1000);
- HEAP32[((tmPtr)>>2)] = date.getUTCSeconds();
- HEAP32[(((tmPtr)+(4))>>2)] = date.getUTCMinutes();
- HEAP32[(((tmPtr)+(8))>>2)] = date.getUTCHours();
- HEAP32[(((tmPtr)+(12))>>2)] = date.getUTCDate();
- HEAP32[(((tmPtr)+(16))>>2)] = date.getUTCMonth();
- HEAP32[(((tmPtr)+(20))>>2)] = date.getUTCFullYear()-1900;
- HEAP32[(((tmPtr)+(24))>>2)] = date.getUTCDay();
- var start = Date.UTC(date.getUTCFullYear(), 0, 1, 0, 0, 0, 0);
- var yday = ((date.getTime() - start) / (1000 * 60 * 60 * 24))|0;
- HEAP32[(((tmPtr)+(28))>>2)] = yday;
- }
-
- function __isLeapYear(year) {
- return year%4 === 0 && (year%100 !== 0 || year%400 === 0);
- }
-
- var __MONTH_DAYS_LEAP_CUMULATIVE = [0,31,60,91,121,152,182,213,244,274,305,335];
-
- var __MONTH_DAYS_REGULAR_CUMULATIVE = [0,31,59,90,120,151,181,212,243,273,304,334];
- function __yday_from_date(date) {
- var isLeapYear = __isLeapYear(date.getFullYear());
- var monthDaysCumulative = (isLeapYear ? __MONTH_DAYS_LEAP_CUMULATIVE : __MONTH_DAYS_REGULAR_CUMULATIVE);
- var yday = monthDaysCumulative[date.getMonth()] + date.getDate() - 1; // -1 since it's days since Jan 1
-
- return yday;
- }
- function __localtime_js(time, tmPtr) {
- var date = new Date(readI53FromI64(time)*1000);
- HEAP32[((tmPtr)>>2)] = date.getSeconds();
- HEAP32[(((tmPtr)+(4))>>2)] = date.getMinutes();
- HEAP32[(((tmPtr)+(8))>>2)] = date.getHours();
- HEAP32[(((tmPtr)+(12))>>2)] = date.getDate();
- HEAP32[(((tmPtr)+(16))>>2)] = date.getMonth();
- HEAP32[(((tmPtr)+(20))>>2)] = date.getFullYear()-1900;
- HEAP32[(((tmPtr)+(24))>>2)] = date.getDay();
-
- var yday = __yday_from_date(date)|0;
- HEAP32[(((tmPtr)+(28))>>2)] = yday;
- HEAP32[(((tmPtr)+(36))>>2)] = -(date.getTimezoneOffset() * 60);
-
- // Attention: DST is in December in South, and some regions don't have DST at all.
- var start = new Date(date.getFullYear(), 0, 1);
- var summerOffset = new Date(date.getFullYear(), 6, 1).getTimezoneOffset();
- var winterOffset = start.getTimezoneOffset();
- var dst = (summerOffset != winterOffset && date.getTimezoneOffset() == Math.min(winterOffset, summerOffset))|0;
- HEAP32[(((tmPtr)+(32))>>2)] = dst;
- }
- function __mktime_js(tmPtr) {
- var date = new Date(HEAP32[(((tmPtr)+(20))>>2)] + 1900,
- HEAP32[(((tmPtr)+(16))>>2)],
- HEAP32[(((tmPtr)+(12))>>2)],
- HEAP32[(((tmPtr)+(8))>>2)],
- HEAP32[(((tmPtr)+(4))>>2)],
- HEAP32[((tmPtr)>>2)],
- 0);
-
- // There's an ambiguous hour when the time goes back; the tm_isdst field is
- // used to disambiguate it. Date() basically guesses, so we fix it up if it
- // guessed wrong, or fill in tm_isdst with the guess if it's -1.
- var dst = HEAP32[(((tmPtr)+(32))>>2)];
- var guessedOffset = date.getTimezoneOffset();
- var start = new Date(date.getFullYear(), 0, 1);
- var summerOffset = new Date(date.getFullYear(), 6, 1).getTimezoneOffset();
- var winterOffset = start.getTimezoneOffset();
- var dstOffset = Math.min(winterOffset, summerOffset); // DST is in December in South
- if (dst < 0) {
- // Attention: some regions don't have DST at all.
- HEAP32[(((tmPtr)+(32))>>2)] = Number(summerOffset != winterOffset && dstOffset == guessedOffset);
- } else if ((dst > 0) != (dstOffset == guessedOffset)) {
- var nonDstOffset = Math.max(winterOffset, summerOffset);
- var trueOffset = dst > 0 ? dstOffset : nonDstOffset;
- // Don't try setMinutes(date.getMinutes() + ...) -- it's messed up.
- date.setTime(date.getTime() + (trueOffset - guessedOffset)*60000);
- }
-
- HEAP32[(((tmPtr)+(24))>>2)] = date.getDay();
- var yday = __yday_from_date(date)|0;
- HEAP32[(((tmPtr)+(28))>>2)] = yday;
- // To match expected behavior, update fields from date
- HEAP32[((tmPtr)>>2)] = date.getSeconds();
- HEAP32[(((tmPtr)+(4))>>2)] = date.getMinutes();
- HEAP32[(((tmPtr)+(8))>>2)] = date.getHours();
- HEAP32[(((tmPtr)+(12))>>2)] = date.getDate();
- HEAP32[(((tmPtr)+(16))>>2)] = date.getMonth();
- HEAP32[(((tmPtr)+(20))>>2)] = date.getYear();
-
- return (date.getTime() / 1000)|0;
- }
- function allocateUTF8(str) {
- var size = lengthBytesUTF8(str) + 1;
- var ret = _malloc(size);
- if (ret) stringToUTF8Array(str, HEAP8, ret, size);
- return ret;
- }
- function __tzset_js(timezone, daylight, tzname) {
- // TODO: Use (malleable) environment variables instead of system settings.
- var currentYear = new Date().getFullYear();
- var winter = new Date(currentYear, 0, 1);
- var summer = new Date(currentYear, 6, 1);
- var winterOffset = winter.getTimezoneOffset();
- var summerOffset = summer.getTimezoneOffset();
-
- // Local standard timezone offset. Local standard time is not adjusted for daylight savings.
- // This code uses the fact that getTimezoneOffset returns a greater value during Standard Time versus Daylight Saving Time (DST).
- // Thus it determines the expected output during Standard Time, and it compares whether the output of the given date the same (Standard) or less (DST).
- var stdTimezoneOffset = Math.max(winterOffset, summerOffset);
-
- // timezone is specified as seconds west of UTC ("The external variable
- // `timezone` shall be set to the difference, in seconds, between
- // Coordinated Universal Time (UTC) and local standard time."), the same
- // as returned by stdTimezoneOffset.
- // See http://pubs.opengroup.org/onlinepubs/009695399/functions/tzset.html
- HEAPU32[((timezone)>>2)] = stdTimezoneOffset * 60;
-
- HEAP32[((daylight)>>2)] = Number(winterOffset != summerOffset);
-
- function extractZone(date) {
- var match = date.toTimeString().match(/\(([A-Za-z ]+)\)$/);
- return match ? match[1] : "GMT";
- };
- var winterName = extractZone(winter);
- var summerName = extractZone(summer);
- var winterNamePtr = allocateUTF8(winterName);
- var summerNamePtr = allocateUTF8(summerName);
- if (summerOffset < winterOffset) {
- // Northern hemisphere
- HEAPU32[((tzname)>>2)] = winterNamePtr;
- HEAPU32[(((tzname)+(4))>>2)] = summerNamePtr;
- } else {
- HEAPU32[((tzname)>>2)] = summerNamePtr;
- HEAPU32[(((tzname)+(4))>>2)] = winterNamePtr;
- }
- }
- function _abort() {
- abort('native code called abort()');
- }
- function _emscripten_console_error(str) {
- assert(typeof str == 'number');
- console.error(UTF8ToString(str));
- }
- function _emscripten_date_now() {
- return Date.now();
- }
- function getHeapMax() {
- // Stay one Wasm page short of 4GB: while e.g. Chrome is able to allocate
- // full 4GB Wasm memories, the size will wrap back to 0 bytes in Wasm side
- // for any code that deals with heap sizes, which would require special
- // casing all heap size related code to treat 0 specially.
- return 2147483648;
- }
- function _emscripten_get_heap_max() {
- return getHeapMax();
- }
- var _emscripten_get_now;if (ENVIRONMENT_IS_NODE) {
- _emscripten_get_now = () => {
- var t = process['hrtime']();
- return t[0] * 1e3 + t[1] / 1e6;
- };
- } else _emscripten_get_now = () => performance.now();
- ;
- function _emscripten_memcpy_big(dest, src, num) {
- HEAPU8.copyWithin(dest, src, src + num);
- }
-
- function emscripten_realloc_buffer(size) {
- var b = wasmMemory.buffer;
- try {
- // round size grow request up to wasm page size (fixed 64KB per spec)
- wasmMemory.grow((size - b.byteLength + 65535) >>> 16); // .grow() takes a delta compared to the previous size
- updateMemoryViews();
- return 1 /*success*/;
- } catch(e) {
- err('emscripten_realloc_buffer: Attempted to grow heap from ' + b.byteLength + ' bytes to ' + size + ' bytes, but got error: ' + e);
- }
- // implicit 0 return to save code size (caller will cast "undefined" into 0
- // anyhow)
- }
- function _emscripten_resize_heap(requestedSize) {
- var oldSize = HEAPU8.length;
- requestedSize = requestedSize >>> 0;
- // With multithreaded builds, races can happen (another thread might increase the size
- // in between), so return a failure, and let the caller retry.
- assert(requestedSize > oldSize);
-
- // Memory resize rules:
- // 1. Always increase heap size to at least the requested size, rounded up
- // to next page multiple.
- // 2a. If MEMORY_GROWTH_LINEAR_STEP == -1, excessively resize the heap
- // geometrically: increase the heap size according to
- // MEMORY_GROWTH_GEOMETRIC_STEP factor (default +20%), At most
- // overreserve by MEMORY_GROWTH_GEOMETRIC_CAP bytes (default 96MB).
- // 2b. If MEMORY_GROWTH_LINEAR_STEP != -1, excessively resize the heap
- // linearly: increase the heap size by at least
- // MEMORY_GROWTH_LINEAR_STEP bytes.
- // 3. Max size for the heap is capped at 2048MB-WASM_PAGE_SIZE, or by
- // MAXIMUM_MEMORY, or by ASAN limit, depending on which is smallest
- // 4. If we were unable to allocate as much memory, it may be due to
- // over-eager decision to excessively reserve due to (3) above.
- // Hence if an allocation fails, cut down on the amount of excess
- // growth, in an attempt to succeed to perform a smaller allocation.
-
- // A limit is set for how much we can grow. We should not exceed that
- // (the wasm binary specifies it, so if we tried, we'd fail anyhow).
- var maxHeapSize = getHeapMax();
- if (requestedSize > maxHeapSize) {
- err('Cannot enlarge memory, asked to go up to ' + requestedSize + ' bytes, but the limit is ' + maxHeapSize + ' bytes!');
- return false;
- }
-
- let alignUp = (x, multiple) => x + (multiple - x % multiple) % multiple;
-
- // Loop through potential heap size increases. If we attempt a too eager
- // reservation that fails, cut down on the attempted size and reserve a
- // smaller bump instead. (max 3 times, chosen somewhat arbitrarily)
- for (var cutDown = 1; cutDown <= 4; cutDown *= 2) {
- var overGrownHeapSize = oldSize * (1 + 0.2 / cutDown); // ensure geometric growth
- // but limit overreserving (default to capping at +96MB overgrowth at most)
- overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296 );
-
- var newSize = Math.min(maxHeapSize, alignUp(Math.max(requestedSize, overGrownHeapSize), 65536));
-
- var replacement = emscripten_realloc_buffer(newSize);
- if (replacement) {
-
- return true;
- }
- }
- err('Failed to grow the heap from ' + oldSize + ' bytes to ' + newSize + ' bytes, not enough memory!');
- return false;
- }
- var ENV = {};
-
- function getExecutableName() {
- return thisProgram || './this.program';
- }
- function getEnvStrings() {
- if (!getEnvStrings.strings) {
- // Default values.
- // Browser language detection #8751
- var lang = ((typeof navigator == 'object' && navigator.languages && navigator.languages[0]) || 'C').replace('-', '_') + '.UTF-8';
- var env = {
- 'USER': 'web_user',
- 'LOGNAME': 'web_user',
- 'PATH': '/',
- 'PWD': '/',
- 'HOME': '/home/web_user',
- 'LANG': lang,
- '_': getExecutableName()
- };
- // Apply the user-provided values, if any.
- for (var x in ENV) {
- // x is a key in ENV; if ENV[x] is undefined, that means it was
- // explicitly set to be so. We allow user code to do that to
- // force variables with default values to remain unset.
- if (ENV[x] === undefined) delete env[x];
- else env[x] = ENV[x];
- }
- var strings = [];
- for (var x in env) {
- strings.push(x + '=' + env[x]);
- }
- getEnvStrings.strings = strings;
- }
- return getEnvStrings.strings;
- }
-
- /** @param {boolean=} dontAddNull */
- function writeAsciiToMemory(str, buffer, dontAddNull) {
- for (var i = 0; i < str.length; ++i) {
- assert(str.charCodeAt(i) === (str.charCodeAt(i) & 0xff));
- HEAP8[((buffer++)>>0)] = str.charCodeAt(i);
- }
- // Null-terminate the pointer to the HEAP.
- if (!dontAddNull) HEAP8[((buffer)>>0)] = 0;
- }
-
- function _environ_get(__environ, environ_buf) {
- var bufSize = 0;
- getEnvStrings().forEach(function(string, i) {
- var ptr = environ_buf + bufSize;
- HEAPU32[(((__environ)+(i*4))>>2)] = ptr;
- writeAsciiToMemory(string, ptr);
- bufSize += string.length + 1;
- });
- return 0;
- }
-
- function _environ_sizes_get(penviron_count, penviron_buf_size) {
- var strings = getEnvStrings();
- HEAPU32[((penviron_count)>>2)] = strings.length;
- var bufSize = 0;
- strings.forEach(function(string) {
- bufSize += string.length + 1;
- });
- HEAPU32[((penviron_buf_size)>>2)] = bufSize;
- return 0;
- }
-
- function _proc_exit(code) {
- EXITSTATUS = code;
- if (!keepRuntimeAlive()) {
- if (Module['onExit']) Module['onExit'](code);
- ABORT = true;
- }
- quit_(code, new ExitStatus(code));
- }
- /** @param {boolean|number=} implicit */
- function exitJS(status, implicit) {
- EXITSTATUS = status;
-
- checkUnflushedContent();
-
- // if exit() was called explicitly, warn the user if the runtime isn't actually being shut down
- if (keepRuntimeAlive() && !implicit) {
- var msg = 'program exited (with status: ' + status + '), but EXIT_RUNTIME is not set, so halting execution but not exiting the runtime or preventing further async execution (build with EXIT_RUNTIME=1, if you want a true shutdown)';
- readyPromiseReject(msg);
- err(msg);
- }
-
- _proc_exit(status);
- }
- var _exit = exitJS;
- function _fd_close(fd) {
- try {
-
- var stream = SYSCALLS.getStreamFromFD(fd);
- FS.close(stream);
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
- return e.errno;
- }
- }
- /** @param {number=} offset */
- function doReadv(stream, iov, iovcnt, offset) {
- var ret = 0;
- for (var i = 0; i < iovcnt; i++) {
- var ptr = HEAPU32[((iov)>>2)];
- var len = HEAPU32[(((iov)+(4))>>2)];
- iov += 8;
- var curr = FS.read(stream, HEAP8,ptr, len, offset);
- if (curr < 0) return -1;
- ret += curr;
- if (curr < len) break; // nothing more to read
- if (typeof offset !== 'undefined') {
- offset += curr;
- }
- }
- return ret;
- }
-
- function _fd_read(fd, iov, iovcnt, pnum) {
- try {
-
- var stream = SYSCALLS.getStreamFromFD(fd);
- var num = doReadv(stream, iov, iovcnt);
- HEAPU32[((pnum)>>2)] = num;
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
- return e.errno;
- }
- }
-
-
-
-
- function _fd_seek(fd, offset_low, offset_high, whence, newOffset) {
- try {
-
- var offset = convertI32PairToI53Checked(offset_low, offset_high); if (isNaN(offset)) return 61;
- var stream = SYSCALLS.getStreamFromFD(fd);
- FS.llseek(stream, offset, whence);
- (tempI64 = [stream.position>>>0,(tempDouble=stream.position,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[((newOffset)>>2)] = tempI64[0],HEAP32[(((newOffset)+(4))>>2)] = tempI64[1]);
- if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null; // reset readdir state
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
- return e.errno;
- }
- }
- /** @param {number=} offset */
- function doWritev(stream, iov, iovcnt, offset) {
- var ret = 0;
- for (var i = 0; i < iovcnt; i++) {
- var ptr = HEAPU32[((iov)>>2)];
- var len = HEAPU32[(((iov)+(4))>>2)];
- iov += 8;
- var curr = FS.write(stream, HEAP8,ptr, len, offset);
- if (curr < 0) return -1;
- ret += curr;
- if (typeof offset !== 'undefined') {
- offset += curr;
- }
- }
- return ret;
- }
-
- function _fd_write(fd, iov, iovcnt, pnum) {
- try {
-
- var stream = SYSCALLS.getStreamFromFD(fd);
- var num = doWritev(stream, iov, iovcnt);
- HEAPU32[((pnum)>>2)] = num;
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
- return e.errno;
- }
- }
- var FSNode = /** @constructor */ function(parent, name, mode, rdev) {
- if (!parent) {
- parent = this; // root node sets parent to itself
- }
- this.parent = parent;
- this.mount = parent.mount;
- this.mounted = null;
- this.id = FS.nextInode++;
- this.name = name;
- this.mode = mode;
- this.node_ops = {};
- this.stream_ops = {};
- this.rdev = rdev;
- };
- var readMode = 292/*292*/ | 73/*73*/;
- var writeMode = 146/*146*/;
- Object.defineProperties(FSNode.prototype, {
- read: {
- get: /** @this{FSNode} */function() {
- return (this.mode & readMode) === readMode;
- },
- set: /** @this{FSNode} */function(val) {
- val ? this.mode |= readMode : this.mode &= ~readMode;
- }
- },
- write: {
- get: /** @this{FSNode} */function() {
- return (this.mode & writeMode) === writeMode;
- },
- set: /** @this{FSNode} */function(val) {
- val ? this.mode |= writeMode : this.mode &= ~writeMode;
- }
- },
- isFolder: {
- get: /** @this{FSNode} */function() {
- return FS.isDir(this.mode);
- }
- },
- isDevice: {
- get: /** @this{FSNode} */function() {
- return FS.isChrdev(this.mode);
- }
- }
- });
- FS.FSNode = FSNode;
- FS.staticInit();;
- ERRNO_CODES = {
- 'EPERM': 63,
- 'ENOENT': 44,
- 'ESRCH': 71,
- 'EINTR': 27,
- 'EIO': 29,
- 'ENXIO': 60,
- 'E2BIG': 1,
- 'ENOEXEC': 45,
- 'EBADF': 8,
- 'ECHILD': 12,
- 'EAGAIN': 6,
- 'EWOULDBLOCK': 6,
- 'ENOMEM': 48,
- 'EACCES': 2,
- 'EFAULT': 21,
- 'ENOTBLK': 105,
- 'EBUSY': 10,
- 'EEXIST': 20,
- 'EXDEV': 75,
- 'ENODEV': 43,
- 'ENOTDIR': 54,
- 'EISDIR': 31,
- 'EINVAL': 28,
- 'ENFILE': 41,
- 'EMFILE': 33,
- 'ENOTTY': 59,
- 'ETXTBSY': 74,
- 'EFBIG': 22,
- 'ENOSPC': 51,
- 'ESPIPE': 70,
- 'EROFS': 69,
- 'EMLINK': 34,
- 'EPIPE': 64,
- 'EDOM': 18,
- 'ERANGE': 68,
- 'ENOMSG': 49,
- 'EIDRM': 24,
- 'ECHRNG': 106,
- 'EL2NSYNC': 156,
- 'EL3HLT': 107,
- 'EL3RST': 108,
- 'ELNRNG': 109,
- 'EUNATCH': 110,
- 'ENOCSI': 111,
- 'EL2HLT': 112,
- 'EDEADLK': 16,
- 'ENOLCK': 46,
- 'EBADE': 113,
- 'EBADR': 114,
- 'EXFULL': 115,
- 'ENOANO': 104,
- 'EBADRQC': 103,
- 'EBADSLT': 102,
- 'EDEADLOCK': 16,
- 'EBFONT': 101,
- 'ENOSTR': 100,
- 'ENODATA': 116,
- 'ETIME': 117,
- 'ENOSR': 118,
- 'ENONET': 119,
- 'ENOPKG': 120,
- 'EREMOTE': 121,
- 'ENOLINK': 47,
- 'EADV': 122,
- 'ESRMNT': 123,
- 'ECOMM': 124,
- 'EPROTO': 65,
- 'EMULTIHOP': 36,
- 'EDOTDOT': 125,
- 'EBADMSG': 9,
- 'ENOTUNIQ': 126,
- 'EBADFD': 127,
- 'EREMCHG': 128,
- 'ELIBACC': 129,
- 'ELIBBAD': 130,
- 'ELIBSCN': 131,
- 'ELIBMAX': 132,
- 'ELIBEXEC': 133,
- 'ENOSYS': 52,
- 'ENOTEMPTY': 55,
- 'ENAMETOOLONG': 37,
- 'ELOOP': 32,
- 'EOPNOTSUPP': 138,
- 'EPFNOSUPPORT': 139,
- 'ECONNRESET': 15,
- 'ENOBUFS': 42,
- 'EAFNOSUPPORT': 5,
- 'EPROTOTYPE': 67,
- 'ENOTSOCK': 57,
- 'ENOPROTOOPT': 50,
- 'ESHUTDOWN': 140,
- 'ECONNREFUSED': 14,
- 'EADDRINUSE': 3,
- 'ECONNABORTED': 13,
- 'ENETUNREACH': 40,
- 'ENETDOWN': 38,
- 'ETIMEDOUT': 73,
- 'EHOSTDOWN': 142,
- 'EHOSTUNREACH': 23,
- 'EINPROGRESS': 26,
- 'EALREADY': 7,
- 'EDESTADDRREQ': 17,
- 'EMSGSIZE': 35,
- 'EPROTONOSUPPORT': 66,
- 'ESOCKTNOSUPPORT': 137,
- 'EADDRNOTAVAIL': 4,
- 'ENETRESET': 39,
- 'EISCONN': 30,
- 'ENOTCONN': 53,
- 'ETOOMANYREFS': 141,
- 'EUSERS': 136,
- 'EDQUOT': 19,
- 'ESTALE': 72,
- 'ENOTSUP': 138,
- 'ENOMEDIUM': 148,
- 'EILSEQ': 25,
- 'EOVERFLOW': 61,
- 'ECANCELED': 11,
- 'ENOTRECOVERABLE': 56,
- 'EOWNERDEAD': 62,
- 'ESTRPIPE': 135,
- };;
- InternalError = Module['InternalError'] = extendError(Error, 'InternalError');;
- embind_init_charCodes();
- BindingError = Module['BindingError'] = extendError(Error, 'BindingError');;
- init_ClassHandle();
- init_embind();;
- init_RegisteredPointer();
- UnboundTypeError = Module['UnboundTypeError'] = extendError(Error, 'UnboundTypeError');;
- init_emval();;
- var ASSERTIONS = true;
- function checkIncomingModuleAPI() {
- ignoredModuleProp('fetchSettings');
- }
- var asmLibraryArg = {
- "__assert_fail": ___assert_fail,
- "__cxa_throw": ___cxa_throw,
- "__syscall_connect": ___syscall_connect,
- "__syscall_faccessat": ___syscall_faccessat,
- "__syscall_fcntl64": ___syscall_fcntl64,
- "__syscall_fstat64": ___syscall_fstat64,
- "__syscall_ftruncate64": ___syscall_ftruncate64,
- "__syscall_ioctl": ___syscall_ioctl,
- "__syscall_lstat64": ___syscall_lstat64,
- "__syscall_newfstatat": ___syscall_newfstatat,
- "__syscall_openat": ___syscall_openat,
- "__syscall_socket": ___syscall_socket,
- "__syscall_stat64": ___syscall_stat64,
- "_embind_finalize_value_array": __embind_finalize_value_array,
- "_embind_finalize_value_object": __embind_finalize_value_object,
- "_embind_register_bigint": __embind_register_bigint,
- "_embind_register_bool": __embind_register_bool,
- "_embind_register_class": __embind_register_class,
- "_embind_register_class_class_function": __embind_register_class_class_function,
- "_embind_register_class_constructor": __embind_register_class_constructor,
- "_embind_register_class_function": __embind_register_class_function,
- "_embind_register_class_property": __embind_register_class_property,
- "_embind_register_emval": __embind_register_emval,
- "_embind_register_enum": __embind_register_enum,
- "_embind_register_enum_value": __embind_register_enum_value,
- "_embind_register_float": __embind_register_float,
- "_embind_register_integer": __embind_register_integer,
- "_embind_register_memory_view": __embind_register_memory_view,
- "_embind_register_std_string": __embind_register_std_string,
- "_embind_register_std_wstring": __embind_register_std_wstring,
- "_embind_register_value_array": __embind_register_value_array,
- "_embind_register_value_array_element": __embind_register_value_array_element,
- "_embind_register_value_object": __embind_register_value_object,
- "_embind_register_value_object_field": __embind_register_value_object_field,
- "_embind_register_void": __embind_register_void,
- "_emscripten_get_now_is_monotonic": __emscripten_get_now_is_monotonic,
- "_emval_as": __emval_as,
- "_emval_call_method": __emval_call_method,
- "_emval_call_void_method": __emval_call_void_method,
- "_emval_decref": __emval_decref,
- "_emval_equals": __emval_equals,
- "_emval_get_global": __emval_get_global,
- "_emval_get_method_caller": __emval_get_method_caller,
- "_emval_get_module_property": __emval_get_module_property,
- "_emval_get_property": __emval_get_property,
- "_emval_incref": __emval_incref,
- "_emval_instanceof": __emval_instanceof,
- "_emval_is_number": __emval_is_number,
- "_emval_is_string": __emval_is_string,
- "_emval_new": __emval_new,
- "_emval_new_array": __emval_new_array,
- "_emval_new_cstring": __emval_new_cstring,
- "_emval_new_object": __emval_new_object,
- "_emval_run_destructors": __emval_run_destructors,
- "_emval_set_property": __emval_set_property,
- "_emval_take_value": __emval_take_value,
- "_gmtime_js": __gmtime_js,
- "_localtime_js": __localtime_js,
- "_mktime_js": __mktime_js,
- "_tzset_js": __tzset_js,
- "abort": _abort,
- "emscripten_console_error": _emscripten_console_error,
- "emscripten_date_now": _emscripten_date_now,
- "emscripten_get_heap_max": _emscripten_get_heap_max,
- "emscripten_get_now": _emscripten_get_now,
- "emscripten_memcpy_big": _emscripten_memcpy_big,
- "emscripten_resize_heap": _emscripten_resize_heap,
- "environ_get": _environ_get,
- "environ_sizes_get": _environ_sizes_get,
- "exit": _exit,
- "fd_close": _fd_close,
- "fd_read": _fd_read,
- "fd_seek": _fd_seek,
- "fd_write": _fd_write
- };
- var asm = createWasm();
- /** @type {function(...*):?} */
- var ___wasm_call_ctors = Module["___wasm_call_ctors"] = createExportWrapper("__wasm_call_ctors");
- /** @type {function(...*):?} */
- var _malloc = Module["_malloc"] = createExportWrapper("malloc");
- /** @type {function(...*):?} */
- var _fflush = Module["_fflush"] = createExportWrapper("fflush");
- /** @type {function(...*):?} */
- var _free = Module["_free"] = createExportWrapper("free");
- /** @type {function(...*):?} */
- var ___errno_location = Module["___errno_location"] = createExportWrapper("__errno_location");
- /** @type {function(...*):?} */
- var ___getTypeName = Module["___getTypeName"] = createExportWrapper("__getTypeName");
- /** @type {function(...*):?} */
- var __embind_initialize_bindings = Module["__embind_initialize_bindings"] = createExportWrapper("_embind_initialize_bindings");
- /** @type {function(...*):?} */
- var _htons = Module["_htons"] = createExportWrapper("htons");
- /** @type {function(...*):?} */
- var _ntohs = Module["_ntohs"] = createExportWrapper("ntohs");
- /** @type {function(...*):?} */
- var _emscripten_stack_init = Module["_emscripten_stack_init"] = function() {
- return (_emscripten_stack_init = Module["_emscripten_stack_init"] = Module["asm"]["emscripten_stack_init"]).apply(null, arguments);
- };
- /** @type {function(...*):?} */
- var _emscripten_stack_get_free = Module["_emscripten_stack_get_free"] = function() {
- return (_emscripten_stack_get_free = Module["_emscripten_stack_get_free"] = Module["asm"]["emscripten_stack_get_free"]).apply(null, arguments);
- };
- /** @type {function(...*):?} */
- var _emscripten_stack_get_base = Module["_emscripten_stack_get_base"] = function() {
- return (_emscripten_stack_get_base = Module["_emscripten_stack_get_base"] = Module["asm"]["emscripten_stack_get_base"]).apply(null, arguments);
- };
- /** @type {function(...*):?} */
- var _emscripten_stack_get_end = Module["_emscripten_stack_get_end"] = function() {
- return (_emscripten_stack_get_end = Module["_emscripten_stack_get_end"] = Module["asm"]["emscripten_stack_get_end"]).apply(null, arguments);
- };
- /** @type {function(...*):?} */
- var stackSave = Module["stackSave"] = createExportWrapper("stackSave");
- /** @type {function(...*):?} */
- var stackRestore = Module["stackRestore"] = createExportWrapper("stackRestore");
- /** @type {function(...*):?} */
- var stackAlloc = Module["stackAlloc"] = createExportWrapper("stackAlloc");
- /** @type {function(...*):?} */
- var _emscripten_stack_get_current = Module["_emscripten_stack_get_current"] = function() {
- return (_emscripten_stack_get_current = Module["_emscripten_stack_get_current"] = Module["asm"]["emscripten_stack_get_current"]).apply(null, arguments);
- };
- /** @type {function(...*):?} */
- var ___cxa_is_pointer_type = Module["___cxa_is_pointer_type"] = createExportWrapper("__cxa_is_pointer_type");
- /** @type {function(...*):?} */
- var dynCall_ji = Module["dynCall_ji"] = createExportWrapper("dynCall_ji");
- /** @type {function(...*):?} */
- var dynCall_iiijii = Module["dynCall_iiijii"] = createExportWrapper("dynCall_iiijii");
- /** @type {function(...*):?} */
- var dynCall_iij = Module["dynCall_iij"] = createExportWrapper("dynCall_iij");
- /** @type {function(...*):?} */
- var dynCall_vij = Module["dynCall_vij"] = createExportWrapper("dynCall_vij");
- /** @type {function(...*):?} */
- var dynCall_jiji = Module["dynCall_jiji"] = createExportWrapper("dynCall_jiji");
- // === Auto-generated postamble setup entry stuff ===
- var unexportedRuntimeSymbols = [
- 'run',
- 'UTF8ArrayToString',
- 'UTF8ToString',
- 'stringToUTF8Array',
- 'stringToUTF8',
- 'lengthBytesUTF8',
- 'addOnPreRun',
- 'addOnInit',
- 'addOnPreMain',
- 'addOnExit',
- 'addOnPostRun',
- 'addRunDependency',
- 'removeRunDependency',
- 'FS_createFolder',
- 'FS_createPath',
- 'FS_createDataFile',
- 'FS_createPreloadedFile',
- 'FS_createLazyFile',
- 'FS_createLink',
- 'FS_createDevice',
- 'FS_unlink',
- 'getLEB',
- 'getFunctionTables',
- 'alignFunctionTables',
- 'registerFunctions',
- 'prettyPrint',
- 'getCompilerSetting',
- 'out',
- 'err',
- 'callMain',
- 'abort',
- 'keepRuntimeAlive',
- 'wasmMemory',
- 'stackAlloc',
- 'stackSave',
- 'stackRestore',
- 'getTempRet0',
- 'setTempRet0',
- 'writeStackCookie',
- 'checkStackCookie',
- 'ptrToString',
- 'zeroMemory',
- 'stringToNewUTF8',
- 'exitJS',
- 'getHeapMax',
- 'emscripten_realloc_buffer',
- 'ENV',
- 'ERRNO_CODES',
- 'ERRNO_MESSAGES',
- 'setErrNo',
- 'inetPton4',
- 'inetNtop4',
- 'inetPton6',
- 'inetNtop6',
- 'readSockaddr',
- 'writeSockaddr',
- 'DNS',
- 'getHostByName',
- 'Protocols',
- 'Sockets',
- 'getRandomDevice',
- 'warnOnce',
- 'traverseStack',
- 'UNWIND_CACHE',
- 'convertPCtoSourceLocation',
- 'readEmAsmArgsArray',
- 'readEmAsmArgs',
- 'runEmAsmFunction',
- 'runMainThreadEmAsm',
- 'jstoi_q',
- 'jstoi_s',
- 'getExecutableName',
- 'listenOnce',
- 'autoResumeAudioContext',
- 'dynCallLegacy',
- 'getDynCaller',
- 'dynCall',
- 'handleException',
- 'runtimeKeepalivePush',
- 'runtimeKeepalivePop',
- 'callUserCallback',
- 'maybeExit',
- 'safeSetTimeout',
- 'asmjsMangle',
- 'asyncLoad',
- 'alignMemory',
- 'mmapAlloc',
- 'handleAllocator',
- 'writeI53ToI64',
- 'writeI53ToI64Clamped',
- 'writeI53ToI64Signaling',
- 'writeI53ToU64Clamped',
- 'writeI53ToU64Signaling',
- 'readI53FromI64',
- 'readI53FromU64',
- 'convertI32PairToI53',
- 'convertI32PairToI53Checked',
- 'convertU32PairToI53',
- 'getCFunc',
- 'ccall',
- 'cwrap',
- 'uleb128Encode',
- 'sigToWasmTypes',
- 'generateFuncType',
- 'convertJsFunctionToWasm',
- 'freeTableIndexes',
- 'functionsInTableMap',
- 'getEmptyTableSlot',
- 'updateTableMap',
- 'addFunction',
- 'removeFunction',
- 'reallyNegative',
- 'unSign',
- 'strLen',
- 'reSign',
- 'formatString',
- 'setValue',
- 'getValue',
- 'PATH',
- 'PATH_FS',
- 'intArrayFromString',
- 'intArrayToString',
- 'AsciiToString',
- 'stringToAscii',
- 'UTF16Decoder',
- 'UTF16ToString',
- 'stringToUTF16',
- 'lengthBytesUTF16',
- 'UTF32ToString',
- 'stringToUTF32',
- 'lengthBytesUTF32',
- 'allocateUTF8',
- 'allocateUTF8OnStack',
- 'writeStringToMemory',
- 'writeArrayToMemory',
- 'writeAsciiToMemory',
- 'SYSCALLS',
- 'getSocketFromFD',
- 'getSocketAddress',
- 'JSEvents',
- 'registerKeyEventCallback',
- 'specialHTMLTargets',
- 'maybeCStringToJsString',
- 'findEventTarget',
- 'findCanvasEventTarget',
- 'getBoundingClientRect',
- 'fillMouseEventData',
- 'registerMouseEventCallback',
- 'registerWheelEventCallback',
- 'registerUiEventCallback',
- 'registerFocusEventCallback',
- 'fillDeviceOrientationEventData',
- 'registerDeviceOrientationEventCallback',
- 'fillDeviceMotionEventData',
- 'registerDeviceMotionEventCallback',
- 'screenOrientation',
- 'fillOrientationChangeEventData',
- 'registerOrientationChangeEventCallback',
- 'fillFullscreenChangeEventData',
- 'registerFullscreenChangeEventCallback',
- 'JSEvents_requestFullscreen',
- 'JSEvents_resizeCanvasForFullscreen',
- 'registerRestoreOldStyle',
- 'hideEverythingExceptGivenElement',
- 'restoreHiddenElements',
- 'setLetterbox',
- 'currentFullscreenStrategy',
- 'restoreOldWindowedStyle',
- 'softFullscreenResizeWebGLRenderTarget',
- 'doRequestFullscreen',
- 'fillPointerlockChangeEventData',
- 'registerPointerlockChangeEventCallback',
- 'registerPointerlockErrorEventCallback',
- 'requestPointerLock',
- 'fillVisibilityChangeEventData',
- 'registerVisibilityChangeEventCallback',
- 'registerTouchEventCallback',
- 'fillGamepadEventData',
- 'registerGamepadEventCallback',
- 'registerBeforeUnloadEventCallback',
- 'fillBatteryEventData',
- 'battery',
- 'registerBatteryEventCallback',
- 'setCanvasElementSize',
- 'getCanvasElementSize',
- 'demangle',
- 'demangleAll',
- 'jsStackTrace',
- 'stackTrace',
- 'ExitStatus',
- 'getEnvStrings',
- 'checkWasiClock',
- 'doReadv',
- 'doWritev',
- 'dlopenMissingError',
- 'createDyncallWrapper',
- 'setImmediateWrapped',
- 'clearImmediateWrapped',
- 'polyfillSetImmediate',
- 'promiseMap',
- 'newNativePromise',
- 'getPromise',
- 'uncaughtExceptionCount',
- 'exceptionLast',
- 'exceptionCaught',
- 'ExceptionInfo',
- 'exception_addRef',
- 'exception_decRef',
- 'Browser',
- 'setMainLoop',
- 'wget',
- 'FS',
- 'MEMFS',
- 'TTY',
- 'PIPEFS',
- 'SOCKFS',
- '_setNetworkCallback',
- 'tempFixedLengthArray',
- 'miniTempWebGLFloatBuffers',
- 'heapObjectForWebGLType',
- 'heapAccessShiftForWebGLHeap',
- 'GL',
- 'emscriptenWebGLGet',
- 'computeUnpackAlignedImageSize',
- 'emscriptenWebGLGetTexPixelData',
- 'emscriptenWebGLGetUniform',
- 'webglGetUniformLocation',
- 'webglPrepareUniformLocationsBeforeFirstUse',
- 'webglGetLeftBracePos',
- 'emscriptenWebGLGetVertexAttrib',
- 'writeGLArray',
- 'AL',
- 'SDL_unicode',
- 'SDL_ttfContext',
- 'SDL_audio',
- 'SDL',
- 'SDL_gfx',
- 'GLUT',
- 'EGL',
- 'GLFW_Window',
- 'GLFW',
- 'GLEW',
- 'IDBStore',
- 'runAndAbortIfError',
- 'ALLOC_NORMAL',
- 'ALLOC_STACK',
- 'allocate',
- 'InternalError',
- 'BindingError',
- 'UnboundTypeError',
- 'PureVirtualError',
- 'init_embind',
- 'throwInternalError',
- 'throwBindingError',
- 'throwUnboundTypeError',
- 'ensureOverloadTable',
- 'exposePublicSymbol',
- 'replacePublicSymbol',
- 'extendError',
- 'createNamedFunction',
- 'embindRepr',
- 'registeredInstances',
- 'getBasestPointer',
- 'registerInheritedInstance',
- 'unregisterInheritedInstance',
- 'getInheritedInstance',
- 'getInheritedInstanceCount',
- 'getLiveInheritedInstances',
- 'registeredTypes',
- 'awaitingDependencies',
- 'typeDependencies',
- 'registeredPointers',
- 'registerType',
- 'whenDependentTypesAreResolved',
- 'embind_charCodes',
- 'embind_init_charCodes',
- 'readLatin1String',
- 'getTypeName',
- 'heap32VectorToArray',
- 'requireRegisteredType',
- 'getShiftFromSize',
- 'integerReadValueFromPointer',
- 'enumReadValueFromPointer',
- 'floatReadValueFromPointer',
- 'simpleReadValueFromPointer',
- 'runDestructors',
- 'new_',
- 'craftInvokerFunction',
- 'embind__requireFunction',
- 'tupleRegistrations',
- 'structRegistrations',
- 'genericPointerToWireType',
- 'constNoSmartPtrRawPointerToWireType',
- 'nonConstNoSmartPtrRawPointerToWireType',
- 'init_RegisteredPointer',
- 'RegisteredPointer',
- 'RegisteredPointer_getPointee',
- 'RegisteredPointer_destructor',
- 'RegisteredPointer_deleteObject',
- 'RegisteredPointer_fromWireType',
- 'runDestructor',
- 'releaseClassHandle',
- 'finalizationRegistry',
- 'detachFinalizer_deps',
- 'detachFinalizer',
- 'attachFinalizer',
- 'makeClassHandle',
- 'init_ClassHandle',
- 'ClassHandle',
- 'ClassHandle_isAliasOf',
- 'throwInstanceAlreadyDeleted',
- 'ClassHandle_clone',
- 'ClassHandle_delete',
- 'deletionQueue',
- 'ClassHandle_isDeleted',
- 'ClassHandle_deleteLater',
- 'flushPendingDeletes',
- 'delayFunction',
- 'setDelayFunction',
- 'RegisteredClass',
- 'shallowCopyInternalPointer',
- 'downcastPointer',
- 'upcastPointer',
- 'validateThis',
- 'char_0',
- 'char_9',
- 'makeLegalFunctionName',
- 'emval_handle_array',
- 'emval_free_list',
- 'emval_symbols',
- 'init_emval',
- 'count_emval_handles',
- 'get_first_emval',
- 'getStringOrSymbol',
- 'Emval',
- 'emval_newers',
- 'craftEmvalAllocator',
- 'emval_get_global',
- 'emval_lookupTypes',
- 'emval_allocateDestructors',
- 'emval_methodCallers',
- 'emval_addMethodCaller',
- 'emval_registeredMethods',
- ];
- unexportedRuntimeSymbols.forEach(unexportedRuntimeSymbol);
- var missingLibrarySymbols = [
- 'stringToNewUTF8',
- 'writeSockaddr',
- 'getHostByName',
- 'traverseStack',
- 'convertPCtoSourceLocation',
- 'readEmAsmArgs',
- 'runEmAsmFunction',
- 'runMainThreadEmAsm',
- 'jstoi_s',
- 'listenOnce',
- 'autoResumeAudioContext',
- 'handleException',
- 'runtimeKeepalivePush',
- 'runtimeKeepalivePop',
- 'callUserCallback',
- 'maybeExit',
- 'safeSetTimeout',
- 'asmjsMangle',
- 'handleAllocator',
- 'writeI53ToI64',
- 'writeI53ToI64Clamped',
- 'writeI53ToI64Signaling',
- 'writeI53ToU64Clamped',
- 'writeI53ToU64Signaling',
- 'readI53FromU64',
- 'convertI32PairToI53',
- 'convertU32PairToI53',
- 'getCFunc',
- 'ccall',
- 'cwrap',
- 'uleb128Encode',
- 'sigToWasmTypes',
- 'generateFuncType',
- 'convertJsFunctionToWasm',
- 'getEmptyTableSlot',
- 'updateTableMap',
- 'addFunction',
- 'removeFunction',
- 'reallyNegative',
- 'unSign',
- 'strLen',
- 'reSign',
- 'formatString',
- 'intArrayToString',
- 'AsciiToString',
- 'stringToAscii',
- 'allocateUTF8OnStack',
- 'writeStringToMemory',
- 'writeArrayToMemory',
- 'registerKeyEventCallback',
- 'maybeCStringToJsString',
- 'findEventTarget',
- 'findCanvasEventTarget',
- 'getBoundingClientRect',
- 'fillMouseEventData',
- 'registerMouseEventCallback',
- 'registerWheelEventCallback',
- 'registerUiEventCallback',
- 'registerFocusEventCallback',
- 'fillDeviceOrientationEventData',
- 'registerDeviceOrientationEventCallback',
- 'fillDeviceMotionEventData',
- 'registerDeviceMotionEventCallback',
- 'screenOrientation',
- 'fillOrientationChangeEventData',
- 'registerOrientationChangeEventCallback',
- 'fillFullscreenChangeEventData',
- 'registerFullscreenChangeEventCallback',
- 'JSEvents_requestFullscreen',
- 'JSEvents_resizeCanvasForFullscreen',
- 'registerRestoreOldStyle',
- 'hideEverythingExceptGivenElement',
- 'restoreHiddenElements',
- 'setLetterbox',
- 'softFullscreenResizeWebGLRenderTarget',
- 'doRequestFullscreen',
- 'fillPointerlockChangeEventData',
- 'registerPointerlockChangeEventCallback',
- 'registerPointerlockErrorEventCallback',
- 'requestPointerLock',
- 'fillVisibilityChangeEventData',
- 'registerVisibilityChangeEventCallback',
- 'registerTouchEventCallback',
- 'fillGamepadEventData',
- 'registerGamepadEventCallback',
- 'registerBeforeUnloadEventCallback',
- 'fillBatteryEventData',
- 'battery',
- 'registerBatteryEventCallback',
- 'setCanvasElementSize',
- 'getCanvasElementSize',
- 'jsStackTrace',
- 'stackTrace',
- 'checkWasiClock',
- 'createDyncallWrapper',
- 'setImmediateWrapped',
- 'clearImmediateWrapped',
- 'polyfillSetImmediate',
- 'newNativePromise',
- 'getPromise',
- 'exception_addRef',
- 'exception_decRef',
- 'setMainLoop',
- '_setNetworkCallback',
- 'heapObjectForWebGLType',
- 'heapAccessShiftForWebGLHeap',
- 'emscriptenWebGLGet',
- 'computeUnpackAlignedImageSize',
- 'emscriptenWebGLGetTexPixelData',
- 'emscriptenWebGLGetUniform',
- 'webglGetUniformLocation',
- 'webglPrepareUniformLocationsBeforeFirstUse',
- 'webglGetLeftBracePos',
- 'emscriptenWebGLGetVertexAttrib',
- 'writeGLArray',
- 'SDL_unicode',
- 'SDL_ttfContext',
- 'SDL_audio',
- 'GLFW_Window',
- 'runAndAbortIfError',
- 'ALLOC_NORMAL',
- 'ALLOC_STACK',
- 'allocate',
- 'registerInheritedInstance',
- 'unregisterInheritedInstance',
- ];
- missingLibrarySymbols.forEach(missingLibrarySymbol)
- var calledRun;
- dependenciesFulfilled = function runCaller() {
- // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
- if (!calledRun) run();
- if (!calledRun) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
- };
- function stackCheckInit() {
- // This is normally called automatically during __wasm_call_ctors but need to
- // get these values before even running any of the ctors so we call it redundantly
- // here.
- _emscripten_stack_init();
- // TODO(sbc): Move writeStackCookie to native to to avoid this.
- writeStackCookie();
- }
- /** @type {function(Array=)} */
- function run(args) {
- args = args || arguments_;
- if (runDependencies > 0) {
- return;
- }
- stackCheckInit();
- preRun();
- // a preRun added a dependency, run will be called later
- if (runDependencies > 0) {
- return;
- }
- function doRun() {
- // run may have just been called through dependencies being fulfilled just in this very frame,
- // or while the async setStatus time below was happening
- if (calledRun) return;
- calledRun = true;
- Module['calledRun'] = true;
- if (ABORT) return;
- initRuntime();
- readyPromiseResolve(Module);
- if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized']();
- assert(!Module['_main'], 'compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]');
- postRun();
- }
- if (Module['setStatus']) {
- Module['setStatus']('Running...');
- setTimeout(function() {
- setTimeout(function() {
- Module['setStatus']('');
- }, 1);
- doRun();
- }, 1);
- } else
- {
- doRun();
- }
- checkStackCookie();
- }
- function checkUnflushedContent() {
- // Compiler settings do not allow exiting the runtime, so flushing
- // the streams is not possible. but in ASSERTIONS mode we check
- // if there was something to flush, and if so tell the user they
- // should request that the runtime be exitable.
- // Normally we would not even include flush() at all, but in ASSERTIONS
- // builds we do so just for this check, and here we see if there is any
- // content to flush, that is, we check if there would have been
- // something a non-ASSERTIONS build would have not seen.
- // How we flush the streams depends on whether we are in SYSCALLS_REQUIRE_FILESYSTEM=0
- // mode (which has its own special function for this; otherwise, all
- // the code is inside libc)
- var oldOut = out;
- var oldErr = err;
- var has = false;
- out = err = (x) => {
- has = true;
- }
- try { // it doesn't matter if it fails
- _fflush(0);
- // also flush in the JS FS layer
- ['stdout', 'stderr'].forEach(function(name) {
- var info = FS.analyzePath('/dev/' + name);
- if (!info) return;
- var stream = info.object;
- var rdev = stream.rdev;
- var tty = TTY.ttys[rdev];
- if (tty && tty.output && tty.output.length) {
- has = true;
- }
- });
- } catch(e) {}
- out = oldOut;
- err = oldErr;
- if (has) {
- warnOnce('stdio streams had content in them that was not flushed. you should set EXIT_RUNTIME to 1 (see the FAQ), or make sure to emit a newline when you printf etc.');
- }
- }
- if (Module['preInit']) {
- if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
- while (Module['preInit'].length > 0) {
- Module['preInit'].pop()();
- }
- }
- run();
- return rhino3dm.ready
- }
- );
- })();
- export default rhino3dm;
|