| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- /* JavaScript API. */
- #ifndef jsapi_h
- #define jsapi_h
- #include "mozilla/AlreadyAddRefed.h"
- #include "mozilla/FloatingPoint.h"
- #include "mozilla/MemoryReporting.h"
- #include "mozilla/Range.h"
- #include "mozilla/RangedPtr.h"
- #include "mozilla/RefCounted.h"
- #include "mozilla/RefPtr.h"
- #include "mozilla/Variant.h"
- #include <stdarg.h>
- #include <stddef.h>
- #include <stdint.h>
- #include <stdio.h>
- #include "jsalloc.h"
- #include "jspubtd.h"
- #include "js/CallArgs.h"
- #include "js/CharacterEncoding.h"
- #include "js/Class.h"
- #include "js/GCVector.h"
- #include "js/HashTable.h"
- #include "js/Id.h"
- #include "js/Principals.h"
- #include "js/Realm.h"
- #include "js/RootingAPI.h"
- #include "js/TracingAPI.h"
- #include "js/Utility.h"
- #include "js/Value.h"
- #include "js/Vector.h"
- /************************************************************************/
- namespace JS {
- class TwoByteChars;
- #ifdef JS_DEBUG
- class JS_PUBLIC_API(AutoCheckRequestDepth)
- {
- JSContext* cx;
- public:
- explicit AutoCheckRequestDepth(JSContext* cx);
- explicit AutoCheckRequestDepth(js::ContextFriendFields* cx);
- ~AutoCheckRequestDepth();
- };
- # define CHECK_REQUEST(cx) \
- JS::AutoCheckRequestDepth _autoCheckRequestDepth(cx)
- #else
- # define CHECK_REQUEST(cx) \
- ((void) 0)
- #endif /* JS_DEBUG */
- /** AutoValueArray roots an internal fixed-size array of Values. */
- template <size_t N>
- class MOZ_RAII AutoValueArray : public AutoGCRooter
- {
- const size_t length_;
- Value elements_[N];
- public:
- explicit AutoValueArray(JSContext* cx
- MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
- : AutoGCRooter(cx, VALARRAY), length_(N)
- {
- /* Always initialize in case we GC before assignment. */
- mozilla::PodArrayZero(elements_);
- MOZ_GUARD_OBJECT_NOTIFIER_INIT;
- }
- unsigned length() const { return length_; }
- const Value* begin() const { return elements_; }
- Value* begin() { return elements_; }
- HandleValue operator[](unsigned i) const {
- MOZ_ASSERT(i < N);
- return HandleValue::fromMarkedLocation(&elements_[i]);
- }
- MutableHandleValue operator[](unsigned i) {
- MOZ_ASSERT(i < N);
- return MutableHandleValue::fromMarkedLocation(&elements_[i]);
- }
- MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
- };
- template<class T>
- class MOZ_RAII AutoVectorRooterBase : protected AutoGCRooter
- {
- typedef js::Vector<T, 8> VectorImpl;
- VectorImpl vector;
- public:
- explicit AutoVectorRooterBase(JSContext* cx, ptrdiff_t tag
- MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
- : AutoGCRooter(cx, tag), vector(cx)
- {
- MOZ_GUARD_OBJECT_NOTIFIER_INIT;
- }
- explicit AutoVectorRooterBase(js::ContextFriendFields* cx, ptrdiff_t tag
- MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
- : AutoGCRooter(cx, tag), vector(cx)
- {
- MOZ_GUARD_OBJECT_NOTIFIER_INIT;
- }
- typedef T ElementType;
- typedef typename VectorImpl::Range Range;
- size_t length() const { return vector.length(); }
- bool empty() const { return vector.empty(); }
- MOZ_MUST_USE bool append(const T& v) { return vector.append(v); }
- MOZ_MUST_USE bool appendN(const T& v, size_t len) { return vector.appendN(v, len); }
- MOZ_MUST_USE bool append(const T* ptr, size_t len) { return vector.append(ptr, len); }
- MOZ_MUST_USE bool appendAll(const AutoVectorRooterBase<T>& other) {
- return vector.appendAll(other.vector);
- }
- MOZ_MUST_USE bool insert(T* p, const T& val) { return vector.insert(p, val); }
- /* For use when space has already been reserved. */
- void infallibleAppend(const T& v) { vector.infallibleAppend(v); }
- void popBack() { vector.popBack(); }
- T popCopy() { return vector.popCopy(); }
- MOZ_MUST_USE bool growBy(size_t inc) {
- size_t oldLength = vector.length();
- if (!vector.growByUninitialized(inc))
- return false;
- makeRangeGCSafe(oldLength);
- return true;
- }
- MOZ_MUST_USE bool resize(size_t newLength) {
- size_t oldLength = vector.length();
- if (newLength <= oldLength) {
- vector.shrinkBy(oldLength - newLength);
- return true;
- }
- if (!vector.growByUninitialized(newLength - oldLength))
- return false;
- makeRangeGCSafe(oldLength);
- return true;
- }
- void clear() { vector.clear(); }
- MOZ_MUST_USE bool reserve(size_t newLength) {
- return vector.reserve(newLength);
- }
- JS::MutableHandle<T> operator[](size_t i) {
- return JS::MutableHandle<T>::fromMarkedLocation(&vector[i]);
- }
- JS::Handle<T> operator[](size_t i) const {
- return JS::Handle<T>::fromMarkedLocation(&vector[i]);
- }
- const T* begin() const { return vector.begin(); }
- T* begin() { return vector.begin(); }
- const T* end() const { return vector.end(); }
- T* end() { return vector.end(); }
- Range all() { return vector.all(); }
- const T& back() const { return vector.back(); }
- friend void AutoGCRooter::trace(JSTracer* trc);
- private:
- void makeRangeGCSafe(size_t oldLength) {
- T* t = vector.begin() + oldLength;
- for (size_t i = oldLength; i < vector.length(); ++i, ++t)
- memset(t, 0, sizeof(T));
- }
- MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
- };
- template <typename T>
- class MOZ_RAII AutoVectorRooter : public AutoVectorRooterBase<T>
- {
- public:
- explicit AutoVectorRooter(JSContext* cx
- MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
- : AutoVectorRooterBase<T>(cx, this->GetTag(T()))
- {
- MOZ_GUARD_OBJECT_NOTIFIER_INIT;
- }
- explicit AutoVectorRooter(js::ContextFriendFields* cx
- MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
- : AutoVectorRooterBase<T>(cx, this->GetTag(T()))
- {
- MOZ_GUARD_OBJECT_NOTIFIER_INIT;
- }
- MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
- };
- class AutoValueVector : public Rooted<GCVector<Value, 8>> {
- using Vec = GCVector<Value, 8>;
- using Base = Rooted<Vec>;
- public:
- explicit AutoValueVector(JSContext* cx) : Base(cx, Vec(cx)) {}
- explicit AutoValueVector(js::ContextFriendFields* cx) : Base(cx, Vec(cx)) {}
- };
- class AutoIdVector : public Rooted<GCVector<jsid, 8>> {
- using Vec = GCVector<jsid, 8>;
- using Base = Rooted<Vec>;
- public:
- explicit AutoIdVector(JSContext* cx) : Base(cx, Vec(cx)) {}
- explicit AutoIdVector(js::ContextFriendFields* cx) : Base(cx, Vec(cx)) {}
- bool appendAll(const AutoIdVector& other) { return this->Base::appendAll(other.get()); }
- };
- class AutoObjectVector : public Rooted<GCVector<JSObject*, 8>> {
- using Vec = GCVector<JSObject*, 8>;
- using Base = Rooted<Vec>;
- public:
- explicit AutoObjectVector(JSContext* cx) : Base(cx, Vec(cx)) {}
- explicit AutoObjectVector(js::ContextFriendFields* cx) : Base(cx, Vec(cx)) {}
- };
- using ValueVector = JS::GCVector<JS::Value>;
- using IdVector = JS::GCVector<jsid>;
- using ScriptVector = JS::GCVector<JSScript*>;
- using StringVector = JS::GCVector<JSString*>;
- template<class Key, class Value>
- class MOZ_RAII AutoHashMapRooter : protected AutoGCRooter
- {
- private:
- typedef js::HashMap<Key, Value> HashMapImpl;
- public:
- explicit AutoHashMapRooter(JSContext* cx, ptrdiff_t tag
- MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
- : AutoGCRooter(cx, tag), map(cx)
- {
- MOZ_GUARD_OBJECT_NOTIFIER_INIT;
- }
- typedef Key KeyType;
- typedef Value ValueType;
- typedef typename HashMapImpl::Entry Entry;
- typedef typename HashMapImpl::Lookup Lookup;
- typedef typename HashMapImpl::Ptr Ptr;
- typedef typename HashMapImpl::AddPtr AddPtr;
- bool init(uint32_t len = 16) {
- return map.init(len);
- }
- bool initialized() const {
- return map.initialized();
- }
- Ptr lookup(const Lookup& l) const {
- return map.lookup(l);
- }
- void remove(Ptr p) {
- map.remove(p);
- }
- AddPtr lookupForAdd(const Lookup& l) const {
- return map.lookupForAdd(l);
- }
- template<typename KeyInput, typename ValueInput>
- bool add(AddPtr& p, const KeyInput& k, const ValueInput& v) {
- return map.add(p, k, v);
- }
- bool add(AddPtr& p, const Key& k) {
- return map.add(p, k);
- }
- template<typename KeyInput, typename ValueInput>
- bool relookupOrAdd(AddPtr& p, const KeyInput& k, const ValueInput& v) {
- return map.relookupOrAdd(p, k, v);
- }
- typedef typename HashMapImpl::Range Range;
- Range all() const {
- return map.all();
- }
- typedef typename HashMapImpl::Enum Enum;
- void clear() {
- map.clear();
- }
- void finish() {
- map.finish();
- }
- bool empty() const {
- return map.empty();
- }
- uint32_t count() const {
- return map.count();
- }
- size_t capacity() const {
- return map.capacity();
- }
- size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
- return map.sizeOfExcludingThis(mallocSizeOf);
- }
- size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
- return map.sizeOfIncludingThis(mallocSizeOf);
- }
- /************************************************** Shorthand operations */
- bool has(const Lookup& l) const {
- return map.has(l);
- }
- template<typename KeyInput, typename ValueInput>
- bool put(const KeyInput& k, const ValueInput& v) {
- return map.put(k, v);
- }
- template<typename KeyInput, typename ValueInput>
- bool putNew(const KeyInput& k, const ValueInput& v) {
- return map.putNew(k, v);
- }
- Ptr lookupWithDefault(const Key& k, const Value& defaultValue) {
- return map.lookupWithDefault(k, defaultValue);
- }
- void remove(const Lookup& l) {
- map.remove(l);
- }
- friend void AutoGCRooter::trace(JSTracer* trc);
- private:
- AutoHashMapRooter(const AutoHashMapRooter& hmr) = delete;
- AutoHashMapRooter& operator=(const AutoHashMapRooter& hmr) = delete;
- HashMapImpl map;
- MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
- };
- template<class T>
- class MOZ_RAII AutoHashSetRooter : protected AutoGCRooter
- {
- private:
- typedef js::HashSet<T> HashSetImpl;
- public:
- explicit AutoHashSetRooter(JSContext* cx, ptrdiff_t tag
- MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
- : AutoGCRooter(cx, tag), set(cx)
- {
- MOZ_GUARD_OBJECT_NOTIFIER_INIT;
- }
- typedef typename HashSetImpl::Lookup Lookup;
- typedef typename HashSetImpl::Ptr Ptr;
- typedef typename HashSetImpl::AddPtr AddPtr;
- bool init(uint32_t len = 16) {
- return set.init(len);
- }
- bool initialized() const {
- return set.initialized();
- }
- Ptr lookup(const Lookup& l) const {
- return set.lookup(l);
- }
- void remove(Ptr p) {
- set.remove(p);
- }
- AddPtr lookupForAdd(const Lookup& l) const {
- return set.lookupForAdd(l);
- }
- bool add(AddPtr& p, const T& t) {
- return set.add(p, t);
- }
- bool relookupOrAdd(AddPtr& p, const Lookup& l, const T& t) {
- return set.relookupOrAdd(p, l, t);
- }
- typedef typename HashSetImpl::Range Range;
- Range all() const {
- return set.all();
- }
- typedef typename HashSetImpl::Enum Enum;
- void clear() {
- set.clear();
- }
- void finish() {
- set.finish();
- }
- bool empty() const {
- return set.empty();
- }
- uint32_t count() const {
- return set.count();
- }
- size_t capacity() const {
- return set.capacity();
- }
- size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
- return set.sizeOfExcludingThis(mallocSizeOf);
- }
- size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
- return set.sizeOfIncludingThis(mallocSizeOf);
- }
- /************************************************** Shorthand operations */
- bool has(const Lookup& l) const {
- return set.has(l);
- }
- bool put(const T& t) {
- return set.put(t);
- }
- bool putNew(const T& t) {
- return set.putNew(t);
- }
- void remove(const Lookup& l) {
- set.remove(l);
- }
- friend void AutoGCRooter::trace(JSTracer* trc);
- private:
- AutoHashSetRooter(const AutoHashSetRooter& hmr) = delete;
- AutoHashSetRooter& operator=(const AutoHashSetRooter& hmr) = delete;
- HashSetImpl set;
- MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
- };
- /**
- * Custom rooting behavior for internal and external clients.
- */
- class MOZ_RAII JS_PUBLIC_API(CustomAutoRooter) : private AutoGCRooter
- {
- public:
- template <typename CX>
- explicit CustomAutoRooter(const CX& cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
- : AutoGCRooter(cx, CUSTOM)
- {
- MOZ_GUARD_OBJECT_NOTIFIER_INIT;
- }
- friend void AutoGCRooter::trace(JSTracer* trc);
- protected:
- virtual ~CustomAutoRooter() {}
- /** Supplied by derived class to trace roots. */
- virtual void trace(JSTracer* trc) = 0;
- private:
- MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
- };
- /** A handle to an array of rooted values. */
- class HandleValueArray
- {
- const size_t length_;
- const Value * const elements_;
- HandleValueArray(size_t len, const Value* elements) : length_(len), elements_(elements) {}
- public:
- explicit HandleValueArray(const RootedValue& value) : length_(1), elements_(value.address()) {}
- MOZ_IMPLICIT HandleValueArray(const AutoValueVector& values)
- : length_(values.length()), elements_(values.begin()) {}
- template <size_t N>
- MOZ_IMPLICIT HandleValueArray(const AutoValueArray<N>& values) : length_(N), elements_(values.begin()) {}
- /** CallArgs must already be rooted somewhere up the stack. */
- MOZ_IMPLICIT HandleValueArray(const JS::CallArgs& args) : length_(args.length()), elements_(args.array()) {}
- /** Use with care! Only call this if the data is guaranteed to be marked. */
- static HandleValueArray fromMarkedLocation(size_t len, const Value* elements) {
- return HandleValueArray(len, elements);
- }
- static HandleValueArray subarray(const HandleValueArray& values, size_t startIndex, size_t len) {
- MOZ_ASSERT(startIndex + len <= values.length());
- return HandleValueArray(len, values.begin() + startIndex);
- }
- static HandleValueArray empty() {
- return HandleValueArray(0, nullptr);
- }
- size_t length() const { return length_; }
- const Value* begin() const { return elements_; }
- HandleValue operator[](size_t i) const {
- MOZ_ASSERT(i < length_);
- return HandleValue::fromMarkedLocation(&elements_[i]);
- }
- };
- } /* namespace JS */
- /************************************************************************/
- struct JSFreeOp {
- protected:
- JSRuntime* runtime_;
- explicit JSFreeOp(JSRuntime* rt)
- : runtime_(rt) { }
- public:
- JSRuntime* runtime() const {
- MOZ_ASSERT(runtime_);
- return runtime_;
- }
- };
- /* Callbacks and their arguments. */
- /************************************************************************/
- typedef enum JSGCStatus {
- JSGC_BEGIN,
- JSGC_END
- } JSGCStatus;
- typedef void
- (* JSGCCallback)(JSContext* cx, JSGCStatus status, void* data);
- typedef void
- (* JSObjectsTenuredCallback)(JSContext* cx, void* data);
- typedef enum JSFinalizeStatus {
- /**
- * Called when preparing to sweep a group of zones, before anything has been
- * swept. The collector will not yield to the mutator before calling the
- * callback with JSFINALIZE_GROUP_END status.
- */
- JSFINALIZE_GROUP_START,
- /**
- * Called when preparing to sweep a group of zones. Weak references to
- * unmarked things have been removed and things that are not swept
- * incrementally have been finalized at this point. The collector may yield
- * to the mutator after this point.
- */
- JSFINALIZE_GROUP_END,
- /**
- * Called at the end of collection when everything has been swept.
- */
- JSFINALIZE_COLLECTION_END
- } JSFinalizeStatus;
- typedef void
- (* JSFinalizeCallback)(JSFreeOp* fop, JSFinalizeStatus status, bool isZoneGC, void* data);
- typedef void
- (* JSWeakPointerZoneGroupCallback)(JSContext* cx, void* data);
- typedef void
- (* JSWeakPointerCompartmentCallback)(JSContext* cx, JSCompartment* comp, void* data);
- typedef bool
- (* JSInterruptCallback)(JSContext* cx);
- typedef JSObject*
- (* JSGetIncumbentGlobalCallback)(JSContext* cx);
- typedef bool
- (* JSEnqueuePromiseJobCallback)(JSContext* cx, JS::HandleObject job,
- JS::HandleObject allocationSite, JS::HandleObject incumbentGlobal,
- void* data);
- enum class PromiseRejectionHandlingState {
- Unhandled,
- Handled
- };
- typedef void
- (* JSPromiseRejectionTrackerCallback)(JSContext* cx, JS::HandleObject promise,
- PromiseRejectionHandlingState state, void* data);
- typedef void
- (* JSProcessPromiseCallback)(JSContext* cx, JS::HandleObject promise);
- /**
- * Possible exception types. These types are part of a JSErrorFormatString
- * structure. They define which error to throw in case of a runtime error.
- *
- * JSEXN_WARN is used for warnings in js.msg files (for instance because we
- * don't want to prepend 'Error:' to warning messages). This value can go away
- * if we ever decide to use an entirely separate mechanism for warnings.
- */
- typedef enum JSExnType {
- JSEXN_ERR,
- JSEXN_FIRST = JSEXN_ERR,
- JSEXN_INTERNALERR,
- JSEXN_EVALERR,
- JSEXN_RANGEERR,
- JSEXN_REFERENCEERR,
- JSEXN_SYNTAXERR,
- JSEXN_TYPEERR,
- JSEXN_URIERR,
- JSEXN_DEBUGGEEWOULDRUN,
- JSEXN_WASMCOMPILEERROR,
- JSEXN_WASMRUNTIMEERROR,
- JSEXN_WARN,
- JSEXN_LIMIT
- } JSExnType;
- typedef struct JSErrorFormatString {
- /** The error message name in ASCII. */
- const char* name;
- /** The error format string in ASCII. */
- const char* format;
- /** The number of arguments to expand in the formatted error message. */
- uint16_t argCount;
- /** One of the JSExnType constants above. */
- int16_t exnType;
- } JSErrorFormatString;
- typedef const JSErrorFormatString*
- (* JSErrorCallback)(void* userRef, const unsigned errorNumber);
- typedef bool
- (* JSLocaleToUpperCase)(JSContext* cx, JS::HandleString src, JS::MutableHandleValue rval);
- typedef bool
- (* JSLocaleToLowerCase)(JSContext* cx, JS::HandleString src, JS::MutableHandleValue rval);
- typedef bool
- (* JSLocaleCompare)(JSContext* cx, JS::HandleString src1, JS::HandleString src2,
- JS::MutableHandleValue rval);
- typedef bool
- (* JSLocaleToUnicode)(JSContext* cx, const char* src, JS::MutableHandleValue rval);
- /**
- * Callback used to ask the embedding for the cross compartment wrapper handler
- * that implements the desired prolicy for this kind of object in the
- * destination compartment. |obj| is the object to be wrapped. If |existing| is
- * non-nullptr, it will point to an existing wrapper object that should be
- * re-used if possible. |existing| is guaranteed to be a cross-compartment
- * wrapper with a lazily-defined prototype and the correct global. It is
- * guaranteed not to wrap a function.
- */
- typedef JSObject*
- (* JSWrapObjectCallback)(JSContext* cx, JS::HandleObject existing, JS::HandleObject obj);
- /**
- * Callback used by the wrap hook to ask the embedding to prepare an object
- * for wrapping in a context. This might include unwrapping other wrappers
- * or even finding a more suitable object for the new compartment.
- */
- typedef void
- (* JSPreWrapCallback)(JSContext* cx, JS::HandleObject scope, JS::HandleObject obj,
- JS::HandleObject objectPassedToWrap,
- JS::MutableHandleObject retObj);
- struct JSWrapObjectCallbacks
- {
- JSWrapObjectCallback wrap;
- JSPreWrapCallback preWrap;
- };
- typedef void
- (* JSDestroyCompartmentCallback)(JSFreeOp* fop, JSCompartment* compartment);
- typedef size_t
- (* JSSizeOfIncludingThisCompartmentCallback)(mozilla::MallocSizeOf mallocSizeOf,
- JSCompartment* compartment);
- typedef void
- (* JSZoneCallback)(JS::Zone* zone);
- typedef void
- (* JSCompartmentNameCallback)(JSContext* cx, JSCompartment* compartment,
- char* buf, size_t bufsize);
- /************************************************************************/
- static MOZ_ALWAYS_INLINE JS::Value
- JS_NumberValue(double d)
- {
- int32_t i;
- d = JS::CanonicalizeNaN(d);
- if (mozilla::NumberIsInt32(d, &i))
- return JS::Int32Value(i);
- return JS::DoubleValue(d);
- }
- /************************************************************************/
- JS_PUBLIC_API(bool)
- JS_StringHasBeenPinned(JSContext* cx, JSString* str);
- namespace JS {
- /**
- * Container class for passing in script source buffers to the JS engine. This
- * not only groups the buffer and length values, it also provides a way to
- * optionally pass ownership of the buffer to the JS engine without copying.
- * Rules for use:
- *
- * 1) The data array must be allocated with js_malloc() or js_realloc() if
- * ownership is being granted to the SourceBufferHolder.
- * 2) If ownership is not given to the SourceBufferHolder, then the memory
- * must be kept alive until the JS compilation is complete.
- * 3) Any code calling SourceBufferHolder::take() must guarantee to keep the
- * memory alive until JS compilation completes. Normally only the JS
- * engine should be calling take().
- *
- * Example use:
- *
- * size_t length = 512;
- * char16_t* chars = static_cast<char16_t*>(js_malloc(sizeof(char16_t) * length));
- * JS::SourceBufferHolder srcBuf(chars, length, JS::SourceBufferHolder::GiveOwnership);
- * JS::Compile(cx, options, srcBuf);
- */
- class MOZ_STACK_CLASS SourceBufferHolder final
- {
- public:
- enum Ownership {
- NoOwnership,
- GiveOwnership
- };
- SourceBufferHolder(const char16_t* data, size_t dataLength, Ownership ownership)
- : data_(data),
- length_(dataLength),
- ownsChars_(ownership == GiveOwnership)
- {
- // Ensure that null buffers properly return an unowned, empty,
- // null-terminated string.
- static const char16_t NullChar_ = 0;
- if (!get()) {
- data_ = &NullChar_;
- length_ = 0;
- ownsChars_ = false;
- }
- }
- SourceBufferHolder(SourceBufferHolder&& other)
- : data_(other.data_),
- length_(other.length_),
- ownsChars_(other.ownsChars_)
- {
- other.data_ = nullptr;
- other.length_ = 0;
- other.ownsChars_ = false;
- }
- ~SourceBufferHolder() {
- if (ownsChars_)
- js_free(const_cast<char16_t*>(data_));
- }
- // Access the underlying source buffer without affecting ownership.
- const char16_t* get() const { return data_; }
- // Length of the source buffer in char16_t code units (not bytes)
- size_t length() const { return length_; }
- // Returns true if the SourceBufferHolder owns the buffer and will free
- // it upon destruction. If true, it is legal to call take().
- bool ownsChars() const { return ownsChars_; }
- // Retrieve and take ownership of the underlying data buffer. The caller
- // is now responsible for calling js_free() on the returned value, *but only
- // after JS script compilation has completed*.
- //
- // After the buffer has been taken the SourceBufferHolder functions as if
- // it had been constructed on an unowned buffer; get() and length() still
- // work. In order for this to be safe the taken buffer must be kept alive
- // until after JS script compilation completes as noted above.
- //
- // Note, it's the caller's responsibility to check ownsChars() before taking
- // the buffer. Taking and then free'ing an unowned buffer will have dire
- // consequences.
- char16_t* take() {
- MOZ_ASSERT(ownsChars_);
- ownsChars_ = false;
- return const_cast<char16_t*>(data_);
- }
- private:
- SourceBufferHolder(SourceBufferHolder&) = delete;
- SourceBufferHolder& operator=(SourceBufferHolder&) = delete;
- const char16_t* data_;
- size_t length_;
- bool ownsChars_;
- };
- } /* namespace JS */
- /************************************************************************/
- /* Property attributes, set in JSPropertySpec and passed to API functions.
- *
- * NB: The data structure in which some of these values are stored only uses
- * a uint8_t to store the relevant information. Proceed with caution if
- * trying to reorder or change the the first byte worth of flags.
- */
- #define JSPROP_ENUMERATE 0x01 /* property is visible to for/in loop */
- #define JSPROP_READONLY 0x02 /* not settable: assignment is no-op.
- This flag is only valid when neither
- JSPROP_GETTER nor JSPROP_SETTER is
- set. */
- #define JSPROP_PERMANENT 0x04 /* property cannot be deleted */
- #define JSPROP_PROPOP_ACCESSORS 0x08 /* Passed to JS_Define(UC)Property* and
- JS_DefineElement if getters/setters
- are JSGetterOp/JSSetterOp */
- #define JSPROP_GETTER 0x10 /* property holds getter function */
- #define JSPROP_SETTER 0x20 /* property holds setter function */
- #define JSPROP_SHARED 0x40 /* don't allocate a value slot for this
- property; don't copy the property on
- set of the same-named property in an
- object that delegates to a prototype
- containing this property */
- #define JSPROP_INTERNAL_USE_BIT 0x80 /* internal JS engine use only */
- #define JSFUN_STUB_GSOPS 0x200 /* use JS_PropertyStub getter/setter
- instead of defaulting to class gsops
- for property holding function */
- #define JSFUN_CONSTRUCTOR 0x400 /* native that can be called as a ctor */
- // 0x800 /* Unused */
- #define JSFUN_HAS_REST 0x1000 /* function has ...rest parameter. */
- #define JSFUN_FLAGS_MASK 0x1e00 /* | of all the JSFUN_* flags */
- /*
- * If set, will allow redefining a non-configurable property, but only on a
- * non-DOM global. This is a temporary hack that will need to go away in bug
- * 1105518.
- */
- #define JSPROP_REDEFINE_NONCONFIGURABLE 0x1000
- /*
- * Resolve hooks and enumerate hooks must pass this flag when calling
- * JS_Define* APIs to reify lazily-defined properties.
- *
- * JSPROP_RESOLVING is used only with property-defining APIs. It tells the
- * engine to skip the resolve hook when performing the lookup at the beginning
- * of property definition. This keeps the resolve hook from accidentally
- * triggering itself: unchecked recursion.
- *
- * For enumerate hooks, triggering the resolve hook would be merely silly, not
- * fatal, except in some cases involving non-configurable properties.
- */
- #define JSPROP_RESOLVING 0x2000
- #define JSPROP_IGNORE_ENUMERATE 0x4000 /* ignore the value in JSPROP_ENUMERATE.
- This flag only valid when defining over
- an existing property. */
- #define JSPROP_IGNORE_READONLY 0x8000 /* ignore the value in JSPROP_READONLY.
- This flag only valid when defining over
- an existing property. */
- #define JSPROP_IGNORE_PERMANENT 0x10000 /* ignore the value in JSPROP_PERMANENT.
- This flag only valid when defining over
- an existing property. */
- #define JSPROP_IGNORE_VALUE 0x20000 /* ignore the Value in the descriptor. Nothing was
- specified when passed to Object.defineProperty
- from script. */
- /** Microseconds since the epoch, midnight, January 1, 1970 UTC. */
- extern JS_PUBLIC_API(int64_t)
- JS_Now(void);
- /** Don't want to export data, so provide accessors for non-inline Values. */
- extern JS_PUBLIC_API(JS::Value)
- JS_GetNaNValue(JSContext* cx);
- extern JS_PUBLIC_API(JS::Value)
- JS_GetNegativeInfinityValue(JSContext* cx);
- extern JS_PUBLIC_API(JS::Value)
- JS_GetPositiveInfinityValue(JSContext* cx);
- extern JS_PUBLIC_API(JS::Value)
- JS_GetEmptyStringValue(JSContext* cx);
- extern JS_PUBLIC_API(JSString*)
- JS_GetEmptyString(JSContext* cx);
- extern JS_PUBLIC_API(bool)
- JS_ValueToObject(JSContext* cx, JS::HandleValue v, JS::MutableHandleObject objp);
- extern JS_PUBLIC_API(JSFunction*)
- JS_ValueToFunction(JSContext* cx, JS::HandleValue v);
- extern JS_PUBLIC_API(JSFunction*)
- JS_ValueToConstructor(JSContext* cx, JS::HandleValue v);
- extern JS_PUBLIC_API(JSString*)
- JS_ValueToSource(JSContext* cx, JS::Handle<JS::Value> v);
- extern JS_PUBLIC_API(bool)
- JS_DoubleIsInt32(double d, int32_t* ip);
- extern JS_PUBLIC_API(JSType)
- JS_TypeOfValue(JSContext* cx, JS::Handle<JS::Value> v);
- namespace JS {
- extern JS_PUBLIC_API(const char*)
- InformalValueTypeName(const JS::Value& v);
- } /* namespace JS */
- extern JS_PUBLIC_API(bool)
- JS_StrictlyEqual(JSContext* cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool* equal);
- extern JS_PUBLIC_API(bool)
- JS_LooselyEqual(JSContext* cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool* equal);
- extern JS_PUBLIC_API(bool)
- JS_SameValue(JSContext* cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool* same);
- /** True iff fun is the global eval function. */
- extern JS_PUBLIC_API(bool)
- JS_IsBuiltinEvalFunction(JSFunction* fun);
- /** True iff fun is the Function constructor. */
- extern JS_PUBLIC_API(bool)
- JS_IsBuiltinFunctionConstructor(JSFunction* fun);
- /************************************************************************/
- /*
- * Locking, contexts, and memory allocation.
- *
- * It is important that SpiderMonkey be initialized, and the first context
- * be created, in a single-threaded fashion. Otherwise the behavior of the
- * library is undefined.
- * See: http://developer.mozilla.org/en/docs/Category:JSAPI_Reference
- */
- extern JS_PUBLIC_API(JSContext*)
- JS_NewContext(uint32_t maxbytes,
- uint32_t maxNurseryBytes = JS::DefaultNurseryBytes,
- JSContext* parentContext = nullptr);
- extern JS_PUBLIC_API(void)
- JS_DestroyContext(JSContext* cx);
- typedef double (*JS_CurrentEmbedderTimeFunction)();
- /**
- * The embedding can specify a time function that will be used in some
- * situations. The function can return the time however it likes; but
- * the norm is to return times in units of milliseconds since an
- * arbitrary, but consistent, epoch. If the time function is not set,
- * a built-in default will be used.
- */
- JS_PUBLIC_API(void)
- JS_SetCurrentEmbedderTimeFunction(JS_CurrentEmbedderTimeFunction timeFn);
- /**
- * Return the time as computed using the current time function, or a
- * suitable default if one has not been set.
- */
- JS_PUBLIC_API(double)
- JS_GetCurrentEmbedderTime();
- JS_PUBLIC_API(void*)
- JS_GetContextPrivate(JSContext* cx);
- JS_PUBLIC_API(void)
- JS_SetContextPrivate(JSContext* cx, void* data);
- extern JS_PUBLIC_API(JSContext*)
- JS_GetParentContext(JSContext* cx);
- extern JS_PUBLIC_API(void)
- JS_BeginRequest(JSContext* cx);
- extern JS_PUBLIC_API(void)
- JS_EndRequest(JSContext* cx);
- extern JS_PUBLIC_API(void)
- JS_SetFutexCanWait(JSContext* cx);
- namespace js {
- void
- AssertHeapIsIdle(JSRuntime* rt);
- } /* namespace js */
- class MOZ_RAII JSAutoRequest
- {
- public:
- explicit JSAutoRequest(JSContext* cx
- MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
- : mContext(cx)
- {
- MOZ_GUARD_OBJECT_NOTIFIER_INIT;
- JS_BeginRequest(mContext);
- }
- ~JSAutoRequest() {
- JS_EndRequest(mContext);
- }
- protected:
- JSContext* mContext;
- MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
- #if 0
- private:
- static void* operator new(size_t) CPP_THROW_NEW { return 0; }
- static void operator delete(void*, size_t) { }
- #endif
- };
- extern JS_PUBLIC_API(JSVersion)
- JS_GetVersion(JSContext* cx);
- /**
- * Mutate the version on the compartment. This is generally discouraged, but
- * necessary to support the version mutation in the js and xpc shell command
- * set.
- *
- * It would be nice to put this in jsfriendapi, but the linkage requirements
- * of the shells make that impossible.
- */
- JS_PUBLIC_API(void)
- JS_SetVersionForCompartment(JSCompartment* compartment, JSVersion version);
- extern JS_PUBLIC_API(const char*)
- JS_VersionToString(JSVersion version);
- extern JS_PUBLIC_API(JSVersion)
- JS_StringToVersion(const char* string);
- namespace JS {
- class JS_PUBLIC_API(ContextOptions) {
- public:
- ContextOptions()
- : baseline_(true),
- ion_(true),
- asmJS_(true),
- wasm_(false),
- wasmAlwaysBaseline_(false),
- throwOnAsmJSValidationFailure_(false),
- nativeRegExp_(true),
- unboxedArrays_(false),
- asyncStack_(true),
- throwOnDebuggeeWouldRun_(true),
- dumpStackOnDebuggeeWouldRun_(false),
- werror_(false),
- strictMode_(false),
- extraWarnings_(false)
- {
- }
- bool baseline() const { return baseline_; }
- ContextOptions& setBaseline(bool flag) {
- baseline_ = flag;
- return *this;
- }
- ContextOptions& toggleBaseline() {
- baseline_ = !baseline_;
- return *this;
- }
- bool ion() const { return ion_; }
- ContextOptions& setIon(bool flag) {
- ion_ = flag;
- return *this;
- }
- ContextOptions& toggleIon() {
- ion_ = !ion_;
- return *this;
- }
- bool asmJS() const { return asmJS_; }
- ContextOptions& setAsmJS(bool flag) {
- asmJS_ = flag;
- return *this;
- }
- ContextOptions& toggleAsmJS() {
- asmJS_ = !asmJS_;
- return *this;
- }
- bool wasm() const { return wasm_; }
- ContextOptions& setWasm(bool flag) {
- wasm_ = flag;
- return *this;
- }
- ContextOptions& toggleWasm() {
- wasm_ = !wasm_;
- return *this;
- }
- bool wasmAlwaysBaseline() const { return wasmAlwaysBaseline_; }
- ContextOptions& setWasmAlwaysBaseline(bool flag) {
- wasmAlwaysBaseline_ = flag;
- return *this;
- }
- ContextOptions& toggleWasmAlwaysBaseline() {
- wasmAlwaysBaseline_ = !wasmAlwaysBaseline_;
- return *this;
- }
- bool throwOnAsmJSValidationFailure() const { return throwOnAsmJSValidationFailure_; }
- ContextOptions& setThrowOnAsmJSValidationFailure(bool flag) {
- throwOnAsmJSValidationFailure_ = flag;
- return *this;
- }
- ContextOptions& toggleThrowOnAsmJSValidationFailure() {
- throwOnAsmJSValidationFailure_ = !throwOnAsmJSValidationFailure_;
- return *this;
- }
- bool nativeRegExp() const { return nativeRegExp_; }
- ContextOptions& setNativeRegExp(bool flag) {
- nativeRegExp_ = flag;
- return *this;
- }
- bool unboxedArrays() const { return unboxedArrays_; }
- ContextOptions& setUnboxedArrays(bool flag) {
- unboxedArrays_ = flag;
- return *this;
- }
- bool asyncStack() const { return asyncStack_; }
- ContextOptions& setAsyncStack(bool flag) {
- asyncStack_ = flag;
- return *this;
- }
- bool throwOnDebuggeeWouldRun() const { return throwOnDebuggeeWouldRun_; }
- ContextOptions& setThrowOnDebuggeeWouldRun(bool flag) {
- throwOnDebuggeeWouldRun_ = flag;
- return *this;
- }
- bool dumpStackOnDebuggeeWouldRun() const { return dumpStackOnDebuggeeWouldRun_; }
- ContextOptions& setDumpStackOnDebuggeeWouldRun(bool flag) {
- dumpStackOnDebuggeeWouldRun_ = flag;
- return *this;
- }
- bool werror() const { return werror_; }
- ContextOptions& setWerror(bool flag) {
- werror_ = flag;
- return *this;
- }
- ContextOptions& toggleWerror() {
- werror_ = !werror_;
- return *this;
- }
- bool strictMode() const { return strictMode_; }
- ContextOptions& setStrictMode(bool flag) {
- strictMode_ = flag;
- return *this;
- }
- ContextOptions& toggleStrictMode() {
- strictMode_ = !strictMode_;
- return *this;
- }
- bool extraWarnings() const { return extraWarnings_; }
- ContextOptions& setExtraWarnings(bool flag) {
- extraWarnings_ = flag;
- return *this;
- }
- ContextOptions& toggleExtraWarnings() {
- extraWarnings_ = !extraWarnings_;
- return *this;
- }
- private:
- bool baseline_ : 1;
- bool ion_ : 1;
- bool asmJS_ : 1;
- bool wasm_ : 1;
- bool wasmAlwaysBaseline_ : 1;
- bool throwOnAsmJSValidationFailure_ : 1;
- bool nativeRegExp_ : 1;
- bool unboxedArrays_ : 1;
- bool asyncStack_ : 1;
- bool throwOnDebuggeeWouldRun_ : 1;
- bool dumpStackOnDebuggeeWouldRun_ : 1;
- bool werror_ : 1;
- bool strictMode_ : 1;
- bool extraWarnings_ : 1;
- };
- JS_PUBLIC_API(ContextOptions&)
- ContextOptionsRef(JSContext* cx);
- /**
- * Initialize the runtime's self-hosted code. Embeddings should call this
- * exactly once per runtime/context, before the first JS_NewGlobalObject
- * call.
- */
- JS_PUBLIC_API(bool)
- InitSelfHostedCode(JSContext* cx);
- /**
- * Asserts (in debug and release builds) that `obj` belongs to the current
- * thread's context.
- */
- JS_PUBLIC_API(void)
- AssertObjectBelongsToCurrentThread(JSObject* obj);
- } /* namespace JS */
- extern JS_PUBLIC_API(const char*)
- JS_GetImplementationVersion(void);
- extern JS_PUBLIC_API(void)
- JS_SetDestroyCompartmentCallback(JSContext* cx, JSDestroyCompartmentCallback callback);
- extern JS_PUBLIC_API(void)
- JS_SetSizeOfIncludingThisCompartmentCallback(JSContext* cx,
- JSSizeOfIncludingThisCompartmentCallback callback);
- extern JS_PUBLIC_API(void)
- JS_SetDestroyZoneCallback(JSContext* cx, JSZoneCallback callback);
- extern JS_PUBLIC_API(void)
- JS_SetSweepZoneCallback(JSContext* cx, JSZoneCallback callback);
- extern JS_PUBLIC_API(void)
- JS_SetCompartmentNameCallback(JSContext* cx, JSCompartmentNameCallback callback);
- extern JS_PUBLIC_API(void)
- JS_SetWrapObjectCallbacks(JSContext* cx, const JSWrapObjectCallbacks* callbacks);
- extern JS_PUBLIC_API(void)
- JS_SetCompartmentPrivate(JSCompartment* compartment, void* data);
- extern JS_PUBLIC_API(void*)
- JS_GetCompartmentPrivate(JSCompartment* compartment);
- extern JS_PUBLIC_API(void)
- JS_SetZoneUserData(JS::Zone* zone, void* data);
- extern JS_PUBLIC_API(void*)
- JS_GetZoneUserData(JS::Zone* zone);
- extern JS_PUBLIC_API(bool)
- JS_WrapObject(JSContext* cx, JS::MutableHandleObject objp);
- extern JS_PUBLIC_API(bool)
- JS_WrapValue(JSContext* cx, JS::MutableHandleValue vp);
- extern JS_PUBLIC_API(JSObject*)
- JS_TransplantObject(JSContext* cx, JS::HandleObject origobj, JS::HandleObject target);
- extern JS_PUBLIC_API(bool)
- JS_RefreshCrossCompartmentWrappers(JSContext* cx, JS::Handle<JSObject*> obj);
- /*
- * At any time, a JSContext has a current (possibly-nullptr) compartment.
- * Compartments are described in:
- *
- * developer.mozilla.org/en-US/docs/SpiderMonkey/SpiderMonkey_compartments
- *
- * The current compartment of a context may be changed. The preferred way to do
- * this is with JSAutoCompartment:
- *
- * void foo(JSContext* cx, JSObject* obj) {
- * // in some compartment 'c'
- * {
- * JSAutoCompartment ac(cx, obj); // constructor enters
- * // in the compartment of 'obj'
- * } // destructor leaves
- * // back in compartment 'c'
- * }
- *
- * For more complicated uses that don't neatly fit in a C++ stack frame, the
- * compartment can entered and left using separate function calls:
- *
- * void foo(JSContext* cx, JSObject* obj) {
- * // in 'oldCompartment'
- * JSCompartment* oldCompartment = JS_EnterCompartment(cx, obj);
- * // in the compartment of 'obj'
- * JS_LeaveCompartment(cx, oldCompartment);
- * // back in 'oldCompartment'
- * }
- *
- * Note: these calls must still execute in a LIFO manner w.r.t all other
- * enter/leave calls on the context. Furthermore, only the return value of a
- * JS_EnterCompartment call may be passed as the 'oldCompartment' argument of
- * the corresponding JS_LeaveCompartment call.
- */
- class MOZ_RAII JS_PUBLIC_API(JSAutoCompartment)
- {
- JSContext* cx_;
- JSCompartment* oldCompartment_;
- public:
- JSAutoCompartment(JSContext* cx, JSObject* target
- MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
- JSAutoCompartment(JSContext* cx, JSScript* target
- MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
- ~JSAutoCompartment();
- MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
- };
- class MOZ_RAII JS_PUBLIC_API(JSAutoNullableCompartment)
- {
- JSContext* cx_;
- JSCompartment* oldCompartment_;
- public:
- explicit JSAutoNullableCompartment(JSContext* cx, JSObject* targetOrNull
- MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
- ~JSAutoNullableCompartment();
- MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
- };
- /** NB: This API is infallible; a nullptr return value does not indicate error. */
- extern JS_PUBLIC_API(JSCompartment*)
- JS_EnterCompartment(JSContext* cx, JSObject* target);
- extern JS_PUBLIC_API(void)
- JS_LeaveCompartment(JSContext* cx, JSCompartment* oldCompartment);
- typedef void (*JSIterateCompartmentCallback)(JSContext* cx, void* data, JSCompartment* compartment);
- /**
- * This function calls |compartmentCallback| on every compartment. Beware that
- * there is no guarantee that the compartment will survive after the callback
- * returns. Also, barriers are disabled via the TraceSession.
- */
- extern JS_PUBLIC_API(void)
- JS_IterateCompartments(JSContext* cx, void* data,
- JSIterateCompartmentCallback compartmentCallback);
- /**
- * Initialize standard JS class constructors, prototypes, and any top-level
- * functions and constants associated with the standard classes (e.g. isNaN
- * for Number).
- *
- * NB: This sets cx's global object to obj if it was null.
- */
- extern JS_PUBLIC_API(bool)
- JS_InitStandardClasses(JSContext* cx, JS::Handle<JSObject*> obj);
- /**
- * Resolve id, which must contain either a string or an int, to a standard
- * class name in obj if possible, defining the class's constructor and/or
- * prototype and storing true in *resolved. If id does not name a standard
- * class or a top-level property induced by initializing a standard class,
- * store false in *resolved and just return true. Return false on error,
- * as usual for bool result-typed API entry points.
- *
- * This API can be called directly from a global object class's resolve op,
- * to define standard classes lazily. The class's enumerate op should call
- * JS_EnumerateStandardClasses(cx, obj), to define eagerly during for..in
- * loops any classes not yet resolved lazily.
- */
- extern JS_PUBLIC_API(bool)
- JS_ResolveStandardClass(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* resolved);
- extern JS_PUBLIC_API(bool)
- JS_MayResolveStandardClass(const JSAtomState& names, jsid id, JSObject* maybeObj);
- extern JS_PUBLIC_API(bool)
- JS_EnumerateStandardClasses(JSContext* cx, JS::HandleObject obj);
- extern JS_PUBLIC_API(bool)
- JS_GetClassObject(JSContext* cx, JSProtoKey key, JS::MutableHandle<JSObject*> objp);
- extern JS_PUBLIC_API(bool)
- JS_GetClassPrototype(JSContext* cx, JSProtoKey key, JS::MutableHandle<JSObject*> objp);
- namespace JS {
- /*
- * Determine if the given object is an instance/prototype/constructor for a standard
- * class. If so, return the associated JSProtoKey. If not, return JSProto_Null.
- */
- extern JS_PUBLIC_API(JSProtoKey)
- IdentifyStandardInstance(JSObject* obj);
- extern JS_PUBLIC_API(JSProtoKey)
- IdentifyStandardPrototype(JSObject* obj);
- extern JS_PUBLIC_API(JSProtoKey)
- IdentifyStandardInstanceOrPrototype(JSObject* obj);
- extern JS_PUBLIC_API(JSProtoKey)
- IdentifyStandardConstructor(JSObject* obj);
- extern JS_PUBLIC_API(void)
- ProtoKeyToId(JSContext* cx, JSProtoKey key, JS::MutableHandleId idp);
- } /* namespace JS */
- extern JS_PUBLIC_API(JSProtoKey)
- JS_IdToProtoKey(JSContext* cx, JS::HandleId id);
- /**
- * Returns the original value of |Function.prototype| from the global object in
- * which |forObj| was created.
- */
- extern JS_PUBLIC_API(JSObject*)
- JS_GetFunctionPrototype(JSContext* cx, JS::HandleObject forObj);
- /**
- * Returns the original value of |Object.prototype| from the global object in
- * which |forObj| was created.
- */
- extern JS_PUBLIC_API(JSObject*)
- JS_GetObjectPrototype(JSContext* cx, JS::HandleObject forObj);
- /**
- * Returns the original value of |Array.prototype| from the global object in
- * which |forObj| was created.
- */
- extern JS_PUBLIC_API(JSObject*)
- JS_GetArrayPrototype(JSContext* cx, JS::HandleObject forObj);
- /**
- * Returns the original value of |Error.prototype| from the global
- * object of the current compartment of cx.
- */
- extern JS_PUBLIC_API(JSObject*)
- JS_GetErrorPrototype(JSContext* cx);
- /**
- * Returns the %IteratorPrototype% object that all built-in iterator prototype
- * chains go through for the global object of the current compartment of cx.
- */
- extern JS_PUBLIC_API(JSObject*)
- JS_GetIteratorPrototype(JSContext* cx);
- extern JS_PUBLIC_API(JSObject*)
- JS_GetGlobalForObject(JSContext* cx, JSObject* obj);
- extern JS_PUBLIC_API(bool)
- JS_IsGlobalObject(JSObject* obj);
- extern JS_PUBLIC_API(JSObject*)
- JS_GlobalLexicalEnvironment(JSObject* obj);
- extern JS_PUBLIC_API(bool)
- JS_HasExtensibleLexicalEnvironment(JSObject* obj);
- extern JS_PUBLIC_API(JSObject*)
- JS_ExtensibleLexicalEnvironment(JSObject* obj);
- /**
- * May return nullptr, if |c| never had a global (e.g. the atoms compartment),
- * or if |c|'s global has been collected.
- */
- extern JS_PUBLIC_API(JSObject*)
- JS_GetGlobalForCompartmentOrNull(JSContext* cx, JSCompartment* c);
- namespace JS {
- extern JS_PUBLIC_API(JSObject*)
- CurrentGlobalOrNull(JSContext* cx);
- } // namespace JS
- /**
- * Add 'Reflect.parse', a SpiderMonkey extension, to the Reflect object on the
- * given global.
- */
- extern JS_PUBLIC_API(bool)
- JS_InitReflectParse(JSContext* cx, JS::HandleObject global);
- /**
- * Add various profiling-related functions as properties of the given object.
- * Defined in builtin/Profilers.cpp.
- */
- extern JS_PUBLIC_API(bool)
- JS_DefineProfilingFunctions(JSContext* cx, JS::HandleObject obj);
- /* Defined in vm/Debugger.cpp. */
- extern JS_PUBLIC_API(bool)
- JS_DefineDebuggerObject(JSContext* cx, JS::HandleObject obj);
- #ifdef JS_HAS_CTYPES
- /**
- * Initialize the 'ctypes' object on a global variable 'obj'. The 'ctypes'
- * object will be sealed.
- */
- extern JS_PUBLIC_API(bool)
- JS_InitCTypesClass(JSContext* cx, JS::HandleObject global);
- /**
- * Convert a unicode string 'source' of length 'slen' to the platform native
- * charset, returning a null-terminated string allocated with JS_malloc. On
- * failure, this function should report an error.
- */
- typedef char*
- (* JSCTypesUnicodeToNativeFun)(JSContext* cx, const char16_t* source, size_t slen);
- /**
- * Set of function pointers that ctypes can use for various internal functions.
- * See JS_SetCTypesCallbacks below. Providing nullptr for a function is safe,
- * and will result in the applicable ctypes functionality not being available.
- */
- struct JSCTypesCallbacks {
- JSCTypesUnicodeToNativeFun unicodeToNative;
- };
- typedef struct JSCTypesCallbacks JSCTypesCallbacks;
- /**
- * Set the callbacks on the provided 'ctypesObj' object. 'callbacks' should be a
- * pointer to static data that exists for the lifetime of 'ctypesObj', but it
- * may safely be altered after calling this function and without having
- * to call this function again.
- */
- extern JS_PUBLIC_API(void)
- JS_SetCTypesCallbacks(JSObject* ctypesObj, const JSCTypesCallbacks* callbacks);
- #endif
- extern JS_PUBLIC_API(void*)
- JS_malloc(JSContext* cx, size_t nbytes);
- extern JS_PUBLIC_API(void*)
- JS_realloc(JSContext* cx, void* p, size_t oldBytes, size_t newBytes);
- /**
- * A wrapper for js_free(p) that may delay js_free(p) invocation as a
- * performance optimization.
- * cx may be nullptr.
- */
- extern JS_PUBLIC_API(void)
- JS_free(JSContext* cx, void* p);
- /**
- * A wrapper for js_free(p) that may delay js_free(p) invocation as a
- * performance optimization as specified by the given JSFreeOp instance.
- */
- extern JS_PUBLIC_API(void)
- JS_freeop(JSFreeOp* fop, void* p);
- extern JS_PUBLIC_API(void)
- JS_updateMallocCounter(JSContext* cx, size_t nbytes);
- extern JS_PUBLIC_API(char*)
- JS_strdup(JSContext* cx, const char* s);
- /**
- * Register externally maintained GC roots.
- *
- * traceOp: the trace operation. For each root the implementation should call
- * JS::TraceEdge whenever the root contains a traceable thing.
- * data: the data argument to pass to each invocation of traceOp.
- */
- extern JS_PUBLIC_API(bool)
- JS_AddExtraGCRootsTracer(JSContext* cx, JSTraceDataOp traceOp, void* data);
- /** Undo a call to JS_AddExtraGCRootsTracer. */
- extern JS_PUBLIC_API(void)
- JS_RemoveExtraGCRootsTracer(JSContext* cx, JSTraceDataOp traceOp, void* data);
- /*
- * Garbage collector API.
- */
- extern JS_PUBLIC_API(void)
- JS_GC(JSContext* cx);
- extern JS_PUBLIC_API(void)
- JS_MaybeGC(JSContext* cx);
- extern JS_PUBLIC_API(void)
- JS_SetGCCallback(JSContext* cx, JSGCCallback cb, void* data);
- extern JS_PUBLIC_API(void)
- JS_SetObjectsTenuredCallback(JSContext* cx, JSObjectsTenuredCallback cb,
- void* data);
- extern JS_PUBLIC_API(bool)
- JS_AddFinalizeCallback(JSContext* cx, JSFinalizeCallback cb, void* data);
- extern JS_PUBLIC_API(void)
- JS_RemoveFinalizeCallback(JSContext* cx, JSFinalizeCallback cb);
- /*
- * Weak pointers and garbage collection
- *
- * Weak pointers are by their nature not marked as part of garbage collection,
- * but they may need to be updated in two cases after a GC:
- *
- * 1) Their referent was found not to be live and is about to be finalized
- * 2) Their referent has been moved by a compacting GC
- *
- * To handle this, any part of the system that maintain weak pointers to
- * JavaScript GC things must register a callback with
- * JS_(Add,Remove)WeakPointer{ZoneGroup,Compartment}Callback(). This callback
- * must then call JS_UpdateWeakPointerAfterGC() on all weak pointers it knows
- * about.
- *
- * Since sweeping is incremental, we have several callbacks to avoid repeatedly
- * having to visit all embedder structures. The WeakPointerZoneGroupCallback is
- * called once for each strongly connected group of zones, whereas the
- * WeakPointerCompartmentCallback is called once for each compartment that is
- * visited while sweeping. Structures that cannot contain references in more
- * than one compartment should sweep the relevant per-compartment structures
- * using the latter callback to minimizer per-slice overhead.
- *
- * The argument to JS_UpdateWeakPointerAfterGC() is an in-out param. If the
- * referent is about to be finalized the pointer will be set to null. If the
- * referent has been moved then the pointer will be updated to point to the new
- * location.
- *
- * Callers of this method are responsible for updating any state that is
- * dependent on the object's address. For example, if the object's address is
- * used as a key in a hashtable, then the object must be removed and
- * re-inserted with the correct hash.
- */
- extern JS_PUBLIC_API(bool)
- JS_AddWeakPointerZoneGroupCallback(JSContext* cx, JSWeakPointerZoneGroupCallback cb, void* data);
- extern JS_PUBLIC_API(void)
- JS_RemoveWeakPointerZoneGroupCallback(JSContext* cx, JSWeakPointerZoneGroupCallback cb);
- extern JS_PUBLIC_API(bool)
- JS_AddWeakPointerCompartmentCallback(JSContext* cx, JSWeakPointerCompartmentCallback cb,
- void* data);
- extern JS_PUBLIC_API(void)
- JS_RemoveWeakPointerCompartmentCallback(JSContext* cx, JSWeakPointerCompartmentCallback cb);
- extern JS_PUBLIC_API(void)
- JS_UpdateWeakPointerAfterGC(JS::Heap<JSObject*>* objp);
- extern JS_PUBLIC_API(void)
- JS_UpdateWeakPointerAfterGCUnbarriered(JSObject** objp);
- typedef enum JSGCParamKey {
- /** Maximum nominal heap before last ditch GC. */
- JSGC_MAX_BYTES = 0,
- /** Number of JS_malloc bytes before last ditch GC. */
- JSGC_MAX_MALLOC_BYTES = 1,
- /** Amount of bytes allocated by the GC. */
- JSGC_BYTES = 3,
- /** Number of times GC has been invoked. Includes both major and minor GC. */
- JSGC_NUMBER = 4,
- /** Select GC mode. */
- JSGC_MODE = 6,
- /** Number of cached empty GC chunks. */
- JSGC_UNUSED_CHUNKS = 7,
- /** Total number of allocated GC chunks. */
- JSGC_TOTAL_CHUNKS = 8,
- /** Max milliseconds to spend in an incremental GC slice. */
- JSGC_SLICE_TIME_BUDGET = 9,
- /** Maximum size the GC mark stack can grow to. */
- JSGC_MARK_STACK_LIMIT = 10,
- /**
- * GCs less than this far apart in time will be considered 'high-frequency GCs'.
- * See setGCLastBytes in jsgc.cpp.
- */
- JSGC_HIGH_FREQUENCY_TIME_LIMIT = 11,
- /** Start of dynamic heap growth. */
- JSGC_HIGH_FREQUENCY_LOW_LIMIT = 12,
- /** End of dynamic heap growth. */
- JSGC_HIGH_FREQUENCY_HIGH_LIMIT = 13,
- /** Upper bound of heap growth. */
- JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX = 14,
- /** Lower bound of heap growth. */
- JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN = 15,
- /** Heap growth for low frequency GCs. */
- JSGC_LOW_FREQUENCY_HEAP_GROWTH = 16,
- /**
- * If false, the heap growth factor is fixed at 3. If true, it is determined
- * based on whether GCs are high- or low- frequency.
- */
- JSGC_DYNAMIC_HEAP_GROWTH = 17,
- /** If true, high-frequency GCs will use a longer mark slice. */
- JSGC_DYNAMIC_MARK_SLICE = 18,
- /** Lower limit after which we limit the heap growth. */
- JSGC_ALLOCATION_THRESHOLD = 19,
- /**
- * We try to keep at least this many unused chunks in the free chunk pool at
- * all times, even after a shrinking GC.
- */
- JSGC_MIN_EMPTY_CHUNK_COUNT = 21,
- /** We never keep more than this many unused chunks in the free chunk pool. */
- JSGC_MAX_EMPTY_CHUNK_COUNT = 22,
- /** Whether compacting GC is enabled. */
- JSGC_COMPACTING_ENABLED = 23,
- /** If true, painting can trigger IGC slices. */
- JSGC_REFRESH_FRAME_SLICES_ENABLED = 24,
- } JSGCParamKey;
- extern JS_PUBLIC_API(void)
- JS_SetGCParameter(JSContext* cx, JSGCParamKey key, uint32_t value);
- extern JS_PUBLIC_API(uint32_t)
- JS_GetGCParameter(JSContext* cx, JSGCParamKey key);
- extern JS_PUBLIC_API(void)
- JS_SetGCParametersBasedOnAvailableMemory(JSContext* cx, uint32_t availMem);
- /**
- * Create a new JSString whose chars member refers to external memory, i.e.,
- * memory requiring application-specific finalization.
- */
- extern JS_PUBLIC_API(JSString*)
- JS_NewExternalString(JSContext* cx, const char16_t* chars, size_t length,
- const JSStringFinalizer* fin);
- /**
- * Return whether 'str' was created with JS_NewExternalString or
- * JS_NewExternalStringWithClosure.
- */
- extern JS_PUBLIC_API(bool)
- JS_IsExternalString(JSString* str);
- /**
- * Return the 'fin' arg passed to JS_NewExternalString.
- */
- extern JS_PUBLIC_API(const JSStringFinalizer*)
- JS_GetExternalStringFinalizer(JSString* str);
- /**
- * Set the size of the native stack that should not be exceed. To disable
- * stack size checking pass 0.
- *
- * SpiderMonkey allows for a distinction between system code (such as GCs, which
- * may incidentally be triggered by script but are not strictly performed on
- * behalf of such script), trusted script (as determined by JS_SetTrustedPrincipals),
- * and untrusted script. Each kind of code may have a different stack quota,
- * allowing embedders to keep higher-priority machinery running in the face of
- * scripted stack exhaustion by something else.
- *
- * The stack quotas for each kind of code should be monotonically descending,
- * and may be specified with this function. If 0 is passed for a given kind
- * of code, it defaults to the value of the next-highest-priority kind.
- *
- * This function may only be called immediately after the runtime is initialized
- * and before any code is executed and/or interrupts requested.
- */
- extern JS_PUBLIC_API(void)
- JS_SetNativeStackQuota(JSContext* cx, size_t systemCodeStackSize,
- size_t trustedScriptStackSize = 0,
- size_t untrustedScriptStackSize = 0);
- /************************************************************************/
- extern JS_PUBLIC_API(bool)
- JS_ValueToId(JSContext* cx, JS::HandleValue v, JS::MutableHandleId idp);
- extern JS_PUBLIC_API(bool)
- JS_StringToId(JSContext* cx, JS::HandleString s, JS::MutableHandleId idp);
- extern JS_PUBLIC_API(bool)
- JS_IdToValue(JSContext* cx, jsid id, JS::MutableHandle<JS::Value> vp);
- namespace JS {
- /**
- * Convert obj to a primitive value. On success, store the result in vp and
- * return true.
- *
- * The hint argument must be JSTYPE_STRING, JSTYPE_NUMBER, or JSTYPE_VOID (no
- * hint).
- *
- * Implements: ES6 7.1.1 ToPrimitive(input, [PreferredType]).
- */
- extern JS_PUBLIC_API(bool)
- ToPrimitive(JSContext* cx, JS::HandleObject obj, JSType hint, JS::MutableHandleValue vp);
- /**
- * If args.get(0) is one of the strings "string", "number", or "default", set
- * *result to JSTYPE_STRING, JSTYPE_NUMBER, or JSTYPE_VOID accordingly and
- * return true. Otherwise, return false with a TypeError pending.
- *
- * This can be useful in implementing a @@toPrimitive method.
- */
- extern JS_PUBLIC_API(bool)
- GetFirstArgumentAsTypeHint(JSContext* cx, CallArgs args, JSType *result);
- } /* namespace JS */
- extern JS_PUBLIC_API(bool)
- JS_PropertyStub(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
- JS::MutableHandleValue vp);
- extern JS_PUBLIC_API(bool)
- JS_StrictPropertyStub(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
- JS::MutableHandleValue vp, JS::ObjectOpResult& result);
- template<typename T>
- struct JSConstScalarSpec {
- const char* name;
- T val;
- };
- typedef JSConstScalarSpec<double> JSConstDoubleSpec;
- typedef JSConstScalarSpec<int32_t> JSConstIntegerSpec;
- struct JSJitInfo;
- /**
- * Wrapper to relace JSNative for JSPropertySpecs and JSFunctionSpecs. This will
- * allow us to pass one JSJitInfo per function with the property/function spec,
- * without additional field overhead.
- */
- typedef struct JSNativeWrapper {
- JSNative op;
- const JSJitInfo* info;
- } JSNativeWrapper;
- /*
- * Macro static initializers which make it easy to pass no JSJitInfo as part of a
- * JSPropertySpec or JSFunctionSpec.
- */
- #define JSNATIVE_WRAPPER(native) { {native, nullptr} }
- /**
- * Description of a property. JS_DefineProperties and JS_InitClass take arrays
- * of these and define many properties at once. JS_PSG, JS_PSGS and JS_PS_END
- * are helper macros for defining such arrays.
- */
- struct JSPropertySpec {
- struct SelfHostedWrapper {
- void* unused;
- const char* funname;
- };
- struct ValueWrapper {
- uintptr_t type;
- union {
- const char* string;
- int32_t int32;
- };
- };
- const char* name;
- uint8_t flags;
- union {
- struct {
- union {
- JSNativeWrapper native;
- SelfHostedWrapper selfHosted;
- } getter;
- union {
- JSNativeWrapper native;
- SelfHostedWrapper selfHosted;
- } setter;
- } accessors;
- ValueWrapper value;
- };
- bool isAccessor() const {
- return !(flags & JSPROP_INTERNAL_USE_BIT);
- }
- bool getValue(JSContext* cx, JS::MutableHandleValue value) const;
- bool isSelfHosted() const {
- MOZ_ASSERT(isAccessor());
- #ifdef DEBUG
- // Verify that our accessors match our JSPROP_GETTER flag.
- if (flags & JSPROP_GETTER)
- checkAccessorsAreSelfHosted();
- else
- checkAccessorsAreNative();
- #endif
- return (flags & JSPROP_GETTER);
- }
- static_assert(sizeof(SelfHostedWrapper) == sizeof(JSNativeWrapper),
- "JSPropertySpec::getter/setter must be compact");
- static_assert(offsetof(SelfHostedWrapper, funname) == offsetof(JSNativeWrapper, info),
- "JS_SELF_HOSTED* macros below require that "
- "SelfHostedWrapper::funname overlay "
- "JSNativeWrapper::info");
- private:
- void checkAccessorsAreNative() const {
- MOZ_ASSERT(accessors.getter.native.op);
- // We may not have a setter at all. So all we can assert here, for the
- // native case is that if we have a jitinfo for the setter then we have
- // a setter op too. This is good enough to make sure we don't have a
- // SelfHostedWrapper for the setter.
- MOZ_ASSERT_IF(accessors.setter.native.info, accessors.setter.native.op);
- }
- void checkAccessorsAreSelfHosted() const {
- MOZ_ASSERT(!accessors.getter.selfHosted.unused);
- MOZ_ASSERT(!accessors.setter.selfHosted.unused);
- }
- };
- namespace JS {
- namespace detail {
- /* NEVER DEFINED, DON'T USE. For use by JS_CAST_NATIVE_TO only. */
- inline int CheckIsNative(JSNative native);
- /* NEVER DEFINED, DON'T USE. For use by JS_CAST_STRING_TO only. */
- template<size_t N>
- inline int
- CheckIsCharacterLiteral(const char (&arr)[N]);
- /* NEVER DEFINED, DON'T USE. For use by JS_CAST_INT32_TO only. */
- inline int CheckIsInt32(int32_t value);
- /* NEVER DEFINED, DON'T USE. For use by JS_PROPERTYOP_GETTER only. */
- inline int CheckIsGetterOp(JSGetterOp op);
- /* NEVER DEFINED, DON'T USE. For use by JS_PROPERTYOP_SETTER only. */
- inline int CheckIsSetterOp(JSSetterOp op);
- } // namespace detail
- } // namespace JS
- #define JS_CAST_NATIVE_TO(v, To) \
- (static_cast<void>(sizeof(JS::detail::CheckIsNative(v))), \
- reinterpret_cast<To>(v))
- #define JS_CAST_STRING_TO(s, To) \
- (static_cast<void>(sizeof(JS::detail::CheckIsCharacterLiteral(s))), \
- reinterpret_cast<To>(s))
- #define JS_CAST_INT32_TO(s, To) \
- (static_cast<void>(sizeof(JS::detail::CheckIsInt32(s))), \
- reinterpret_cast<To>(s))
- #define JS_CHECK_ACCESSOR_FLAGS(flags) \
- (static_cast<mozilla::EnableIf<((flags) & ~(JSPROP_ENUMERATE | JSPROP_PERMANENT)) == 0>::Type>(0), \
- (flags))
- #define JS_PROPERTYOP_GETTER(v) \
- (static_cast<void>(sizeof(JS::detail::CheckIsGetterOp(v))), \
- reinterpret_cast<JSNative>(v))
- #define JS_PROPERTYOP_SETTER(v) \
- (static_cast<void>(sizeof(JS::detail::CheckIsSetterOp(v))), \
- reinterpret_cast<JSNative>(v))
- #define JS_STUBGETTER JS_PROPERTYOP_GETTER(JS_PropertyStub)
- #define JS_STUBSETTER JS_PROPERTYOP_SETTER(JS_StrictPropertyStub)
- #define JS_PS_ACCESSOR_SPEC(name, getter, setter, flags, extraFlags) \
- { name, uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | extraFlags), \
- { { getter, setter } } }
- #define JS_PS_VALUE_SPEC(name, value, flags) \
- { name, uint8_t(flags | JSPROP_INTERNAL_USE_BIT), \
- { { value, JSNATIVE_WRAPPER(nullptr) } } }
- #define SELFHOSTED_WRAPPER(name) \
- { { nullptr, JS_CAST_STRING_TO(name, const JSJitInfo*) } }
- #define STRINGVALUE_WRAPPER(value) \
- { { reinterpret_cast<JSNative>(JSVAL_TYPE_STRING), JS_CAST_STRING_TO(value, const JSJitInfo*) } }
- #define INT32VALUE_WRAPPER(value) \
- { { reinterpret_cast<JSNative>(JSVAL_TYPE_INT32), JS_CAST_INT32_TO(value, const JSJitInfo*) } }
- /*
- * JSPropertySpec uses JSNativeWrapper. These macros encapsulate the definition
- * of JSNative-backed JSPropertySpecs, by defining the JSNativeWrappers for
- * them.
- */
- #define JS_PSG(name, getter, flags) \
- JS_PS_ACCESSOR_SPEC(name, JSNATIVE_WRAPPER(getter), JSNATIVE_WRAPPER(nullptr), flags, \
- JSPROP_SHARED)
- #define JS_PSGS(name, getter, setter, flags) \
- JS_PS_ACCESSOR_SPEC(name, JSNATIVE_WRAPPER(getter), JSNATIVE_WRAPPER(setter), flags, \
- JSPROP_SHARED)
- #define JS_SELF_HOSTED_GET(name, getterName, flags) \
- JS_PS_ACCESSOR_SPEC(name, SELFHOSTED_WRAPPER(getterName), JSNATIVE_WRAPPER(nullptr), flags, \
- JSPROP_SHARED | JSPROP_GETTER)
- #define JS_SELF_HOSTED_GETSET(name, getterName, setterName, flags) \
- JS_PS_ACCESSOR_SPEC(name, SELFHOSTED_WRAPPER(getterName), SELFHOSTED_WRAPPER(setterName), \
- flags, JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER)
- #define JS_SELF_HOSTED_SYM_GET(symbol, getterName, flags) \
- JS_PS_ACCESSOR_SPEC(reinterpret_cast<const char*>(uint32_t(::JS::SymbolCode::symbol) + 1), \
- SELFHOSTED_WRAPPER(getterName), JSNATIVE_WRAPPER(nullptr), flags, \
- JSPROP_SHARED | JSPROP_GETTER)
- #define JS_STRING_PS(name, string, flags) \
- JS_PS_VALUE_SPEC(name, STRINGVALUE_WRAPPER(string), flags)
- #define JS_STRING_SYM_PS(symbol, string, flags) \
- JS_PS_VALUE_SPEC(reinterpret_cast<const char*>(uint32_t(::JS::SymbolCode::symbol) + 1), \
- STRINGVALUE_WRAPPER(string), flags)
- #define JS_INT32_PS(name, value, flags) \
- JS_PS_VALUE_SPEC(name, INT32VALUE_WRAPPER(value), flags)
- #define JS_PS_END \
- JS_PS_ACCESSOR_SPEC(nullptr, JSNATIVE_WRAPPER(nullptr), JSNATIVE_WRAPPER(nullptr), 0, 0)
- /**
- * To define a native function, set call to a JSNativeWrapper. To define a
- * self-hosted function, set selfHostedName to the name of a function
- * compiled during JSRuntime::initSelfHosting.
- */
- struct JSFunctionSpec {
- const char* name;
- JSNativeWrapper call;
- uint16_t nargs;
- uint16_t flags;
- const char* selfHostedName;
- };
- /*
- * Terminating sentinel initializer to put at the end of a JSFunctionSpec array
- * that's passed to JS_DefineFunctions or JS_InitClass.
- */
- #define JS_FS_END JS_FS(nullptr,nullptr,0,0)
- /*
- * Initializer macros for a JSFunctionSpec array element. JS_FN (whose name pays
- * homage to the old JSNative/JSFastNative split) simply adds the flag
- * JSFUN_STUB_GSOPS. JS_FNINFO allows the simple adding of
- * JSJitInfos. JS_SELF_HOSTED_FN declares a self-hosted function.
- * JS_INLINABLE_FN allows specifying an InlinableNative enum value for natives
- * inlined or specialized by the JIT. Finally JS_FNSPEC has slots for all the
- * fields.
- *
- * The _SYM variants allow defining a function with a symbol key rather than a
- * string key. For example, use JS_SYM_FN(iterator, ...) to define an
- * @@iterator method.
- */
- #define JS_FS(name,call,nargs,flags) \
- JS_FNSPEC(name, call, nullptr, nargs, flags, nullptr)
- #define JS_FN(name,call,nargs,flags) \
- JS_FNSPEC(name, call, nullptr, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr)
- #define JS_INLINABLE_FN(name,call,nargs,flags,native) \
- JS_FNSPEC(name, call, &js::jit::JitInfo_##native, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr)
- #define JS_SYM_FN(symbol,call,nargs,flags) \
- JS_SYM_FNSPEC(symbol, call, nullptr, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr)
- #define JS_FNINFO(name,call,info,nargs,flags) \
- JS_FNSPEC(name, call, info, nargs, flags, nullptr)
- #define JS_SELF_HOSTED_FN(name,selfHostedName,nargs,flags) \
- JS_FNSPEC(name, nullptr, nullptr, nargs, flags, selfHostedName)
- #define JS_SELF_HOSTED_SYM_FN(symbol, selfHostedName, nargs, flags) \
- JS_SYM_FNSPEC(symbol, nullptr, nullptr, nargs, flags, selfHostedName)
- #define JS_SYM_FNSPEC(symbol, call, info, nargs, flags, selfHostedName) \
- JS_FNSPEC(reinterpret_cast<const char*>( \
- uint32_t(::JS::SymbolCode::symbol) + 1), \
- call, info, nargs, flags, selfHostedName)
- #define JS_FNSPEC(name,call,info,nargs,flags,selfHostedName) \
- {name, {call, info}, nargs, flags, selfHostedName}
- extern JS_PUBLIC_API(JSObject*)
- JS_InitClass(JSContext* cx, JS::HandleObject obj, JS::HandleObject parent_proto,
- const JSClass* clasp, JSNative constructor, unsigned nargs,
- const JSPropertySpec* ps, const JSFunctionSpec* fs,
- const JSPropertySpec* static_ps, const JSFunctionSpec* static_fs);
- /**
- * Set up ctor.prototype = proto and proto.constructor = ctor with the
- * right property flags.
- */
- extern JS_PUBLIC_API(bool)
- JS_LinkConstructorAndPrototype(JSContext* cx, JS::Handle<JSObject*> ctor,
- JS::Handle<JSObject*> proto);
- extern JS_PUBLIC_API(const JSClass*)
- JS_GetClass(JSObject* obj);
- extern JS_PUBLIC_API(bool)
- JS_InstanceOf(JSContext* cx, JS::Handle<JSObject*> obj, const JSClass* clasp, JS::CallArgs* args);
- extern JS_PUBLIC_API(bool)
- JS_HasInstance(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<JS::Value> v, bool* bp);
- namespace JS {
- // Implementation of
- // http://www.ecma-international.org/ecma-262/6.0/#sec-ordinaryhasinstance. If
- // you're looking for the equivalent of "instanceof", you want JS_HasInstance,
- // not this function.
- extern JS_PUBLIC_API(bool)
- OrdinaryHasInstance(JSContext* cx, HandleObject objArg, HandleValue v, bool* bp);
- } // namespace JS
- extern JS_PUBLIC_API(void*)
- JS_GetPrivate(JSObject* obj);
- extern JS_PUBLIC_API(void)
- JS_SetPrivate(JSObject* obj, void* data);
- extern JS_PUBLIC_API(void*)
- JS_GetInstancePrivate(JSContext* cx, JS::Handle<JSObject*> obj, const JSClass* clasp,
- JS::CallArgs* args);
- extern JS_PUBLIC_API(JSObject*)
- JS_GetConstructor(JSContext* cx, JS::Handle<JSObject*> proto);
- namespace JS {
- enum ZoneSpecifier {
- FreshZone = 0,
- SystemZone = 1
- };
- /**
- * CompartmentCreationOptions specifies options relevant to creating a new
- * compartment, that are either immutable characteristics of that compartment
- * or that are discarded after the compartment has been created.
- *
- * Access to these options on an existing compartment is read-only: if you
- * need particular selections, make them before you create the compartment.
- */
- class JS_PUBLIC_API(CompartmentCreationOptions)
- {
- public:
- CompartmentCreationOptions()
- : addonId_(nullptr),
- traceGlobal_(nullptr),
- invisibleToDebugger_(false),
- mergeable_(false),
- preserveJitCode_(false),
- cloneSingletons_(false),
- sharedMemoryAndAtomics_(false),
- secureContext_(false)
- {
- zone_.spec = JS::FreshZone;
- }
- // A null add-on ID means that the compartment is not associated with an
- // add-on.
- JSAddonId* addonIdOrNull() const { return addonId_; }
- CompartmentCreationOptions& setAddonId(JSAddonId* id) {
- addonId_ = id;
- return *this;
- }
- JSTraceOp getTrace() const {
- return traceGlobal_;
- }
- CompartmentCreationOptions& setTrace(JSTraceOp op) {
- traceGlobal_ = op;
- return *this;
- }
- void* zonePointer() const {
- MOZ_ASSERT(uintptr_t(zone_.pointer) > uintptr_t(JS::SystemZone));
- return zone_.pointer;
- }
- ZoneSpecifier zoneSpecifier() const { return zone_.spec; }
- CompartmentCreationOptions& setZone(ZoneSpecifier spec);
- CompartmentCreationOptions& setSameZoneAs(JSObject* obj);
- // Certain scopes (i.e. XBL compilation scopes) are implementation details
- // of the embedding, and references to them should never leak out to script.
- // This flag causes the this compartment to skip firing onNewGlobalObject
- // and makes addDebuggee a no-op for this global.
- bool invisibleToDebugger() const { return invisibleToDebugger_; }
- CompartmentCreationOptions& setInvisibleToDebugger(bool flag) {
- invisibleToDebugger_ = flag;
- return *this;
- }
- // Compartments used for off-thread compilation have their contents merged
- // into a target compartment when the compilation is finished. This is only
- // allowed if this flag is set. The invisibleToDebugger flag must also be
- // set for such compartments.
- bool mergeable() const { return mergeable_; }
- CompartmentCreationOptions& setMergeable(bool flag) {
- mergeable_ = flag;
- return *this;
- }
- // Determines whether this compartment should preserve JIT code on
- // non-shrinking GCs.
- bool preserveJitCode() const { return preserveJitCode_; }
- CompartmentCreationOptions& setPreserveJitCode(bool flag) {
- preserveJitCode_ = flag;
- return *this;
- }
- bool cloneSingletons() const { return cloneSingletons_; }
- CompartmentCreationOptions& setCloneSingletons(bool flag) {
- cloneSingletons_ = flag;
- return *this;
- }
- bool getSharedMemoryAndAtomicsEnabled() const;
- CompartmentCreationOptions& setSharedMemoryAndAtomicsEnabled(bool flag);
- // This flag doesn't affect JS engine behavior. It is used by Gecko to
- // mark whether content windows and workers are "Secure Context"s. See
- // https://w3c.github.io/webappsec-secure-contexts/
- // https://bugzilla.mozilla.org/show_bug.cgi?id=1162772#c34
- bool secureContext() const { return secureContext_; }
- CompartmentCreationOptions& setSecureContext(bool flag) {
- secureContext_ = flag;
- return *this;
- }
- private:
- JSAddonId* addonId_;
- JSTraceOp traceGlobal_;
- union {
- ZoneSpecifier spec;
- void* pointer; // js::Zone* is not exposed in the API.
- } zone_;
- bool invisibleToDebugger_;
- bool mergeable_;
- bool preserveJitCode_;
- bool cloneSingletons_;
- bool sharedMemoryAndAtomics_;
- bool secureContext_;
- };
- /**
- * CompartmentBehaviors specifies behaviors of a compartment that can be
- * changed after the compartment's been created.
- */
- class JS_PUBLIC_API(CompartmentBehaviors)
- {
- public:
- class Override {
- public:
- Override() : mode_(Default) {}
- bool get(bool defaultValue) const {
- if (mode_ == Default)
- return defaultValue;
- return mode_ == ForceTrue;
- }
- void set(bool overrideValue) {
- mode_ = overrideValue ? ForceTrue : ForceFalse;
- }
- void reset() {
- mode_ = Default;
- }
- private:
- enum Mode {
- Default,
- ForceTrue,
- ForceFalse
- };
- Mode mode_;
- };
- CompartmentBehaviors()
- : version_(JSVERSION_UNKNOWN)
- , discardSource_(false)
- , disableLazyParsing_(false)
- , singletonsAsTemplates_(true)
- {
- }
- JSVersion version() const { return version_; }
- CompartmentBehaviors& setVersion(JSVersion aVersion) {
- MOZ_ASSERT(aVersion != JSVERSION_UNKNOWN);
- version_ = aVersion;
- return *this;
- }
- // For certain globals, we know enough about the code that will run in them
- // that we can discard script source entirely.
- bool discardSource() const { return discardSource_; }
- CompartmentBehaviors& setDiscardSource(bool flag) {
- discardSource_ = flag;
- return *this;
- }
- bool disableLazyParsing() const { return disableLazyParsing_; }
- CompartmentBehaviors& setDisableLazyParsing(bool flag) {
- disableLazyParsing_ = flag;
- return *this;
- }
- bool extraWarnings(JSContext* cx) const;
- Override& extraWarningsOverride() { return extraWarningsOverride_; }
- bool getSingletonsAsTemplates() const {
- return singletonsAsTemplates_;
- }
- CompartmentBehaviors& setSingletonsAsValues() {
- singletonsAsTemplates_ = false;
- return *this;
- }
- private:
- JSVersion version_;
- bool discardSource_;
- bool disableLazyParsing_;
- Override extraWarningsOverride_;
- // To XDR singletons, we need to ensure that all singletons are all used as
- // templates, by making JSOP_OBJECT return a clone of the JSScript
- // singleton, instead of returning the value which is baked in the JSScript.
- bool singletonsAsTemplates_;
- };
- /**
- * CompartmentOptions specifies compartment characteristics: both those that
- * can't be changed on a compartment once it's been created
- * (CompartmentCreationOptions), and those that can be changed on an existing
- * compartment (CompartmentBehaviors).
- */
- class JS_PUBLIC_API(CompartmentOptions)
- {
- public:
- explicit CompartmentOptions()
- : creationOptions_(),
- behaviors_()
- {}
- CompartmentOptions(const CompartmentCreationOptions& compartmentCreation,
- const CompartmentBehaviors& compartmentBehaviors)
- : creationOptions_(compartmentCreation),
- behaviors_(compartmentBehaviors)
- {}
- // CompartmentCreationOptions specify fundamental compartment
- // characteristics that must be specified when the compartment is created,
- // that can't be changed after the compartment is created.
- CompartmentCreationOptions& creationOptions() {
- return creationOptions_;
- }
- const CompartmentCreationOptions& creationOptions() const {
- return creationOptions_;
- }
- // CompartmentBehaviors specify compartment characteristics that can be
- // changed after the compartment is created.
- CompartmentBehaviors& behaviors() {
- return behaviors_;
- }
- const CompartmentBehaviors& behaviors() const {
- return behaviors_;
- }
- private:
- CompartmentCreationOptions creationOptions_;
- CompartmentBehaviors behaviors_;
- };
- JS_PUBLIC_API(const CompartmentCreationOptions&)
- CompartmentCreationOptionsRef(JSCompartment* compartment);
- JS_PUBLIC_API(const CompartmentCreationOptions&)
- CompartmentCreationOptionsRef(JSObject* obj);
- JS_PUBLIC_API(const CompartmentCreationOptions&)
- CompartmentCreationOptionsRef(JSContext* cx);
- JS_PUBLIC_API(CompartmentBehaviors&)
- CompartmentBehaviorsRef(JSCompartment* compartment);
- JS_PUBLIC_API(CompartmentBehaviors&)
- CompartmentBehaviorsRef(JSObject* obj);
- JS_PUBLIC_API(CompartmentBehaviors&)
- CompartmentBehaviorsRef(JSContext* cx);
- /**
- * During global creation, we fire notifications to callbacks registered
- * via the Debugger API. These callbacks are arbitrary script, and can touch
- * the global in arbitrary ways. When that happens, the global should not be
- * in a half-baked state. But this creates a problem for consumers that need
- * to set slots on the global to put it in a consistent state.
- *
- * This API provides a way for consumers to set slots atomically (immediately
- * after the global is created), before any debugger hooks are fired. It's
- * unfortunately on the clunky side, but that's the way the cookie crumbles.
- *
- * If callers have no additional state on the global to set up, they may pass
- * |FireOnNewGlobalHook| to JS_NewGlobalObject, which causes that function to
- * fire the hook as its final act before returning. Otherwise, callers should
- * pass |DontFireOnNewGlobalHook|, which means that they are responsible for
- * invoking JS_FireOnNewGlobalObject upon successfully creating the global. If
- * an error occurs and the operation aborts, callers should skip firing the
- * hook. But otherwise, callers must take care to fire the hook exactly once
- * before compiling any script in the global's scope (we have assertions in
- * place to enforce this). This lets us be sure that debugger clients never miss
- * breakpoints.
- */
- enum OnNewGlobalHookOption {
- FireOnNewGlobalHook,
- DontFireOnNewGlobalHook
- };
- } /* namespace JS */
- extern JS_PUBLIC_API(JSObject*)
- JS_NewGlobalObject(JSContext* cx, const JSClass* clasp, JSPrincipals* principals,
- JS::OnNewGlobalHookOption hookOption,
- const JS::CompartmentOptions& options);
- /**
- * Spidermonkey does not have a good way of keeping track of what compartments should be marked on
- * their own. We can mark the roots unconditionally, but marking GC things only relevant in live
- * compartments is hard. To mitigate this, we create a static trace hook, installed on each global
- * object, from which we can be sure the compartment is relevant, and mark it.
- *
- * It is still possible to specify custom trace hooks for global object classes. They can be
- * provided via the CompartmentOptions passed to JS_NewGlobalObject.
- */
- extern JS_PUBLIC_API(void)
- JS_GlobalObjectTraceHook(JSTracer* trc, JSObject* global);
- extern JS_PUBLIC_API(void)
- JS_FireOnNewGlobalObject(JSContext* cx, JS::HandleObject global);
- extern JS_PUBLIC_API(JSObject*)
- JS_NewObject(JSContext* cx, const JSClass* clasp);
- extern JS_PUBLIC_API(bool)
- JS_IsNative(JSObject* obj);
- /**
- * Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a default
- * proto. If proto is nullptr, the JS object will have `null` as [[Prototype]].
- */
- extern JS_PUBLIC_API(JSObject*)
- JS_NewObjectWithGivenProto(JSContext* cx, const JSClass* clasp, JS::Handle<JSObject*> proto);
- /** Creates a new plain object, like `new Object()`, with Object.prototype as [[Prototype]]. */
- extern JS_PUBLIC_API(JSObject*)
- JS_NewPlainObject(JSContext* cx);
- /**
- * Freeze obj, and all objects it refers to, recursively. This will not recurse
- * through non-extensible objects, on the assumption that those are already
- * deep-frozen.
- */
- extern JS_PUBLIC_API(bool)
- JS_DeepFreezeObject(JSContext* cx, JS::Handle<JSObject*> obj);
- /**
- * Freezes an object; see ES5's Object.freeze(obj) method.
- */
- extern JS_PUBLIC_API(bool)
- JS_FreezeObject(JSContext* cx, JS::Handle<JSObject*> obj);
- /*** Property descriptors ************************************************************************/
- namespace JS {
- struct JS_PUBLIC_API(PropertyDescriptor) {
- JSObject* obj;
- unsigned attrs;
- JSGetterOp getter;
- JSSetterOp setter;
- JS::Value value;
- PropertyDescriptor()
- : obj(nullptr), attrs(0), getter(nullptr), setter(nullptr), value(JS::UndefinedValue())
- {}
- static void trace(PropertyDescriptor* self, JSTracer* trc) { self->trace(trc); }
- void trace(JSTracer* trc);
- };
- template <typename Outer>
- class PropertyDescriptorOperations
- {
- const PropertyDescriptor& desc() const { return static_cast<const Outer*>(this)->get(); }
- bool has(unsigned bit) const {
- MOZ_ASSERT(bit != 0);
- MOZ_ASSERT((bit & (bit - 1)) == 0); // only a single bit
- return (desc().attrs & bit) != 0;
- }
- bool hasAny(unsigned bits) const {
- return (desc().attrs & bits) != 0;
- }
- bool hasAll(unsigned bits) const {
- return (desc().attrs & bits) == bits;
- }
- // Non-API attributes bit used internally for arguments objects.
- enum { SHADOWABLE = JSPROP_INTERNAL_USE_BIT };
- public:
- // Descriptors with JSGetterOp/JSSetterOp are considered data
- // descriptors. It's complicated.
- bool isAccessorDescriptor() const { return hasAny(JSPROP_GETTER | JSPROP_SETTER); }
- bool isGenericDescriptor() const {
- return (desc().attrs&
- (JSPROP_GETTER | JSPROP_SETTER | JSPROP_IGNORE_READONLY | JSPROP_IGNORE_VALUE)) ==
- (JSPROP_IGNORE_READONLY | JSPROP_IGNORE_VALUE);
- }
- bool isDataDescriptor() const { return !isAccessorDescriptor() && !isGenericDescriptor(); }
- bool hasConfigurable() const { return !has(JSPROP_IGNORE_PERMANENT); }
- bool configurable() const { MOZ_ASSERT(hasConfigurable()); return !has(JSPROP_PERMANENT); }
- bool hasEnumerable() const { return !has(JSPROP_IGNORE_ENUMERATE); }
- bool enumerable() const { MOZ_ASSERT(hasEnumerable()); return has(JSPROP_ENUMERATE); }
- bool hasValue() const { return !isAccessorDescriptor() && !has(JSPROP_IGNORE_VALUE); }
- JS::HandleValue value() const {
- return JS::HandleValue::fromMarkedLocation(&desc().value);
- }
- bool hasWritable() const { return !isAccessorDescriptor() && !has(JSPROP_IGNORE_READONLY); }
- bool writable() const { MOZ_ASSERT(hasWritable()); return !has(JSPROP_READONLY); }
- bool hasGetterObject() const { return has(JSPROP_GETTER); }
- JS::HandleObject getterObject() const {
- MOZ_ASSERT(hasGetterObject());
- return JS::HandleObject::fromMarkedLocation(
- reinterpret_cast<JSObject* const*>(&desc().getter));
- }
- bool hasSetterObject() const { return has(JSPROP_SETTER); }
- JS::HandleObject setterObject() const {
- MOZ_ASSERT(hasSetterObject());
- return JS::HandleObject::fromMarkedLocation(
- reinterpret_cast<JSObject* const*>(&desc().setter));
- }
- bool hasGetterOrSetter() const { return desc().getter || desc().setter; }
- bool isShared() const { return has(JSPROP_SHARED); }
- JS::HandleObject object() const {
- return JS::HandleObject::fromMarkedLocation(&desc().obj);
- }
- unsigned attributes() const { return desc().attrs; }
- JSGetterOp getter() const { return desc().getter; }
- JSSetterOp setter() const { return desc().setter; }
- void assertValid() const {
- #ifdef DEBUG
- MOZ_ASSERT((attributes() & ~(JSPROP_ENUMERATE | JSPROP_IGNORE_ENUMERATE |
- JSPROP_PERMANENT | JSPROP_IGNORE_PERMANENT |
- JSPROP_READONLY | JSPROP_IGNORE_READONLY |
- JSPROP_IGNORE_VALUE |
- JSPROP_GETTER |
- JSPROP_SETTER |
- JSPROP_SHARED |
- JSPROP_REDEFINE_NONCONFIGURABLE |
- JSPROP_RESOLVING |
- SHADOWABLE)) == 0);
- MOZ_ASSERT(!hasAll(JSPROP_IGNORE_ENUMERATE | JSPROP_ENUMERATE));
- MOZ_ASSERT(!hasAll(JSPROP_IGNORE_PERMANENT | JSPROP_PERMANENT));
- if (isAccessorDescriptor()) {
- MOZ_ASSERT(has(JSPROP_SHARED));
- MOZ_ASSERT(!has(JSPROP_READONLY));
- MOZ_ASSERT(!has(JSPROP_IGNORE_READONLY));
- MOZ_ASSERT(!has(JSPROP_IGNORE_VALUE));
- MOZ_ASSERT(!has(SHADOWABLE));
- MOZ_ASSERT(value().isUndefined());
- MOZ_ASSERT_IF(!has(JSPROP_GETTER), !getter());
- MOZ_ASSERT_IF(!has(JSPROP_SETTER), !setter());
- } else {
- MOZ_ASSERT(!hasAll(JSPROP_IGNORE_READONLY | JSPROP_READONLY));
- MOZ_ASSERT_IF(has(JSPROP_IGNORE_VALUE), value().isUndefined());
- }
- MOZ_ASSERT(getter() != JS_PropertyStub);
- MOZ_ASSERT(setter() != JS_StrictPropertyStub);
- MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_ENUMERATE));
- MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_PERMANENT));
- MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_READONLY));
- MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_VALUE));
- MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_REDEFINE_NONCONFIGURABLE));
- #endif
- }
- void assertComplete() const {
- #ifdef DEBUG
- assertValid();
- MOZ_ASSERT((attributes() & ~(JSPROP_ENUMERATE |
- JSPROP_PERMANENT |
- JSPROP_READONLY |
- JSPROP_GETTER |
- JSPROP_SETTER |
- JSPROP_SHARED |
- JSPROP_REDEFINE_NONCONFIGURABLE |
- JSPROP_RESOLVING |
- SHADOWABLE)) == 0);
- MOZ_ASSERT_IF(isAccessorDescriptor(), has(JSPROP_GETTER) && has(JSPROP_SETTER));
- #endif
- }
- void assertCompleteIfFound() const {
- #ifdef DEBUG
- if (object())
- assertComplete();
- #endif
- }
- };
- template <typename Outer>
- class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations<Outer>
- {
- PropertyDescriptor& desc() { return static_cast<Outer*>(this)->get(); }
- public:
- void clear() {
- object().set(nullptr);
- setAttributes(0);
- setGetter(nullptr);
- setSetter(nullptr);
- value().setUndefined();
- }
- void initFields(HandleObject obj, HandleValue v, unsigned attrs,
- JSGetterOp getterOp, JSSetterOp setterOp) {
- MOZ_ASSERT(getterOp != JS_PropertyStub);
- MOZ_ASSERT(setterOp != JS_StrictPropertyStub);
- object().set(obj);
- value().set(v);
- setAttributes(attrs);
- setGetter(getterOp);
- setSetter(setterOp);
- }
- void assign(PropertyDescriptor& other) {
- object().set(other.obj);
- setAttributes(other.attrs);
- setGetter(other.getter);
- setSetter(other.setter);
- value().set(other.value);
- }
- void setDataDescriptor(HandleValue v, unsigned attrs) {
- MOZ_ASSERT((attrs & ~(JSPROP_ENUMERATE |
- JSPROP_PERMANENT |
- JSPROP_READONLY |
- JSPROP_IGNORE_ENUMERATE |
- JSPROP_IGNORE_PERMANENT |
- JSPROP_IGNORE_READONLY)) == 0);
- object().set(nullptr);
- setAttributes(attrs);
- setGetter(nullptr);
- setSetter(nullptr);
- value().set(v);
- }
- JS::MutableHandleObject object() {
- return JS::MutableHandleObject::fromMarkedLocation(&desc().obj);
- }
- unsigned& attributesRef() { return desc().attrs; }
- JSGetterOp& getter() { return desc().getter; }
- JSSetterOp& setter() { return desc().setter; }
- JS::MutableHandleValue value() {
- return JS::MutableHandleValue::fromMarkedLocation(&desc().value);
- }
- void setValue(JS::HandleValue v) {
- MOZ_ASSERT(!(desc().attrs & (JSPROP_GETTER | JSPROP_SETTER)));
- attributesRef() &= ~JSPROP_IGNORE_VALUE;
- value().set(v);
- }
- void setConfigurable(bool configurable) {
- setAttributes((desc().attrs & ~(JSPROP_IGNORE_PERMANENT | JSPROP_PERMANENT)) |
- (configurable ? 0 : JSPROP_PERMANENT));
- }
- void setEnumerable(bool enumerable) {
- setAttributes((desc().attrs & ~(JSPROP_IGNORE_ENUMERATE | JSPROP_ENUMERATE)) |
- (enumerable ? JSPROP_ENUMERATE : 0));
- }
- void setWritable(bool writable) {
- MOZ_ASSERT(!(desc().attrs & (JSPROP_GETTER | JSPROP_SETTER)));
- setAttributes((desc().attrs & ~(JSPROP_IGNORE_READONLY | JSPROP_READONLY)) |
- (writable ? 0 : JSPROP_READONLY));
- }
- void setAttributes(unsigned attrs) { desc().attrs = attrs; }
- void setGetter(JSGetterOp op) {
- MOZ_ASSERT(op != JS_PropertyStub);
- desc().getter = op;
- }
- void setSetter(JSSetterOp op) {
- MOZ_ASSERT(op != JS_StrictPropertyStub);
- desc().setter = op;
- }
- void setGetterObject(JSObject* obj) {
- desc().getter = reinterpret_cast<JSGetterOp>(obj);
- desc().attrs &= ~(JSPROP_IGNORE_VALUE | JSPROP_IGNORE_READONLY | JSPROP_READONLY);
- desc().attrs |= JSPROP_GETTER | JSPROP_SHARED;
- }
- void setSetterObject(JSObject* obj) {
- desc().setter = reinterpret_cast<JSSetterOp>(obj);
- desc().attrs &= ~(JSPROP_IGNORE_VALUE | JSPROP_IGNORE_READONLY | JSPROP_READONLY);
- desc().attrs |= JSPROP_SETTER | JSPROP_SHARED;
- }
- JS::MutableHandleObject getterObject() {
- MOZ_ASSERT(this->hasGetterObject());
- return JS::MutableHandleObject::fromMarkedLocation(
- reinterpret_cast<JSObject**>(&desc().getter));
- }
- JS::MutableHandleObject setterObject() {
- MOZ_ASSERT(this->hasSetterObject());
- return JS::MutableHandleObject::fromMarkedLocation(
- reinterpret_cast<JSObject**>(&desc().setter));
- }
- };
- } /* namespace JS */
- namespace js {
- template <>
- class RootedBase<JS::PropertyDescriptor>
- : public JS::MutablePropertyDescriptorOperations<JS::Rooted<JS::PropertyDescriptor>>
- {};
- template <>
- class HandleBase<JS::PropertyDescriptor>
- : public JS::PropertyDescriptorOperations<JS::Handle<JS::PropertyDescriptor>>
- {};
- template <>
- class MutableHandleBase<JS::PropertyDescriptor>
- : public JS::MutablePropertyDescriptorOperations<JS::MutableHandle<JS::PropertyDescriptor>>
- {};
- } /* namespace js */
- namespace JS {
- extern JS_PUBLIC_API(bool)
- ObjectToCompletePropertyDescriptor(JSContext* cx,
- JS::HandleObject obj,
- JS::HandleValue descriptor,
- JS::MutableHandle<PropertyDescriptor> desc);
- /*
- * ES6 draft rev 32 (2015 Feb 2) 6.2.4.4 FromPropertyDescriptor(Desc).
- *
- * If desc.object() is null, then vp is set to undefined.
- */
- extern JS_PUBLIC_API(bool)
- FromPropertyDescriptor(JSContext* cx,
- JS::Handle<JS::PropertyDescriptor> desc,
- JS::MutableHandleValue vp);
- } // namespace JS
- /*** Standard internal methods ********************************************************************
- *
- * The functions below are the fundamental operations on objects.
- *
- * ES6 specifies 14 internal methods that define how objects behave. The
- * standard is actually quite good on this topic, though you may have to read
- * it a few times. See ES6 sections 6.1.7.2 and 6.1.7.3.
- *
- * When 'obj' is an ordinary object, these functions have boring standard
- * behavior as specified by ES6 section 9.1; see the section about internal
- * methods in js/src/vm/NativeObject.h.
- *
- * Proxies override the behavior of internal methods. So when 'obj' is a proxy,
- * any one of the functions below could do just about anything. See
- * js/public/Proxy.h.
- */
- /**
- * Get the prototype of obj, storing it in result.
- *
- * Implements: ES6 [[GetPrototypeOf]] internal method.
- */
- extern JS_PUBLIC_API(bool)
- JS_GetPrototype(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject result);
- /**
- * If |obj| (underneath any functionally-transparent wrapper proxies) has as
- * its [[GetPrototypeOf]] trap the ordinary [[GetPrototypeOf]] behavior defined
- * for ordinary objects, set |*isOrdinary = true| and store |obj|'s prototype
- * in |result|. Otherwise set |*isOrdinary = false|. In case of error, both
- * outparams have unspecified value.
- */
- extern JS_PUBLIC_API(bool)
- JS_GetPrototypeIfOrdinary(JSContext* cx, JS::HandleObject obj, bool* isOrdinary,
- JS::MutableHandleObject result);
- /**
- * Change the prototype of obj.
- *
- * Implements: ES6 [[SetPrototypeOf]] internal method.
- *
- * In cases where ES6 [[SetPrototypeOf]] returns false without an exception,
- * JS_SetPrototype throws a TypeError and returns false.
- *
- * Performance warning: JS_SetPrototype is very bad for performance. It may
- * cause compiled jit-code to be invalidated. It also causes not only obj but
- * all other objects in the same "group" as obj to be permanently deoptimized.
- * It's better to create the object with the right prototype from the start.
- */
- extern JS_PUBLIC_API(bool)
- JS_SetPrototype(JSContext* cx, JS::HandleObject obj, JS::HandleObject proto);
- /**
- * Determine whether obj is extensible. Extensible objects can have new
- * properties defined on them. Inextensible objects can't, and their
- * [[Prototype]] slot is fixed as well.
- *
- * Implements: ES6 [[IsExtensible]] internal method.
- */
- extern JS_PUBLIC_API(bool)
- JS_IsExtensible(JSContext* cx, JS::HandleObject obj, bool* extensible);
- /**
- * Attempt to make |obj| non-extensible.
- *
- * Not all failures are treated as errors. See the comment on
- * JS::ObjectOpResult in js/public/Class.h.
- *
- * Implements: ES6 [[PreventExtensions]] internal method.
- */
- extern JS_PUBLIC_API(bool)
- JS_PreventExtensions(JSContext* cx, JS::HandleObject obj, JS::ObjectOpResult& result);
- /**
- * Attempt to make the [[Prototype]] of |obj| immutable, such that any attempt
- * to modify it will fail. If an error occurs during the attempt, return false
- * (with a pending exception set, depending upon the nature of the error). If
- * no error occurs, return true with |*succeeded| set to indicate whether the
- * attempt successfully made the [[Prototype]] immutable.
- *
- * This is a nonstandard internal method.
- */
- extern JS_PUBLIC_API(bool)
- JS_SetImmutablePrototype(JSContext* cx, JS::HandleObject obj, bool* succeeded);
- /**
- * Get a description of one of obj's own properties. If no such property exists
- * on obj, return true with desc.object() set to null.
- *
- * Implements: ES6 [[GetOwnProperty]] internal method.
- */
- extern JS_PUBLIC_API(bool)
- JS_GetOwnPropertyDescriptorById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
- JS::MutableHandle<JS::PropertyDescriptor> desc);
- extern JS_PUBLIC_API(bool)
- JS_GetOwnPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char* name,
- JS::MutableHandle<JS::PropertyDescriptor> desc);
- extern JS_PUBLIC_API(bool)
- JS_GetOwnUCPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char16_t* name,
- JS::MutableHandle<JS::PropertyDescriptor> desc);
- /**
- * Like JS_GetOwnPropertyDescriptorById, but also searches the prototype chain
- * if no own property is found directly on obj. The object on which the
- * property is found is returned in desc.object(). If the property is not found
- * on the prototype chain, this returns true with desc.object() set to null.
- */
- extern JS_PUBLIC_API(bool)
- JS_GetPropertyDescriptorById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
- JS::MutableHandle<JS::PropertyDescriptor> desc);
- extern JS_PUBLIC_API(bool)
- JS_GetPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char* name,
- JS::MutableHandle<JS::PropertyDescriptor> desc);
- /**
- * Define a property on obj.
- *
- * This function uses JS::ObjectOpResult to indicate conditions that ES6
- * specifies as non-error failures. This is inconvenient at best, so use this
- * function only if you are implementing a proxy handler's defineProperty()
- * method. For all other purposes, use one of the many DefineProperty functions
- * below that throw an exception in all failure cases.
- *
- * Implements: ES6 [[DefineOwnProperty]] internal method.
- */
- extern JS_PUBLIC_API(bool)
- JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
- JS::Handle<JS::PropertyDescriptor> desc,
- JS::ObjectOpResult& result);
- /**
- * Define a property on obj, throwing a TypeError if the attempt fails.
- * This is the C++ equivalent of `Object.defineProperty(obj, id, desc)`.
- */
- extern JS_PUBLIC_API(bool)
- JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
- JS::Handle<JS::PropertyDescriptor> desc);
- extern JS_PUBLIC_API(bool)
- JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value,
- unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject value,
- unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleString value,
- unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, int32_t value,
- unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, uint32_t value,
- unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, double value,
- unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleValue value,
- unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleObject value,
- unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleString value,
- unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, int32_t value,
- unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, uint32_t value,
- unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, double value,
- unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
- JS::Handle<JS::PropertyDescriptor> desc,
- JS::ObjectOpResult& result);
- extern JS_PUBLIC_API(bool)
- JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
- JS::Handle<JS::PropertyDescriptor> desc);
- extern JS_PUBLIC_API(bool)
- JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
- JS::HandleValue value, unsigned attrs,
- JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
- JS::HandleObject value, unsigned attrs,
- JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
- JS::HandleString value, unsigned attrs,
- JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
- int32_t value, unsigned attrs,
- JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
- uint32_t value, unsigned attrs,
- JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
- double value, unsigned attrs,
- JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleValue value,
- unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleObject value,
- unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleString value,
- unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, int32_t value,
- unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, uint32_t value,
- unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
- extern JS_PUBLIC_API(bool)
- JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, double value,
- unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
- /**
- * Compute the expression `id in obj`.
- *
- * If obj has an own or inherited property obj[id], set *foundp = true and
- * return true. If not, set *foundp = false and return true. On error, return
- * false with an exception pending.
- *
- * Implements: ES6 [[Has]] internal method.
- */
- extern JS_PUBLIC_API(bool)
- JS_HasPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp);
- extern JS_PUBLIC_API(bool)
- JS_HasProperty(JSContext* cx, JS::HandleObject obj, const char* name, bool* foundp);
- extern JS_PUBLIC_API(bool)
- JS_HasUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
- bool* vp);
- extern JS_PUBLIC_API(bool)
- JS_HasElement(JSContext* cx, JS::HandleObject obj, uint32_t index, bool* foundp);
- /**
- * Determine whether obj has an own property with the key `id`.
- *
- * Implements: ES6 7.3.11 HasOwnProperty(O, P).
- */
- extern JS_PUBLIC_API(bool)
- JS_HasOwnPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp);
- extern JS_PUBLIC_API(bool)
- JS_HasOwnProperty(JSContext* cx, JS::HandleObject obj, const char* name, bool* foundp);
- /**
- * Get the value of the property `obj[id]`, or undefined if no such property
- * exists. This is the C++ equivalent of `vp = Reflect.get(obj, id, receiver)`.
- *
- * Most callers don't need the `receiver` argument. Consider using
- * JS_GetProperty instead. (But if you're implementing a proxy handler's set()
- * method, it's often correct to call this function and pass the receiver
- * through.)
- *
- * Implements: ES6 [[Get]] internal method.
- */
- extern JS_PUBLIC_API(bool)
- JS_ForwardGetPropertyTo(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
- JS::HandleValue receiver, JS::MutableHandleValue vp);
- extern JS_PUBLIC_API(bool)
- JS_ForwardGetElementTo(JSContext* cx, JS::HandleObject obj, uint32_t index,
- JS::HandleObject receiver, JS::MutableHandleValue vp);
- /**
- * Get the value of the property `obj[id]`, or undefined if no such property
- * exists. The result is stored in vp.
- *
- * Implements: ES6 7.3.1 Get(O, P).
- */
- extern JS_PUBLIC_API(bool)
- JS_GetPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
- JS::MutableHandleValue vp);
- extern JS_PUBLIC_API(bool)
- JS_GetProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::MutableHandleValue vp);
- extern JS_PUBLIC_API(bool)
- JS_GetUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
- JS::MutableHandleValue vp);
- extern JS_PUBLIC_API(bool)
- JS_GetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp);
- /**
- * Perform the same property assignment as `Reflect.set(obj, id, v, receiver)`.
- *
- * This function has a `receiver` argument that most callers don't need.
- * Consider using JS_SetProperty instead.
- *
- * Implements: ES6 [[Set]] internal method.
- */
- extern JS_PUBLIC_API(bool)
- JS_ForwardSetPropertyTo(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v,
- JS::HandleValue receiver, JS::ObjectOpResult& result);
- /**
- * Perform the assignment `obj[id] = v`.
- *
- * This function performs non-strict assignment, so if the property is
- * read-only, nothing happens and no error is thrown.
- */
- extern JS_PUBLIC_API(bool)
- JS_SetPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v);
- extern JS_PUBLIC_API(bool)
- JS_SetProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleValue v);
- extern JS_PUBLIC_API(bool)
- JS_SetUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
- JS::HandleValue v);
- extern JS_PUBLIC_API(bool)
- JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleValue v);
- extern JS_PUBLIC_API(bool)
- JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleObject v);
- extern JS_PUBLIC_API(bool)
- JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleString v);
- extern JS_PUBLIC_API(bool)
- JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, int32_t v);
- extern JS_PUBLIC_API(bool)
- JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, uint32_t v);
- extern JS_PUBLIC_API(bool)
- JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, double v);
- /**
- * Delete a property. This is the C++ equivalent of
- * `result = Reflect.deleteProperty(obj, id)`.
- *
- * This function has a `result` out parameter that most callers don't need.
- * Unless you can pass through an ObjectOpResult provided by your caller, it's
- * probably best to use the JS_DeletePropertyById signature with just 3
- * arguments.
- *
- * Implements: ES6 [[Delete]] internal method.
- */
- extern JS_PUBLIC_API(bool)
- JS_DeletePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
- JS::ObjectOpResult& result);
- extern JS_PUBLIC_API(bool)
- JS_DeleteProperty(JSContext* cx, JS::HandleObject obj, const char* name,
- JS::ObjectOpResult& result);
- extern JS_PUBLIC_API(bool)
- JS_DeleteUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
- JS::ObjectOpResult& result);
- extern JS_PUBLIC_API(bool)
- JS_DeleteElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::ObjectOpResult& result);
- /**
- * Delete a property, ignoring strict failures. This is the C++ equivalent of
- * the JS `delete obj[id]` in non-strict mode code.
- */
- extern JS_PUBLIC_API(bool)
- JS_DeletePropertyById(JSContext* cx, JS::HandleObject obj, jsid id);
- extern JS_PUBLIC_API(bool)
- JS_DeleteProperty(JSContext* cx, JS::HandleObject obj, const char* name);
- extern JS_PUBLIC_API(bool)
- JS_DeleteElement(JSContext* cx, JS::HandleObject obj, uint32_t index);
- /**
- * Get an array of the non-symbol enumerable properties of obj.
- * This function is roughly equivalent to:
- *
- * var result = [];
- * for (key in obj)
- * result.push(key);
- * return result;
- *
- * This is the closest thing we currently have to the ES6 [[Enumerate]]
- * internal method.
- *
- * The array of ids returned by JS_Enumerate must be rooted to protect its
- * contents from garbage collection. Use JS::Rooted<JS::IdVector>.
- */
- extern JS_PUBLIC_API(bool)
- JS_Enumerate(JSContext* cx, JS::HandleObject obj, JS::MutableHandle<JS::IdVector> props);
- /*
- * API for determining callability and constructability. [[Call]] and
- * [[Construct]] are internal methods that aren't present on all objects, so it
- * is useful to ask if they are there or not. The standard itself asks these
- * questions routinely.
- */
- namespace JS {
- /**
- * Return true if the given object is callable. In ES6 terms, an object is
- * callable if it has a [[Call]] internal method.
- *
- * Implements: ES6 7.2.3 IsCallable(argument).
- *
- * Functions are callable. A scripted proxy or wrapper is callable if its
- * target is callable. Most other objects aren't callable.
- */
- extern JS_PUBLIC_API(bool)
- IsCallable(JSObject* obj);
- /**
- * Return true if the given object is a constructor. In ES6 terms, an object is
- * a constructor if it has a [[Construct]] internal method. The expression
- * `new obj()` throws a TypeError if obj is not a constructor.
- *
- * Implements: ES6 7.2.4 IsConstructor(argument).
- *
- * JS functions and classes are constructors. Arrow functions and most builtin
- * functions are not. A scripted proxy or wrapper is a constructor if its
- * target is a constructor.
- */
- extern JS_PUBLIC_API(bool)
- IsConstructor(JSObject* obj);
- } /* namespace JS */
- /**
- * Call a function, passing a this-value and arguments. This is the C++
- * equivalent of `rval = Reflect.apply(fun, obj, args)`.
- *
- * Implements: ES6 7.3.12 Call(F, V, [argumentsList]).
- * Use this function to invoke the [[Call]] internal method.
- */
- extern JS_PUBLIC_API(bool)
- JS_CallFunctionValue(JSContext* cx, JS::HandleObject obj, JS::HandleValue fval,
- const JS::HandleValueArray& args, JS::MutableHandleValue rval);
- extern JS_PUBLIC_API(bool)
- JS_CallFunction(JSContext* cx, JS::HandleObject obj, JS::HandleFunction fun,
- const JS::HandleValueArray& args, JS::MutableHandleValue rval);
- /**
- * Perform the method call `rval = obj[name](args)`.
- */
- extern JS_PUBLIC_API(bool)
- JS_CallFunctionName(JSContext* cx, JS::HandleObject obj, const char* name,
- const JS::HandleValueArray& args, JS::MutableHandleValue rval);
- namespace JS {
- static inline bool
- Call(JSContext* cx, JS::HandleObject thisObj, JS::HandleFunction fun,
- const JS::HandleValueArray& args, MutableHandleValue rval)
- {
- return !!JS_CallFunction(cx, thisObj, fun, args, rval);
- }
- static inline bool
- Call(JSContext* cx, JS::HandleObject thisObj, JS::HandleValue fun, const JS::HandleValueArray& args,
- MutableHandleValue rval)
- {
- return !!JS_CallFunctionValue(cx, thisObj, fun, args, rval);
- }
- static inline bool
- Call(JSContext* cx, JS::HandleObject thisObj, const char* name, const JS::HandleValueArray& args,
- MutableHandleValue rval)
- {
- return !!JS_CallFunctionName(cx, thisObj, name, args, rval);
- }
- extern JS_PUBLIC_API(bool)
- Call(JSContext* cx, JS::HandleValue thisv, JS::HandleValue fun, const JS::HandleValueArray& args,
- MutableHandleValue rval);
- static inline bool
- Call(JSContext* cx, JS::HandleValue thisv, JS::HandleObject funObj, const JS::HandleValueArray& args,
- MutableHandleValue rval)
- {
- MOZ_ASSERT(funObj);
- JS::RootedValue fun(cx, JS::ObjectValue(*funObj));
- return Call(cx, thisv, fun, args, rval);
- }
- /**
- * Invoke a constructor. This is the C++ equivalent of
- * `rval = Reflect.construct(fun, args, newTarget)`.
- *
- * JS::Construct() takes a `newTarget` argument that most callers don't need.
- * Consider using the four-argument Construct signature instead. (But if you're
- * implementing a subclass or a proxy handler's construct() method, this is the
- * right function to call.)
- *
- * Implements: ES6 7.3.13 Construct(F, [argumentsList], [newTarget]).
- * Use this function to invoke the [[Construct]] internal method.
- */
- extern JS_PUBLIC_API(bool)
- Construct(JSContext* cx, JS::HandleValue fun, HandleObject newTarget,
- const JS::HandleValueArray &args, MutableHandleObject objp);
- /**
- * Invoke a constructor. This is the C++ equivalent of
- * `rval = new fun(...args)`.
- *
- * Implements: ES6 7.3.13 Construct(F, [argumentsList], [newTarget]), when
- * newTarget is omitted.
- */
- extern JS_PUBLIC_API(bool)
- Construct(JSContext* cx, JS::HandleValue fun, const JS::HandleValueArray& args,
- MutableHandleObject objp);
- } /* namespace JS */
- /**
- * Invoke a constructor, like the JS expression `new ctor(...args)`. Returns
- * the new object, or null on error.
- */
- extern JS_PUBLIC_API(JSObject*)
- JS_New(JSContext* cx, JS::HandleObject ctor, const JS::HandleValueArray& args);
- /*** Other property-defining functions ***********************************************************/
- extern JS_PUBLIC_API(JSObject*)
- JS_DefineObject(JSContext* cx, JS::HandleObject obj, const char* name,
- const JSClass* clasp = nullptr, unsigned attrs = 0);
- extern JS_PUBLIC_API(bool)
- JS_DefineConstDoubles(JSContext* cx, JS::HandleObject obj, const JSConstDoubleSpec* cds);
- extern JS_PUBLIC_API(bool)
- JS_DefineConstIntegers(JSContext* cx, JS::HandleObject obj, const JSConstIntegerSpec* cis);
- extern JS_PUBLIC_API(bool)
- JS_DefineProperties(JSContext* cx, JS::HandleObject obj, const JSPropertySpec* ps);
- /* * */
- extern JS_PUBLIC_API(bool)
- JS_AlreadyHasOwnPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
- bool* foundp);
- extern JS_PUBLIC_API(bool)
- JS_AlreadyHasOwnProperty(JSContext* cx, JS::HandleObject obj, const char* name,
- bool* foundp);
- extern JS_PUBLIC_API(bool)
- JS_AlreadyHasOwnUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name,
- size_t namelen, bool* foundp);
- extern JS_PUBLIC_API(bool)
- JS_AlreadyHasOwnElement(JSContext* cx, JS::HandleObject obj, uint32_t index, bool* foundp);
- extern JS_PUBLIC_API(JSObject*)
- JS_NewArrayObject(JSContext* cx, const JS::HandleValueArray& contents);
- extern JS_PUBLIC_API(JSObject*)
- JS_NewArrayObject(JSContext* cx, size_t length);
- /**
- * Returns true and sets |*isArray| indicating whether |value| is an Array
- * object or a wrapper around one, otherwise returns false on failure.
- *
- * This method returns true with |*isArray == false| when passed a proxy whose
- * target is an Array, or when passed a revoked proxy.
- */
- extern JS_PUBLIC_API(bool)
- JS_IsArrayObject(JSContext* cx, JS::HandleValue value, bool* isArray);
- /**
- * Returns true and sets |*isArray| indicating whether |obj| is an Array object
- * or a wrapper around one, otherwise returns false on failure.
- *
- * This method returns true with |*isArray == false| when passed a proxy whose
- * target is an Array, or when passed a revoked proxy.
- */
- extern JS_PUBLIC_API(bool)
- JS_IsArrayObject(JSContext* cx, JS::HandleObject obj, bool* isArray);
- extern JS_PUBLIC_API(bool)
- JS_GetArrayLength(JSContext* cx, JS::Handle<JSObject*> obj, uint32_t* lengthp);
- extern JS_PUBLIC_API(bool)
- JS_SetArrayLength(JSContext* cx, JS::Handle<JSObject*> obj, uint32_t length);
- namespace JS {
- /**
- * Returns true and sets |*isMap| indicating whether |obj| is an Map object
- * or a wrapper around one, otherwise returns false on failure.
- *
- * This method returns true with |*isMap == false| when passed a proxy whose
- * target is an Map, or when passed a revoked proxy.
- */
- extern JS_PUBLIC_API(bool)
- IsMapObject(JSContext* cx, JS::HandleObject obj, bool* isMap);
- /**
- * Returns true and sets |*isSet| indicating whether |obj| is an Set object
- * or a wrapper around one, otherwise returns false on failure.
- *
- * This method returns true with |*isSet == false| when passed a proxy whose
- * target is an Set, or when passed a revoked proxy.
- */
- extern JS_PUBLIC_API(bool)
- IsSetObject(JSContext* cx, JS::HandleObject obj, bool* isSet);
- } /* namespace JS */
- /**
- * Assign 'undefined' to all of the object's non-reserved slots. Note: this is
- * done for all slots, regardless of the associated property descriptor.
- */
- JS_PUBLIC_API(void)
- JS_SetAllNonReservedSlotsToUndefined(JSContext* cx, JSObject* objArg);
- /**
- * Create a new array buffer with the given contents. It must be legal to pass
- * these contents to free(). On success, the ownership is transferred to the
- * new array buffer.
- */
- extern JS_PUBLIC_API(JSObject*)
- JS_NewArrayBufferWithContents(JSContext* cx, size_t nbytes, void* contents);
- /**
- * Create a new array buffer with the given contents. The array buffer does not take ownership of
- * contents, and JS_DetachArrayBuffer must be called before the contents are disposed of.
- */
- extern JS_PUBLIC_API(JSObject*)
- JS_NewArrayBufferWithExternalContents(JSContext* cx, size_t nbytes, void* contents);
- /**
- * Steal the contents of the given array buffer. The array buffer has its
- * length set to 0 and its contents array cleared. The caller takes ownership
- * of the return value and must free it or transfer ownership via
- * JS_NewArrayBufferWithContents when done using it.
- */
- extern JS_PUBLIC_API(void*)
- JS_StealArrayBufferContents(JSContext* cx, JS::HandleObject obj);
- /**
- * Returns a pointer to the ArrayBuffer |obj|'s data. |obj| and its views will store and expose
- * the data in the returned pointer: assigning into the returned pointer will affect values exposed
- * by views of |obj| and vice versa.
- *
- * The caller must ultimately deallocate the returned pointer to avoid leaking. The memory is
- * *not* garbage-collected with |obj|. These steps must be followed to deallocate:
- *
- * 1. The ArrayBuffer |obj| must be detached using JS_DetachArrayBuffer.
- * 2. The returned pointer must be freed using JS_free.
- *
- * To perform step 1, callers *must* hold a reference to |obj| until they finish using the returned
- * pointer. They *must not* attempt to let |obj| be GC'd, then JS_free the pointer.
- *
- * If |obj| isn't an ArrayBuffer, this function returns null and reports an error.
- */
- extern JS_PUBLIC_API(void*)
- JS_ExternalizeArrayBufferContents(JSContext* cx, JS::HandleObject obj);
- /**
- * Create a new mapped array buffer with the given memory mapped contents. It
- * must be legal to free the contents pointer by unmapping it. On success,
- * ownership is transferred to the new mapped array buffer.
- */
- extern JS_PUBLIC_API(JSObject*)
- JS_NewMappedArrayBufferWithContents(JSContext* cx, size_t nbytes, void* contents);
- /**
- * Create memory mapped array buffer contents.
- * Caller must take care of closing fd after calling this function.
- */
- extern JS_PUBLIC_API(void*)
- JS_CreateMappedArrayBufferContents(int fd, size_t offset, size_t length);
- /**
- * Release the allocated resource of mapped array buffer contents before the
- * object is created.
- * If a new object has been created by JS_NewMappedArrayBufferWithContents()
- * with this content, then JS_DetachArrayBuffer() should be used instead to
- * release the resource used by the object.
- */
- extern JS_PUBLIC_API(void)
- JS_ReleaseMappedArrayBufferContents(void* contents, size_t length);
- extern JS_PUBLIC_API(JS::Value)
- JS_GetReservedSlot(JSObject* obj, uint32_t index);
- extern JS_PUBLIC_API(void)
- JS_SetReservedSlot(JSObject* obj, uint32_t index, const JS::Value& v);
- /************************************************************************/
- /*
- * Functions and scripts.
- */
- extern JS_PUBLIC_API(JSFunction*)
- JS_NewFunction(JSContext* cx, JSNative call, unsigned nargs, unsigned flags,
- const char* name);
- namespace JS {
- extern JS_PUBLIC_API(JSFunction*)
- GetSelfHostedFunction(JSContext* cx, const char* selfHostedName, HandleId id,
- unsigned nargs);
- /**
- * Create a new function based on the given JSFunctionSpec, *fs.
- * id is the result of a successful call to
- * `PropertySpecNameToPermanentId(cx, fs->name, &id)`.
- *
- * Unlike JS_DefineFunctions, this does not treat fs as an array.
- * *fs must not be JS_FS_END.
- */
- extern JS_PUBLIC_API(JSFunction*)
- NewFunctionFromSpec(JSContext* cx, const JSFunctionSpec* fs, HandleId id);
- } /* namespace JS */
- extern JS_PUBLIC_API(JSObject*)
- JS_GetFunctionObject(JSFunction* fun);
- /**
- * Return the function's identifier as a JSString, or null if fun is unnamed.
- * The returned string lives as long as fun, so you don't need to root a saved
- * reference to it if fun is well-connected or rooted, and provided you bound
- * the use of the saved reference by fun's lifetime.
- */
- extern JS_PUBLIC_API(JSString*)
- JS_GetFunctionId(JSFunction* fun);
- /**
- * Return a function's display name. This is the defined name if one was given
- * where the function was defined, or it could be an inferred name by the JS
- * engine in the case that the function was defined to be anonymous. This can
- * still return nullptr if a useful display name could not be inferred. The
- * same restrictions on rooting as those in JS_GetFunctionId apply.
- */
- extern JS_PUBLIC_API(JSString*)
- JS_GetFunctionDisplayId(JSFunction* fun);
- /*
- * Return the arity (length) of fun.
- */
- extern JS_PUBLIC_API(uint16_t)
- JS_GetFunctionArity(JSFunction* fun);
- /**
- * Infallible predicate to test whether obj is a function object (faster than
- * comparing obj's class name to "Function", but equivalent unless someone has
- * overwritten the "Function" identifier with a different constructor and then
- * created instances using that constructor that might be passed in as obj).
- */
- extern JS_PUBLIC_API(bool)
- JS_ObjectIsFunction(JSContext* cx, JSObject* obj);
- extern JS_PUBLIC_API(bool)
- JS_IsNativeFunction(JSObject* funobj, JSNative call);
- /** Return whether the given function is a valid constructor. */
- extern JS_PUBLIC_API(bool)
- JS_IsConstructor(JSFunction* fun);
- extern JS_PUBLIC_API(bool)
- JS_DefineFunctions(JSContext* cx, JS::Handle<JSObject*> obj, const JSFunctionSpec* fs);
- extern JS_PUBLIC_API(JSFunction*)
- JS_DefineFunction(JSContext* cx, JS::Handle<JSObject*> obj, const char* name, JSNative call,
- unsigned nargs, unsigned attrs);
- extern JS_PUBLIC_API(JSFunction*)
- JS_DefineUCFunction(JSContext* cx, JS::Handle<JSObject*> obj,
- const char16_t* name, size_t namelen, JSNative call,
- unsigned nargs, unsigned attrs);
- extern JS_PUBLIC_API(JSFunction*)
- JS_DefineFunctionById(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JSNative call,
- unsigned nargs, unsigned attrs);
- extern JS_PUBLIC_API(bool)
- JS_IsFunctionBound(JSFunction* fun);
- extern JS_PUBLIC_API(JSObject*)
- JS_GetBoundFunctionTarget(JSFunction* fun);
- namespace JS {
- /**
- * Clone a top-level function into cx's global. This function will dynamically
- * fail if funobj was lexically nested inside some other function.
- */
- extern JS_PUBLIC_API(JSObject*)
- CloneFunctionObject(JSContext* cx, HandleObject funobj);
- /**
- * As above, but providing an explicit scope chain. scopeChain must not include
- * the global object on it; that's implicit. It needs to contain the other
- * objects that should end up on the clone's scope chain.
- */
- extern JS_PUBLIC_API(JSObject*)
- CloneFunctionObject(JSContext* cx, HandleObject funobj, AutoObjectVector& scopeChain);
- } // namespace JS
- /**
- * Given a buffer, return false if the buffer might become a valid
- * javascript statement with the addition of more lines. Otherwise return
- * true. The intent is to support interactive compilation - accumulate
- * lines in a buffer until JS_BufferIsCompilableUnit is true, then pass it to
- * the compiler.
- */
- extern JS_PUBLIC_API(bool)
- JS_BufferIsCompilableUnit(JSContext* cx, JS::Handle<JSObject*> obj, const char* utf8,
- size_t length);
- /**
- * |script| will always be set. On failure, it will be set to nullptr.
- */
- extern JS_PUBLIC_API(bool)
- JS_CompileScript(JSContext* cx, const char* ascii, size_t length,
- const JS::CompileOptions& options,
- JS::MutableHandleScript script);
- /**
- * |script| will always be set. On failure, it will be set to nullptr.
- */
- extern JS_PUBLIC_API(bool)
- JS_CompileUCScript(JSContext* cx, const char16_t* chars, size_t length,
- const JS::CompileOptions& options,
- JS::MutableHandleScript script);
- extern JS_PUBLIC_API(JSObject*)
- JS_GetGlobalFromScript(JSScript* script);
- extern JS_PUBLIC_API(const char*)
- JS_GetScriptFilename(JSScript* script);
- extern JS_PUBLIC_API(unsigned)
- JS_GetScriptBaseLineNumber(JSContext* cx, JSScript* script);
- extern JS_PUBLIC_API(JSScript*)
- JS_GetFunctionScript(JSContext* cx, JS::HandleFunction fun);
- namespace JS {
- /* Options for JavaScript compilation. */
- /*
- * In the most common use case, a CompileOptions instance is allocated on the
- * stack, and holds non-owning references to non-POD option values: strings;
- * principals; objects; and so on. The code declaring the instance guarantees
- * that such option values will outlive the CompileOptions itself: objects are
- * otherwise rooted; principals have had their reference counts bumped; strings
- * will not be freed until the CompileOptions goes out of scope. In this
- * situation, CompileOptions only refers to things others own, so it can be
- * lightweight.
- *
- * In some cases, however, we need to hold compilation options with a
- * non-stack-like lifetime. For example, JS::CompileOffThread needs to save
- * compilation options where a worker thread can find them, and then return
- * immediately. The worker thread will come along at some later point, and use
- * the options.
- *
- * The compiler itself just needs to be able to access a collection of options;
- * it doesn't care who owns them, or what's keeping them alive. It does its own
- * addrefs/copies/tracing/etc.
- *
- * Furthermore, in some cases compile options are propagated from one entity to
- * another (e.g. from a scriipt to a function defined in that script). This
- * involves copying over some, but not all, of the options.
- *
- * So, we have a class hierarchy that reflects these four use cases:
- *
- * - TransitiveCompileOptions is the common base class, representing options
- * that should get propagated from a script to functions defined in that
- * script. This is never instantiated directly.
- *
- * - ReadOnlyCompileOptions is the only subclass of TransitiveCompileOptions,
- * representing a full set of compile options. It can be used by code that
- * simply needs to access options set elsewhere, like the compiler. This,
- * again, is never instantiated directly.
- *
- * - The usual CompileOptions class must be stack-allocated, and holds
- * non-owning references to the filename, element, and so on. It's derived
- * from ReadOnlyCompileOptions, so the compiler can use it.
- *
- * - OwningCompileOptions roots / copies / reference counts of all its values,
- * and unroots / frees / releases them when it is destructed. It too is
- * derived from ReadOnlyCompileOptions, so the compiler accepts it.
- */
- enum class AsmJSOption : uint8_t { Enabled, Disabled, DisabledByDebugger };
- /**
- * The common base class for the CompileOptions hierarchy.
- *
- * Use this in code that needs to propagate compile options from one compilation
- * unit to another.
- */
- class JS_FRIEND_API(TransitiveCompileOptions)
- {
- protected:
- // The Web Platform allows scripts to be loaded from arbitrary cross-origin
- // sources. This allows an attack by which a malicious website loads a
- // sensitive file (say, a bank statement) cross-origin (using the user's
- // cookies), and sniffs the generated syntax errors (via a window.onerror
- // handler) for juicy morsels of its contents.
- //
- // To counter this attack, HTML5 specifies that script errors should be
- // sanitized ("muted") when the script is not same-origin with the global
- // for which it is loaded. Callers should set this flag for cross-origin
- // scripts, and it will be propagated appropriately to child scripts and
- // passed back in JSErrorReports.
- bool mutedErrors_;
- const char* filename_;
- const char* introducerFilename_;
- const char16_t* sourceMapURL_;
- // This constructor leaves 'version' set to JSVERSION_UNKNOWN. The structure
- // is unusable until that's set to something more specific; the derived
- // classes' constructors take care of that, in ways appropriate to their
- // purpose.
- TransitiveCompileOptions()
- : mutedErrors_(false),
- filename_(nullptr),
- introducerFilename_(nullptr),
- sourceMapURL_(nullptr),
- version(JSVERSION_UNKNOWN),
- versionSet(false),
- utf8(false),
- selfHostingMode(false),
- canLazilyParse(true),
- strictOption(false),
- extraWarningsOption(false),
- werrorOption(false),
- asmJSOption(AsmJSOption::Disabled),
- throwOnAsmJSValidationFailureOption(false),
- forceAsync(false),
- installedFile(false),
- sourceIsLazy(false),
- introductionType(nullptr),
- introductionLineno(0),
- introductionOffset(0),
- hasIntroductionInfo(false)
- { }
- // Set all POD options (those not requiring reference counts, copies,
- // rooting, or other hand-holding) to their values in |rhs|.
- void copyPODTransitiveOptions(const TransitiveCompileOptions& rhs);
- public:
- // Read-only accessors for non-POD options. The proper way to set these
- // depends on the derived type.
- bool mutedErrors() const { return mutedErrors_; }
- const char* filename() const { return filename_; }
- const char* introducerFilename() const { return introducerFilename_; }
- const char16_t* sourceMapURL() const { return sourceMapURL_; }
- virtual JSObject* element() const = 0;
- virtual JSString* elementAttributeName() const = 0;
- virtual JSScript* introductionScript() const = 0;
- // POD options.
- JSVersion version;
- bool versionSet;
- bool utf8;
- bool selfHostingMode;
- bool canLazilyParse;
- bool strictOption;
- bool extraWarningsOption;
- bool werrorOption;
- AsmJSOption asmJSOption;
- bool throwOnAsmJSValidationFailureOption;
- bool forceAsync;
- bool installedFile; // 'true' iff pre-compiling js file in packaged app
- bool sourceIsLazy;
- // |introductionType| is a statically allocated C string:
- // one of "eval", "Function", or "GeneratorFunction".
- const char* introductionType;
- unsigned introductionLineno;
- uint32_t introductionOffset;
- bool hasIntroductionInfo;
- private:
- void operator=(const TransitiveCompileOptions&) = delete;
- };
- /**
- * The class representing a full set of compile options.
- *
- * Use this in code that only needs to access compilation options created
- * elsewhere, like the compiler. Don't instantiate this class (the constructor
- * is protected anyway); instead, create instances only of the derived classes:
- * CompileOptions and OwningCompileOptions.
- */
- class JS_FRIEND_API(ReadOnlyCompileOptions) : public TransitiveCompileOptions
- {
- friend class CompileOptions;
- protected:
- ReadOnlyCompileOptions()
- : TransitiveCompileOptions(),
- lineno(1),
- column(0),
- isRunOnce(false),
- noScriptRval(false)
- { }
- // Set all POD options (those not requiring reference counts, copies,
- // rooting, or other hand-holding) to their values in |rhs|.
- void copyPODOptions(const ReadOnlyCompileOptions& rhs);
- public:
- // Read-only accessors for non-POD options. The proper way to set these
- // depends on the derived type.
- bool mutedErrors() const { return mutedErrors_; }
- const char* filename() const { return filename_; }
- const char* introducerFilename() const { return introducerFilename_; }
- const char16_t* sourceMapURL() const { return sourceMapURL_; }
- virtual JSObject* element() const = 0;
- virtual JSString* elementAttributeName() const = 0;
- virtual JSScript* introductionScript() const = 0;
- // POD options.
- unsigned lineno;
- unsigned column;
- // isRunOnce only applies to non-function scripts.
- bool isRunOnce;
- bool noScriptRval;
- private:
- void operator=(const ReadOnlyCompileOptions&) = delete;
- };
- /**
- * Compilation options, with dynamic lifetime. An instance of this type
- * makes a copy of / holds / roots all dynamically allocated resources
- * (principals; elements; strings) that it refers to. Its destructor frees
- * / drops / unroots them. This is heavier than CompileOptions, below, but
- * unlike CompileOptions, it can outlive any given stack frame.
- *
- * Note that this *roots* any JS values it refers to - they're live
- * unconditionally. Thus, instances of this type can't be owned, directly
- * or indirectly, by a JavaScript object: if any value that this roots ever
- * comes to refer to the object that owns this, then the whole cycle, and
- * anything else it entrains, will never be freed.
- */
- class JS_FRIEND_API(OwningCompileOptions) : public ReadOnlyCompileOptions
- {
- PersistentRootedObject elementRoot;
- PersistentRootedString elementAttributeNameRoot;
- PersistentRootedScript introductionScriptRoot;
- public:
- // A minimal constructor, for use with OwningCompileOptions::copy. This
- // leaves |this.version| set to JSVERSION_UNKNOWN; the instance
- // shouldn't be used until we've set that to something real (as |copy|
- // will).
- explicit OwningCompileOptions(JSContext* cx);
- ~OwningCompileOptions();
- JSObject* element() const override { return elementRoot; }
- JSString* elementAttributeName() const override { return elementAttributeNameRoot; }
- JSScript* introductionScript() const override { return introductionScriptRoot; }
- // Set this to a copy of |rhs|. Return false on OOM.
- bool copy(JSContext* cx, const ReadOnlyCompileOptions& rhs);
- /* These setters make copies of their string arguments, and are fallible. */
- bool setFile(JSContext* cx, const char* f);
- bool setFileAndLine(JSContext* cx, const char* f, unsigned l);
- bool setSourceMapURL(JSContext* cx, const char16_t* s);
- bool setIntroducerFilename(JSContext* cx, const char* s);
- /* These setters are infallible, and can be chained. */
- OwningCompileOptions& setLine(unsigned l) { lineno = l; return *this; }
- OwningCompileOptions& setElement(JSObject* e) {
- elementRoot = e;
- return *this;
- }
- OwningCompileOptions& setElementAttributeName(JSString* p) {
- elementAttributeNameRoot = p;
- return *this;
- }
- OwningCompileOptions& setIntroductionScript(JSScript* s) {
- introductionScriptRoot = s;
- return *this;
- }
- OwningCompileOptions& setMutedErrors(bool mute) {
- mutedErrors_ = mute;
- return *this;
- }
- OwningCompileOptions& setVersion(JSVersion v) {
- version = v;
- versionSet = true;
- return *this;
- }
- OwningCompileOptions& setUTF8(bool u) { utf8 = u; return *this; }
- OwningCompileOptions& setColumn(unsigned c) { column = c; return *this; }
- OwningCompileOptions& setIsRunOnce(bool once) { isRunOnce = once; return *this; }
- OwningCompileOptions& setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; }
- OwningCompileOptions& setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; }
- OwningCompileOptions& setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; }
- OwningCompileOptions& setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; }
- OwningCompileOptions& setIntroductionType(const char* t) { introductionType = t; return *this; }
- bool setIntroductionInfo(JSContext* cx, const char* introducerFn, const char* intro,
- unsigned line, JSScript* script, uint32_t offset)
- {
- if (!setIntroducerFilename(cx, introducerFn))
- return false;
- introductionType = intro;
- introductionLineno = line;
- introductionScriptRoot = script;
- introductionOffset = offset;
- hasIntroductionInfo = true;
- return true;
- }
- private:
- void operator=(const CompileOptions& rhs) = delete;
- };
- /**
- * Compilation options stored on the stack. An instance of this type
- * simply holds references to dynamically allocated resources (element;
- * filename; source map URL) that are owned by something else. If you
- * create an instance of this type, it's up to you to guarantee that
- * everything you store in it will outlive it.
- */
- class MOZ_STACK_CLASS JS_FRIEND_API(CompileOptions) final : public ReadOnlyCompileOptions
- {
- RootedObject elementRoot;
- RootedString elementAttributeNameRoot;
- RootedScript introductionScriptRoot;
- public:
- explicit CompileOptions(JSContext* cx, JSVersion version = JSVERSION_UNKNOWN);
- CompileOptions(js::ContextFriendFields* cx, const ReadOnlyCompileOptions& rhs)
- : ReadOnlyCompileOptions(), elementRoot(cx), elementAttributeNameRoot(cx),
- introductionScriptRoot(cx)
- {
- copyPODOptions(rhs);
- filename_ = rhs.filename();
- introducerFilename_ = rhs.introducerFilename();
- sourceMapURL_ = rhs.sourceMapURL();
- elementRoot = rhs.element();
- elementAttributeNameRoot = rhs.elementAttributeName();
- introductionScriptRoot = rhs.introductionScript();
- }
- CompileOptions(js::ContextFriendFields* cx, const TransitiveCompileOptions& rhs)
- : ReadOnlyCompileOptions(), elementRoot(cx), elementAttributeNameRoot(cx),
- introductionScriptRoot(cx)
- {
- copyPODTransitiveOptions(rhs);
- filename_ = rhs.filename();
- introducerFilename_ = rhs.introducerFilename();
- sourceMapURL_ = rhs.sourceMapURL();
- elementRoot = rhs.element();
- elementAttributeNameRoot = rhs.elementAttributeName();
- introductionScriptRoot = rhs.introductionScript();
- }
- JSObject* element() const override { return elementRoot; }
- JSString* elementAttributeName() const override { return elementAttributeNameRoot; }
- JSScript* introductionScript() const override { return introductionScriptRoot; }
- CompileOptions& setFile(const char* f) { filename_ = f; return *this; }
- CompileOptions& setLine(unsigned l) { lineno = l; return *this; }
- CompileOptions& setFileAndLine(const char* f, unsigned l) {
- filename_ = f; lineno = l; return *this;
- }
- CompileOptions& setSourceMapURL(const char16_t* s) { sourceMapURL_ = s; return *this; }
- CompileOptions& setElement(JSObject* e) { elementRoot = e; return *this; }
- CompileOptions& setElementAttributeName(JSString* p) {
- elementAttributeNameRoot = p;
- return *this;
- }
- CompileOptions& setIntroductionScript(JSScript* s) {
- introductionScriptRoot = s;
- return *this;
- }
- CompileOptions& setMutedErrors(bool mute) {
- mutedErrors_ = mute;
- return *this;
- }
- CompileOptions& setVersion(JSVersion v) {
- version = v;
- versionSet = true;
- return *this;
- }
- CompileOptions& setUTF8(bool u) { utf8 = u; return *this; }
- CompileOptions& setColumn(unsigned c) { column = c; return *this; }
- CompileOptions& setIsRunOnce(bool once) { isRunOnce = once; return *this; }
- CompileOptions& setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; }
- CompileOptions& setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; }
- CompileOptions& setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; }
- CompileOptions& setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; }
- CompileOptions& setIntroductionType(const char* t) { introductionType = t; return *this; }
- CompileOptions& setIntroductionInfo(const char* introducerFn, const char* intro,
- unsigned line, JSScript* script, uint32_t offset)
- {
- introducerFilename_ = introducerFn;
- introductionType = intro;
- introductionLineno = line;
- introductionScriptRoot = script;
- introductionOffset = offset;
- hasIntroductionInfo = true;
- return *this;
- }
- CompileOptions& maybeMakeStrictMode(bool strict) {
- strictOption = strictOption || strict;
- return *this;
- }
- private:
- void operator=(const CompileOptions& rhs) = delete;
- };
- /**
- * |script| will always be set. On failure, it will be set to nullptr.
- */
- extern JS_PUBLIC_API(bool)
- Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
- SourceBufferHolder& srcBuf, JS::MutableHandleScript script);
- extern JS_PUBLIC_API(bool)
- Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
- const char* bytes, size_t length, JS::MutableHandleScript script);
- extern JS_PUBLIC_API(bool)
- Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
- const char16_t* chars, size_t length, JS::MutableHandleScript script);
- extern JS_PUBLIC_API(bool)
- Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
- FILE* file, JS::MutableHandleScript script);
- extern JS_PUBLIC_API(bool)
- Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
- const char* filename, JS::MutableHandleScript script);
- extern JS_PUBLIC_API(bool)
- CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
- SourceBufferHolder& srcBuf, JS::MutableHandleScript script);
- extern JS_PUBLIC_API(bool)
- CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
- const char* bytes, size_t length, JS::MutableHandleScript script);
- extern JS_PUBLIC_API(bool)
- CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
- const char16_t* chars, size_t length, JS::MutableHandleScript script);
- extern JS_PUBLIC_API(bool)
- CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
- FILE* file, JS::MutableHandleScript script);
- extern JS_PUBLIC_API(bool)
- CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
- const char* filename, JS::MutableHandleScript script);
- extern JS_PUBLIC_API(bool)
- CanCompileOffThread(JSContext* cx, const ReadOnlyCompileOptions& options, size_t length);
- /*
- * Off thread compilation control flow.
- *
- * After successfully triggering an off thread compile of a script, the
- * callback will eventually be invoked with the specified data and a token
- * for the compilation. The callback will be invoked while off the main thread,
- * so must ensure that its operations are thread safe. Afterwards, one of the
- * following functions must be invoked on the main thread:
- *
- * - FinishOffThreadScript, to get the result script (or nullptr on failure).
- * - CancelOffThreadScript, to free the resources without creating a script.
- *
- * The characters passed in to CompileOffThread must remain live until the
- * callback is invoked, and the resulting script will be rooted until the call
- * to FinishOffThreadScript.
- */
- extern JS_PUBLIC_API(bool)
- CompileOffThread(JSContext* cx, const ReadOnlyCompileOptions& options,
- const char16_t* chars, size_t length,
- OffThreadCompileCallback callback, void* callbackData);
- extern JS_PUBLIC_API(JSScript*)
- FinishOffThreadScript(JSContext* cx, void* token);
- extern JS_PUBLIC_API(void)
- CancelOffThreadScript(JSContext* cx, void* token);
- extern JS_PUBLIC_API(bool)
- CompileOffThreadModule(JSContext* cx, const ReadOnlyCompileOptions& options,
- const char16_t* chars, size_t length,
- OffThreadCompileCallback callback, void* callbackData);
- extern JS_PUBLIC_API(JSObject*)
- FinishOffThreadModule(JSContext* cx, void* token);
- extern JS_PUBLIC_API(void)
- CancelOffThreadModule(JSContext* cx, void* token);
- /**
- * Compile a function with envChain plus the global as its scope chain.
- * envChain must contain objects in the current compartment of cx. The actual
- * scope chain used for the function will consist of With wrappers for those
- * objects, followed by the current global of the compartment cx is in. This
- * global must not be explicitly included in the scope chain.
- */
- extern JS_PUBLIC_API(bool)
- CompileFunction(JSContext* cx, AutoObjectVector& envChain,
- const ReadOnlyCompileOptions& options,
- const char* name, unsigned nargs, const char* const* argnames,
- const char16_t* chars, size_t length, JS::MutableHandleFunction fun);
- /**
- * Same as above, but taking a SourceBufferHolder for the function body.
- */
- extern JS_PUBLIC_API(bool)
- CompileFunction(JSContext* cx, AutoObjectVector& envChain,
- const ReadOnlyCompileOptions& options,
- const char* name, unsigned nargs, const char* const* argnames,
- SourceBufferHolder& srcBuf, JS::MutableHandleFunction fun);
- /**
- * Same as above, but taking a const char * for the function body.
- */
- extern JS_PUBLIC_API(bool)
- CompileFunction(JSContext* cx, AutoObjectVector& envChain,
- const ReadOnlyCompileOptions& options,
- const char* name, unsigned nargs, const char* const* argnames,
- const char* bytes, size_t length, JS::MutableHandleFunction fun);
- } /* namespace JS */
- extern JS_PUBLIC_API(JSString*)
- JS_DecompileScript(JSContext* cx, JS::Handle<JSScript*> script, const char* name, unsigned indent);
- /*
- * API extension: OR this into indent to avoid pretty-printing the decompiled
- * source resulting from JS_DecompileFunction.
- */
- #define JS_DONT_PRETTY_PRINT ((unsigned)0x8000)
- extern JS_PUBLIC_API(JSString*)
- JS_DecompileFunction(JSContext* cx, JS::Handle<JSFunction*> fun, unsigned indent);
- /*
- * NB: JS_ExecuteScript and the JS::Evaluate APIs come in two flavors: either
- * they use the global as the scope, or they take an AutoObjectVector of objects
- * to use as the scope chain. In the former case, the global is also used as
- * the "this" keyword value and the variables object (ECMA parlance for where
- * 'var' and 'function' bind names) of the execution context for script. In the
- * latter case, the first object in the provided list is used, unless the list
- * is empty, in which case the global is used.
- *
- * Why a runtime option? The alternative is to add APIs duplicating those
- * for the other value of flags, and that doesn't seem worth the code bloat
- * cost. Such new entry points would probably have less obvious names, too, so
- * would not tend to be used. The ContextOptionsRef adjustment, OTOH, can be
- * more easily hacked into existing code that does not depend on the bug; such
- * code can continue to use the familiar JS::Evaluate, etc., entry points.
- */
- /**
- * Evaluate a script in the scope of the current global of cx.
- */
- extern JS_PUBLIC_API(bool)
- JS_ExecuteScript(JSContext* cx, JS::HandleScript script, JS::MutableHandleValue rval);
- extern JS_PUBLIC_API(bool)
- JS_ExecuteScript(JSContext* cx, JS::HandleScript script);
- /**
- * As above, but providing an explicit scope chain. envChain must not include
- * the global object on it; that's implicit. It needs to contain the other
- * objects that should end up on the script's scope chain.
- */
- extern JS_PUBLIC_API(bool)
- JS_ExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain,
- JS::HandleScript script, JS::MutableHandleValue rval);
- extern JS_PUBLIC_API(bool)
- JS_ExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain, JS::HandleScript script);
- namespace JS {
- /**
- * Like the above, but handles a cross-compartment script. If the script is
- * cross-compartment, it is cloned into the current compartment before executing.
- */
- extern JS_PUBLIC_API(bool)
- CloneAndExecuteScript(JSContext* cx, JS::Handle<JSScript*> script,
- JS::MutableHandleValue rval);
- } /* namespace JS */
- namespace JS {
- /**
- * Evaluate the given source buffer in the scope of the current global of cx.
- */
- extern JS_PUBLIC_API(bool)
- Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
- SourceBufferHolder& srcBuf, JS::MutableHandleValue rval);
- /**
- * As above, but providing an explicit scope chain. envChain must not include
- * the global object on it; that's implicit. It needs to contain the other
- * objects that should end up on the script's scope chain.
- */
- extern JS_PUBLIC_API(bool)
- Evaluate(JSContext* cx, AutoObjectVector& envChain, const ReadOnlyCompileOptions& options,
- SourceBufferHolder& srcBuf, JS::MutableHandleValue rval);
- /**
- * Evaluate the given character buffer in the scope of the current global of cx.
- */
- extern JS_PUBLIC_API(bool)
- Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
- const char16_t* chars, size_t length, JS::MutableHandleValue rval);
- /**
- * As above, but providing an explicit scope chain. envChain must not include
- * the global object on it; that's implicit. It needs to contain the other
- * objects that should end up on the script's scope chain.
- */
- extern JS_PUBLIC_API(bool)
- Evaluate(JSContext* cx, AutoObjectVector& envChain, const ReadOnlyCompileOptions& options,
- const char16_t* chars, size_t length, JS::MutableHandleValue rval);
- /**
- * Evaluate the given byte buffer in the scope of the current global of cx.
- */
- extern JS_PUBLIC_API(bool)
- Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
- const char* bytes, size_t length, JS::MutableHandleValue rval);
- /**
- * Evaluate the given file in the scope of the current global of cx.
- */
- extern JS_PUBLIC_API(bool)
- Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
- const char* filename, JS::MutableHandleValue rval);
- /**
- * Get the HostResolveImportedModule hook for a global.
- */
- extern JS_PUBLIC_API(JSFunction*)
- GetModuleResolveHook(JSContext* cx);
- /**
- * Set the HostResolveImportedModule hook for a global to the given function.
- */
- extern JS_PUBLIC_API(void)
- SetModuleResolveHook(JSContext* cx, JS::HandleFunction func);
- /**
- * Parse the given source buffer as a module in the scope of the current global
- * of cx and return a source text module record.
- */
- extern JS_PUBLIC_API(bool)
- CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options,
- SourceBufferHolder& srcBuf, JS::MutableHandleObject moduleRecord);
- /**
- * Set the [[HostDefined]] field of a source text module record to the given
- * value.
- */
- extern JS_PUBLIC_API(void)
- SetModuleHostDefinedField(JSObject* module, const JS::Value& value);
- /**
- * Get the [[HostDefined]] field of a source text module record.
- */
- extern JS_PUBLIC_API(JS::Value)
- GetModuleHostDefinedField(JSObject* module);
- /*
- * Perform the ModuleDeclarationInstantiation operation on on the give source
- * text module record.
- *
- * This transitively resolves all module dependencies (calling the
- * HostResolveImportedModule hook) and initializes the environment record for
- * the module.
- */
- extern JS_PUBLIC_API(bool)
- ModuleDeclarationInstantiation(JSContext* cx, JS::HandleObject moduleRecord);
- /*
- * Perform the ModuleEvaluation operation on on the give source text module
- * record.
- *
- * This does nothing if this module has already been evaluated. Otherwise, it
- * transitively evaluates all dependences of this module and then evaluates this
- * module.
- *
- * ModuleDeclarationInstantiation must have completed prior to calling this.
- */
- extern JS_PUBLIC_API(bool)
- ModuleEvaluation(JSContext* cx, JS::HandleObject moduleRecord);
- /*
- * Get a list of the module specifiers used by a source text module
- * record to request importation of modules.
- *
- * The result is a JavaScript array of string values. To extract the individual
- * values use only JS_GetArrayLength and JS_GetElement with indices 0 to
- * length - 1.
- */
- extern JS_PUBLIC_API(JSObject*)
- GetRequestedModules(JSContext* cx, JS::HandleObject moduleRecord);
- /*
- * Get the script associated with a module.
- */
- extern JS_PUBLIC_API(JSScript*)
- GetModuleScript(JSContext* cx, JS::HandleObject moduleRecord);
- } /* namespace JS */
- extern JS_PUBLIC_API(bool)
- JS_CheckForInterrupt(JSContext* cx);
- /*
- * These functions allow setting an interrupt callback that will be called
- * from the JS thread some time after any thread triggered the callback using
- * JS_RequestInterruptCallback(cx).
- *
- * To schedule the GC and for other activities the engine internally triggers
- * interrupt callbacks. The embedding should thus not rely on callbacks being
- * triggered through the external API only.
- *
- * Important note: Additional callbacks can occur inside the callback handler
- * if it re-enters the JS engine. The embedding must ensure that the callback
- * is disconnected before attempting such re-entry.
- */
- extern JS_PUBLIC_API(bool)
- JS_AddInterruptCallback(JSContext* cx, JSInterruptCallback callback);
- extern JS_PUBLIC_API(bool)
- JS_DisableInterruptCallback(JSContext* cx);
- extern JS_PUBLIC_API(void)
- JS_ResetInterruptCallback(JSContext* cx, bool enable);
- extern JS_PUBLIC_API(void)
- JS_RequestInterruptCallback(JSContext* cx);
- namespace JS {
- /**
- * Sets the callback that's invoked whenever an incumbent global is required.
- *
- * SpiderMonkey doesn't itself have a notion of incumbent globals as defined
- * by the html spec, so we need the embedding to provide this.
- * See dom/base/ScriptSettings.h for details.
- */
- extern JS_PUBLIC_API(void)
- SetGetIncumbentGlobalCallback(JSContext* cx, JSGetIncumbentGlobalCallback callback);
- /**
- * Sets the callback that's invoked whenever a Promise job should be enqeued.
- *
- * SpiderMonkey doesn't schedule Promise resolution jobs itself; instead,
- * using this function the embedding can provide a callback to do that
- * scheduling. The provided `callback` is invoked with the promise job,
- * the corresponding Promise's allocation stack, and the `data` pointer
- * passed here as arguments.
- */
- extern JS_PUBLIC_API(void)
- SetEnqueuePromiseJobCallback(JSContext* cx, JSEnqueuePromiseJobCallback callback,
- void* data = nullptr);
- /**
- * Sets the callback that's invoked whenever a Promise is rejected without
- * a rejection handler, and when a Promise that was previously rejected
- * without a handler gets a handler attached.
- */
- extern JS_PUBLIC_API(void)
- SetPromiseRejectionTrackerCallback(JSContext* cx, JSPromiseRejectionTrackerCallback callback,
- void* data = nullptr);
- /**
- * Returns a new instance of the Promise builtin class in the current
- * compartment, with the right slot layout. If a `proto` is passed, that gets
- * set as the instance's [[Prototype]] instead of the original value of
- * `Promise.prototype`.
- */
- extern JS_PUBLIC_API(JSObject*)
- NewPromiseObject(JSContext* cx, JS::HandleObject executor, JS::HandleObject proto = nullptr);
- /**
- * Returns true if the given object is an unwrapped PromiseObject, false
- * otherwise.
- */
- extern JS_PUBLIC_API(bool)
- IsPromiseObject(JS::HandleObject obj);
- /**
- * Returns the current compartment's original Promise constructor.
- */
- extern JS_PUBLIC_API(JSObject*)
- GetPromiseConstructor(JSContext* cx);
- /**
- * Returns the current compartment's original Promise.prototype.
- */
- extern JS_PUBLIC_API(JSObject*)
- GetPromisePrototype(JSContext* cx);
- // Keep this in sync with the PROMISE_STATE defines in SelfHostingDefines.h.
- enum class PromiseState {
- Pending,
- Fulfilled,
- Rejected
- };
- /**
- * Returns the given Promise's state as a JS::PromiseState enum value.
- */
- extern JS_PUBLIC_API(PromiseState)
- GetPromiseState(JS::HandleObject promise);
- /**
- * Returns the given Promise's process-unique ID.
- */
- JS_PUBLIC_API(uint64_t)
- GetPromiseID(JS::HandleObject promise);
- /**
- * Returns the given Promise's result: either the resolution value for
- * fulfilled promises, or the rejection reason for rejected ones.
- */
- extern JS_PUBLIC_API(JS::Value)
- GetPromiseResult(JS::HandleObject promise);
- /**
- * Returns a js::SavedFrame linked list of the stack that lead to the given
- * Promise's allocation.
- */
- extern JS_PUBLIC_API(JSObject*)
- GetPromiseAllocationSite(JS::HandleObject promise);
- extern JS_PUBLIC_API(JSObject*)
- GetPromiseResolutionSite(JS::HandleObject promise);
- #ifdef DEBUG
- extern JS_PUBLIC_API(void)
- DumpPromiseAllocationSite(JSContext* cx, JS::HandleObject promise);
- extern JS_PUBLIC_API(void)
- DumpPromiseResolutionSite(JSContext* cx, JS::HandleObject promise);
- #endif
- /**
- * Calls the current compartment's original Promise.resolve on the original
- * Promise constructor, with `resolutionValue` passed as an argument.
- */
- extern JS_PUBLIC_API(JSObject*)
- CallOriginalPromiseResolve(JSContext* cx, JS::HandleValue resolutionValue);
- /**
- * Calls the current compartment's original Promise.reject on the original
- * Promise constructor, with `resolutionValue` passed as an argument.
- */
- extern JS_PUBLIC_API(JSObject*)
- CallOriginalPromiseReject(JSContext* cx, JS::HandleValue rejectionValue);
- /**
- * Resolves the given Promise with the given `resolutionValue`.
- *
- * Calls the `resolve` function that was passed to the executor function when
- * the Promise was created.
- */
- extern JS_PUBLIC_API(bool)
- ResolvePromise(JSContext* cx, JS::HandleObject promise, JS::HandleValue resolutionValue);
- /**
- * Rejects the given `promise` with the given `rejectionValue`.
- *
- * Calls the `reject` function that was passed to the executor function when
- * the Promise was created.
- */
- extern JS_PUBLIC_API(bool)
- RejectPromise(JSContext* cx, JS::HandleObject promise, JS::HandleValue rejectionValue);
- /**
- * Calls the current compartment's original Promise.prototype.then on the
- * given `promise`, with `onResolve` and `onReject` passed as arguments.
- *
- * Asserts if the passed-in `promise` object isn't an unwrapped instance of
- * `Promise` or a subclass or `onResolve` and `onReject` aren't both either
- * `nullptr` or callable objects.
- */
- extern JS_PUBLIC_API(JSObject*)
- CallOriginalPromiseThen(JSContext* cx, JS::HandleObject promise,
- JS::HandleObject onResolve, JS::HandleObject onReject);
- /**
- * Unforgeable, optimized version of the JS builtin Promise.prototype.then.
- *
- * Takes a Promise instance and `onResolve`, `onReject` callables to enqueue
- * as reactions for that promise. In difference to Promise.prototype.then,
- * this doesn't create and return a new Promise instance.
- *
- * Asserts if the passed-in `promise` object isn't an unwrapped instance of
- * `Promise` or a subclass or `onResolve` and `onReject` aren't both callable
- * objects.
- */
- extern JS_PUBLIC_API(bool)
- AddPromiseReactions(JSContext* cx, JS::HandleObject promise,
- JS::HandleObject onResolve, JS::HandleObject onReject);
- /**
- * Unforgeable version of the JS builtin Promise.all.
- *
- * Takes an AutoObjectVector of Promise objects and returns a promise that's
- * resolved with an array of resolution values when all those promises ahve
- * been resolved, or rejected with the rejection value of the first rejected
- * promise.
- *
- * Asserts if the array isn't dense or one of the entries isn't an unwrapped
- * instance of Promise or a subclass.
- */
- extern JS_PUBLIC_API(JSObject*)
- GetWaitForAllPromise(JSContext* cx, const JS::AutoObjectVector& promises);
- /**
- * An AsyncTask represents a SpiderMonkey-internal operation that starts on a
- * JSContext's owner thread, possibly executes on other threads, completes, and
- * then needs to be scheduled to run again on the JSContext's owner thread. The
- * embedding provides for this final dispatch back to the JSContext's owner
- * thread by calling methods on this interface when requested.
- */
- struct JS_PUBLIC_API(AsyncTask)
- {
- AsyncTask() : user(nullptr) {}
- virtual ~AsyncTask() {}
- /**
- * After the FinishAsyncTaskCallback is called and succeeds, one of these
- * two functions will be called on the original JSContext's owner thread.
- */
- virtual void finish(JSContext* cx) = 0;
- virtual void cancel(JSContext* cx) = 0;
- /* The embedding may use this field to attach arbitrary data to a task. */
- void* user;
- };
- /**
- * A new AsyncTask object, created inside SpiderMonkey on the JSContext's owner
- * thread, will be passed to the StartAsyncTaskCallback before it is dispatched
- * to another thread. The embedding may use the AsyncTask::user field to attach
- * additional task state.
- *
- * If this function succeeds, SpiderMonkey will call the FinishAsyncTaskCallback
- * at some point in the future. Otherwise, FinishAsyncTaskCallback will *not*
- * be called. SpiderMonkey assumes that, if StartAsyncTaskCallback fails, it is
- * because the JSContext is being shut down.
- */
- typedef bool
- (*StartAsyncTaskCallback)(JSContext* cx, AsyncTask* task);
- /**
- * The FinishAsyncTaskCallback may be called from any thread and will only be
- * passed AsyncTasks that have already been started via StartAsyncTaskCallback.
- * If the embedding returns 'true', indicating success, the embedding must call
- * either task->finish() or task->cancel() on the JSContext's owner thread at
- * some point in the future.
- */
- typedef bool
- (*FinishAsyncTaskCallback)(AsyncTask* task);
- /**
- * Set the above callbacks for the given context.
- */
- extern JS_PUBLIC_API(void)
- SetAsyncTaskCallbacks(JSContext* cx, StartAsyncTaskCallback start, FinishAsyncTaskCallback finish);
- } // namespace JS
- extern JS_PUBLIC_API(bool)
- JS_IsRunning(JSContext* cx);
- namespace JS {
- /**
- * This class can be used to store a pointer to the youngest frame of a saved
- * stack in the specified JSContext. This reference will be picked up by any new
- * calls performed until the class is destroyed, with the specified asyncCause,
- * that must not be empty.
- *
- * Any stack capture initiated during these new calls will go through the async
- * stack instead of the current stack.
- *
- * Capturing the stack before a new call is performed will not be affected.
- *
- * The provided chain of SavedFrame objects can live in any compartment,
- * although it will be copied to the compartment where the stack is captured.
- *
- * See also `js/src/doc/SavedFrame/SavedFrame.md` for documentation on async
- * stack frames.
- */
- class MOZ_STACK_CLASS JS_PUBLIC_API(AutoSetAsyncStackForNewCalls)
- {
- JSContext* cx;
- RootedObject oldAsyncStack;
- const char* oldAsyncCause;
- bool oldAsyncCallIsExplicit;
- public:
- enum class AsyncCallKind {
- // The ordinary kind of call, where we may apply an async
- // parent if there is no ordinary parent.
- IMPLICIT,
- // An explicit async parent, e.g., callFunctionWithAsyncStack,
- // where we always want to override any ordinary parent.
- EXPLICIT
- };
- // The stack parameter cannot be null by design, because it would be
- // ambiguous whether that would clear any scheduled async stack and make the
- // normal stack reappear in the new call, or just keep the async stack
- // already scheduled for the new call, if any.
- //
- // asyncCause is owned by the caller and its lifetime must outlive the
- // lifetime of the AutoSetAsyncStackForNewCalls object. It is strongly
- // encouraged that asyncCause be a string constant or similar statically
- // allocated string.
- AutoSetAsyncStackForNewCalls(JSContext* cx, HandleObject stack,
- const char* asyncCause,
- AsyncCallKind kind = AsyncCallKind::IMPLICIT);
- ~AutoSetAsyncStackForNewCalls();
- };
- } // namespace JS
- /************************************************************************/
- /*
- * Strings.
- *
- * NB: JS_NewUCString takes ownership of bytes on success, avoiding a copy;
- * but on error (signified by null return), it leaves chars owned by the
- * caller. So the caller must free bytes in the error case, if it has no use
- * for them. In contrast, all the JS_New*StringCopy* functions do not take
- * ownership of the character memory passed to them -- they copy it.
- */
- extern JS_PUBLIC_API(JSString*)
- JS_NewStringCopyN(JSContext* cx, const char* s, size_t n);
- extern JS_PUBLIC_API(JSString*)
- JS_NewStringCopyZ(JSContext* cx, const char* s);
- extern JS_PUBLIC_API(JSString*)
- JS_NewStringCopyUTF8Z(JSContext* cx, const JS::ConstUTF8CharsZ s);
- extern JS_PUBLIC_API(JSString*)
- JS_NewStringCopyUTF8N(JSContext* cx, const JS::UTF8Chars s);
- extern JS_PUBLIC_API(JSString*)
- JS_AtomizeAndPinJSString(JSContext* cx, JS::HandleString str);
- extern JS_PUBLIC_API(JSString*)
- JS_AtomizeStringN(JSContext* cx, const char* s, size_t length);
- extern JS_PUBLIC_API(JSString*)
- JS_AtomizeString(JSContext* cx, const char* s);
- extern JS_PUBLIC_API(JSString*)
- JS_AtomizeAndPinStringN(JSContext* cx, const char* s, size_t length);
- extern JS_PUBLIC_API(JSString*)
- JS_AtomizeAndPinString(JSContext* cx, const char* s);
- extern JS_PUBLIC_API(JSString*)
- JS_NewUCString(JSContext* cx, char16_t* chars, size_t length);
- extern JS_PUBLIC_API(JSString*)
- JS_NewUCStringCopyN(JSContext* cx, const char16_t* s, size_t n);
- extern JS_PUBLIC_API(JSString*)
- JS_NewUCStringCopyZ(JSContext* cx, const char16_t* s);
- extern JS_PUBLIC_API(JSString*)
- JS_AtomizeUCStringN(JSContext* cx, const char16_t* s, size_t length);
- extern JS_PUBLIC_API(JSString*)
- JS_AtomizeUCString(JSContext* cx, const char16_t* s);
- extern JS_PUBLIC_API(JSString*)
- JS_AtomizeAndPinUCStringN(JSContext* cx, const char16_t* s, size_t length);
- extern JS_PUBLIC_API(JSString*)
- JS_AtomizeAndPinUCString(JSContext* cx, const char16_t* s);
- extern JS_PUBLIC_API(bool)
- JS_CompareStrings(JSContext* cx, JSString* str1, JSString* str2, int32_t* result);
- extern JS_PUBLIC_API(bool)
- JS_StringEqualsAscii(JSContext* cx, JSString* str, const char* asciiBytes, bool* match);
- extern JS_PUBLIC_API(size_t)
- JS_PutEscapedString(JSContext* cx, char* buffer, size_t size, JSString* str, char quote);
- extern JS_PUBLIC_API(bool)
- JS_FileEscapedString(FILE* fp, JSString* str, char quote);
- /*
- * Extracting string characters and length.
- *
- * While getting the length of a string is infallible, getting the chars can
- * fail. As indicated by the lack of a JSContext parameter, there are two
- * special cases where getting the chars is infallible:
- *
- * The first case is for strings that have been atomized, e.g. directly by
- * JS_AtomizeAndPinString or implicitly because it is stored in a jsid.
- *
- * The second case is "flat" strings that have been explicitly prepared in a
- * fallible context by JS_FlattenString. To catch errors, a separate opaque
- * JSFlatString type is returned by JS_FlattenString and expected by
- * JS_GetFlatStringChars. Note, though, that this is purely a syntactic
- * distinction: the input and output of JS_FlattenString are the same actual
- * GC-thing. If a JSString is known to be flat, JS_ASSERT_STRING_IS_FLAT can be
- * used to make a debug-checked cast. Example:
- *
- * // in a fallible context
- * JSFlatString* fstr = JS_FlattenString(cx, str);
- * if (!fstr)
- * return false;
- * MOZ_ASSERT(fstr == JS_ASSERT_STRING_IS_FLAT(str));
- *
- * // in an infallible context, for the same 'str'
- * AutoCheckCannotGC nogc;
- * const char16_t* chars = JS_GetTwoByteFlatStringChars(nogc, fstr)
- * MOZ_ASSERT(chars);
- *
- * Flat strings and interned strings are always null-terminated, so
- * JS_FlattenString can be used to get a null-terminated string.
- *
- * Additionally, string characters are stored as either Latin1Char (8-bit)
- * or char16_t (16-bit). Clients can use JS_StringHasLatin1Chars and can then
- * call either the Latin1* or TwoByte* functions. Some functions like
- * JS_CopyStringChars and JS_GetStringCharAt accept both Latin1 and TwoByte
- * strings.
- */
- extern JS_PUBLIC_API(size_t)
- JS_GetStringLength(JSString* str);
- extern JS_PUBLIC_API(bool)
- JS_StringIsFlat(JSString* str);
- /** Returns true iff the string's characters are stored as Latin1. */
- extern JS_PUBLIC_API(bool)
- JS_StringHasLatin1Chars(JSString* str);
- extern JS_PUBLIC_API(const JS::Latin1Char*)
- JS_GetLatin1StringCharsAndLength(JSContext* cx, const JS::AutoCheckCannotGC& nogc, JSString* str,
- size_t* length);
- extern JS_PUBLIC_API(const char16_t*)
- JS_GetTwoByteStringCharsAndLength(JSContext* cx, const JS::AutoCheckCannotGC& nogc, JSString* str,
- size_t* length);
- extern JS_PUBLIC_API(bool)
- JS_GetStringCharAt(JSContext* cx, JSString* str, size_t index, char16_t* res);
- extern JS_PUBLIC_API(char16_t)
- JS_GetFlatStringCharAt(JSFlatString* str, size_t index);
- extern JS_PUBLIC_API(const char16_t*)
- JS_GetTwoByteExternalStringChars(JSString* str);
- extern JS_PUBLIC_API(bool)
- JS_CopyStringChars(JSContext* cx, mozilla::Range<char16_t> dest, JSString* str);
- extern JS_PUBLIC_API(JSFlatString*)
- JS_FlattenString(JSContext* cx, JSString* str);
- extern JS_PUBLIC_API(const JS::Latin1Char*)
- JS_GetLatin1FlatStringChars(const JS::AutoCheckCannotGC& nogc, JSFlatString* str);
- extern JS_PUBLIC_API(const char16_t*)
- JS_GetTwoByteFlatStringChars(const JS::AutoCheckCannotGC& nogc, JSFlatString* str);
- static MOZ_ALWAYS_INLINE JSFlatString*
- JSID_TO_FLAT_STRING(jsid id)
- {
- MOZ_ASSERT(JSID_IS_STRING(id));
- return (JSFlatString*)(JSID_BITS(id));
- }
- static MOZ_ALWAYS_INLINE JSFlatString*
- JS_ASSERT_STRING_IS_FLAT(JSString* str)
- {
- MOZ_ASSERT(JS_StringIsFlat(str));
- return (JSFlatString*)str;
- }
- static MOZ_ALWAYS_INLINE JSString*
- JS_FORGET_STRING_FLATNESS(JSFlatString* fstr)
- {
- return (JSString*)fstr;
- }
- /*
- * Additional APIs that avoid fallibility when given a flat string.
- */
- extern JS_PUBLIC_API(bool)
- JS_FlatStringEqualsAscii(JSFlatString* str, const char* asciiBytes);
- extern JS_PUBLIC_API(size_t)
- JS_PutEscapedFlatString(char* buffer, size_t size, JSFlatString* str, char quote);
- /**
- * Create a dependent string, i.e., a string that owns no character storage,
- * but that refers to a slice of another string's chars. Dependent strings
- * are mutable by definition, so the thread safety comments above apply.
- */
- extern JS_PUBLIC_API(JSString*)
- JS_NewDependentString(JSContext* cx, JS::HandleString str, size_t start,
- size_t length);
- /**
- * Concatenate two strings, possibly resulting in a rope.
- * See above for thread safety comments.
- */
- extern JS_PUBLIC_API(JSString*)
- JS_ConcatStrings(JSContext* cx, JS::HandleString left, JS::HandleString right);
- /**
- * For JS_DecodeBytes, set *dstlenp to the size of the destination buffer before
- * the call; on return, *dstlenp contains the number of characters actually
- * stored. To determine the necessary destination buffer size, make a sizing
- * call that passes nullptr for dst.
- *
- * On errors, the functions report the error. In that case, *dstlenp contains
- * the number of characters or bytes transferred so far. If cx is nullptr, no
- * error is reported on failure, and the functions simply return false.
- *
- * NB: This function does not store an additional zero byte or char16_t after the
- * transcoded string.
- */
- JS_PUBLIC_API(bool)
- JS_DecodeBytes(JSContext* cx, const char* src, size_t srclen, char16_t* dst,
- size_t* dstlenp);
- /**
- * A variation on JS_EncodeCharacters where a null terminated string is
- * returned that you are expected to call JS_free on when done.
- */
- JS_PUBLIC_API(char*)
- JS_EncodeString(JSContext* cx, JSString* str);
- /**
- * Same behavior as JS_EncodeString(), but encode into UTF-8 string
- */
- JS_PUBLIC_API(char*)
- JS_EncodeStringToUTF8(JSContext* cx, JS::HandleString str);
- /**
- * Get number of bytes in the string encoding (without accounting for a
- * terminating zero bytes. The function returns (size_t) -1 if the string
- * can not be encoded into bytes and reports an error using cx accordingly.
- */
- JS_PUBLIC_API(size_t)
- JS_GetStringEncodingLength(JSContext* cx, JSString* str);
- /**
- * Encode string into a buffer. The function does not stores an additional
- * zero byte. The function returns (size_t) -1 if the string can not be
- * encoded into bytes with no error reported. Otherwise it returns the number
- * of bytes that are necessary to encode the string. If that exceeds the
- * length parameter, the string will be cut and only length bytes will be
- * written into the buffer.
- */
- JS_PUBLIC_API(size_t)
- JS_EncodeStringToBuffer(JSContext* cx, JSString* str, char* buffer, size_t length);
- class MOZ_RAII JSAutoByteString
- {
- public:
- JSAutoByteString(JSContext* cx, JSString* str
- MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
- : mBytes(JS_EncodeString(cx, str))
- {
- MOZ_ASSERT(cx);
- MOZ_GUARD_OBJECT_NOTIFIER_INIT;
- }
- explicit JSAutoByteString(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
- : mBytes(nullptr)
- {
- MOZ_GUARD_OBJECT_NOTIFIER_INIT;
- }
- ~JSAutoByteString() {
- JS_free(nullptr, mBytes);
- }
- /* Take ownership of the given byte array. */
- void initBytes(char* bytes) {
- MOZ_ASSERT(!mBytes);
- mBytes = bytes;
- }
- char* encodeLatin1(JSContext* cx, JSString* str) {
- MOZ_ASSERT(!mBytes);
- MOZ_ASSERT(cx);
- mBytes = JS_EncodeString(cx, str);
- return mBytes;
- }
- char* encodeLatin1(js::ExclusiveContext* cx, JSString* str);
- char* encodeUtf8(JSContext* cx, JS::HandleString str) {
- MOZ_ASSERT(!mBytes);
- MOZ_ASSERT(cx);
- mBytes = JS_EncodeStringToUTF8(cx, str);
- return mBytes;
- }
- void clear() {
- js_free(mBytes);
- mBytes = nullptr;
- }
- char* ptr() const {
- return mBytes;
- }
- bool operator!() const {
- return !mBytes;
- }
- size_t length() const {
- if (!mBytes)
- return 0;
- return strlen(mBytes);
- }
- private:
- char* mBytes;
- MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
- /* Copy and assignment are not supported. */
- JSAutoByteString(const JSAutoByteString& another);
- JSAutoByteString& operator=(const JSAutoByteString& another);
- };
- namespace JS {
- extern JS_PUBLIC_API(JSAddonId*)
- NewAddonId(JSContext* cx, JS::HandleString str);
- extern JS_PUBLIC_API(JSString*)
- StringOfAddonId(JSAddonId* id);
- extern JS_PUBLIC_API(JSAddonId*)
- AddonIdOfObject(JSObject* obj);
- } // namespace JS
- /************************************************************************/
- /*
- * Symbols
- */
- namespace JS {
- /**
- * Create a new Symbol with the given description. This function never returns
- * a Symbol that is in the Runtime-wide symbol registry.
- *
- * If description is null, the new Symbol's [[Description]] attribute is
- * undefined.
- */
- JS_PUBLIC_API(Symbol*)
- NewSymbol(JSContext* cx, HandleString description);
- /**
- * Symbol.for as specified in ES6.
- *
- * Get a Symbol with the description 'key' from the Runtime-wide symbol registry.
- * If there is not already a Symbol with that description in the registry, a new
- * Symbol is created and registered. 'key' must not be null.
- */
- JS_PUBLIC_API(Symbol*)
- GetSymbolFor(JSContext* cx, HandleString key);
- /**
- * Get the [[Description]] attribute of the given symbol.
- *
- * This function is infallible. If it returns null, that means the symbol's
- * [[Description]] is undefined.
- */
- JS_PUBLIC_API(JSString*)
- GetSymbolDescription(HandleSymbol symbol);
- /* Well-known symbols. */
- #define JS_FOR_EACH_WELL_KNOWN_SYMBOL(macro) \
- macro(isConcatSpreadable) \
- macro(iterator) \
- macro(match) \
- macro(replace) \
- macro(search) \
- macro(species) \
- macro(hasInstance) \
- macro(split) \
- macro(toPrimitive) \
- macro(toStringTag) \
- macro(unscopables)
- enum class SymbolCode : uint32_t {
- // There is one SymbolCode for each well-known symbol.
- #define JS_DEFINE_SYMBOL_ENUM(name) name,
- JS_FOR_EACH_WELL_KNOWN_SYMBOL(JS_DEFINE_SYMBOL_ENUM) // SymbolCode::iterator, etc.
- #undef JS_DEFINE_SYMBOL_ENUM
- Limit,
- InSymbolRegistry = 0xfffffffe, // created by Symbol.for() or JS::GetSymbolFor()
- UniqueSymbol = 0xffffffff // created by Symbol() or JS::NewSymbol()
- };
- /* For use in loops that iterate over the well-known symbols. */
- const size_t WellKnownSymbolLimit = size_t(SymbolCode::Limit);
- /**
- * Return the SymbolCode telling what sort of symbol `symbol` is.
- *
- * A symbol's SymbolCode never changes once it is created.
- */
- JS_PUBLIC_API(SymbolCode)
- GetSymbolCode(Handle<Symbol*> symbol);
- /**
- * Get one of the well-known symbols defined by ES6. A single set of well-known
- * symbols is shared by all compartments in a JSRuntime.
- *
- * `which` must be in the range [0, WellKnownSymbolLimit).
- */
- JS_PUBLIC_API(Symbol*)
- GetWellKnownSymbol(JSContext* cx, SymbolCode which);
- /**
- * Return true if the given JSPropertySpec::name or JSFunctionSpec::name value
- * is actually a symbol code and not a string. See JS_SYM_FN.
- */
- inline bool
- PropertySpecNameIsSymbol(const char* name)
- {
- uintptr_t u = reinterpret_cast<uintptr_t>(name);
- return u != 0 && u - 1 < WellKnownSymbolLimit;
- }
- JS_PUBLIC_API(bool)
- PropertySpecNameEqualsId(const char* name, HandleId id);
- /**
- * Create a jsid that does not need to be marked for GC.
- *
- * 'name' is a JSPropertySpec::name or JSFunctionSpec::name value. The
- * resulting jsid, on success, is either an interned string or a well-known
- * symbol; either way it is immune to GC so there is no need to visit *idp
- * during GC marking.
- */
- JS_PUBLIC_API(bool)
- PropertySpecNameToPermanentId(JSContext* cx, const char* name, jsid* idp);
- } /* namespace JS */
- /************************************************************************/
- /*
- * JSON functions
- */
- typedef bool (* JSONWriteCallback)(const char16_t* buf, uint32_t len, void* data);
- /**
- * JSON.stringify as specified by ES5.
- */
- JS_PUBLIC_API(bool)
- JS_Stringify(JSContext* cx, JS::MutableHandleValue value, JS::HandleObject replacer,
- JS::HandleValue space, JSONWriteCallback callback, void* data);
- namespace JS {
- /**
- * An API akin to JS_Stringify but with the goal of not having observable
- * side-effects when the stringification is performed. This means it does not
- * allow a replacer or a custom space, and has the following constraints on its
- * input:
- *
- * 1) The input must be a plain object or array, not an abitrary value.
- * 2) Every value in the graph reached by the algorithm starting with this
- * object must be one of the following: null, undefined, a string (NOT a
- * string object!), a boolean, a finite number (i.e. no NaN or Infinity or
- * -Infinity), a plain object with no accessor properties, or an Array with
- * no holes.
- *
- * The actual behavior differs from JS_Stringify only in asserting the above and
- * NOT attempting to get the "toJSON" property from things, since that could
- * clearly have side-effects.
- */
- JS_PUBLIC_API(bool)
- ToJSONMaybeSafely(JSContext* cx, JS::HandleObject input,
- JSONWriteCallback callback, void* data);
- } /* namespace JS */
- /**
- * JSON.parse as specified by ES5.
- */
- JS_PUBLIC_API(bool)
- JS_ParseJSON(JSContext* cx, const char16_t* chars, uint32_t len, JS::MutableHandleValue vp);
- JS_PUBLIC_API(bool)
- JS_ParseJSON(JSContext* cx, JS::HandleString str, JS::MutableHandleValue vp);
- JS_PUBLIC_API(bool)
- JS_ParseJSONWithReviver(JSContext* cx, const char16_t* chars, uint32_t len, JS::HandleValue reviver,
- JS::MutableHandleValue vp);
- JS_PUBLIC_API(bool)
- JS_ParseJSONWithReviver(JSContext* cx, JS::HandleString str, JS::HandleValue reviver,
- JS::MutableHandleValue vp);
- /************************************************************************/
- /**
- * The default locale for the ECMAScript Internationalization API
- * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat).
- * Note that the Internationalization API encourages clients to
- * specify their own locales.
- * The locale string remains owned by the caller.
- */
- extern JS_PUBLIC_API(bool)
- JS_SetDefaultLocale(JSContext* cx, const char* locale);
- /**
- * Look up the default locale for the ECMAScript Internationalization API.
- */
- extern JS_PUBLIC_API(JS::UniqueChars)
- JS_GetDefaultLocale(JSContext* cx);
- /**
- * Reset the default locale to OS defaults.
- */
- extern JS_PUBLIC_API(void)
- JS_ResetDefaultLocale(JSContext* cx);
- /**
- * Locale specific string conversion and error message callbacks.
- */
- struct JSLocaleCallbacks {
- JSLocaleToUpperCase localeToUpperCase;
- JSLocaleToLowerCase localeToLowerCase;
- JSLocaleCompare localeCompare; // not used #if EXPOSE_INTL_API
- JSLocaleToUnicode localeToUnicode;
- };
- /**
- * Establish locale callbacks. The pointer must persist as long as the
- * JSContext. Passing nullptr restores the default behaviour.
- */
- extern JS_PUBLIC_API(void)
- JS_SetLocaleCallbacks(JSContext* cx, const JSLocaleCallbacks* callbacks);
- /**
- * Return the address of the current locale callbacks struct, which may
- * be nullptr.
- */
- extern JS_PUBLIC_API(const JSLocaleCallbacks*)
- JS_GetLocaleCallbacks(JSContext* cx);
- /************************************************************************/
- /*
- * Error reporting.
- */
- namespace JS {
- const uint16_t MaxNumErrorArguments = 10;
- };
- /**
- * Report an exception represented by the sprintf-like conversion of format
- * and its arguments.
- */
- extern JS_PUBLIC_API(void)
- JS_ReportErrorASCII(JSContext* cx, const char* format, ...)
- MOZ_FORMAT_PRINTF(2, 3);
- extern JS_PUBLIC_API(void)
- JS_ReportErrorLatin1(JSContext* cx, const char* format, ...)
- MOZ_FORMAT_PRINTF(2, 3);
- extern JS_PUBLIC_API(void)
- JS_ReportErrorUTF8(JSContext* cx, const char* format, ...)
- MOZ_FORMAT_PRINTF(2, 3);
- /*
- * Use an errorNumber to retrieve the format string, args are char*
- */
- extern JS_PUBLIC_API(void)
- JS_ReportErrorNumberASCII(JSContext* cx, JSErrorCallback errorCallback,
- void* userRef, const unsigned errorNumber, ...);
- extern JS_PUBLIC_API(void)
- JS_ReportErrorNumberASCIIVA(JSContext* cx, JSErrorCallback errorCallback,
- void* userRef, const unsigned errorNumber, va_list ap);
- extern JS_PUBLIC_API(void)
- JS_ReportErrorNumberLatin1(JSContext* cx, JSErrorCallback errorCallback,
- void* userRef, const unsigned errorNumber, ...);
- #ifdef va_start
- extern JS_PUBLIC_API(void)
- JS_ReportErrorNumberLatin1VA(JSContext* cx, JSErrorCallback errorCallback,
- void* userRef, const unsigned errorNumber, va_list ap);
- #endif
- extern JS_PUBLIC_API(void)
- JS_ReportErrorNumberUTF8(JSContext* cx, JSErrorCallback errorCallback,
- void* userRef, const unsigned errorNumber, ...);
- #ifdef va_start
- extern JS_PUBLIC_API(void)
- JS_ReportErrorNumberUTF8VA(JSContext* cx, JSErrorCallback errorCallback,
- void* userRef, const unsigned errorNumber, va_list ap);
- #endif
- /*
- * Use an errorNumber to retrieve the format string, args are char16_t*
- */
- extern JS_PUBLIC_API(void)
- JS_ReportErrorNumberUC(JSContext* cx, JSErrorCallback errorCallback,
- void* userRef, const unsigned errorNumber, ...);
- extern JS_PUBLIC_API(void)
- JS_ReportErrorNumberUCArray(JSContext* cx, JSErrorCallback errorCallback,
- void* userRef, const unsigned errorNumber,
- const char16_t** args);
- /**
- * As above, but report a warning instead (JSREPORT_IS_WARNING(report.flags)).
- * Return true if there was no error trying to issue the warning, and if the
- * warning was not converted into an error due to the JSOPTION_WERROR option
- * being set, false otherwise.
- */
- extern JS_PUBLIC_API(bool)
- JS_ReportWarningASCII(JSContext* cx, const char* format, ...)
- MOZ_FORMAT_PRINTF(2, 3);
- extern JS_PUBLIC_API(bool)
- JS_ReportWarningLatin1(JSContext* cx, const char* format, ...)
- MOZ_FORMAT_PRINTF(2, 3);
- extern JS_PUBLIC_API(bool)
- JS_ReportWarningUTF8(JSContext* cx, const char* format, ...)
- MOZ_FORMAT_PRINTF(2, 3);
- extern JS_PUBLIC_API(bool)
- JS_ReportErrorFlagsAndNumberASCII(JSContext* cx, unsigned flags,
- JSErrorCallback errorCallback, void* userRef,
- const unsigned errorNumber, ...);
- extern JS_PUBLIC_API(bool)
- JS_ReportErrorFlagsAndNumberLatin1(JSContext* cx, unsigned flags,
- JSErrorCallback errorCallback, void* userRef,
- const unsigned errorNumber, ...);
- extern JS_PUBLIC_API(bool)
- JS_ReportErrorFlagsAndNumberUTF8(JSContext* cx, unsigned flags,
- JSErrorCallback errorCallback, void* userRef,
- const unsigned errorNumber, ...);
- extern JS_PUBLIC_API(bool)
- JS_ReportErrorFlagsAndNumberUC(JSContext* cx, unsigned flags,
- JSErrorCallback errorCallback, void* userRef,
- const unsigned errorNumber, ...);
- /**
- * Complain when out of memory.
- */
- extern JS_PUBLIC_API(void)
- JS_ReportOutOfMemory(JSContext* cx);
- /**
- * Complain when an allocation size overflows the maximum supported limit.
- */
- extern JS_PUBLIC_API(void)
- JS_ReportAllocationOverflow(JSContext* cx);
- class JSErrorReport
- {
- // The (default) error message.
- // If ownsMessage_ is true, the it is freed in destructor.
- JS::ConstUTF8CharsZ message_;
- // Offending source line without final '\n'.
- // If ownsLinebuf__ is true, the buffer is freed in destructor.
- const char16_t* linebuf_;
- // Number of chars in linebuf_. Does not include trailing '\0'.
- size_t linebufLength_;
- // The 0-based offset of error token in linebuf_.
- size_t tokenOffset_;
- public:
- JSErrorReport()
- : linebuf_(nullptr), linebufLength_(0), tokenOffset_(0),
- filename(nullptr), lineno(0), column(0),
- flags(0), errorNumber(0),
- exnType(0), isMuted(false),
- ownsLinebuf_(false), ownsMessage_(false)
- {}
- ~JSErrorReport() {
- freeLinebuf();
- freeMessage();
- }
- const char* filename; /* source file name, URL, etc., or null */
- unsigned lineno; /* source line number */
- unsigned column; /* zero-based column index in line */
- unsigned flags; /* error/warning, etc. */
- unsigned errorNumber; /* the error number, e.g. see js.msg */
- int16_t exnType; /* One of the JSExnType constants */
- bool isMuted : 1; /* See the comment in ReadOnlyCompileOptions. */
- private:
- bool ownsLinebuf_ : 1;
- bool ownsMessage_ : 1;
- public:
- const char16_t* linebuf() const {
- return linebuf_;
- }
- size_t linebufLength() const {
- return linebufLength_;
- }
- size_t tokenOffset() const {
- return tokenOffset_;
- }
- void initOwnedLinebuf(const char16_t* linebufArg, size_t linebufLengthArg, size_t tokenOffsetArg) {
- initBorrowedLinebuf(linebufArg, linebufLengthArg, tokenOffsetArg);
- ownsLinebuf_ = true;
- }
- void initBorrowedLinebuf(const char16_t* linebufArg, size_t linebufLengthArg, size_t tokenOffsetArg);
- void freeLinebuf();
- const JS::ConstUTF8CharsZ message() const {
- return message_;
- }
- void initOwnedMessage(const char* messageArg) {
- initBorrowedMessage(messageArg);
- ownsMessage_ = true;
- }
- void initBorrowedMessage(const char* messageArg) {
- MOZ_ASSERT(!message_);
- message_ = JS::ConstUTF8CharsZ(messageArg, strlen(messageArg));
- }
- JSString* newMessageString(JSContext* cx);
- void freeMessage();
- };
- /*
- * JSErrorReport flag values. These may be freely composed.
- */
- #define JSREPORT_ERROR 0x0 /* pseudo-flag for default case */
- #define JSREPORT_WARNING 0x1 /* reported via JS_ReportWarning */
- #define JSREPORT_EXCEPTION 0x2 /* exception was thrown */
- #define JSREPORT_STRICT 0x4 /* error or warning due to strict option */
- #define JSREPORT_USER_1 0x8 /* user-defined flag */
- /*
- * If JSREPORT_EXCEPTION is set, then a JavaScript-catchable exception
- * has been thrown for this runtime error, and the host should ignore it.
- * Exception-aware hosts should also check for JS_IsExceptionPending if
- * JS_ExecuteScript returns failure, and signal or propagate the exception, as
- * appropriate.
- */
- #define JSREPORT_IS_WARNING(flags) (((flags) & JSREPORT_WARNING) != 0)
- #define JSREPORT_IS_EXCEPTION(flags) (((flags) & JSREPORT_EXCEPTION) != 0)
- #define JSREPORT_IS_STRICT(flags) (((flags) & JSREPORT_STRICT) != 0)
- namespace JS {
- using WarningReporter = void (*)(JSContext* cx, JSErrorReport* report);
- extern JS_PUBLIC_API(WarningReporter)
- SetWarningReporter(JSContext* cx, WarningReporter reporter);
- extern JS_PUBLIC_API(WarningReporter)
- GetWarningReporter(JSContext* cx);
- extern JS_PUBLIC_API(bool)
- CreateError(JSContext* cx, JSExnType type, HandleObject stack,
- HandleString fileName, uint32_t lineNumber, uint32_t columnNumber,
- JSErrorReport* report, HandleString message, MutableHandleValue rval);
- /************************************************************************/
- /*
- * Weak Maps.
- */
- extern JS_PUBLIC_API(JSObject*)
- NewWeakMapObject(JSContext* cx);
- extern JS_PUBLIC_API(bool)
- IsWeakMapObject(JSObject* obj);
- extern JS_PUBLIC_API(bool)
- GetWeakMapEntry(JSContext* cx, JS::HandleObject mapObj, JS::HandleObject key,
- JS::MutableHandleValue val);
- extern JS_PUBLIC_API(bool)
- SetWeakMapEntry(JSContext* cx, JS::HandleObject mapObj, JS::HandleObject key,
- JS::HandleValue val);
- /*
- * Map
- */
- extern JS_PUBLIC_API(JSObject*)
- NewMapObject(JSContext* cx);
- extern JS_PUBLIC_API(uint32_t)
- MapSize(JSContext* cx, HandleObject obj);
- extern JS_PUBLIC_API(bool)
- MapGet(JSContext* cx, HandleObject obj,
- HandleValue key, MutableHandleValue rval);
- extern JS_PUBLIC_API(bool)
- MapHas(JSContext* cx, HandleObject obj, HandleValue key, bool* rval);
- extern JS_PUBLIC_API(bool)
- MapSet(JSContext* cx, HandleObject obj, HandleValue key, HandleValue val);
- extern JS_PUBLIC_API(bool)
- MapDelete(JSContext *cx, HandleObject obj, HandleValue key, bool *rval);
- extern JS_PUBLIC_API(bool)
- MapClear(JSContext* cx, HandleObject obj);
- extern JS_PUBLIC_API(bool)
- MapKeys(JSContext* cx, HandleObject obj, MutableHandleValue rval);
- extern JS_PUBLIC_API(bool)
- MapValues(JSContext* cx, HandleObject obj, MutableHandleValue rval);
- extern JS_PUBLIC_API(bool)
- MapEntries(JSContext* cx, HandleObject obj, MutableHandleValue rval);
- extern JS_PUBLIC_API(bool)
- MapForEach(JSContext *cx, HandleObject obj, HandleValue callbackFn, HandleValue thisVal);
- /*
- * Set
- */
- extern JS_PUBLIC_API(JSObject *)
- NewSetObject(JSContext *cx);
- extern JS_PUBLIC_API(uint32_t)
- SetSize(JSContext *cx, HandleObject obj);
- extern JS_PUBLIC_API(bool)
- SetHas(JSContext *cx, HandleObject obj, HandleValue key, bool *rval);
- extern JS_PUBLIC_API(bool)
- SetDelete(JSContext *cx, HandleObject obj, HandleValue key, bool *rval);
- extern JS_PUBLIC_API(bool)
- SetAdd(JSContext *cx, HandleObject obj, HandleValue key);
- extern JS_PUBLIC_API(bool)
- SetClear(JSContext *cx, HandleObject obj);
- extern JS_PUBLIC_API(bool)
- SetKeys(JSContext *cx, HandleObject obj, MutableHandleValue rval);
- extern JS_PUBLIC_API(bool)
- SetValues(JSContext *cx, HandleObject obj, MutableHandleValue rval);
- extern JS_PUBLIC_API(bool)
- SetEntries(JSContext *cx, HandleObject obj, MutableHandleValue rval);
- extern JS_PUBLIC_API(bool)
- SetForEach(JSContext *cx, HandleObject obj, HandleValue callbackFn, HandleValue thisVal);
- } /* namespace JS */
- /*
- * Dates.
- */
- extern JS_PUBLIC_API(JSObject*)
- JS_NewDateObject(JSContext* cx, int year, int mon, int mday, int hour, int min, int sec);
- /**
- * Returns true and sets |*isDate| indicating whether |obj| is a Date object or
- * a wrapper around one, otherwise returns false on failure.
- *
- * This method returns true with |*isDate == false| when passed a proxy whose
- * target is a Date, or when passed a revoked proxy.
- */
- extern JS_PUBLIC_API(bool)
- JS_ObjectIsDate(JSContext* cx, JS::HandleObject obj, bool* isDate);
- /************************************************************************/
- /*
- * Regular Expressions.
- */
- #define JSREG_FOLD 0x01u /* fold uppercase to lowercase */
- #define JSREG_GLOB 0x02u /* global exec, creates array of matches */
- #define JSREG_MULTILINE 0x04u /* treat ^ and $ as begin and end of line */
- #define JSREG_STICKY 0x08u /* only match starting at lastIndex */
- #define JSREG_UNICODE 0x10u /* unicode */
- extern JS_PUBLIC_API(JSObject*)
- JS_NewRegExpObject(JSContext* cx, const char* bytes, size_t length, unsigned flags);
- extern JS_PUBLIC_API(JSObject*)
- JS_NewUCRegExpObject(JSContext* cx, const char16_t* chars, size_t length, unsigned flags);
- extern JS_PUBLIC_API(bool)
- JS_SetRegExpInput(JSContext* cx, JS::HandleObject obj, JS::HandleString input);
- extern JS_PUBLIC_API(bool)
- JS_ClearRegExpStatics(JSContext* cx, JS::HandleObject obj);
- extern JS_PUBLIC_API(bool)
- JS_ExecuteRegExp(JSContext* cx, JS::HandleObject obj, JS::HandleObject reobj,
- char16_t* chars, size_t length, size_t* indexp, bool test,
- JS::MutableHandleValue rval);
- /* RegExp interface for clients without a global object. */
- extern JS_PUBLIC_API(bool)
- JS_ExecuteRegExpNoStatics(JSContext* cx, JS::HandleObject reobj, char16_t* chars, size_t length,
- size_t* indexp, bool test, JS::MutableHandleValue rval);
- /**
- * Returns true and sets |*isRegExp| indicating whether |obj| is a RegExp
- * object or a wrapper around one, otherwise returns false on failure.
- *
- * This method returns true with |*isRegExp == false| when passed a proxy whose
- * target is a RegExp, or when passed a revoked proxy.
- */
- extern JS_PUBLIC_API(bool)
- JS_ObjectIsRegExp(JSContext* cx, JS::HandleObject obj, bool* isRegExp);
- extern JS_PUBLIC_API(unsigned)
- JS_GetRegExpFlags(JSContext* cx, JS::HandleObject obj);
- extern JS_PUBLIC_API(JSString*)
- JS_GetRegExpSource(JSContext* cx, JS::HandleObject obj);
- /************************************************************************/
- extern JS_PUBLIC_API(bool)
- JS_IsExceptionPending(JSContext* cx);
- extern JS_PUBLIC_API(bool)
- JS_GetPendingException(JSContext* cx, JS::MutableHandleValue vp);
- extern JS_PUBLIC_API(void)
- JS_SetPendingException(JSContext* cx, JS::HandleValue v);
- extern JS_PUBLIC_API(void)
- JS_ClearPendingException(JSContext* cx);
- namespace JS {
- /**
- * Save and later restore the current exception state of a given JSContext.
- * This is useful for implementing behavior in C++ that's like try/catch
- * or try/finally in JS.
- *
- * Typical usage:
- *
- * bool ok = JS::Evaluate(cx, ...);
- * AutoSaveExceptionState savedExc(cx);
- * ... cleanup that might re-enter JS ...
- * return ok;
- */
- class JS_PUBLIC_API(AutoSaveExceptionState)
- {
- private:
- JSContext* context;
- bool wasPropagatingForcedReturn;
- bool wasOverRecursed;
- bool wasThrowing;
- RootedValue exceptionValue;
- public:
- /*
- * Take a snapshot of cx's current exception state. Then clear any current
- * pending exception in cx.
- */
- explicit AutoSaveExceptionState(JSContext* cx);
- /*
- * If neither drop() nor restore() was called, restore the exception
- * state only if no exception is currently pending on cx.
- */
- ~AutoSaveExceptionState();
- /*
- * Discard any stored exception state.
- * If this is called, the destructor is a no-op.
- */
- void drop() {
- wasPropagatingForcedReturn = false;
- wasOverRecursed = false;
- wasThrowing = false;
- exceptionValue.setUndefined();
- }
- /*
- * Replace cx's exception state with the stored exception state. Then
- * discard the stored exception state. If this is called, the
- * destructor is a no-op.
- */
- void restore();
- };
- } /* namespace JS */
- /* Deprecated API. Use AutoSaveExceptionState instead. */
- extern JS_PUBLIC_API(JSExceptionState*)
- JS_SaveExceptionState(JSContext* cx);
- extern JS_PUBLIC_API(void)
- JS_RestoreExceptionState(JSContext* cx, JSExceptionState* state);
- extern JS_PUBLIC_API(void)
- JS_DropExceptionState(JSContext* cx, JSExceptionState* state);
- /**
- * If the given object is an exception object, the exception will have (or be
- * able to lazily create) an error report struct, and this function will return
- * the address of that struct. Otherwise, it returns nullptr. The lifetime
- * of the error report struct that might be returned is the same as the
- * lifetime of the exception object.
- */
- extern JS_PUBLIC_API(JSErrorReport*)
- JS_ErrorFromException(JSContext* cx, JS::HandleObject obj);
- /**
- * If the given object is an exception object (or an unwrappable
- * cross-compartment wrapper for one), return the stack for that exception, if
- * any. Will return null if the given object is not an exception object
- * (including if it's null or a security wrapper that can't be unwrapped) or if
- * the exception has no stack.
- */
- extern JS_PUBLIC_API(JSObject*)
- ExceptionStackOrNull(JS::HandleObject obj);
- /*
- * Throws a StopIteration exception on cx.
- */
- extern JS_PUBLIC_API(bool)
- JS_ThrowStopIteration(JSContext* cx);
- extern JS_PUBLIC_API(bool)
- JS_IsStopIteration(const JS::Value& v);
- /**
- * A JS context always has an "owner thread". The owner thread is set when the
- * context is created (to the current thread) and practically all entry points
- * into the JS engine check that a context (or anything contained in the
- * context: runtime, compartment, object, etc) is only touched by its owner
- * thread. Embeddings may check this invariant outside the JS engine by calling
- * JS_AbortIfWrongThread (which will abort if not on the owner thread, even for
- * non-debug builds).
- */
- extern JS_PUBLIC_API(void)
- JS_AbortIfWrongThread(JSContext* cx);
- /************************************************************************/
- /**
- * A constructor can request that the JS engine create a default new 'this'
- * object of the given class, using the callee to determine parentage and
- * [[Prototype]].
- */
- extern JS_PUBLIC_API(JSObject*)
- JS_NewObjectForConstructor(JSContext* cx, const JSClass* clasp, const JS::CallArgs& args);
- /************************************************************************/
- #ifdef JS_GC_ZEAL
- #define JS_DEFAULT_ZEAL_FREQ 100
- extern JS_PUBLIC_API(void)
- JS_GetGCZealBits(JSContext* cx, uint32_t* zealBits, uint32_t* frequency, uint32_t* nextScheduled);
- extern JS_PUBLIC_API(void)
- JS_SetGCZeal(JSContext* cx, uint8_t zeal, uint32_t frequency);
- extern JS_PUBLIC_API(void)
- JS_ScheduleGC(JSContext* cx, uint32_t count);
- #endif
- extern JS_PUBLIC_API(void)
- JS_SetParallelParsingEnabled(JSContext* cx, bool enabled);
- extern JS_PUBLIC_API(void)
- JS_SetOffthreadIonCompilationEnabled(JSContext* cx, bool enabled);
- #define JIT_COMPILER_OPTIONS(Register) \
- Register(BASELINE_WARMUP_TRIGGER, "baseline.warmup.trigger") \
- Register(ION_WARMUP_TRIGGER, "ion.warmup.trigger") \
- Register(ION_GVN_ENABLE, "ion.gvn.enable") \
- Register(ION_FORCE_IC, "ion.forceinlineCaches") \
- Register(ION_ENABLE, "ion.enable") \
- Register(ION_INTERRUPT_WITHOUT_SIGNAL, "ion.interrupt-without-signals") \
- Register(ION_CHECK_RANGE_ANALYSIS, "ion.check-range-analysis") \
- Register(BASELINE_ENABLE, "baseline.enable") \
- Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable") \
- Register(JUMP_THRESHOLD, "jump-threshold") \
- Register(ASMJS_ATOMICS_ENABLE, "asmjs.atomics.enable") \
- Register(WASM_TEST_MODE, "wasm.test-mode") \
- Register(WASM_FOLD_OFFSETS, "wasm.fold-offsets")
- typedef enum JSJitCompilerOption {
- #define JIT_COMPILER_DECLARE(key, str) \
- JSJITCOMPILER_ ## key,
- JIT_COMPILER_OPTIONS(JIT_COMPILER_DECLARE)
- #undef JIT_COMPILER_DECLARE
- JSJITCOMPILER_NOT_AN_OPTION
- } JSJitCompilerOption;
- extern JS_PUBLIC_API(void)
- JS_SetGlobalJitCompilerOption(JSContext* cx, JSJitCompilerOption opt, uint32_t value);
- extern JS_PUBLIC_API(bool)
- JS_GetGlobalJitCompilerOption(JSContext* cx, JSJitCompilerOption opt, uint32_t* valueOut);
- /**
- * Convert a uint32_t index into a jsid.
- */
- extern JS_PUBLIC_API(bool)
- JS_IndexToId(JSContext* cx, uint32_t index, JS::MutableHandleId);
- /**
- * Convert chars into a jsid.
- *
- * |chars| may not be an index.
- */
- extern JS_PUBLIC_API(bool)
- JS_CharsToId(JSContext* cx, JS::TwoByteChars chars, JS::MutableHandleId);
- /**
- * Test if the given string is a valid ECMAScript identifier
- */
- extern JS_PUBLIC_API(bool)
- JS_IsIdentifier(JSContext* cx, JS::HandleString str, bool* isIdentifier);
- /**
- * Test whether the given chars + length are a valid ECMAScript identifier.
- * This version is infallible, so just returns whether the chars are an
- * identifier.
- */
- extern JS_PUBLIC_API(bool)
- JS_IsIdentifier(const char16_t* chars, size_t length);
- namespace js {
- class ScriptSource;
- } // namespace js
- namespace JS {
- class MOZ_RAII JS_PUBLIC_API(AutoFilename)
- {
- private:
- js::ScriptSource* ss_;
- mozilla::Variant<const char*, UniqueChars> filename_;
- AutoFilename(const AutoFilename&) = delete;
- AutoFilename& operator=(const AutoFilename&) = delete;
- public:
- AutoFilename()
- : ss_(nullptr),
- filename_(mozilla::AsVariant<const char*>(nullptr))
- {}
- ~AutoFilename() {
- reset();
- }
- void reset();
- void setOwned(UniqueChars&& filename);
- void setUnowned(const char* filename);
- void setScriptSource(js::ScriptSource* ss);
- const char* get() const;
- };
- /**
- * Return the current filename, line number and column number of the most
- * currently running frame. Returns true if a scripted frame was found, false
- * otherwise.
- *
- * If a the embedding has hidden the scripted caller for the topmost activation
- * record, this will also return false.
- */
- extern JS_PUBLIC_API(bool)
- DescribeScriptedCaller(JSContext* cx, AutoFilename* filename = nullptr,
- unsigned* lineno = nullptr, unsigned* column = nullptr);
- extern JS_PUBLIC_API(JSObject*)
- GetScriptedCallerGlobal(JSContext* cx);
- /**
- * Informs the JS engine that the scripted caller should be hidden. This can be
- * used by the embedding to maintain an override of the scripted caller in its
- * calculations, by hiding the scripted caller in the JS engine and pushing data
- * onto a separate stack, which it inspects when DescribeScriptedCaller returns
- * null.
- *
- * We maintain a counter on each activation record. Add() increments the counter
- * of the topmost activation, and Remove() decrements it. The count may never
- * drop below zero, and must always be exactly zero when the activation is
- * popped from the stack.
- */
- extern JS_PUBLIC_API(void)
- HideScriptedCaller(JSContext* cx);
- extern JS_PUBLIC_API(void)
- UnhideScriptedCaller(JSContext* cx);
- class MOZ_RAII AutoHideScriptedCaller
- {
- public:
- explicit AutoHideScriptedCaller(JSContext* cx
- MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
- : mContext(cx)
- {
- MOZ_GUARD_OBJECT_NOTIFIER_INIT;
- HideScriptedCaller(mContext);
- }
- ~AutoHideScriptedCaller() {
- UnhideScriptedCaller(mContext);
- }
- protected:
- JSContext* mContext;
- MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
- };
- /*
- * Encode/Decode interpreted scripts and functions to/from memory.
- */
- typedef mozilla::Vector<uint8_t> TranscodeBuffer;
- enum TranscodeResult
- {
- // Successful encoding / decoding.
- TranscodeResult_Ok = 0,
- // A warning message, is set to the message out-param.
- TranscodeResult_Failure = 0x100,
- TranscodeResult_Failure_BadBuildId = TranscodeResult_Failure | 0x1,
- TranscodeResult_Failure_RunOnceNotSupported = TranscodeResult_Failure | 0x2,
- TranscodeResult_Failure_AsmJSNotSupported = TranscodeResult_Failure | 0x3,
- TranscodeResult_Failure_UnknownClassKind = TranscodeResult_Failure | 0x4,
- // A error, the JSContext has a pending exception.
- TranscodeResult_Throw = 0x200
- };
- extern JS_PUBLIC_API(TranscodeResult)
- EncodeScript(JSContext* cx, TranscodeBuffer& buffer, JS::HandleScript script);
- extern JS_PUBLIC_API(TranscodeResult)
- EncodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer, JS::HandleObject funobj);
- extern JS_PUBLIC_API(TranscodeResult)
- DecodeScript(JSContext* cx, TranscodeBuffer& buffer, JS::MutableHandleScript scriptp,
- size_t cursorIndex = 0);
- extern JS_PUBLIC_API(TranscodeResult)
- DecodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer, JS::MutableHandleFunction funp,
- size_t cursorIndex = 0);
- } /* namespace JS */
- namespace js {
- enum class StackFormat { SpiderMonkey, V8, Default };
- /*
- * Sets the format used for stringifying Error stacks.
- *
- * The default format is StackFormat::SpiderMonkey. Use StackFormat::V8
- * in order to emulate V8's stack formatting. StackFormat::Default can't be
- * used here.
- */
- extern JS_PUBLIC_API(void)
- SetStackFormat(JSContext* cx, StackFormat format);
- extern JS_PUBLIC_API(StackFormat)
- GetStackFormat(JSContext* cx);
- }
- namespace JS {
- /*
- * This callback represents a request by the JS engine to open for reading the
- * existing cache entry for the given global and char range that may contain a
- * module. If a cache entry exists, the callback shall return 'true' and return
- * the size, base address and an opaque file handle as outparams. If the
- * callback returns 'true', the JS engine guarantees a call to
- * CloseAsmJSCacheEntryForReadOp, passing the same base address, size and
- * handle.
- */
- typedef bool
- (* OpenAsmJSCacheEntryForReadOp)(HandleObject global, const char16_t* begin, const char16_t* limit,
- size_t* size, const uint8_t** memory, intptr_t* handle);
- typedef void
- (* CloseAsmJSCacheEntryForReadOp)(size_t size, const uint8_t* memory, intptr_t handle);
- /** The list of reasons why an asm.js module may not be stored in the cache. */
- enum AsmJSCacheResult
- {
- AsmJSCache_Success,
- AsmJSCache_MIN = AsmJSCache_Success,
- AsmJSCache_ModuleTooSmall,
- AsmJSCache_SynchronousScript,
- AsmJSCache_QuotaExceeded,
- AsmJSCache_StorageInitFailure,
- AsmJSCache_Disabled_Internal,
- AsmJSCache_Disabled_ShellFlags,
- AsmJSCache_Disabled_JitInspector,
- AsmJSCache_InternalError,
- AsmJSCache_Disabled_PrivateBrowsing,
- AsmJSCache_LIMIT
- };
- /*
- * This callback represents a request by the JS engine to open for writing a
- * cache entry of the given size for the given global and char range containing
- * the just-compiled module. If cache entry space is available, the callback
- * shall return 'true' and return the base address and an opaque file handle as
- * outparams. If the callback returns 'true', the JS engine guarantees a call
- * to CloseAsmJSCacheEntryForWriteOp passing the same base address, size and
- * handle.
- *
- * If 'installed' is true, then the cache entry is associated with a permanently
- * installed JS file (e.g., in a packaged webapp). This information allows the
- * embedding to store the cache entry in a installed location associated with
- * the principal of 'global' where it will not be evicted until the associated
- * installed JS file is removed.
- */
- typedef AsmJSCacheResult
- (* OpenAsmJSCacheEntryForWriteOp)(HandleObject global, bool installed,
- const char16_t* begin, const char16_t* end,
- size_t size, uint8_t** memory, intptr_t* handle);
- typedef void
- (* CloseAsmJSCacheEntryForWriteOp)(size_t size, uint8_t* memory, intptr_t handle);
- struct AsmJSCacheOps
- {
- OpenAsmJSCacheEntryForReadOp openEntryForRead;
- CloseAsmJSCacheEntryForReadOp closeEntryForRead;
- OpenAsmJSCacheEntryForWriteOp openEntryForWrite;
- CloseAsmJSCacheEntryForWriteOp closeEntryForWrite;
- };
- extern JS_PUBLIC_API(void)
- SetAsmJSCacheOps(JSContext* cx, const AsmJSCacheOps* callbacks);
- /**
- * Return the buildId (represented as a sequence of characters) associated with
- * the currently-executing build. If the JS engine is embedded such that a
- * single cache entry can be observed by different compiled versions of the JS
- * engine, it is critical that the buildId shall change for each new build of
- * the JS engine.
- */
- typedef js::Vector<char, 0, js::SystemAllocPolicy> BuildIdCharVector;
- typedef bool
- (* BuildIdOp)(BuildIdCharVector* buildId);
- extern JS_PUBLIC_API(void)
- SetBuildIdOp(JSContext* cx, BuildIdOp buildIdOp);
- /**
- * The WasmModule interface allows the embedding to hold a reference to the
- * underying C++ implementation of a JS WebAssembly.Module object for purposes
- * of (de)serialization off the object's JSRuntime's thread.
- *
- * - Serialization starts when WebAssembly.Module is passed to the
- * structured-clone algorithm. JS::GetWasmModule is called on the JSRuntime
- * thread that initiated the structured clone to get the JS::WasmModule.
- * This interface is then taken to a background thread where serializedSize()
- * and serialize() are called to write the object to two files: a bytecode file
- * that always allows successful deserialization and a compiled-code file keyed
- * on cpu- and build-id that may become invalid if either of these change between
- * serialization and deserialization. After serialization, the reference is
- * dropped from the background thread.
- *
- * - Deserialization starts when the structured clone algorithm encounters a
- * serialized WebAssembly.Module. On a background thread, the compiled-code file
- * is opened and CompiledWasmModuleAssumptionsMatch is called to see if it is
- * still valid (as described above). DeserializeWasmModule is then called to
- * construct a JS::WasmModule (also on the background thread), passing the
- * bytecode file descriptor and, if valid, the compiled-code file descriptor.
- * The JS::WasmObject is then transported to the JSRuntime thread (which
- * originated the request) and the wrapping WebAssembly.Module object is created
- * by calling createObject().
- */
- struct WasmModule : mozilla::external::AtomicRefCounted<WasmModule>
- {
- MOZ_DECLARE_REFCOUNTED_TYPENAME(WasmModule)
- virtual ~WasmModule() {}
- virtual void serializedSize(size_t* maybeBytecodeSize, size_t* maybeCompiledSize) const = 0;
- virtual void serialize(uint8_t* maybeBytecodeBegin, size_t maybeBytecodeSize,
- uint8_t* maybeCompiledBegin, size_t maybeCompiledSize) const = 0;
- virtual JSObject* createObject(JSContext* cx) = 0;
- };
- extern JS_PUBLIC_API(bool)
- IsWasmModuleObject(HandleObject obj);
- extern JS_PUBLIC_API(RefPtr<WasmModule>)
- GetWasmModule(HandleObject obj);
- extern JS_PUBLIC_API(bool)
- CompiledWasmModuleAssumptionsMatch(PRFileDesc* compiled, BuildIdCharVector&& buildId);
- extern JS_PUBLIC_API(RefPtr<WasmModule>)
- DeserializeWasmModule(PRFileDesc* bytecode, PRFileDesc* maybeCompiled, BuildIdCharVector&& buildId,
- JS::UniqueChars filename, unsigned line, unsigned column);
- /**
- * Convenience class for imitating a JS level for-of loop. Typical usage:
- *
- * ForOfIterator it(cx);
- * if (!it.init(iterable))
- * return false;
- * RootedValue val(cx);
- * while (true) {
- * bool done;
- * if (!it.next(&val, &done))
- * return false;
- * if (done)
- * break;
- * if (!DoStuff(cx, val))
- * return false;
- * }
- */
- class MOZ_STACK_CLASS JS_PUBLIC_API(ForOfIterator) {
- protected:
- JSContext* cx_;
- /*
- * Use the ForOfPIC on the global object (see vm/GlobalObject.h) to try
- * to optimize iteration across arrays.
- *
- * Case 1: Regular Iteration
- * iterator - pointer to the iterator object.
- * index - fixed to NOT_ARRAY (== UINT32_MAX)
- *
- * Case 2: Optimized Array Iteration
- * iterator - pointer to the array object.
- * index - current position in array.
- *
- * The cases are distinguished by whether or not |index| is equal to NOT_ARRAY.
- */
- JS::RootedObject iterator;
- uint32_t index;
- static const uint32_t NOT_ARRAY = UINT32_MAX;
- ForOfIterator(const ForOfIterator&) = delete;
- ForOfIterator& operator=(const ForOfIterator&) = delete;
- public:
- explicit ForOfIterator(JSContext* cx) : cx_(cx), iterator(cx_), index(NOT_ARRAY) { }
- enum NonIterableBehavior {
- ThrowOnNonIterable,
- AllowNonIterable
- };
- /**
- * Initialize the iterator. If AllowNonIterable is passed then if getting
- * the @@iterator property from iterable returns undefined init() will just
- * return true instead of throwing. Callers must then check
- * valueIsIterable() before continuing with the iteration.
- */
- bool init(JS::HandleValue iterable,
- NonIterableBehavior nonIterableBehavior = ThrowOnNonIterable);
- /**
- * Get the next value from the iterator. If false *done is true
- * after this call, do not examine val.
- */
- bool next(JS::MutableHandleValue val, bool* done);
- /**
- * If initialized with throwOnNonCallable = false, check whether
- * the value is iterable.
- */
- bool valueIsIterable() const {
- return iterator;
- }
- private:
- inline bool nextFromOptimizedArray(MutableHandleValue val, bool* done);
- bool materializeArrayIterator();
- };
- /**
- * If a large allocation fails when calling pod_{calloc,realloc}CanGC, the JS
- * engine may call the large-allocation- failure callback, if set, to allow the
- * embedding to flush caches, possibly perform shrinking GCs, etc. to make some
- * room. The allocation will then be retried (and may still fail.)
- */
- typedef void
- (* LargeAllocationFailureCallback)(void* data);
- extern JS_PUBLIC_API(void)
- SetLargeAllocationFailureCallback(JSContext* cx, LargeAllocationFailureCallback afc, void* data);
- /**
- * Unlike the error reporter, which is only called if the exception for an OOM
- * bubbles up and is not caught, the OutOfMemoryCallback is called immediately
- * at the OOM site to allow the embedding to capture the current state of heap
- * allocation before anything is freed. If the large-allocation-failure callback
- * is called at all (not all allocation sites call the large-allocation-failure
- * callback on failure), it is called before the out-of-memory callback; the
- * out-of-memory callback is only called if the allocation still fails after the
- * large-allocation-failure callback has returned.
- */
- typedef void
- (* OutOfMemoryCallback)(JSContext* cx, void* data);
- extern JS_PUBLIC_API(void)
- SetOutOfMemoryCallback(JSContext* cx, OutOfMemoryCallback cb, void* data);
- /**
- * Capture all frames.
- */
- struct AllFrames { };
- /**
- * Capture at most this many frames.
- */
- struct MaxFrames
- {
- uint32_t maxFrames;
- explicit MaxFrames(uint32_t max)
- : maxFrames(max)
- {
- MOZ_ASSERT(max > 0);
- }
- };
- /**
- * Capture the first frame with the given principals. By default, do not
- * consider self-hosted frames with the given principals as satisfying the stack
- * capture.
- */
- struct FirstSubsumedFrame
- {
- JSContext* cx;
- JSPrincipals* principals;
- bool ignoreSelfHosted;
- /**
- * Use the cx's current compartment's principals.
- */
- explicit FirstSubsumedFrame(JSContext* cx, bool ignoreSelfHostedFrames = true);
- explicit FirstSubsumedFrame(JSContext* ctx, JSPrincipals* p, bool ignoreSelfHostedFrames = true)
- : cx(ctx)
- , principals(p)
- , ignoreSelfHosted(ignoreSelfHostedFrames)
- {
- if (principals)
- JS_HoldPrincipals(principals);
- }
- // No copying because we want to avoid holding and dropping principals
- // unnecessarily.
- FirstSubsumedFrame(const FirstSubsumedFrame&) = delete;
- FirstSubsumedFrame& operator=(const FirstSubsumedFrame&) = delete;
- FirstSubsumedFrame(FirstSubsumedFrame&& rhs)
- : principals(rhs.principals)
- , ignoreSelfHosted(rhs.ignoreSelfHosted)
- {
- MOZ_ASSERT(this != &rhs, "self move disallowed");
- rhs.principals = nullptr;
- }
- FirstSubsumedFrame& operator=(FirstSubsumedFrame&& rhs) {
- new (this) FirstSubsumedFrame(mozilla::Move(rhs));
- return *this;
- }
- ~FirstSubsumedFrame() {
- if (principals)
- JS_DropPrincipals(cx, principals);
- }
- };
- using StackCapture = mozilla::Variant<AllFrames, MaxFrames, FirstSubsumedFrame>;
- /**
- * Capture the current call stack as a chain of SavedFrame JSObjects, and set
- * |stackp| to the SavedFrame for the youngest stack frame, or nullptr if there
- * are no JS frames on the stack.
- *
- * The |capture| parameter describes the portion of the JS stack to capture:
- *
- * * |JS::AllFrames|: Capture all frames on the stack.
- *
- * * |JS::MaxFrames|: Capture no more than |JS::MaxFrames::maxFrames| from the
- * stack.
- *
- * * |JS::FirstSubsumedFrame|: Capture the first frame whose principals are
- * subsumed by |JS::FirstSubsumedFrame::principals|. By default, do not
- * consider self-hosted frames; this can be controlled via the
- * |JS::FirstSubsumedFrame::ignoreSelfHosted| flag. Do not capture any async
- * stack.
- */
- extern JS_PUBLIC_API(bool)
- CaptureCurrentStack(JSContext* cx, MutableHandleObject stackp,
- StackCapture&& capture = StackCapture(AllFrames()));
- /*
- * This is a utility function for preparing an async stack to be used
- * by some other object. This may be used when you need to treat a
- * given stack trace as an async parent. If you just need to capture
- * the current stack, async parents and all, use CaptureCurrentStack
- * instead.
- *
- * Here |asyncStack| is the async stack to prepare. It is copied into
- * |cx|'s current compartment, and the newest frame is given
- * |asyncCause| as its asynchronous cause. If |maxFrameCount| is
- * non-zero, capture at most the youngest |maxFrameCount| frames. The
- * new stack object is written to |stackp|. Returns true on success,
- * or sets an exception and returns |false| on error.
- */
- extern JS_PUBLIC_API(bool)
- CopyAsyncStack(JSContext* cx, HandleObject asyncStack,
- HandleString asyncCause, MutableHandleObject stackp,
- unsigned maxFrameCount);
- /*
- * Accessors for working with SavedFrame JSObjects
- *
- * Each of these functions assert that if their `HandleObject savedFrame`
- * argument is non-null, its JSClass is the SavedFrame class (or it is a
- * cross-compartment or Xray wrapper around an object with the SavedFrame class)
- * and the object is not the SavedFrame.prototype object.
- *
- * Each of these functions will find the first SavedFrame object in the chain
- * whose underlying stack frame principals are subsumed by the cx's current
- * compartment's principals, and operate on that SavedFrame object. This
- * prevents leaking information about privileged frames to un-privileged
- * callers. As a result, the SavedFrame in parameters do _NOT_ need to be in the
- * same compartment as the cx, and the various out parameters are _NOT_
- * guaranteed to be in the same compartment as cx.
- *
- * You may consider or skip over self-hosted frames by passing
- * `SavedFrameSelfHosted::Include` or `SavedFrameSelfHosted::Exclude`
- * respectively.
- *
- * Additionally, it may be the case that there is no such SavedFrame object
- * whose captured frame's principals are subsumed by the caller's compartment's
- * principals! If the `HandleObject savedFrame` argument is null, or the
- * caller's principals do not subsume any of the chained SavedFrame object's
- * principals, `SavedFrameResult::AccessDenied` is returned and a (hopefully)
- * sane default value is chosen for the out param.
- *
- * See also `js/src/doc/SavedFrame/SavedFrame.md`.
- */
- enum class SavedFrameResult {
- Ok,
- AccessDenied
- };
- enum class SavedFrameSelfHosted {
- Include,
- Exclude
- };
- /**
- * Given a SavedFrame JSObject, get its source property. Defaults to the empty
- * string.
- */
- extern JS_PUBLIC_API(SavedFrameResult)
- GetSavedFrameSource(JSContext* cx, HandleObject savedFrame, MutableHandleString sourcep,
- SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
- /**
- * Given a SavedFrame JSObject, get its line property. Defaults to 0.
- */
- extern JS_PUBLIC_API(SavedFrameResult)
- GetSavedFrameLine(JSContext* cx, HandleObject savedFrame, uint32_t* linep,
- SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
- /**
- * Given a SavedFrame JSObject, get its column property. Defaults to 0.
- */
- extern JS_PUBLIC_API(SavedFrameResult)
- GetSavedFrameColumn(JSContext* cx, HandleObject savedFrame, uint32_t* columnp,
- SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
- /**
- * Given a SavedFrame JSObject, get its functionDisplayName string, or nullptr
- * if SpiderMonkey was unable to infer a name for the captured frame's
- * function. Defaults to nullptr.
- */
- extern JS_PUBLIC_API(SavedFrameResult)
- GetSavedFrameFunctionDisplayName(JSContext* cx, HandleObject savedFrame, MutableHandleString namep,
- SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
- /**
- * Given a SavedFrame JSObject, get its asyncCause string. Defaults to nullptr.
- */
- extern JS_PUBLIC_API(SavedFrameResult)
- GetSavedFrameAsyncCause(JSContext* cx, HandleObject savedFrame, MutableHandleString asyncCausep,
- SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
- /**
- * Given a SavedFrame JSObject, get its asyncParent SavedFrame object or nullptr
- * if there is no asyncParent. The `asyncParentp` out parameter is _NOT_
- * guaranteed to be in the cx's compartment. Defaults to nullptr.
- */
- extern JS_PUBLIC_API(SavedFrameResult)
- GetSavedFrameAsyncParent(JSContext* cx, HandleObject savedFrame, MutableHandleObject asyncParentp,
- SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
- /**
- * Given a SavedFrame JSObject, get its parent SavedFrame object or nullptr if
- * it is the oldest frame in the stack. The `parentp` out parameter is _NOT_
- * guaranteed to be in the cx's compartment. Defaults to nullptr.
- */
- extern JS_PUBLIC_API(SavedFrameResult)
- GetSavedFrameParent(JSContext* cx, HandleObject savedFrame, MutableHandleObject parentp,
- SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
- /**
- * Given a SavedFrame JSObject stack, stringify it in the same format as
- * Error.prototype.stack. The stringified stack out parameter is placed in the
- * cx's compartment. Defaults to the empty string.
- *
- * The same notes above about SavedFrame accessors applies here as well: cx
- * doesn't need to be in stack's compartment, and stack can be null, a
- * SavedFrame object, or a wrapper (CCW or Xray) around a SavedFrame object.
- *
- * Optional indent parameter specifies the number of white spaces to indent
- * each line.
- */
- extern JS_PUBLIC_API(bool)
- BuildStackString(JSContext* cx, HandleObject stack, MutableHandleString stringp,
- size_t indent = 0, js::StackFormat stackFormat = js::StackFormat::Default);
- /**
- * Return true iff the given object is either a SavedFrame object or wrapper
- * around a SavedFrame object, and it is not the SavedFrame.prototype object.
- */
- extern JS_PUBLIC_API(bool)
- IsSavedFrame(JSObject* obj);
- } /* namespace JS */
- /* Stopwatch-based performance monitoring. */
- namespace js {
- class AutoStopwatch;
- /**
- * Abstract base class for a representation of the performance of a
- * component. Embeddings interested in performance monitoring should
- * provide a concrete implementation of this class, as well as the
- * relevant callbacks (see below).
- */
- struct PerformanceGroup {
- PerformanceGroup();
- // The current iteration of the event loop.
- uint64_t iteration() const;
- // `true` if an instance of `AutoStopwatch` is already monitoring
- // the performance of this performance group for this iteration
- // of the event loop, `false` otherwise.
- bool isAcquired(uint64_t it) const;
- // `true` if a specific instance of `AutoStopwatch` is already monitoring
- // the performance of this performance group for this iteration
- // of the event loop, `false` otherwise.
- bool isAcquired(uint64_t it, const AutoStopwatch* owner) const;
- // Mark that an instance of `AutoStopwatch` is monitoring
- // the performance of this group for a given iteration.
- void acquire(uint64_t it, const AutoStopwatch* owner);
- // Mark that no `AutoStopwatch` is monitoring the
- // performance of this group for the iteration.
- void release(uint64_t it, const AutoStopwatch* owner);
- // The number of cycles spent in this group during this iteration
- // of the event loop. Note that cycles are not a reliable measure,
- // especially over short intervals. See Stopwatch.* for a more
- // complete discussion on the imprecision of cycle measurement.
- uint64_t recentCycles(uint64_t iteration) const;
- void addRecentCycles(uint64_t iteration, uint64_t cycles);
- // The number of times this group has been activated during this
- // iteration of the event loop.
- uint64_t recentTicks(uint64_t iteration) const;
- void addRecentTicks(uint64_t iteration, uint64_t ticks);
- // The number of microseconds spent doing CPOW during this
- // iteration of the event loop.
- uint64_t recentCPOW(uint64_t iteration) const;
- void addRecentCPOW(uint64_t iteration, uint64_t CPOW);
- // Get rid of any data that pretends to be recent.
- void resetRecentData();
- // `true` if new measures should be added to this group, `false`
- // otherwise.
- bool isActive() const;
- void setIsActive(bool);
- // `true` if this group has been used in the current iteration,
- // `false` otherwise.
- bool isUsedInThisIteration() const;
- void setIsUsedInThisIteration(bool);
- protected:
- // An implementation of `delete` for this object. Must be provided
- // by the embedding.
- virtual void Delete() = 0;
- private:
- // The number of cycles spent in this group during this iteration
- // of the event loop. Note that cycles are not a reliable measure,
- // especially over short intervals. See Runtime.cpp for a more
- // complete discussion on the imprecision of cycle measurement.
- uint64_t recentCycles_;
- // The number of times this group has been activated during this
- // iteration of the event loop.
- uint64_t recentTicks_;
- // The number of microseconds spent doing CPOW during this
- // iteration of the event loop.
- uint64_t recentCPOW_;
- // The current iteration of the event loop. If necessary,
- // may safely overflow.
- uint64_t iteration_;
- // `true` if new measures should be added to this group, `false`
- // otherwise.
- bool isActive_;
- // `true` if this group has been used in the current iteration,
- // `false` otherwise.
- bool isUsedInThisIteration_;
- // The stopwatch currently monitoring the group,
- // or `nullptr` if none. Used ony for comparison.
- const AutoStopwatch* owner_;
- public:
- // Compatibility with RefPtr<>
- void AddRef();
- void Release();
- uint64_t refCount_;
- };
- using PerformanceGroupVector = mozilla::Vector<RefPtr<js::PerformanceGroup>, 0, SystemAllocPolicy>;
- /**
- * Commit any Performance Monitoring data.
- *
- * Until `FlushMonitoring` has been called, all PerformanceMonitoring data is invisible
- * to the outside world and can cancelled with a call to `ResetMonitoring`.
- */
- extern JS_PUBLIC_API(bool)
- FlushPerformanceMonitoring(JSContext*);
- /**
- * Cancel any measurement that hasn't been committed.
- */
- extern JS_PUBLIC_API(void)
- ResetPerformanceMonitoring(JSContext*);
- /**
- * Cleanup any memory used by performance monitoring.
- */
- extern JS_PUBLIC_API(void)
- DisposePerformanceMonitoring(JSContext*);
- /**
- * Turn on/off stopwatch-based CPU monitoring.
- *
- * `SetStopwatchIsMonitoringCPOW` or `SetStopwatchIsMonitoringJank`
- * may return `false` if monitoring could not be activated, which may
- * happen if we are out of memory.
- */
- extern JS_PUBLIC_API(bool)
- SetStopwatchIsMonitoringCPOW(JSContext*, bool);
- extern JS_PUBLIC_API(bool)
- GetStopwatchIsMonitoringCPOW(JSContext*);
- extern JS_PUBLIC_API(bool)
- SetStopwatchIsMonitoringJank(JSContext*, bool);
- extern JS_PUBLIC_API(bool)
- GetStopwatchIsMonitoringJank(JSContext*);
- // Extract the CPU rescheduling data.
- extern JS_PUBLIC_API(void)
- GetPerfMonitoringTestCpuRescheduling(JSContext*, uint64_t* stayed, uint64_t* moved);
- /**
- * Add a number of microseconds to the time spent waiting on CPOWs
- * since process start.
- */
- extern JS_PUBLIC_API(void)
- AddCPOWPerformanceDelta(JSContext*, uint64_t delta);
- typedef bool
- (*StopwatchStartCallback)(uint64_t, void*);
- extern JS_PUBLIC_API(bool)
- SetStopwatchStartCallback(JSContext*, StopwatchStartCallback, void*);
- typedef bool
- (*StopwatchCommitCallback)(uint64_t, PerformanceGroupVector&, void*);
- extern JS_PUBLIC_API(bool)
- SetStopwatchCommitCallback(JSContext*, StopwatchCommitCallback, void*);
- typedef bool
- (*GetGroupsCallback)(JSContext*, PerformanceGroupVector&, void*);
- extern JS_PUBLIC_API(bool)
- SetGetPerformanceGroupsCallback(JSContext*, GetGroupsCallback, void*);
- } /* namespace js */
- #endif /* jsapi_h */
|