jsapi.h 226 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  2. * vim: set ts=8 sts=4 et sw=4 tw=99:
  3. * This Source Code Form is subject to the terms of the Mozilla Public
  4. * License, v. 2.0. If a copy of the MPL was not distributed with this
  5. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6. /* JavaScript API. */
  7. #ifndef jsapi_h
  8. #define jsapi_h
  9. #include "mozilla/AlreadyAddRefed.h"
  10. #include "mozilla/FloatingPoint.h"
  11. #include "mozilla/MemoryReporting.h"
  12. #include "mozilla/Range.h"
  13. #include "mozilla/RangedPtr.h"
  14. #include "mozilla/RefCounted.h"
  15. #include "mozilla/RefPtr.h"
  16. #include "mozilla/Variant.h"
  17. #include <stdarg.h>
  18. #include <stddef.h>
  19. #include <stdint.h>
  20. #include <stdio.h>
  21. #include "jsalloc.h"
  22. #include "jspubtd.h"
  23. #include "js/CallArgs.h"
  24. #include "js/CharacterEncoding.h"
  25. #include "js/Class.h"
  26. #include "js/GCVector.h"
  27. #include "js/HashTable.h"
  28. #include "js/Id.h"
  29. #include "js/Principals.h"
  30. #include "js/Realm.h"
  31. #include "js/RootingAPI.h"
  32. #include "js/TracingAPI.h"
  33. #include "js/Utility.h"
  34. #include "js/Value.h"
  35. #include "js/Vector.h"
  36. /************************************************************************/
  37. namespace JS {
  38. class TwoByteChars;
  39. #ifdef JS_DEBUG
  40. class JS_PUBLIC_API(AutoCheckRequestDepth)
  41. {
  42. JSContext* cx;
  43. public:
  44. explicit AutoCheckRequestDepth(JSContext* cx);
  45. explicit AutoCheckRequestDepth(js::ContextFriendFields* cx);
  46. ~AutoCheckRequestDepth();
  47. };
  48. # define CHECK_REQUEST(cx) \
  49. JS::AutoCheckRequestDepth _autoCheckRequestDepth(cx)
  50. #else
  51. # define CHECK_REQUEST(cx) \
  52. ((void) 0)
  53. #endif /* JS_DEBUG */
  54. /** AutoValueArray roots an internal fixed-size array of Values. */
  55. template <size_t N>
  56. class MOZ_RAII AutoValueArray : public AutoGCRooter
  57. {
  58. const size_t length_;
  59. Value elements_[N];
  60. public:
  61. explicit AutoValueArray(JSContext* cx
  62. MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
  63. : AutoGCRooter(cx, VALARRAY), length_(N)
  64. {
  65. /* Always initialize in case we GC before assignment. */
  66. mozilla::PodArrayZero(elements_);
  67. MOZ_GUARD_OBJECT_NOTIFIER_INIT;
  68. }
  69. unsigned length() const { return length_; }
  70. const Value* begin() const { return elements_; }
  71. Value* begin() { return elements_; }
  72. HandleValue operator[](unsigned i) const {
  73. MOZ_ASSERT(i < N);
  74. return HandleValue::fromMarkedLocation(&elements_[i]);
  75. }
  76. MutableHandleValue operator[](unsigned i) {
  77. MOZ_ASSERT(i < N);
  78. return MutableHandleValue::fromMarkedLocation(&elements_[i]);
  79. }
  80. MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
  81. };
  82. template<class T>
  83. class MOZ_RAII AutoVectorRooterBase : protected AutoGCRooter
  84. {
  85. typedef js::Vector<T, 8> VectorImpl;
  86. VectorImpl vector;
  87. public:
  88. explicit AutoVectorRooterBase(JSContext* cx, ptrdiff_t tag
  89. MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
  90. : AutoGCRooter(cx, tag), vector(cx)
  91. {
  92. MOZ_GUARD_OBJECT_NOTIFIER_INIT;
  93. }
  94. explicit AutoVectorRooterBase(js::ContextFriendFields* cx, ptrdiff_t tag
  95. MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
  96. : AutoGCRooter(cx, tag), vector(cx)
  97. {
  98. MOZ_GUARD_OBJECT_NOTIFIER_INIT;
  99. }
  100. typedef T ElementType;
  101. typedef typename VectorImpl::Range Range;
  102. size_t length() const { return vector.length(); }
  103. bool empty() const { return vector.empty(); }
  104. MOZ_MUST_USE bool append(const T& v) { return vector.append(v); }
  105. MOZ_MUST_USE bool appendN(const T& v, size_t len) { return vector.appendN(v, len); }
  106. MOZ_MUST_USE bool append(const T* ptr, size_t len) { return vector.append(ptr, len); }
  107. MOZ_MUST_USE bool appendAll(const AutoVectorRooterBase<T>& other) {
  108. return vector.appendAll(other.vector);
  109. }
  110. MOZ_MUST_USE bool insert(T* p, const T& val) { return vector.insert(p, val); }
  111. /* For use when space has already been reserved. */
  112. void infallibleAppend(const T& v) { vector.infallibleAppend(v); }
  113. void popBack() { vector.popBack(); }
  114. T popCopy() { return vector.popCopy(); }
  115. MOZ_MUST_USE bool growBy(size_t inc) {
  116. size_t oldLength = vector.length();
  117. if (!vector.growByUninitialized(inc))
  118. return false;
  119. makeRangeGCSafe(oldLength);
  120. return true;
  121. }
  122. MOZ_MUST_USE bool resize(size_t newLength) {
  123. size_t oldLength = vector.length();
  124. if (newLength <= oldLength) {
  125. vector.shrinkBy(oldLength - newLength);
  126. return true;
  127. }
  128. if (!vector.growByUninitialized(newLength - oldLength))
  129. return false;
  130. makeRangeGCSafe(oldLength);
  131. return true;
  132. }
  133. void clear() { vector.clear(); }
  134. MOZ_MUST_USE bool reserve(size_t newLength) {
  135. return vector.reserve(newLength);
  136. }
  137. JS::MutableHandle<T> operator[](size_t i) {
  138. return JS::MutableHandle<T>::fromMarkedLocation(&vector[i]);
  139. }
  140. JS::Handle<T> operator[](size_t i) const {
  141. return JS::Handle<T>::fromMarkedLocation(&vector[i]);
  142. }
  143. const T* begin() const { return vector.begin(); }
  144. T* begin() { return vector.begin(); }
  145. const T* end() const { return vector.end(); }
  146. T* end() { return vector.end(); }
  147. Range all() { return vector.all(); }
  148. const T& back() const { return vector.back(); }
  149. friend void AutoGCRooter::trace(JSTracer* trc);
  150. private:
  151. void makeRangeGCSafe(size_t oldLength) {
  152. T* t = vector.begin() + oldLength;
  153. for (size_t i = oldLength; i < vector.length(); ++i, ++t)
  154. memset(t, 0, sizeof(T));
  155. }
  156. MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
  157. };
  158. template <typename T>
  159. class MOZ_RAII AutoVectorRooter : public AutoVectorRooterBase<T>
  160. {
  161. public:
  162. explicit AutoVectorRooter(JSContext* cx
  163. MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
  164. : AutoVectorRooterBase<T>(cx, this->GetTag(T()))
  165. {
  166. MOZ_GUARD_OBJECT_NOTIFIER_INIT;
  167. }
  168. explicit AutoVectorRooter(js::ContextFriendFields* cx
  169. MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
  170. : AutoVectorRooterBase<T>(cx, this->GetTag(T()))
  171. {
  172. MOZ_GUARD_OBJECT_NOTIFIER_INIT;
  173. }
  174. MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
  175. };
  176. class AutoValueVector : public Rooted<GCVector<Value, 8>> {
  177. using Vec = GCVector<Value, 8>;
  178. using Base = Rooted<Vec>;
  179. public:
  180. explicit AutoValueVector(JSContext* cx) : Base(cx, Vec(cx)) {}
  181. explicit AutoValueVector(js::ContextFriendFields* cx) : Base(cx, Vec(cx)) {}
  182. };
  183. class AutoIdVector : public Rooted<GCVector<jsid, 8>> {
  184. using Vec = GCVector<jsid, 8>;
  185. using Base = Rooted<Vec>;
  186. public:
  187. explicit AutoIdVector(JSContext* cx) : Base(cx, Vec(cx)) {}
  188. explicit AutoIdVector(js::ContextFriendFields* cx) : Base(cx, Vec(cx)) {}
  189. bool appendAll(const AutoIdVector& other) { return this->Base::appendAll(other.get()); }
  190. };
  191. class AutoObjectVector : public Rooted<GCVector<JSObject*, 8>> {
  192. using Vec = GCVector<JSObject*, 8>;
  193. using Base = Rooted<Vec>;
  194. public:
  195. explicit AutoObjectVector(JSContext* cx) : Base(cx, Vec(cx)) {}
  196. explicit AutoObjectVector(js::ContextFriendFields* cx) : Base(cx, Vec(cx)) {}
  197. };
  198. using ValueVector = JS::GCVector<JS::Value>;
  199. using IdVector = JS::GCVector<jsid>;
  200. using ScriptVector = JS::GCVector<JSScript*>;
  201. using StringVector = JS::GCVector<JSString*>;
  202. template<class Key, class Value>
  203. class MOZ_RAII AutoHashMapRooter : protected AutoGCRooter
  204. {
  205. private:
  206. typedef js::HashMap<Key, Value> HashMapImpl;
  207. public:
  208. explicit AutoHashMapRooter(JSContext* cx, ptrdiff_t tag
  209. MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
  210. : AutoGCRooter(cx, tag), map(cx)
  211. {
  212. MOZ_GUARD_OBJECT_NOTIFIER_INIT;
  213. }
  214. typedef Key KeyType;
  215. typedef Value ValueType;
  216. typedef typename HashMapImpl::Entry Entry;
  217. typedef typename HashMapImpl::Lookup Lookup;
  218. typedef typename HashMapImpl::Ptr Ptr;
  219. typedef typename HashMapImpl::AddPtr AddPtr;
  220. bool init(uint32_t len = 16) {
  221. return map.init(len);
  222. }
  223. bool initialized() const {
  224. return map.initialized();
  225. }
  226. Ptr lookup(const Lookup& l) const {
  227. return map.lookup(l);
  228. }
  229. void remove(Ptr p) {
  230. map.remove(p);
  231. }
  232. AddPtr lookupForAdd(const Lookup& l) const {
  233. return map.lookupForAdd(l);
  234. }
  235. template<typename KeyInput, typename ValueInput>
  236. bool add(AddPtr& p, const KeyInput& k, const ValueInput& v) {
  237. return map.add(p, k, v);
  238. }
  239. bool add(AddPtr& p, const Key& k) {
  240. return map.add(p, k);
  241. }
  242. template<typename KeyInput, typename ValueInput>
  243. bool relookupOrAdd(AddPtr& p, const KeyInput& k, const ValueInput& v) {
  244. return map.relookupOrAdd(p, k, v);
  245. }
  246. typedef typename HashMapImpl::Range Range;
  247. Range all() const {
  248. return map.all();
  249. }
  250. typedef typename HashMapImpl::Enum Enum;
  251. void clear() {
  252. map.clear();
  253. }
  254. void finish() {
  255. map.finish();
  256. }
  257. bool empty() const {
  258. return map.empty();
  259. }
  260. uint32_t count() const {
  261. return map.count();
  262. }
  263. size_t capacity() const {
  264. return map.capacity();
  265. }
  266. size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
  267. return map.sizeOfExcludingThis(mallocSizeOf);
  268. }
  269. size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
  270. return map.sizeOfIncludingThis(mallocSizeOf);
  271. }
  272. /************************************************** Shorthand operations */
  273. bool has(const Lookup& l) const {
  274. return map.has(l);
  275. }
  276. template<typename KeyInput, typename ValueInput>
  277. bool put(const KeyInput& k, const ValueInput& v) {
  278. return map.put(k, v);
  279. }
  280. template<typename KeyInput, typename ValueInput>
  281. bool putNew(const KeyInput& k, const ValueInput& v) {
  282. return map.putNew(k, v);
  283. }
  284. Ptr lookupWithDefault(const Key& k, const Value& defaultValue) {
  285. return map.lookupWithDefault(k, defaultValue);
  286. }
  287. void remove(const Lookup& l) {
  288. map.remove(l);
  289. }
  290. friend void AutoGCRooter::trace(JSTracer* trc);
  291. private:
  292. AutoHashMapRooter(const AutoHashMapRooter& hmr) = delete;
  293. AutoHashMapRooter& operator=(const AutoHashMapRooter& hmr) = delete;
  294. HashMapImpl map;
  295. MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
  296. };
  297. template<class T>
  298. class MOZ_RAII AutoHashSetRooter : protected AutoGCRooter
  299. {
  300. private:
  301. typedef js::HashSet<T> HashSetImpl;
  302. public:
  303. explicit AutoHashSetRooter(JSContext* cx, ptrdiff_t tag
  304. MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
  305. : AutoGCRooter(cx, tag), set(cx)
  306. {
  307. MOZ_GUARD_OBJECT_NOTIFIER_INIT;
  308. }
  309. typedef typename HashSetImpl::Lookup Lookup;
  310. typedef typename HashSetImpl::Ptr Ptr;
  311. typedef typename HashSetImpl::AddPtr AddPtr;
  312. bool init(uint32_t len = 16) {
  313. return set.init(len);
  314. }
  315. bool initialized() const {
  316. return set.initialized();
  317. }
  318. Ptr lookup(const Lookup& l) const {
  319. return set.lookup(l);
  320. }
  321. void remove(Ptr p) {
  322. set.remove(p);
  323. }
  324. AddPtr lookupForAdd(const Lookup& l) const {
  325. return set.lookupForAdd(l);
  326. }
  327. bool add(AddPtr& p, const T& t) {
  328. return set.add(p, t);
  329. }
  330. bool relookupOrAdd(AddPtr& p, const Lookup& l, const T& t) {
  331. return set.relookupOrAdd(p, l, t);
  332. }
  333. typedef typename HashSetImpl::Range Range;
  334. Range all() const {
  335. return set.all();
  336. }
  337. typedef typename HashSetImpl::Enum Enum;
  338. void clear() {
  339. set.clear();
  340. }
  341. void finish() {
  342. set.finish();
  343. }
  344. bool empty() const {
  345. return set.empty();
  346. }
  347. uint32_t count() const {
  348. return set.count();
  349. }
  350. size_t capacity() const {
  351. return set.capacity();
  352. }
  353. size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
  354. return set.sizeOfExcludingThis(mallocSizeOf);
  355. }
  356. size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
  357. return set.sizeOfIncludingThis(mallocSizeOf);
  358. }
  359. /************************************************** Shorthand operations */
  360. bool has(const Lookup& l) const {
  361. return set.has(l);
  362. }
  363. bool put(const T& t) {
  364. return set.put(t);
  365. }
  366. bool putNew(const T& t) {
  367. return set.putNew(t);
  368. }
  369. void remove(const Lookup& l) {
  370. set.remove(l);
  371. }
  372. friend void AutoGCRooter::trace(JSTracer* trc);
  373. private:
  374. AutoHashSetRooter(const AutoHashSetRooter& hmr) = delete;
  375. AutoHashSetRooter& operator=(const AutoHashSetRooter& hmr) = delete;
  376. HashSetImpl set;
  377. MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
  378. };
  379. /**
  380. * Custom rooting behavior for internal and external clients.
  381. */
  382. class MOZ_RAII JS_PUBLIC_API(CustomAutoRooter) : private AutoGCRooter
  383. {
  384. public:
  385. template <typename CX>
  386. explicit CustomAutoRooter(const CX& cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
  387. : AutoGCRooter(cx, CUSTOM)
  388. {
  389. MOZ_GUARD_OBJECT_NOTIFIER_INIT;
  390. }
  391. friend void AutoGCRooter::trace(JSTracer* trc);
  392. protected:
  393. virtual ~CustomAutoRooter() {}
  394. /** Supplied by derived class to trace roots. */
  395. virtual void trace(JSTracer* trc) = 0;
  396. private:
  397. MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
  398. };
  399. /** A handle to an array of rooted values. */
  400. class HandleValueArray
  401. {
  402. const size_t length_;
  403. const Value * const elements_;
  404. HandleValueArray(size_t len, const Value* elements) : length_(len), elements_(elements) {}
  405. public:
  406. explicit HandleValueArray(const RootedValue& value) : length_(1), elements_(value.address()) {}
  407. MOZ_IMPLICIT HandleValueArray(const AutoValueVector& values)
  408. : length_(values.length()), elements_(values.begin()) {}
  409. template <size_t N>
  410. MOZ_IMPLICIT HandleValueArray(const AutoValueArray<N>& values) : length_(N), elements_(values.begin()) {}
  411. /** CallArgs must already be rooted somewhere up the stack. */
  412. MOZ_IMPLICIT HandleValueArray(const JS::CallArgs& args) : length_(args.length()), elements_(args.array()) {}
  413. /** Use with care! Only call this if the data is guaranteed to be marked. */
  414. static HandleValueArray fromMarkedLocation(size_t len, const Value* elements) {
  415. return HandleValueArray(len, elements);
  416. }
  417. static HandleValueArray subarray(const HandleValueArray& values, size_t startIndex, size_t len) {
  418. MOZ_ASSERT(startIndex + len <= values.length());
  419. return HandleValueArray(len, values.begin() + startIndex);
  420. }
  421. static HandleValueArray empty() {
  422. return HandleValueArray(0, nullptr);
  423. }
  424. size_t length() const { return length_; }
  425. const Value* begin() const { return elements_; }
  426. HandleValue operator[](size_t i) const {
  427. MOZ_ASSERT(i < length_);
  428. return HandleValue::fromMarkedLocation(&elements_[i]);
  429. }
  430. };
  431. } /* namespace JS */
  432. /************************************************************************/
  433. struct JSFreeOp {
  434. protected:
  435. JSRuntime* runtime_;
  436. explicit JSFreeOp(JSRuntime* rt)
  437. : runtime_(rt) { }
  438. public:
  439. JSRuntime* runtime() const {
  440. MOZ_ASSERT(runtime_);
  441. return runtime_;
  442. }
  443. };
  444. /* Callbacks and their arguments. */
  445. /************************************************************************/
  446. typedef enum JSGCStatus {
  447. JSGC_BEGIN,
  448. JSGC_END
  449. } JSGCStatus;
  450. typedef void
  451. (* JSGCCallback)(JSContext* cx, JSGCStatus status, void* data);
  452. typedef void
  453. (* JSObjectsTenuredCallback)(JSContext* cx, void* data);
  454. typedef enum JSFinalizeStatus {
  455. /**
  456. * Called when preparing to sweep a group of zones, before anything has been
  457. * swept. The collector will not yield to the mutator before calling the
  458. * callback with JSFINALIZE_GROUP_END status.
  459. */
  460. JSFINALIZE_GROUP_START,
  461. /**
  462. * Called when preparing to sweep a group of zones. Weak references to
  463. * unmarked things have been removed and things that are not swept
  464. * incrementally have been finalized at this point. The collector may yield
  465. * to the mutator after this point.
  466. */
  467. JSFINALIZE_GROUP_END,
  468. /**
  469. * Called at the end of collection when everything has been swept.
  470. */
  471. JSFINALIZE_COLLECTION_END
  472. } JSFinalizeStatus;
  473. typedef void
  474. (* JSFinalizeCallback)(JSFreeOp* fop, JSFinalizeStatus status, bool isZoneGC, void* data);
  475. typedef void
  476. (* JSWeakPointerZoneGroupCallback)(JSContext* cx, void* data);
  477. typedef void
  478. (* JSWeakPointerCompartmentCallback)(JSContext* cx, JSCompartment* comp, void* data);
  479. typedef bool
  480. (* JSInterruptCallback)(JSContext* cx);
  481. typedef JSObject*
  482. (* JSGetIncumbentGlobalCallback)(JSContext* cx);
  483. typedef bool
  484. (* JSEnqueuePromiseJobCallback)(JSContext* cx, JS::HandleObject job,
  485. JS::HandleObject allocationSite, JS::HandleObject incumbentGlobal,
  486. void* data);
  487. enum class PromiseRejectionHandlingState {
  488. Unhandled,
  489. Handled
  490. };
  491. typedef void
  492. (* JSPromiseRejectionTrackerCallback)(JSContext* cx, JS::HandleObject promise,
  493. PromiseRejectionHandlingState state, void* data);
  494. typedef void
  495. (* JSProcessPromiseCallback)(JSContext* cx, JS::HandleObject promise);
  496. /**
  497. * Possible exception types. These types are part of a JSErrorFormatString
  498. * structure. They define which error to throw in case of a runtime error.
  499. *
  500. * JSEXN_WARN is used for warnings in js.msg files (for instance because we
  501. * don't want to prepend 'Error:' to warning messages). This value can go away
  502. * if we ever decide to use an entirely separate mechanism for warnings.
  503. */
  504. typedef enum JSExnType {
  505. JSEXN_ERR,
  506. JSEXN_FIRST = JSEXN_ERR,
  507. JSEXN_INTERNALERR,
  508. JSEXN_EVALERR,
  509. JSEXN_RANGEERR,
  510. JSEXN_REFERENCEERR,
  511. JSEXN_SYNTAXERR,
  512. JSEXN_TYPEERR,
  513. JSEXN_URIERR,
  514. JSEXN_DEBUGGEEWOULDRUN,
  515. JSEXN_WASMCOMPILEERROR,
  516. JSEXN_WASMRUNTIMEERROR,
  517. JSEXN_WARN,
  518. JSEXN_LIMIT
  519. } JSExnType;
  520. typedef struct JSErrorFormatString {
  521. /** The error message name in ASCII. */
  522. const char* name;
  523. /** The error format string in ASCII. */
  524. const char* format;
  525. /** The number of arguments to expand in the formatted error message. */
  526. uint16_t argCount;
  527. /** One of the JSExnType constants above. */
  528. int16_t exnType;
  529. } JSErrorFormatString;
  530. typedef const JSErrorFormatString*
  531. (* JSErrorCallback)(void* userRef, const unsigned errorNumber);
  532. typedef bool
  533. (* JSLocaleToUpperCase)(JSContext* cx, JS::HandleString src, JS::MutableHandleValue rval);
  534. typedef bool
  535. (* JSLocaleToLowerCase)(JSContext* cx, JS::HandleString src, JS::MutableHandleValue rval);
  536. typedef bool
  537. (* JSLocaleCompare)(JSContext* cx, JS::HandleString src1, JS::HandleString src2,
  538. JS::MutableHandleValue rval);
  539. typedef bool
  540. (* JSLocaleToUnicode)(JSContext* cx, const char* src, JS::MutableHandleValue rval);
  541. /**
  542. * Callback used to ask the embedding for the cross compartment wrapper handler
  543. * that implements the desired prolicy for this kind of object in the
  544. * destination compartment. |obj| is the object to be wrapped. If |existing| is
  545. * non-nullptr, it will point to an existing wrapper object that should be
  546. * re-used if possible. |existing| is guaranteed to be a cross-compartment
  547. * wrapper with a lazily-defined prototype and the correct global. It is
  548. * guaranteed not to wrap a function.
  549. */
  550. typedef JSObject*
  551. (* JSWrapObjectCallback)(JSContext* cx, JS::HandleObject existing, JS::HandleObject obj);
  552. /**
  553. * Callback used by the wrap hook to ask the embedding to prepare an object
  554. * for wrapping in a context. This might include unwrapping other wrappers
  555. * or even finding a more suitable object for the new compartment.
  556. */
  557. typedef void
  558. (* JSPreWrapCallback)(JSContext* cx, JS::HandleObject scope, JS::HandleObject obj,
  559. JS::HandleObject objectPassedToWrap,
  560. JS::MutableHandleObject retObj);
  561. struct JSWrapObjectCallbacks
  562. {
  563. JSWrapObjectCallback wrap;
  564. JSPreWrapCallback preWrap;
  565. };
  566. typedef void
  567. (* JSDestroyCompartmentCallback)(JSFreeOp* fop, JSCompartment* compartment);
  568. typedef size_t
  569. (* JSSizeOfIncludingThisCompartmentCallback)(mozilla::MallocSizeOf mallocSizeOf,
  570. JSCompartment* compartment);
  571. typedef void
  572. (* JSZoneCallback)(JS::Zone* zone);
  573. typedef void
  574. (* JSCompartmentNameCallback)(JSContext* cx, JSCompartment* compartment,
  575. char* buf, size_t bufsize);
  576. /************************************************************************/
  577. static MOZ_ALWAYS_INLINE JS::Value
  578. JS_NumberValue(double d)
  579. {
  580. int32_t i;
  581. d = JS::CanonicalizeNaN(d);
  582. if (mozilla::NumberIsInt32(d, &i))
  583. return JS::Int32Value(i);
  584. return JS::DoubleValue(d);
  585. }
  586. /************************************************************************/
  587. JS_PUBLIC_API(bool)
  588. JS_StringHasBeenPinned(JSContext* cx, JSString* str);
  589. namespace JS {
  590. /**
  591. * Container class for passing in script source buffers to the JS engine. This
  592. * not only groups the buffer and length values, it also provides a way to
  593. * optionally pass ownership of the buffer to the JS engine without copying.
  594. * Rules for use:
  595. *
  596. * 1) The data array must be allocated with js_malloc() or js_realloc() if
  597. * ownership is being granted to the SourceBufferHolder.
  598. * 2) If ownership is not given to the SourceBufferHolder, then the memory
  599. * must be kept alive until the JS compilation is complete.
  600. * 3) Any code calling SourceBufferHolder::take() must guarantee to keep the
  601. * memory alive until JS compilation completes. Normally only the JS
  602. * engine should be calling take().
  603. *
  604. * Example use:
  605. *
  606. * size_t length = 512;
  607. * char16_t* chars = static_cast<char16_t*>(js_malloc(sizeof(char16_t) * length));
  608. * JS::SourceBufferHolder srcBuf(chars, length, JS::SourceBufferHolder::GiveOwnership);
  609. * JS::Compile(cx, options, srcBuf);
  610. */
  611. class MOZ_STACK_CLASS SourceBufferHolder final
  612. {
  613. public:
  614. enum Ownership {
  615. NoOwnership,
  616. GiveOwnership
  617. };
  618. SourceBufferHolder(const char16_t* data, size_t dataLength, Ownership ownership)
  619. : data_(data),
  620. length_(dataLength),
  621. ownsChars_(ownership == GiveOwnership)
  622. {
  623. // Ensure that null buffers properly return an unowned, empty,
  624. // null-terminated string.
  625. static const char16_t NullChar_ = 0;
  626. if (!get()) {
  627. data_ = &NullChar_;
  628. length_ = 0;
  629. ownsChars_ = false;
  630. }
  631. }
  632. SourceBufferHolder(SourceBufferHolder&& other)
  633. : data_(other.data_),
  634. length_(other.length_),
  635. ownsChars_(other.ownsChars_)
  636. {
  637. other.data_ = nullptr;
  638. other.length_ = 0;
  639. other.ownsChars_ = false;
  640. }
  641. ~SourceBufferHolder() {
  642. if (ownsChars_)
  643. js_free(const_cast<char16_t*>(data_));
  644. }
  645. // Access the underlying source buffer without affecting ownership.
  646. const char16_t* get() const { return data_; }
  647. // Length of the source buffer in char16_t code units (not bytes)
  648. size_t length() const { return length_; }
  649. // Returns true if the SourceBufferHolder owns the buffer and will free
  650. // it upon destruction. If true, it is legal to call take().
  651. bool ownsChars() const { return ownsChars_; }
  652. // Retrieve and take ownership of the underlying data buffer. The caller
  653. // is now responsible for calling js_free() on the returned value, *but only
  654. // after JS script compilation has completed*.
  655. //
  656. // After the buffer has been taken the SourceBufferHolder functions as if
  657. // it had been constructed on an unowned buffer; get() and length() still
  658. // work. In order for this to be safe the taken buffer must be kept alive
  659. // until after JS script compilation completes as noted above.
  660. //
  661. // Note, it's the caller's responsibility to check ownsChars() before taking
  662. // the buffer. Taking and then free'ing an unowned buffer will have dire
  663. // consequences.
  664. char16_t* take() {
  665. MOZ_ASSERT(ownsChars_);
  666. ownsChars_ = false;
  667. return const_cast<char16_t*>(data_);
  668. }
  669. private:
  670. SourceBufferHolder(SourceBufferHolder&) = delete;
  671. SourceBufferHolder& operator=(SourceBufferHolder&) = delete;
  672. const char16_t* data_;
  673. size_t length_;
  674. bool ownsChars_;
  675. };
  676. } /* namespace JS */
  677. /************************************************************************/
  678. /* Property attributes, set in JSPropertySpec and passed to API functions.
  679. *
  680. * NB: The data structure in which some of these values are stored only uses
  681. * a uint8_t to store the relevant information. Proceed with caution if
  682. * trying to reorder or change the the first byte worth of flags.
  683. */
  684. #define JSPROP_ENUMERATE 0x01 /* property is visible to for/in loop */
  685. #define JSPROP_READONLY 0x02 /* not settable: assignment is no-op.
  686. This flag is only valid when neither
  687. JSPROP_GETTER nor JSPROP_SETTER is
  688. set. */
  689. #define JSPROP_PERMANENT 0x04 /* property cannot be deleted */
  690. #define JSPROP_PROPOP_ACCESSORS 0x08 /* Passed to JS_Define(UC)Property* and
  691. JS_DefineElement if getters/setters
  692. are JSGetterOp/JSSetterOp */
  693. #define JSPROP_GETTER 0x10 /* property holds getter function */
  694. #define JSPROP_SETTER 0x20 /* property holds setter function */
  695. #define JSPROP_SHARED 0x40 /* don't allocate a value slot for this
  696. property; don't copy the property on
  697. set of the same-named property in an
  698. object that delegates to a prototype
  699. containing this property */
  700. #define JSPROP_INTERNAL_USE_BIT 0x80 /* internal JS engine use only */
  701. #define JSFUN_STUB_GSOPS 0x200 /* use JS_PropertyStub getter/setter
  702. instead of defaulting to class gsops
  703. for property holding function */
  704. #define JSFUN_CONSTRUCTOR 0x400 /* native that can be called as a ctor */
  705. // 0x800 /* Unused */
  706. #define JSFUN_HAS_REST 0x1000 /* function has ...rest parameter. */
  707. #define JSFUN_FLAGS_MASK 0x1e00 /* | of all the JSFUN_* flags */
  708. /*
  709. * If set, will allow redefining a non-configurable property, but only on a
  710. * non-DOM global. This is a temporary hack that will need to go away in bug
  711. * 1105518.
  712. */
  713. #define JSPROP_REDEFINE_NONCONFIGURABLE 0x1000
  714. /*
  715. * Resolve hooks and enumerate hooks must pass this flag when calling
  716. * JS_Define* APIs to reify lazily-defined properties.
  717. *
  718. * JSPROP_RESOLVING is used only with property-defining APIs. It tells the
  719. * engine to skip the resolve hook when performing the lookup at the beginning
  720. * of property definition. This keeps the resolve hook from accidentally
  721. * triggering itself: unchecked recursion.
  722. *
  723. * For enumerate hooks, triggering the resolve hook would be merely silly, not
  724. * fatal, except in some cases involving non-configurable properties.
  725. */
  726. #define JSPROP_RESOLVING 0x2000
  727. #define JSPROP_IGNORE_ENUMERATE 0x4000 /* ignore the value in JSPROP_ENUMERATE.
  728. This flag only valid when defining over
  729. an existing property. */
  730. #define JSPROP_IGNORE_READONLY 0x8000 /* ignore the value in JSPROP_READONLY.
  731. This flag only valid when defining over
  732. an existing property. */
  733. #define JSPROP_IGNORE_PERMANENT 0x10000 /* ignore the value in JSPROP_PERMANENT.
  734. This flag only valid when defining over
  735. an existing property. */
  736. #define JSPROP_IGNORE_VALUE 0x20000 /* ignore the Value in the descriptor. Nothing was
  737. specified when passed to Object.defineProperty
  738. from script. */
  739. /** Microseconds since the epoch, midnight, January 1, 1970 UTC. */
  740. extern JS_PUBLIC_API(int64_t)
  741. JS_Now(void);
  742. /** Don't want to export data, so provide accessors for non-inline Values. */
  743. extern JS_PUBLIC_API(JS::Value)
  744. JS_GetNaNValue(JSContext* cx);
  745. extern JS_PUBLIC_API(JS::Value)
  746. JS_GetNegativeInfinityValue(JSContext* cx);
  747. extern JS_PUBLIC_API(JS::Value)
  748. JS_GetPositiveInfinityValue(JSContext* cx);
  749. extern JS_PUBLIC_API(JS::Value)
  750. JS_GetEmptyStringValue(JSContext* cx);
  751. extern JS_PUBLIC_API(JSString*)
  752. JS_GetEmptyString(JSContext* cx);
  753. extern JS_PUBLIC_API(bool)
  754. JS_ValueToObject(JSContext* cx, JS::HandleValue v, JS::MutableHandleObject objp);
  755. extern JS_PUBLIC_API(JSFunction*)
  756. JS_ValueToFunction(JSContext* cx, JS::HandleValue v);
  757. extern JS_PUBLIC_API(JSFunction*)
  758. JS_ValueToConstructor(JSContext* cx, JS::HandleValue v);
  759. extern JS_PUBLIC_API(JSString*)
  760. JS_ValueToSource(JSContext* cx, JS::Handle<JS::Value> v);
  761. extern JS_PUBLIC_API(bool)
  762. JS_DoubleIsInt32(double d, int32_t* ip);
  763. extern JS_PUBLIC_API(JSType)
  764. JS_TypeOfValue(JSContext* cx, JS::Handle<JS::Value> v);
  765. namespace JS {
  766. extern JS_PUBLIC_API(const char*)
  767. InformalValueTypeName(const JS::Value& v);
  768. } /* namespace JS */
  769. extern JS_PUBLIC_API(bool)
  770. JS_StrictlyEqual(JSContext* cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool* equal);
  771. extern JS_PUBLIC_API(bool)
  772. JS_LooselyEqual(JSContext* cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool* equal);
  773. extern JS_PUBLIC_API(bool)
  774. JS_SameValue(JSContext* cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool* same);
  775. /** True iff fun is the global eval function. */
  776. extern JS_PUBLIC_API(bool)
  777. JS_IsBuiltinEvalFunction(JSFunction* fun);
  778. /** True iff fun is the Function constructor. */
  779. extern JS_PUBLIC_API(bool)
  780. JS_IsBuiltinFunctionConstructor(JSFunction* fun);
  781. /************************************************************************/
  782. /*
  783. * Locking, contexts, and memory allocation.
  784. *
  785. * It is important that SpiderMonkey be initialized, and the first context
  786. * be created, in a single-threaded fashion. Otherwise the behavior of the
  787. * library is undefined.
  788. * See: http://developer.mozilla.org/en/docs/Category:JSAPI_Reference
  789. */
  790. extern JS_PUBLIC_API(JSContext*)
  791. JS_NewContext(uint32_t maxbytes,
  792. uint32_t maxNurseryBytes = JS::DefaultNurseryBytes,
  793. JSContext* parentContext = nullptr);
  794. extern JS_PUBLIC_API(void)
  795. JS_DestroyContext(JSContext* cx);
  796. typedef double (*JS_CurrentEmbedderTimeFunction)();
  797. /**
  798. * The embedding can specify a time function that will be used in some
  799. * situations. The function can return the time however it likes; but
  800. * the norm is to return times in units of milliseconds since an
  801. * arbitrary, but consistent, epoch. If the time function is not set,
  802. * a built-in default will be used.
  803. */
  804. JS_PUBLIC_API(void)
  805. JS_SetCurrentEmbedderTimeFunction(JS_CurrentEmbedderTimeFunction timeFn);
  806. /**
  807. * Return the time as computed using the current time function, or a
  808. * suitable default if one has not been set.
  809. */
  810. JS_PUBLIC_API(double)
  811. JS_GetCurrentEmbedderTime();
  812. JS_PUBLIC_API(void*)
  813. JS_GetContextPrivate(JSContext* cx);
  814. JS_PUBLIC_API(void)
  815. JS_SetContextPrivate(JSContext* cx, void* data);
  816. extern JS_PUBLIC_API(JSContext*)
  817. JS_GetParentContext(JSContext* cx);
  818. extern JS_PUBLIC_API(void)
  819. JS_BeginRequest(JSContext* cx);
  820. extern JS_PUBLIC_API(void)
  821. JS_EndRequest(JSContext* cx);
  822. extern JS_PUBLIC_API(void)
  823. JS_SetFutexCanWait(JSContext* cx);
  824. namespace js {
  825. void
  826. AssertHeapIsIdle(JSRuntime* rt);
  827. } /* namespace js */
  828. class MOZ_RAII JSAutoRequest
  829. {
  830. public:
  831. explicit JSAutoRequest(JSContext* cx
  832. MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
  833. : mContext(cx)
  834. {
  835. MOZ_GUARD_OBJECT_NOTIFIER_INIT;
  836. JS_BeginRequest(mContext);
  837. }
  838. ~JSAutoRequest() {
  839. JS_EndRequest(mContext);
  840. }
  841. protected:
  842. JSContext* mContext;
  843. MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
  844. #if 0
  845. private:
  846. static void* operator new(size_t) CPP_THROW_NEW { return 0; }
  847. static void operator delete(void*, size_t) { }
  848. #endif
  849. };
  850. extern JS_PUBLIC_API(JSVersion)
  851. JS_GetVersion(JSContext* cx);
  852. /**
  853. * Mutate the version on the compartment. This is generally discouraged, but
  854. * necessary to support the version mutation in the js and xpc shell command
  855. * set.
  856. *
  857. * It would be nice to put this in jsfriendapi, but the linkage requirements
  858. * of the shells make that impossible.
  859. */
  860. JS_PUBLIC_API(void)
  861. JS_SetVersionForCompartment(JSCompartment* compartment, JSVersion version);
  862. extern JS_PUBLIC_API(const char*)
  863. JS_VersionToString(JSVersion version);
  864. extern JS_PUBLIC_API(JSVersion)
  865. JS_StringToVersion(const char* string);
  866. namespace JS {
  867. class JS_PUBLIC_API(ContextOptions) {
  868. public:
  869. ContextOptions()
  870. : baseline_(true),
  871. ion_(true),
  872. asmJS_(true),
  873. wasm_(false),
  874. wasmAlwaysBaseline_(false),
  875. throwOnAsmJSValidationFailure_(false),
  876. nativeRegExp_(true),
  877. unboxedArrays_(false),
  878. asyncStack_(true),
  879. throwOnDebuggeeWouldRun_(true),
  880. dumpStackOnDebuggeeWouldRun_(false),
  881. werror_(false),
  882. strictMode_(false),
  883. extraWarnings_(false)
  884. {
  885. }
  886. bool baseline() const { return baseline_; }
  887. ContextOptions& setBaseline(bool flag) {
  888. baseline_ = flag;
  889. return *this;
  890. }
  891. ContextOptions& toggleBaseline() {
  892. baseline_ = !baseline_;
  893. return *this;
  894. }
  895. bool ion() const { return ion_; }
  896. ContextOptions& setIon(bool flag) {
  897. ion_ = flag;
  898. return *this;
  899. }
  900. ContextOptions& toggleIon() {
  901. ion_ = !ion_;
  902. return *this;
  903. }
  904. bool asmJS() const { return asmJS_; }
  905. ContextOptions& setAsmJS(bool flag) {
  906. asmJS_ = flag;
  907. return *this;
  908. }
  909. ContextOptions& toggleAsmJS() {
  910. asmJS_ = !asmJS_;
  911. return *this;
  912. }
  913. bool wasm() const { return wasm_; }
  914. ContextOptions& setWasm(bool flag) {
  915. wasm_ = flag;
  916. return *this;
  917. }
  918. ContextOptions& toggleWasm() {
  919. wasm_ = !wasm_;
  920. return *this;
  921. }
  922. bool wasmAlwaysBaseline() const { return wasmAlwaysBaseline_; }
  923. ContextOptions& setWasmAlwaysBaseline(bool flag) {
  924. wasmAlwaysBaseline_ = flag;
  925. return *this;
  926. }
  927. ContextOptions& toggleWasmAlwaysBaseline() {
  928. wasmAlwaysBaseline_ = !wasmAlwaysBaseline_;
  929. return *this;
  930. }
  931. bool throwOnAsmJSValidationFailure() const { return throwOnAsmJSValidationFailure_; }
  932. ContextOptions& setThrowOnAsmJSValidationFailure(bool flag) {
  933. throwOnAsmJSValidationFailure_ = flag;
  934. return *this;
  935. }
  936. ContextOptions& toggleThrowOnAsmJSValidationFailure() {
  937. throwOnAsmJSValidationFailure_ = !throwOnAsmJSValidationFailure_;
  938. return *this;
  939. }
  940. bool nativeRegExp() const { return nativeRegExp_; }
  941. ContextOptions& setNativeRegExp(bool flag) {
  942. nativeRegExp_ = flag;
  943. return *this;
  944. }
  945. bool unboxedArrays() const { return unboxedArrays_; }
  946. ContextOptions& setUnboxedArrays(bool flag) {
  947. unboxedArrays_ = flag;
  948. return *this;
  949. }
  950. bool asyncStack() const { return asyncStack_; }
  951. ContextOptions& setAsyncStack(bool flag) {
  952. asyncStack_ = flag;
  953. return *this;
  954. }
  955. bool throwOnDebuggeeWouldRun() const { return throwOnDebuggeeWouldRun_; }
  956. ContextOptions& setThrowOnDebuggeeWouldRun(bool flag) {
  957. throwOnDebuggeeWouldRun_ = flag;
  958. return *this;
  959. }
  960. bool dumpStackOnDebuggeeWouldRun() const { return dumpStackOnDebuggeeWouldRun_; }
  961. ContextOptions& setDumpStackOnDebuggeeWouldRun(bool flag) {
  962. dumpStackOnDebuggeeWouldRun_ = flag;
  963. return *this;
  964. }
  965. bool werror() const { return werror_; }
  966. ContextOptions& setWerror(bool flag) {
  967. werror_ = flag;
  968. return *this;
  969. }
  970. ContextOptions& toggleWerror() {
  971. werror_ = !werror_;
  972. return *this;
  973. }
  974. bool strictMode() const { return strictMode_; }
  975. ContextOptions& setStrictMode(bool flag) {
  976. strictMode_ = flag;
  977. return *this;
  978. }
  979. ContextOptions& toggleStrictMode() {
  980. strictMode_ = !strictMode_;
  981. return *this;
  982. }
  983. bool extraWarnings() const { return extraWarnings_; }
  984. ContextOptions& setExtraWarnings(bool flag) {
  985. extraWarnings_ = flag;
  986. return *this;
  987. }
  988. ContextOptions& toggleExtraWarnings() {
  989. extraWarnings_ = !extraWarnings_;
  990. return *this;
  991. }
  992. private:
  993. bool baseline_ : 1;
  994. bool ion_ : 1;
  995. bool asmJS_ : 1;
  996. bool wasm_ : 1;
  997. bool wasmAlwaysBaseline_ : 1;
  998. bool throwOnAsmJSValidationFailure_ : 1;
  999. bool nativeRegExp_ : 1;
  1000. bool unboxedArrays_ : 1;
  1001. bool asyncStack_ : 1;
  1002. bool throwOnDebuggeeWouldRun_ : 1;
  1003. bool dumpStackOnDebuggeeWouldRun_ : 1;
  1004. bool werror_ : 1;
  1005. bool strictMode_ : 1;
  1006. bool extraWarnings_ : 1;
  1007. };
  1008. JS_PUBLIC_API(ContextOptions&)
  1009. ContextOptionsRef(JSContext* cx);
  1010. /**
  1011. * Initialize the runtime's self-hosted code. Embeddings should call this
  1012. * exactly once per runtime/context, before the first JS_NewGlobalObject
  1013. * call.
  1014. */
  1015. JS_PUBLIC_API(bool)
  1016. InitSelfHostedCode(JSContext* cx);
  1017. /**
  1018. * Asserts (in debug and release builds) that `obj` belongs to the current
  1019. * thread's context.
  1020. */
  1021. JS_PUBLIC_API(void)
  1022. AssertObjectBelongsToCurrentThread(JSObject* obj);
  1023. } /* namespace JS */
  1024. extern JS_PUBLIC_API(const char*)
  1025. JS_GetImplementationVersion(void);
  1026. extern JS_PUBLIC_API(void)
  1027. JS_SetDestroyCompartmentCallback(JSContext* cx, JSDestroyCompartmentCallback callback);
  1028. extern JS_PUBLIC_API(void)
  1029. JS_SetSizeOfIncludingThisCompartmentCallback(JSContext* cx,
  1030. JSSizeOfIncludingThisCompartmentCallback callback);
  1031. extern JS_PUBLIC_API(void)
  1032. JS_SetDestroyZoneCallback(JSContext* cx, JSZoneCallback callback);
  1033. extern JS_PUBLIC_API(void)
  1034. JS_SetSweepZoneCallback(JSContext* cx, JSZoneCallback callback);
  1035. extern JS_PUBLIC_API(void)
  1036. JS_SetCompartmentNameCallback(JSContext* cx, JSCompartmentNameCallback callback);
  1037. extern JS_PUBLIC_API(void)
  1038. JS_SetWrapObjectCallbacks(JSContext* cx, const JSWrapObjectCallbacks* callbacks);
  1039. extern JS_PUBLIC_API(void)
  1040. JS_SetCompartmentPrivate(JSCompartment* compartment, void* data);
  1041. extern JS_PUBLIC_API(void*)
  1042. JS_GetCompartmentPrivate(JSCompartment* compartment);
  1043. extern JS_PUBLIC_API(void)
  1044. JS_SetZoneUserData(JS::Zone* zone, void* data);
  1045. extern JS_PUBLIC_API(void*)
  1046. JS_GetZoneUserData(JS::Zone* zone);
  1047. extern JS_PUBLIC_API(bool)
  1048. JS_WrapObject(JSContext* cx, JS::MutableHandleObject objp);
  1049. extern JS_PUBLIC_API(bool)
  1050. JS_WrapValue(JSContext* cx, JS::MutableHandleValue vp);
  1051. extern JS_PUBLIC_API(JSObject*)
  1052. JS_TransplantObject(JSContext* cx, JS::HandleObject origobj, JS::HandleObject target);
  1053. extern JS_PUBLIC_API(bool)
  1054. JS_RefreshCrossCompartmentWrappers(JSContext* cx, JS::Handle<JSObject*> obj);
  1055. /*
  1056. * At any time, a JSContext has a current (possibly-nullptr) compartment.
  1057. * Compartments are described in:
  1058. *
  1059. * developer.mozilla.org/en-US/docs/SpiderMonkey/SpiderMonkey_compartments
  1060. *
  1061. * The current compartment of a context may be changed. The preferred way to do
  1062. * this is with JSAutoCompartment:
  1063. *
  1064. * void foo(JSContext* cx, JSObject* obj) {
  1065. * // in some compartment 'c'
  1066. * {
  1067. * JSAutoCompartment ac(cx, obj); // constructor enters
  1068. * // in the compartment of 'obj'
  1069. * } // destructor leaves
  1070. * // back in compartment 'c'
  1071. * }
  1072. *
  1073. * For more complicated uses that don't neatly fit in a C++ stack frame, the
  1074. * compartment can entered and left using separate function calls:
  1075. *
  1076. * void foo(JSContext* cx, JSObject* obj) {
  1077. * // in 'oldCompartment'
  1078. * JSCompartment* oldCompartment = JS_EnterCompartment(cx, obj);
  1079. * // in the compartment of 'obj'
  1080. * JS_LeaveCompartment(cx, oldCompartment);
  1081. * // back in 'oldCompartment'
  1082. * }
  1083. *
  1084. * Note: these calls must still execute in a LIFO manner w.r.t all other
  1085. * enter/leave calls on the context. Furthermore, only the return value of a
  1086. * JS_EnterCompartment call may be passed as the 'oldCompartment' argument of
  1087. * the corresponding JS_LeaveCompartment call.
  1088. */
  1089. class MOZ_RAII JS_PUBLIC_API(JSAutoCompartment)
  1090. {
  1091. JSContext* cx_;
  1092. JSCompartment* oldCompartment_;
  1093. public:
  1094. JSAutoCompartment(JSContext* cx, JSObject* target
  1095. MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
  1096. JSAutoCompartment(JSContext* cx, JSScript* target
  1097. MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
  1098. ~JSAutoCompartment();
  1099. MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
  1100. };
  1101. class MOZ_RAII JS_PUBLIC_API(JSAutoNullableCompartment)
  1102. {
  1103. JSContext* cx_;
  1104. JSCompartment* oldCompartment_;
  1105. public:
  1106. explicit JSAutoNullableCompartment(JSContext* cx, JSObject* targetOrNull
  1107. MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
  1108. ~JSAutoNullableCompartment();
  1109. MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
  1110. };
  1111. /** NB: This API is infallible; a nullptr return value does not indicate error. */
  1112. extern JS_PUBLIC_API(JSCompartment*)
  1113. JS_EnterCompartment(JSContext* cx, JSObject* target);
  1114. extern JS_PUBLIC_API(void)
  1115. JS_LeaveCompartment(JSContext* cx, JSCompartment* oldCompartment);
  1116. typedef void (*JSIterateCompartmentCallback)(JSContext* cx, void* data, JSCompartment* compartment);
  1117. /**
  1118. * This function calls |compartmentCallback| on every compartment. Beware that
  1119. * there is no guarantee that the compartment will survive after the callback
  1120. * returns. Also, barriers are disabled via the TraceSession.
  1121. */
  1122. extern JS_PUBLIC_API(void)
  1123. JS_IterateCompartments(JSContext* cx, void* data,
  1124. JSIterateCompartmentCallback compartmentCallback);
  1125. /**
  1126. * Initialize standard JS class constructors, prototypes, and any top-level
  1127. * functions and constants associated with the standard classes (e.g. isNaN
  1128. * for Number).
  1129. *
  1130. * NB: This sets cx's global object to obj if it was null.
  1131. */
  1132. extern JS_PUBLIC_API(bool)
  1133. JS_InitStandardClasses(JSContext* cx, JS::Handle<JSObject*> obj);
  1134. /**
  1135. * Resolve id, which must contain either a string or an int, to a standard
  1136. * class name in obj if possible, defining the class's constructor and/or
  1137. * prototype and storing true in *resolved. If id does not name a standard
  1138. * class or a top-level property induced by initializing a standard class,
  1139. * store false in *resolved and just return true. Return false on error,
  1140. * as usual for bool result-typed API entry points.
  1141. *
  1142. * This API can be called directly from a global object class's resolve op,
  1143. * to define standard classes lazily. The class's enumerate op should call
  1144. * JS_EnumerateStandardClasses(cx, obj), to define eagerly during for..in
  1145. * loops any classes not yet resolved lazily.
  1146. */
  1147. extern JS_PUBLIC_API(bool)
  1148. JS_ResolveStandardClass(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* resolved);
  1149. extern JS_PUBLIC_API(bool)
  1150. JS_MayResolveStandardClass(const JSAtomState& names, jsid id, JSObject* maybeObj);
  1151. extern JS_PUBLIC_API(bool)
  1152. JS_EnumerateStandardClasses(JSContext* cx, JS::HandleObject obj);
  1153. extern JS_PUBLIC_API(bool)
  1154. JS_GetClassObject(JSContext* cx, JSProtoKey key, JS::MutableHandle<JSObject*> objp);
  1155. extern JS_PUBLIC_API(bool)
  1156. JS_GetClassPrototype(JSContext* cx, JSProtoKey key, JS::MutableHandle<JSObject*> objp);
  1157. namespace JS {
  1158. /*
  1159. * Determine if the given object is an instance/prototype/constructor for a standard
  1160. * class. If so, return the associated JSProtoKey. If not, return JSProto_Null.
  1161. */
  1162. extern JS_PUBLIC_API(JSProtoKey)
  1163. IdentifyStandardInstance(JSObject* obj);
  1164. extern JS_PUBLIC_API(JSProtoKey)
  1165. IdentifyStandardPrototype(JSObject* obj);
  1166. extern JS_PUBLIC_API(JSProtoKey)
  1167. IdentifyStandardInstanceOrPrototype(JSObject* obj);
  1168. extern JS_PUBLIC_API(JSProtoKey)
  1169. IdentifyStandardConstructor(JSObject* obj);
  1170. extern JS_PUBLIC_API(void)
  1171. ProtoKeyToId(JSContext* cx, JSProtoKey key, JS::MutableHandleId idp);
  1172. } /* namespace JS */
  1173. extern JS_PUBLIC_API(JSProtoKey)
  1174. JS_IdToProtoKey(JSContext* cx, JS::HandleId id);
  1175. /**
  1176. * Returns the original value of |Function.prototype| from the global object in
  1177. * which |forObj| was created.
  1178. */
  1179. extern JS_PUBLIC_API(JSObject*)
  1180. JS_GetFunctionPrototype(JSContext* cx, JS::HandleObject forObj);
  1181. /**
  1182. * Returns the original value of |Object.prototype| from the global object in
  1183. * which |forObj| was created.
  1184. */
  1185. extern JS_PUBLIC_API(JSObject*)
  1186. JS_GetObjectPrototype(JSContext* cx, JS::HandleObject forObj);
  1187. /**
  1188. * Returns the original value of |Array.prototype| from the global object in
  1189. * which |forObj| was created.
  1190. */
  1191. extern JS_PUBLIC_API(JSObject*)
  1192. JS_GetArrayPrototype(JSContext* cx, JS::HandleObject forObj);
  1193. /**
  1194. * Returns the original value of |Error.prototype| from the global
  1195. * object of the current compartment of cx.
  1196. */
  1197. extern JS_PUBLIC_API(JSObject*)
  1198. JS_GetErrorPrototype(JSContext* cx);
  1199. /**
  1200. * Returns the %IteratorPrototype% object that all built-in iterator prototype
  1201. * chains go through for the global object of the current compartment of cx.
  1202. */
  1203. extern JS_PUBLIC_API(JSObject*)
  1204. JS_GetIteratorPrototype(JSContext* cx);
  1205. extern JS_PUBLIC_API(JSObject*)
  1206. JS_GetGlobalForObject(JSContext* cx, JSObject* obj);
  1207. extern JS_PUBLIC_API(bool)
  1208. JS_IsGlobalObject(JSObject* obj);
  1209. extern JS_PUBLIC_API(JSObject*)
  1210. JS_GlobalLexicalEnvironment(JSObject* obj);
  1211. extern JS_PUBLIC_API(bool)
  1212. JS_HasExtensibleLexicalEnvironment(JSObject* obj);
  1213. extern JS_PUBLIC_API(JSObject*)
  1214. JS_ExtensibleLexicalEnvironment(JSObject* obj);
  1215. /**
  1216. * May return nullptr, if |c| never had a global (e.g. the atoms compartment),
  1217. * or if |c|'s global has been collected.
  1218. */
  1219. extern JS_PUBLIC_API(JSObject*)
  1220. JS_GetGlobalForCompartmentOrNull(JSContext* cx, JSCompartment* c);
  1221. namespace JS {
  1222. extern JS_PUBLIC_API(JSObject*)
  1223. CurrentGlobalOrNull(JSContext* cx);
  1224. } // namespace JS
  1225. /**
  1226. * Add 'Reflect.parse', a SpiderMonkey extension, to the Reflect object on the
  1227. * given global.
  1228. */
  1229. extern JS_PUBLIC_API(bool)
  1230. JS_InitReflectParse(JSContext* cx, JS::HandleObject global);
  1231. /**
  1232. * Add various profiling-related functions as properties of the given object.
  1233. * Defined in builtin/Profilers.cpp.
  1234. */
  1235. extern JS_PUBLIC_API(bool)
  1236. JS_DefineProfilingFunctions(JSContext* cx, JS::HandleObject obj);
  1237. /* Defined in vm/Debugger.cpp. */
  1238. extern JS_PUBLIC_API(bool)
  1239. JS_DefineDebuggerObject(JSContext* cx, JS::HandleObject obj);
  1240. #ifdef JS_HAS_CTYPES
  1241. /**
  1242. * Initialize the 'ctypes' object on a global variable 'obj'. The 'ctypes'
  1243. * object will be sealed.
  1244. */
  1245. extern JS_PUBLIC_API(bool)
  1246. JS_InitCTypesClass(JSContext* cx, JS::HandleObject global);
  1247. /**
  1248. * Convert a unicode string 'source' of length 'slen' to the platform native
  1249. * charset, returning a null-terminated string allocated with JS_malloc. On
  1250. * failure, this function should report an error.
  1251. */
  1252. typedef char*
  1253. (* JSCTypesUnicodeToNativeFun)(JSContext* cx, const char16_t* source, size_t slen);
  1254. /**
  1255. * Set of function pointers that ctypes can use for various internal functions.
  1256. * See JS_SetCTypesCallbacks below. Providing nullptr for a function is safe,
  1257. * and will result in the applicable ctypes functionality not being available.
  1258. */
  1259. struct JSCTypesCallbacks {
  1260. JSCTypesUnicodeToNativeFun unicodeToNative;
  1261. };
  1262. typedef struct JSCTypesCallbacks JSCTypesCallbacks;
  1263. /**
  1264. * Set the callbacks on the provided 'ctypesObj' object. 'callbacks' should be a
  1265. * pointer to static data that exists for the lifetime of 'ctypesObj', but it
  1266. * may safely be altered after calling this function and without having
  1267. * to call this function again.
  1268. */
  1269. extern JS_PUBLIC_API(void)
  1270. JS_SetCTypesCallbacks(JSObject* ctypesObj, const JSCTypesCallbacks* callbacks);
  1271. #endif
  1272. extern JS_PUBLIC_API(void*)
  1273. JS_malloc(JSContext* cx, size_t nbytes);
  1274. extern JS_PUBLIC_API(void*)
  1275. JS_realloc(JSContext* cx, void* p, size_t oldBytes, size_t newBytes);
  1276. /**
  1277. * A wrapper for js_free(p) that may delay js_free(p) invocation as a
  1278. * performance optimization.
  1279. * cx may be nullptr.
  1280. */
  1281. extern JS_PUBLIC_API(void)
  1282. JS_free(JSContext* cx, void* p);
  1283. /**
  1284. * A wrapper for js_free(p) that may delay js_free(p) invocation as a
  1285. * performance optimization as specified by the given JSFreeOp instance.
  1286. */
  1287. extern JS_PUBLIC_API(void)
  1288. JS_freeop(JSFreeOp* fop, void* p);
  1289. extern JS_PUBLIC_API(void)
  1290. JS_updateMallocCounter(JSContext* cx, size_t nbytes);
  1291. extern JS_PUBLIC_API(char*)
  1292. JS_strdup(JSContext* cx, const char* s);
  1293. /**
  1294. * Register externally maintained GC roots.
  1295. *
  1296. * traceOp: the trace operation. For each root the implementation should call
  1297. * JS::TraceEdge whenever the root contains a traceable thing.
  1298. * data: the data argument to pass to each invocation of traceOp.
  1299. */
  1300. extern JS_PUBLIC_API(bool)
  1301. JS_AddExtraGCRootsTracer(JSContext* cx, JSTraceDataOp traceOp, void* data);
  1302. /** Undo a call to JS_AddExtraGCRootsTracer. */
  1303. extern JS_PUBLIC_API(void)
  1304. JS_RemoveExtraGCRootsTracer(JSContext* cx, JSTraceDataOp traceOp, void* data);
  1305. /*
  1306. * Garbage collector API.
  1307. */
  1308. extern JS_PUBLIC_API(void)
  1309. JS_GC(JSContext* cx);
  1310. extern JS_PUBLIC_API(void)
  1311. JS_MaybeGC(JSContext* cx);
  1312. extern JS_PUBLIC_API(void)
  1313. JS_SetGCCallback(JSContext* cx, JSGCCallback cb, void* data);
  1314. extern JS_PUBLIC_API(void)
  1315. JS_SetObjectsTenuredCallback(JSContext* cx, JSObjectsTenuredCallback cb,
  1316. void* data);
  1317. extern JS_PUBLIC_API(bool)
  1318. JS_AddFinalizeCallback(JSContext* cx, JSFinalizeCallback cb, void* data);
  1319. extern JS_PUBLIC_API(void)
  1320. JS_RemoveFinalizeCallback(JSContext* cx, JSFinalizeCallback cb);
  1321. /*
  1322. * Weak pointers and garbage collection
  1323. *
  1324. * Weak pointers are by their nature not marked as part of garbage collection,
  1325. * but they may need to be updated in two cases after a GC:
  1326. *
  1327. * 1) Their referent was found not to be live and is about to be finalized
  1328. * 2) Their referent has been moved by a compacting GC
  1329. *
  1330. * To handle this, any part of the system that maintain weak pointers to
  1331. * JavaScript GC things must register a callback with
  1332. * JS_(Add,Remove)WeakPointer{ZoneGroup,Compartment}Callback(). This callback
  1333. * must then call JS_UpdateWeakPointerAfterGC() on all weak pointers it knows
  1334. * about.
  1335. *
  1336. * Since sweeping is incremental, we have several callbacks to avoid repeatedly
  1337. * having to visit all embedder structures. The WeakPointerZoneGroupCallback is
  1338. * called once for each strongly connected group of zones, whereas the
  1339. * WeakPointerCompartmentCallback is called once for each compartment that is
  1340. * visited while sweeping. Structures that cannot contain references in more
  1341. * than one compartment should sweep the relevant per-compartment structures
  1342. * using the latter callback to minimizer per-slice overhead.
  1343. *
  1344. * The argument to JS_UpdateWeakPointerAfterGC() is an in-out param. If the
  1345. * referent is about to be finalized the pointer will be set to null. If the
  1346. * referent has been moved then the pointer will be updated to point to the new
  1347. * location.
  1348. *
  1349. * Callers of this method are responsible for updating any state that is
  1350. * dependent on the object's address. For example, if the object's address is
  1351. * used as a key in a hashtable, then the object must be removed and
  1352. * re-inserted with the correct hash.
  1353. */
  1354. extern JS_PUBLIC_API(bool)
  1355. JS_AddWeakPointerZoneGroupCallback(JSContext* cx, JSWeakPointerZoneGroupCallback cb, void* data);
  1356. extern JS_PUBLIC_API(void)
  1357. JS_RemoveWeakPointerZoneGroupCallback(JSContext* cx, JSWeakPointerZoneGroupCallback cb);
  1358. extern JS_PUBLIC_API(bool)
  1359. JS_AddWeakPointerCompartmentCallback(JSContext* cx, JSWeakPointerCompartmentCallback cb,
  1360. void* data);
  1361. extern JS_PUBLIC_API(void)
  1362. JS_RemoveWeakPointerCompartmentCallback(JSContext* cx, JSWeakPointerCompartmentCallback cb);
  1363. extern JS_PUBLIC_API(void)
  1364. JS_UpdateWeakPointerAfterGC(JS::Heap<JSObject*>* objp);
  1365. extern JS_PUBLIC_API(void)
  1366. JS_UpdateWeakPointerAfterGCUnbarriered(JSObject** objp);
  1367. typedef enum JSGCParamKey {
  1368. /** Maximum nominal heap before last ditch GC. */
  1369. JSGC_MAX_BYTES = 0,
  1370. /** Number of JS_malloc bytes before last ditch GC. */
  1371. JSGC_MAX_MALLOC_BYTES = 1,
  1372. /** Amount of bytes allocated by the GC. */
  1373. JSGC_BYTES = 3,
  1374. /** Number of times GC has been invoked. Includes both major and minor GC. */
  1375. JSGC_NUMBER = 4,
  1376. /** Select GC mode. */
  1377. JSGC_MODE = 6,
  1378. /** Number of cached empty GC chunks. */
  1379. JSGC_UNUSED_CHUNKS = 7,
  1380. /** Total number of allocated GC chunks. */
  1381. JSGC_TOTAL_CHUNKS = 8,
  1382. /** Max milliseconds to spend in an incremental GC slice. */
  1383. JSGC_SLICE_TIME_BUDGET = 9,
  1384. /** Maximum size the GC mark stack can grow to. */
  1385. JSGC_MARK_STACK_LIMIT = 10,
  1386. /**
  1387. * GCs less than this far apart in time will be considered 'high-frequency GCs'.
  1388. * See setGCLastBytes in jsgc.cpp.
  1389. */
  1390. JSGC_HIGH_FREQUENCY_TIME_LIMIT = 11,
  1391. /** Start of dynamic heap growth. */
  1392. JSGC_HIGH_FREQUENCY_LOW_LIMIT = 12,
  1393. /** End of dynamic heap growth. */
  1394. JSGC_HIGH_FREQUENCY_HIGH_LIMIT = 13,
  1395. /** Upper bound of heap growth. */
  1396. JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX = 14,
  1397. /** Lower bound of heap growth. */
  1398. JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN = 15,
  1399. /** Heap growth for low frequency GCs. */
  1400. JSGC_LOW_FREQUENCY_HEAP_GROWTH = 16,
  1401. /**
  1402. * If false, the heap growth factor is fixed at 3. If true, it is determined
  1403. * based on whether GCs are high- or low- frequency.
  1404. */
  1405. JSGC_DYNAMIC_HEAP_GROWTH = 17,
  1406. /** If true, high-frequency GCs will use a longer mark slice. */
  1407. JSGC_DYNAMIC_MARK_SLICE = 18,
  1408. /** Lower limit after which we limit the heap growth. */
  1409. JSGC_ALLOCATION_THRESHOLD = 19,
  1410. /**
  1411. * We try to keep at least this many unused chunks in the free chunk pool at
  1412. * all times, even after a shrinking GC.
  1413. */
  1414. JSGC_MIN_EMPTY_CHUNK_COUNT = 21,
  1415. /** We never keep more than this many unused chunks in the free chunk pool. */
  1416. JSGC_MAX_EMPTY_CHUNK_COUNT = 22,
  1417. /** Whether compacting GC is enabled. */
  1418. JSGC_COMPACTING_ENABLED = 23,
  1419. /** If true, painting can trigger IGC slices. */
  1420. JSGC_REFRESH_FRAME_SLICES_ENABLED = 24,
  1421. } JSGCParamKey;
  1422. extern JS_PUBLIC_API(void)
  1423. JS_SetGCParameter(JSContext* cx, JSGCParamKey key, uint32_t value);
  1424. extern JS_PUBLIC_API(uint32_t)
  1425. JS_GetGCParameter(JSContext* cx, JSGCParamKey key);
  1426. extern JS_PUBLIC_API(void)
  1427. JS_SetGCParametersBasedOnAvailableMemory(JSContext* cx, uint32_t availMem);
  1428. /**
  1429. * Create a new JSString whose chars member refers to external memory, i.e.,
  1430. * memory requiring application-specific finalization.
  1431. */
  1432. extern JS_PUBLIC_API(JSString*)
  1433. JS_NewExternalString(JSContext* cx, const char16_t* chars, size_t length,
  1434. const JSStringFinalizer* fin);
  1435. /**
  1436. * Return whether 'str' was created with JS_NewExternalString or
  1437. * JS_NewExternalStringWithClosure.
  1438. */
  1439. extern JS_PUBLIC_API(bool)
  1440. JS_IsExternalString(JSString* str);
  1441. /**
  1442. * Return the 'fin' arg passed to JS_NewExternalString.
  1443. */
  1444. extern JS_PUBLIC_API(const JSStringFinalizer*)
  1445. JS_GetExternalStringFinalizer(JSString* str);
  1446. /**
  1447. * Set the size of the native stack that should not be exceed. To disable
  1448. * stack size checking pass 0.
  1449. *
  1450. * SpiderMonkey allows for a distinction between system code (such as GCs, which
  1451. * may incidentally be triggered by script but are not strictly performed on
  1452. * behalf of such script), trusted script (as determined by JS_SetTrustedPrincipals),
  1453. * and untrusted script. Each kind of code may have a different stack quota,
  1454. * allowing embedders to keep higher-priority machinery running in the face of
  1455. * scripted stack exhaustion by something else.
  1456. *
  1457. * The stack quotas for each kind of code should be monotonically descending,
  1458. * and may be specified with this function. If 0 is passed for a given kind
  1459. * of code, it defaults to the value of the next-highest-priority kind.
  1460. *
  1461. * This function may only be called immediately after the runtime is initialized
  1462. * and before any code is executed and/or interrupts requested.
  1463. */
  1464. extern JS_PUBLIC_API(void)
  1465. JS_SetNativeStackQuota(JSContext* cx, size_t systemCodeStackSize,
  1466. size_t trustedScriptStackSize = 0,
  1467. size_t untrustedScriptStackSize = 0);
  1468. /************************************************************************/
  1469. extern JS_PUBLIC_API(bool)
  1470. JS_ValueToId(JSContext* cx, JS::HandleValue v, JS::MutableHandleId idp);
  1471. extern JS_PUBLIC_API(bool)
  1472. JS_StringToId(JSContext* cx, JS::HandleString s, JS::MutableHandleId idp);
  1473. extern JS_PUBLIC_API(bool)
  1474. JS_IdToValue(JSContext* cx, jsid id, JS::MutableHandle<JS::Value> vp);
  1475. namespace JS {
  1476. /**
  1477. * Convert obj to a primitive value. On success, store the result in vp and
  1478. * return true.
  1479. *
  1480. * The hint argument must be JSTYPE_STRING, JSTYPE_NUMBER, or JSTYPE_VOID (no
  1481. * hint).
  1482. *
  1483. * Implements: ES6 7.1.1 ToPrimitive(input, [PreferredType]).
  1484. */
  1485. extern JS_PUBLIC_API(bool)
  1486. ToPrimitive(JSContext* cx, JS::HandleObject obj, JSType hint, JS::MutableHandleValue vp);
  1487. /**
  1488. * If args.get(0) is one of the strings "string", "number", or "default", set
  1489. * *result to JSTYPE_STRING, JSTYPE_NUMBER, or JSTYPE_VOID accordingly and
  1490. * return true. Otherwise, return false with a TypeError pending.
  1491. *
  1492. * This can be useful in implementing a @@toPrimitive method.
  1493. */
  1494. extern JS_PUBLIC_API(bool)
  1495. GetFirstArgumentAsTypeHint(JSContext* cx, CallArgs args, JSType *result);
  1496. } /* namespace JS */
  1497. extern JS_PUBLIC_API(bool)
  1498. JS_PropertyStub(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
  1499. JS::MutableHandleValue vp);
  1500. extern JS_PUBLIC_API(bool)
  1501. JS_StrictPropertyStub(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
  1502. JS::MutableHandleValue vp, JS::ObjectOpResult& result);
  1503. template<typename T>
  1504. struct JSConstScalarSpec {
  1505. const char* name;
  1506. T val;
  1507. };
  1508. typedef JSConstScalarSpec<double> JSConstDoubleSpec;
  1509. typedef JSConstScalarSpec<int32_t> JSConstIntegerSpec;
  1510. struct JSJitInfo;
  1511. /**
  1512. * Wrapper to relace JSNative for JSPropertySpecs and JSFunctionSpecs. This will
  1513. * allow us to pass one JSJitInfo per function with the property/function spec,
  1514. * without additional field overhead.
  1515. */
  1516. typedef struct JSNativeWrapper {
  1517. JSNative op;
  1518. const JSJitInfo* info;
  1519. } JSNativeWrapper;
  1520. /*
  1521. * Macro static initializers which make it easy to pass no JSJitInfo as part of a
  1522. * JSPropertySpec or JSFunctionSpec.
  1523. */
  1524. #define JSNATIVE_WRAPPER(native) { {native, nullptr} }
  1525. /**
  1526. * Description of a property. JS_DefineProperties and JS_InitClass take arrays
  1527. * of these and define many properties at once. JS_PSG, JS_PSGS and JS_PS_END
  1528. * are helper macros for defining such arrays.
  1529. */
  1530. struct JSPropertySpec {
  1531. struct SelfHostedWrapper {
  1532. void* unused;
  1533. const char* funname;
  1534. };
  1535. struct ValueWrapper {
  1536. uintptr_t type;
  1537. union {
  1538. const char* string;
  1539. int32_t int32;
  1540. };
  1541. };
  1542. const char* name;
  1543. uint8_t flags;
  1544. union {
  1545. struct {
  1546. union {
  1547. JSNativeWrapper native;
  1548. SelfHostedWrapper selfHosted;
  1549. } getter;
  1550. union {
  1551. JSNativeWrapper native;
  1552. SelfHostedWrapper selfHosted;
  1553. } setter;
  1554. } accessors;
  1555. ValueWrapper value;
  1556. };
  1557. bool isAccessor() const {
  1558. return !(flags & JSPROP_INTERNAL_USE_BIT);
  1559. }
  1560. bool getValue(JSContext* cx, JS::MutableHandleValue value) const;
  1561. bool isSelfHosted() const {
  1562. MOZ_ASSERT(isAccessor());
  1563. #ifdef DEBUG
  1564. // Verify that our accessors match our JSPROP_GETTER flag.
  1565. if (flags & JSPROP_GETTER)
  1566. checkAccessorsAreSelfHosted();
  1567. else
  1568. checkAccessorsAreNative();
  1569. #endif
  1570. return (flags & JSPROP_GETTER);
  1571. }
  1572. static_assert(sizeof(SelfHostedWrapper) == sizeof(JSNativeWrapper),
  1573. "JSPropertySpec::getter/setter must be compact");
  1574. static_assert(offsetof(SelfHostedWrapper, funname) == offsetof(JSNativeWrapper, info),
  1575. "JS_SELF_HOSTED* macros below require that "
  1576. "SelfHostedWrapper::funname overlay "
  1577. "JSNativeWrapper::info");
  1578. private:
  1579. void checkAccessorsAreNative() const {
  1580. MOZ_ASSERT(accessors.getter.native.op);
  1581. // We may not have a setter at all. So all we can assert here, for the
  1582. // native case is that if we have a jitinfo for the setter then we have
  1583. // a setter op too. This is good enough to make sure we don't have a
  1584. // SelfHostedWrapper for the setter.
  1585. MOZ_ASSERT_IF(accessors.setter.native.info, accessors.setter.native.op);
  1586. }
  1587. void checkAccessorsAreSelfHosted() const {
  1588. MOZ_ASSERT(!accessors.getter.selfHosted.unused);
  1589. MOZ_ASSERT(!accessors.setter.selfHosted.unused);
  1590. }
  1591. };
  1592. namespace JS {
  1593. namespace detail {
  1594. /* NEVER DEFINED, DON'T USE. For use by JS_CAST_NATIVE_TO only. */
  1595. inline int CheckIsNative(JSNative native);
  1596. /* NEVER DEFINED, DON'T USE. For use by JS_CAST_STRING_TO only. */
  1597. template<size_t N>
  1598. inline int
  1599. CheckIsCharacterLiteral(const char (&arr)[N]);
  1600. /* NEVER DEFINED, DON'T USE. For use by JS_CAST_INT32_TO only. */
  1601. inline int CheckIsInt32(int32_t value);
  1602. /* NEVER DEFINED, DON'T USE. For use by JS_PROPERTYOP_GETTER only. */
  1603. inline int CheckIsGetterOp(JSGetterOp op);
  1604. /* NEVER DEFINED, DON'T USE. For use by JS_PROPERTYOP_SETTER only. */
  1605. inline int CheckIsSetterOp(JSSetterOp op);
  1606. } // namespace detail
  1607. } // namespace JS
  1608. #define JS_CAST_NATIVE_TO(v, To) \
  1609. (static_cast<void>(sizeof(JS::detail::CheckIsNative(v))), \
  1610. reinterpret_cast<To>(v))
  1611. #define JS_CAST_STRING_TO(s, To) \
  1612. (static_cast<void>(sizeof(JS::detail::CheckIsCharacterLiteral(s))), \
  1613. reinterpret_cast<To>(s))
  1614. #define JS_CAST_INT32_TO(s, To) \
  1615. (static_cast<void>(sizeof(JS::detail::CheckIsInt32(s))), \
  1616. reinterpret_cast<To>(s))
  1617. #define JS_CHECK_ACCESSOR_FLAGS(flags) \
  1618. (static_cast<mozilla::EnableIf<((flags) & ~(JSPROP_ENUMERATE | JSPROP_PERMANENT)) == 0>::Type>(0), \
  1619. (flags))
  1620. #define JS_PROPERTYOP_GETTER(v) \
  1621. (static_cast<void>(sizeof(JS::detail::CheckIsGetterOp(v))), \
  1622. reinterpret_cast<JSNative>(v))
  1623. #define JS_PROPERTYOP_SETTER(v) \
  1624. (static_cast<void>(sizeof(JS::detail::CheckIsSetterOp(v))), \
  1625. reinterpret_cast<JSNative>(v))
  1626. #define JS_STUBGETTER JS_PROPERTYOP_GETTER(JS_PropertyStub)
  1627. #define JS_STUBSETTER JS_PROPERTYOP_SETTER(JS_StrictPropertyStub)
  1628. #define JS_PS_ACCESSOR_SPEC(name, getter, setter, flags, extraFlags) \
  1629. { name, uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | extraFlags), \
  1630. { { getter, setter } } }
  1631. #define JS_PS_VALUE_SPEC(name, value, flags) \
  1632. { name, uint8_t(flags | JSPROP_INTERNAL_USE_BIT), \
  1633. { { value, JSNATIVE_WRAPPER(nullptr) } } }
  1634. #define SELFHOSTED_WRAPPER(name) \
  1635. { { nullptr, JS_CAST_STRING_TO(name, const JSJitInfo*) } }
  1636. #define STRINGVALUE_WRAPPER(value) \
  1637. { { reinterpret_cast<JSNative>(JSVAL_TYPE_STRING), JS_CAST_STRING_TO(value, const JSJitInfo*) } }
  1638. #define INT32VALUE_WRAPPER(value) \
  1639. { { reinterpret_cast<JSNative>(JSVAL_TYPE_INT32), JS_CAST_INT32_TO(value, const JSJitInfo*) } }
  1640. /*
  1641. * JSPropertySpec uses JSNativeWrapper. These macros encapsulate the definition
  1642. * of JSNative-backed JSPropertySpecs, by defining the JSNativeWrappers for
  1643. * them.
  1644. */
  1645. #define JS_PSG(name, getter, flags) \
  1646. JS_PS_ACCESSOR_SPEC(name, JSNATIVE_WRAPPER(getter), JSNATIVE_WRAPPER(nullptr), flags, \
  1647. JSPROP_SHARED)
  1648. #define JS_PSGS(name, getter, setter, flags) \
  1649. JS_PS_ACCESSOR_SPEC(name, JSNATIVE_WRAPPER(getter), JSNATIVE_WRAPPER(setter), flags, \
  1650. JSPROP_SHARED)
  1651. #define JS_SELF_HOSTED_GET(name, getterName, flags) \
  1652. JS_PS_ACCESSOR_SPEC(name, SELFHOSTED_WRAPPER(getterName), JSNATIVE_WRAPPER(nullptr), flags, \
  1653. JSPROP_SHARED | JSPROP_GETTER)
  1654. #define JS_SELF_HOSTED_GETSET(name, getterName, setterName, flags) \
  1655. JS_PS_ACCESSOR_SPEC(name, SELFHOSTED_WRAPPER(getterName), SELFHOSTED_WRAPPER(setterName), \
  1656. flags, JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER)
  1657. #define JS_SELF_HOSTED_SYM_GET(symbol, getterName, flags) \
  1658. JS_PS_ACCESSOR_SPEC(reinterpret_cast<const char*>(uint32_t(::JS::SymbolCode::symbol) + 1), \
  1659. SELFHOSTED_WRAPPER(getterName), JSNATIVE_WRAPPER(nullptr), flags, \
  1660. JSPROP_SHARED | JSPROP_GETTER)
  1661. #define JS_STRING_PS(name, string, flags) \
  1662. JS_PS_VALUE_SPEC(name, STRINGVALUE_WRAPPER(string), flags)
  1663. #define JS_STRING_SYM_PS(symbol, string, flags) \
  1664. JS_PS_VALUE_SPEC(reinterpret_cast<const char*>(uint32_t(::JS::SymbolCode::symbol) + 1), \
  1665. STRINGVALUE_WRAPPER(string), flags)
  1666. #define JS_INT32_PS(name, value, flags) \
  1667. JS_PS_VALUE_SPEC(name, INT32VALUE_WRAPPER(value), flags)
  1668. #define JS_PS_END \
  1669. JS_PS_ACCESSOR_SPEC(nullptr, JSNATIVE_WRAPPER(nullptr), JSNATIVE_WRAPPER(nullptr), 0, 0)
  1670. /**
  1671. * To define a native function, set call to a JSNativeWrapper. To define a
  1672. * self-hosted function, set selfHostedName to the name of a function
  1673. * compiled during JSRuntime::initSelfHosting.
  1674. */
  1675. struct JSFunctionSpec {
  1676. const char* name;
  1677. JSNativeWrapper call;
  1678. uint16_t nargs;
  1679. uint16_t flags;
  1680. const char* selfHostedName;
  1681. };
  1682. /*
  1683. * Terminating sentinel initializer to put at the end of a JSFunctionSpec array
  1684. * that's passed to JS_DefineFunctions or JS_InitClass.
  1685. */
  1686. #define JS_FS_END JS_FS(nullptr,nullptr,0,0)
  1687. /*
  1688. * Initializer macros for a JSFunctionSpec array element. JS_FN (whose name pays
  1689. * homage to the old JSNative/JSFastNative split) simply adds the flag
  1690. * JSFUN_STUB_GSOPS. JS_FNINFO allows the simple adding of
  1691. * JSJitInfos. JS_SELF_HOSTED_FN declares a self-hosted function.
  1692. * JS_INLINABLE_FN allows specifying an InlinableNative enum value for natives
  1693. * inlined or specialized by the JIT. Finally JS_FNSPEC has slots for all the
  1694. * fields.
  1695. *
  1696. * The _SYM variants allow defining a function with a symbol key rather than a
  1697. * string key. For example, use JS_SYM_FN(iterator, ...) to define an
  1698. * @@iterator method.
  1699. */
  1700. #define JS_FS(name,call,nargs,flags) \
  1701. JS_FNSPEC(name, call, nullptr, nargs, flags, nullptr)
  1702. #define JS_FN(name,call,nargs,flags) \
  1703. JS_FNSPEC(name, call, nullptr, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr)
  1704. #define JS_INLINABLE_FN(name,call,nargs,flags,native) \
  1705. JS_FNSPEC(name, call, &js::jit::JitInfo_##native, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr)
  1706. #define JS_SYM_FN(symbol,call,nargs,flags) \
  1707. JS_SYM_FNSPEC(symbol, call, nullptr, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr)
  1708. #define JS_FNINFO(name,call,info,nargs,flags) \
  1709. JS_FNSPEC(name, call, info, nargs, flags, nullptr)
  1710. #define JS_SELF_HOSTED_FN(name,selfHostedName,nargs,flags) \
  1711. JS_FNSPEC(name, nullptr, nullptr, nargs, flags, selfHostedName)
  1712. #define JS_SELF_HOSTED_SYM_FN(symbol, selfHostedName, nargs, flags) \
  1713. JS_SYM_FNSPEC(symbol, nullptr, nullptr, nargs, flags, selfHostedName)
  1714. #define JS_SYM_FNSPEC(symbol, call, info, nargs, flags, selfHostedName) \
  1715. JS_FNSPEC(reinterpret_cast<const char*>( \
  1716. uint32_t(::JS::SymbolCode::symbol) + 1), \
  1717. call, info, nargs, flags, selfHostedName)
  1718. #define JS_FNSPEC(name,call,info,nargs,flags,selfHostedName) \
  1719. {name, {call, info}, nargs, flags, selfHostedName}
  1720. extern JS_PUBLIC_API(JSObject*)
  1721. JS_InitClass(JSContext* cx, JS::HandleObject obj, JS::HandleObject parent_proto,
  1722. const JSClass* clasp, JSNative constructor, unsigned nargs,
  1723. const JSPropertySpec* ps, const JSFunctionSpec* fs,
  1724. const JSPropertySpec* static_ps, const JSFunctionSpec* static_fs);
  1725. /**
  1726. * Set up ctor.prototype = proto and proto.constructor = ctor with the
  1727. * right property flags.
  1728. */
  1729. extern JS_PUBLIC_API(bool)
  1730. JS_LinkConstructorAndPrototype(JSContext* cx, JS::Handle<JSObject*> ctor,
  1731. JS::Handle<JSObject*> proto);
  1732. extern JS_PUBLIC_API(const JSClass*)
  1733. JS_GetClass(JSObject* obj);
  1734. extern JS_PUBLIC_API(bool)
  1735. JS_InstanceOf(JSContext* cx, JS::Handle<JSObject*> obj, const JSClass* clasp, JS::CallArgs* args);
  1736. extern JS_PUBLIC_API(bool)
  1737. JS_HasInstance(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<JS::Value> v, bool* bp);
  1738. namespace JS {
  1739. // Implementation of
  1740. // http://www.ecma-international.org/ecma-262/6.0/#sec-ordinaryhasinstance. If
  1741. // you're looking for the equivalent of "instanceof", you want JS_HasInstance,
  1742. // not this function.
  1743. extern JS_PUBLIC_API(bool)
  1744. OrdinaryHasInstance(JSContext* cx, HandleObject objArg, HandleValue v, bool* bp);
  1745. } // namespace JS
  1746. extern JS_PUBLIC_API(void*)
  1747. JS_GetPrivate(JSObject* obj);
  1748. extern JS_PUBLIC_API(void)
  1749. JS_SetPrivate(JSObject* obj, void* data);
  1750. extern JS_PUBLIC_API(void*)
  1751. JS_GetInstancePrivate(JSContext* cx, JS::Handle<JSObject*> obj, const JSClass* clasp,
  1752. JS::CallArgs* args);
  1753. extern JS_PUBLIC_API(JSObject*)
  1754. JS_GetConstructor(JSContext* cx, JS::Handle<JSObject*> proto);
  1755. namespace JS {
  1756. enum ZoneSpecifier {
  1757. FreshZone = 0,
  1758. SystemZone = 1
  1759. };
  1760. /**
  1761. * CompartmentCreationOptions specifies options relevant to creating a new
  1762. * compartment, that are either immutable characteristics of that compartment
  1763. * or that are discarded after the compartment has been created.
  1764. *
  1765. * Access to these options on an existing compartment is read-only: if you
  1766. * need particular selections, make them before you create the compartment.
  1767. */
  1768. class JS_PUBLIC_API(CompartmentCreationOptions)
  1769. {
  1770. public:
  1771. CompartmentCreationOptions()
  1772. : addonId_(nullptr),
  1773. traceGlobal_(nullptr),
  1774. invisibleToDebugger_(false),
  1775. mergeable_(false),
  1776. preserveJitCode_(false),
  1777. cloneSingletons_(false),
  1778. sharedMemoryAndAtomics_(false),
  1779. secureContext_(false)
  1780. {
  1781. zone_.spec = JS::FreshZone;
  1782. }
  1783. // A null add-on ID means that the compartment is not associated with an
  1784. // add-on.
  1785. JSAddonId* addonIdOrNull() const { return addonId_; }
  1786. CompartmentCreationOptions& setAddonId(JSAddonId* id) {
  1787. addonId_ = id;
  1788. return *this;
  1789. }
  1790. JSTraceOp getTrace() const {
  1791. return traceGlobal_;
  1792. }
  1793. CompartmentCreationOptions& setTrace(JSTraceOp op) {
  1794. traceGlobal_ = op;
  1795. return *this;
  1796. }
  1797. void* zonePointer() const {
  1798. MOZ_ASSERT(uintptr_t(zone_.pointer) > uintptr_t(JS::SystemZone));
  1799. return zone_.pointer;
  1800. }
  1801. ZoneSpecifier zoneSpecifier() const { return zone_.spec; }
  1802. CompartmentCreationOptions& setZone(ZoneSpecifier spec);
  1803. CompartmentCreationOptions& setSameZoneAs(JSObject* obj);
  1804. // Certain scopes (i.e. XBL compilation scopes) are implementation details
  1805. // of the embedding, and references to them should never leak out to script.
  1806. // This flag causes the this compartment to skip firing onNewGlobalObject
  1807. // and makes addDebuggee a no-op for this global.
  1808. bool invisibleToDebugger() const { return invisibleToDebugger_; }
  1809. CompartmentCreationOptions& setInvisibleToDebugger(bool flag) {
  1810. invisibleToDebugger_ = flag;
  1811. return *this;
  1812. }
  1813. // Compartments used for off-thread compilation have their contents merged
  1814. // into a target compartment when the compilation is finished. This is only
  1815. // allowed if this flag is set. The invisibleToDebugger flag must also be
  1816. // set for such compartments.
  1817. bool mergeable() const { return mergeable_; }
  1818. CompartmentCreationOptions& setMergeable(bool flag) {
  1819. mergeable_ = flag;
  1820. return *this;
  1821. }
  1822. // Determines whether this compartment should preserve JIT code on
  1823. // non-shrinking GCs.
  1824. bool preserveJitCode() const { return preserveJitCode_; }
  1825. CompartmentCreationOptions& setPreserveJitCode(bool flag) {
  1826. preserveJitCode_ = flag;
  1827. return *this;
  1828. }
  1829. bool cloneSingletons() const { return cloneSingletons_; }
  1830. CompartmentCreationOptions& setCloneSingletons(bool flag) {
  1831. cloneSingletons_ = flag;
  1832. return *this;
  1833. }
  1834. bool getSharedMemoryAndAtomicsEnabled() const;
  1835. CompartmentCreationOptions& setSharedMemoryAndAtomicsEnabled(bool flag);
  1836. // This flag doesn't affect JS engine behavior. It is used by Gecko to
  1837. // mark whether content windows and workers are "Secure Context"s. See
  1838. // https://w3c.github.io/webappsec-secure-contexts/
  1839. // https://bugzilla.mozilla.org/show_bug.cgi?id=1162772#c34
  1840. bool secureContext() const { return secureContext_; }
  1841. CompartmentCreationOptions& setSecureContext(bool flag) {
  1842. secureContext_ = flag;
  1843. return *this;
  1844. }
  1845. private:
  1846. JSAddonId* addonId_;
  1847. JSTraceOp traceGlobal_;
  1848. union {
  1849. ZoneSpecifier spec;
  1850. void* pointer; // js::Zone* is not exposed in the API.
  1851. } zone_;
  1852. bool invisibleToDebugger_;
  1853. bool mergeable_;
  1854. bool preserveJitCode_;
  1855. bool cloneSingletons_;
  1856. bool sharedMemoryAndAtomics_;
  1857. bool secureContext_;
  1858. };
  1859. /**
  1860. * CompartmentBehaviors specifies behaviors of a compartment that can be
  1861. * changed after the compartment's been created.
  1862. */
  1863. class JS_PUBLIC_API(CompartmentBehaviors)
  1864. {
  1865. public:
  1866. class Override {
  1867. public:
  1868. Override() : mode_(Default) {}
  1869. bool get(bool defaultValue) const {
  1870. if (mode_ == Default)
  1871. return defaultValue;
  1872. return mode_ == ForceTrue;
  1873. }
  1874. void set(bool overrideValue) {
  1875. mode_ = overrideValue ? ForceTrue : ForceFalse;
  1876. }
  1877. void reset() {
  1878. mode_ = Default;
  1879. }
  1880. private:
  1881. enum Mode {
  1882. Default,
  1883. ForceTrue,
  1884. ForceFalse
  1885. };
  1886. Mode mode_;
  1887. };
  1888. CompartmentBehaviors()
  1889. : version_(JSVERSION_UNKNOWN)
  1890. , discardSource_(false)
  1891. , disableLazyParsing_(false)
  1892. , singletonsAsTemplates_(true)
  1893. {
  1894. }
  1895. JSVersion version() const { return version_; }
  1896. CompartmentBehaviors& setVersion(JSVersion aVersion) {
  1897. MOZ_ASSERT(aVersion != JSVERSION_UNKNOWN);
  1898. version_ = aVersion;
  1899. return *this;
  1900. }
  1901. // For certain globals, we know enough about the code that will run in them
  1902. // that we can discard script source entirely.
  1903. bool discardSource() const { return discardSource_; }
  1904. CompartmentBehaviors& setDiscardSource(bool flag) {
  1905. discardSource_ = flag;
  1906. return *this;
  1907. }
  1908. bool disableLazyParsing() const { return disableLazyParsing_; }
  1909. CompartmentBehaviors& setDisableLazyParsing(bool flag) {
  1910. disableLazyParsing_ = flag;
  1911. return *this;
  1912. }
  1913. bool extraWarnings(JSContext* cx) const;
  1914. Override& extraWarningsOverride() { return extraWarningsOverride_; }
  1915. bool getSingletonsAsTemplates() const {
  1916. return singletonsAsTemplates_;
  1917. }
  1918. CompartmentBehaviors& setSingletonsAsValues() {
  1919. singletonsAsTemplates_ = false;
  1920. return *this;
  1921. }
  1922. private:
  1923. JSVersion version_;
  1924. bool discardSource_;
  1925. bool disableLazyParsing_;
  1926. Override extraWarningsOverride_;
  1927. // To XDR singletons, we need to ensure that all singletons are all used as
  1928. // templates, by making JSOP_OBJECT return a clone of the JSScript
  1929. // singleton, instead of returning the value which is baked in the JSScript.
  1930. bool singletonsAsTemplates_;
  1931. };
  1932. /**
  1933. * CompartmentOptions specifies compartment characteristics: both those that
  1934. * can't be changed on a compartment once it's been created
  1935. * (CompartmentCreationOptions), and those that can be changed on an existing
  1936. * compartment (CompartmentBehaviors).
  1937. */
  1938. class JS_PUBLIC_API(CompartmentOptions)
  1939. {
  1940. public:
  1941. explicit CompartmentOptions()
  1942. : creationOptions_(),
  1943. behaviors_()
  1944. {}
  1945. CompartmentOptions(const CompartmentCreationOptions& compartmentCreation,
  1946. const CompartmentBehaviors& compartmentBehaviors)
  1947. : creationOptions_(compartmentCreation),
  1948. behaviors_(compartmentBehaviors)
  1949. {}
  1950. // CompartmentCreationOptions specify fundamental compartment
  1951. // characteristics that must be specified when the compartment is created,
  1952. // that can't be changed after the compartment is created.
  1953. CompartmentCreationOptions& creationOptions() {
  1954. return creationOptions_;
  1955. }
  1956. const CompartmentCreationOptions& creationOptions() const {
  1957. return creationOptions_;
  1958. }
  1959. // CompartmentBehaviors specify compartment characteristics that can be
  1960. // changed after the compartment is created.
  1961. CompartmentBehaviors& behaviors() {
  1962. return behaviors_;
  1963. }
  1964. const CompartmentBehaviors& behaviors() const {
  1965. return behaviors_;
  1966. }
  1967. private:
  1968. CompartmentCreationOptions creationOptions_;
  1969. CompartmentBehaviors behaviors_;
  1970. };
  1971. JS_PUBLIC_API(const CompartmentCreationOptions&)
  1972. CompartmentCreationOptionsRef(JSCompartment* compartment);
  1973. JS_PUBLIC_API(const CompartmentCreationOptions&)
  1974. CompartmentCreationOptionsRef(JSObject* obj);
  1975. JS_PUBLIC_API(const CompartmentCreationOptions&)
  1976. CompartmentCreationOptionsRef(JSContext* cx);
  1977. JS_PUBLIC_API(CompartmentBehaviors&)
  1978. CompartmentBehaviorsRef(JSCompartment* compartment);
  1979. JS_PUBLIC_API(CompartmentBehaviors&)
  1980. CompartmentBehaviorsRef(JSObject* obj);
  1981. JS_PUBLIC_API(CompartmentBehaviors&)
  1982. CompartmentBehaviorsRef(JSContext* cx);
  1983. /**
  1984. * During global creation, we fire notifications to callbacks registered
  1985. * via the Debugger API. These callbacks are arbitrary script, and can touch
  1986. * the global in arbitrary ways. When that happens, the global should not be
  1987. * in a half-baked state. But this creates a problem for consumers that need
  1988. * to set slots on the global to put it in a consistent state.
  1989. *
  1990. * This API provides a way for consumers to set slots atomically (immediately
  1991. * after the global is created), before any debugger hooks are fired. It's
  1992. * unfortunately on the clunky side, but that's the way the cookie crumbles.
  1993. *
  1994. * If callers have no additional state on the global to set up, they may pass
  1995. * |FireOnNewGlobalHook| to JS_NewGlobalObject, which causes that function to
  1996. * fire the hook as its final act before returning. Otherwise, callers should
  1997. * pass |DontFireOnNewGlobalHook|, which means that they are responsible for
  1998. * invoking JS_FireOnNewGlobalObject upon successfully creating the global. If
  1999. * an error occurs and the operation aborts, callers should skip firing the
  2000. * hook. But otherwise, callers must take care to fire the hook exactly once
  2001. * before compiling any script in the global's scope (we have assertions in
  2002. * place to enforce this). This lets us be sure that debugger clients never miss
  2003. * breakpoints.
  2004. */
  2005. enum OnNewGlobalHookOption {
  2006. FireOnNewGlobalHook,
  2007. DontFireOnNewGlobalHook
  2008. };
  2009. } /* namespace JS */
  2010. extern JS_PUBLIC_API(JSObject*)
  2011. JS_NewGlobalObject(JSContext* cx, const JSClass* clasp, JSPrincipals* principals,
  2012. JS::OnNewGlobalHookOption hookOption,
  2013. const JS::CompartmentOptions& options);
  2014. /**
  2015. * Spidermonkey does not have a good way of keeping track of what compartments should be marked on
  2016. * their own. We can mark the roots unconditionally, but marking GC things only relevant in live
  2017. * compartments is hard. To mitigate this, we create a static trace hook, installed on each global
  2018. * object, from which we can be sure the compartment is relevant, and mark it.
  2019. *
  2020. * It is still possible to specify custom trace hooks for global object classes. They can be
  2021. * provided via the CompartmentOptions passed to JS_NewGlobalObject.
  2022. */
  2023. extern JS_PUBLIC_API(void)
  2024. JS_GlobalObjectTraceHook(JSTracer* trc, JSObject* global);
  2025. extern JS_PUBLIC_API(void)
  2026. JS_FireOnNewGlobalObject(JSContext* cx, JS::HandleObject global);
  2027. extern JS_PUBLIC_API(JSObject*)
  2028. JS_NewObject(JSContext* cx, const JSClass* clasp);
  2029. extern JS_PUBLIC_API(bool)
  2030. JS_IsNative(JSObject* obj);
  2031. /**
  2032. * Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a default
  2033. * proto. If proto is nullptr, the JS object will have `null` as [[Prototype]].
  2034. */
  2035. extern JS_PUBLIC_API(JSObject*)
  2036. JS_NewObjectWithGivenProto(JSContext* cx, const JSClass* clasp, JS::Handle<JSObject*> proto);
  2037. /** Creates a new plain object, like `new Object()`, with Object.prototype as [[Prototype]]. */
  2038. extern JS_PUBLIC_API(JSObject*)
  2039. JS_NewPlainObject(JSContext* cx);
  2040. /**
  2041. * Freeze obj, and all objects it refers to, recursively. This will not recurse
  2042. * through non-extensible objects, on the assumption that those are already
  2043. * deep-frozen.
  2044. */
  2045. extern JS_PUBLIC_API(bool)
  2046. JS_DeepFreezeObject(JSContext* cx, JS::Handle<JSObject*> obj);
  2047. /**
  2048. * Freezes an object; see ES5's Object.freeze(obj) method.
  2049. */
  2050. extern JS_PUBLIC_API(bool)
  2051. JS_FreezeObject(JSContext* cx, JS::Handle<JSObject*> obj);
  2052. /*** Property descriptors ************************************************************************/
  2053. namespace JS {
  2054. struct JS_PUBLIC_API(PropertyDescriptor) {
  2055. JSObject* obj;
  2056. unsigned attrs;
  2057. JSGetterOp getter;
  2058. JSSetterOp setter;
  2059. JS::Value value;
  2060. PropertyDescriptor()
  2061. : obj(nullptr), attrs(0), getter(nullptr), setter(nullptr), value(JS::UndefinedValue())
  2062. {}
  2063. static void trace(PropertyDescriptor* self, JSTracer* trc) { self->trace(trc); }
  2064. void trace(JSTracer* trc);
  2065. };
  2066. template <typename Outer>
  2067. class PropertyDescriptorOperations
  2068. {
  2069. const PropertyDescriptor& desc() const { return static_cast<const Outer*>(this)->get(); }
  2070. bool has(unsigned bit) const {
  2071. MOZ_ASSERT(bit != 0);
  2072. MOZ_ASSERT((bit & (bit - 1)) == 0); // only a single bit
  2073. return (desc().attrs & bit) != 0;
  2074. }
  2075. bool hasAny(unsigned bits) const {
  2076. return (desc().attrs & bits) != 0;
  2077. }
  2078. bool hasAll(unsigned bits) const {
  2079. return (desc().attrs & bits) == bits;
  2080. }
  2081. // Non-API attributes bit used internally for arguments objects.
  2082. enum { SHADOWABLE = JSPROP_INTERNAL_USE_BIT };
  2083. public:
  2084. // Descriptors with JSGetterOp/JSSetterOp are considered data
  2085. // descriptors. It's complicated.
  2086. bool isAccessorDescriptor() const { return hasAny(JSPROP_GETTER | JSPROP_SETTER); }
  2087. bool isGenericDescriptor() const {
  2088. return (desc().attrs&
  2089. (JSPROP_GETTER | JSPROP_SETTER | JSPROP_IGNORE_READONLY | JSPROP_IGNORE_VALUE)) ==
  2090. (JSPROP_IGNORE_READONLY | JSPROP_IGNORE_VALUE);
  2091. }
  2092. bool isDataDescriptor() const { return !isAccessorDescriptor() && !isGenericDescriptor(); }
  2093. bool hasConfigurable() const { return !has(JSPROP_IGNORE_PERMANENT); }
  2094. bool configurable() const { MOZ_ASSERT(hasConfigurable()); return !has(JSPROP_PERMANENT); }
  2095. bool hasEnumerable() const { return !has(JSPROP_IGNORE_ENUMERATE); }
  2096. bool enumerable() const { MOZ_ASSERT(hasEnumerable()); return has(JSPROP_ENUMERATE); }
  2097. bool hasValue() const { return !isAccessorDescriptor() && !has(JSPROP_IGNORE_VALUE); }
  2098. JS::HandleValue value() const {
  2099. return JS::HandleValue::fromMarkedLocation(&desc().value);
  2100. }
  2101. bool hasWritable() const { return !isAccessorDescriptor() && !has(JSPROP_IGNORE_READONLY); }
  2102. bool writable() const { MOZ_ASSERT(hasWritable()); return !has(JSPROP_READONLY); }
  2103. bool hasGetterObject() const { return has(JSPROP_GETTER); }
  2104. JS::HandleObject getterObject() const {
  2105. MOZ_ASSERT(hasGetterObject());
  2106. return JS::HandleObject::fromMarkedLocation(
  2107. reinterpret_cast<JSObject* const*>(&desc().getter));
  2108. }
  2109. bool hasSetterObject() const { return has(JSPROP_SETTER); }
  2110. JS::HandleObject setterObject() const {
  2111. MOZ_ASSERT(hasSetterObject());
  2112. return JS::HandleObject::fromMarkedLocation(
  2113. reinterpret_cast<JSObject* const*>(&desc().setter));
  2114. }
  2115. bool hasGetterOrSetter() const { return desc().getter || desc().setter; }
  2116. bool isShared() const { return has(JSPROP_SHARED); }
  2117. JS::HandleObject object() const {
  2118. return JS::HandleObject::fromMarkedLocation(&desc().obj);
  2119. }
  2120. unsigned attributes() const { return desc().attrs; }
  2121. JSGetterOp getter() const { return desc().getter; }
  2122. JSSetterOp setter() const { return desc().setter; }
  2123. void assertValid() const {
  2124. #ifdef DEBUG
  2125. MOZ_ASSERT((attributes() & ~(JSPROP_ENUMERATE | JSPROP_IGNORE_ENUMERATE |
  2126. JSPROP_PERMANENT | JSPROP_IGNORE_PERMANENT |
  2127. JSPROP_READONLY | JSPROP_IGNORE_READONLY |
  2128. JSPROP_IGNORE_VALUE |
  2129. JSPROP_GETTER |
  2130. JSPROP_SETTER |
  2131. JSPROP_SHARED |
  2132. JSPROP_REDEFINE_NONCONFIGURABLE |
  2133. JSPROP_RESOLVING |
  2134. SHADOWABLE)) == 0);
  2135. MOZ_ASSERT(!hasAll(JSPROP_IGNORE_ENUMERATE | JSPROP_ENUMERATE));
  2136. MOZ_ASSERT(!hasAll(JSPROP_IGNORE_PERMANENT | JSPROP_PERMANENT));
  2137. if (isAccessorDescriptor()) {
  2138. MOZ_ASSERT(has(JSPROP_SHARED));
  2139. MOZ_ASSERT(!has(JSPROP_READONLY));
  2140. MOZ_ASSERT(!has(JSPROP_IGNORE_READONLY));
  2141. MOZ_ASSERT(!has(JSPROP_IGNORE_VALUE));
  2142. MOZ_ASSERT(!has(SHADOWABLE));
  2143. MOZ_ASSERT(value().isUndefined());
  2144. MOZ_ASSERT_IF(!has(JSPROP_GETTER), !getter());
  2145. MOZ_ASSERT_IF(!has(JSPROP_SETTER), !setter());
  2146. } else {
  2147. MOZ_ASSERT(!hasAll(JSPROP_IGNORE_READONLY | JSPROP_READONLY));
  2148. MOZ_ASSERT_IF(has(JSPROP_IGNORE_VALUE), value().isUndefined());
  2149. }
  2150. MOZ_ASSERT(getter() != JS_PropertyStub);
  2151. MOZ_ASSERT(setter() != JS_StrictPropertyStub);
  2152. MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_ENUMERATE));
  2153. MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_PERMANENT));
  2154. MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_READONLY));
  2155. MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_VALUE));
  2156. MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_REDEFINE_NONCONFIGURABLE));
  2157. #endif
  2158. }
  2159. void assertComplete() const {
  2160. #ifdef DEBUG
  2161. assertValid();
  2162. MOZ_ASSERT((attributes() & ~(JSPROP_ENUMERATE |
  2163. JSPROP_PERMANENT |
  2164. JSPROP_READONLY |
  2165. JSPROP_GETTER |
  2166. JSPROP_SETTER |
  2167. JSPROP_SHARED |
  2168. JSPROP_REDEFINE_NONCONFIGURABLE |
  2169. JSPROP_RESOLVING |
  2170. SHADOWABLE)) == 0);
  2171. MOZ_ASSERT_IF(isAccessorDescriptor(), has(JSPROP_GETTER) && has(JSPROP_SETTER));
  2172. #endif
  2173. }
  2174. void assertCompleteIfFound() const {
  2175. #ifdef DEBUG
  2176. if (object())
  2177. assertComplete();
  2178. #endif
  2179. }
  2180. };
  2181. template <typename Outer>
  2182. class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations<Outer>
  2183. {
  2184. PropertyDescriptor& desc() { return static_cast<Outer*>(this)->get(); }
  2185. public:
  2186. void clear() {
  2187. object().set(nullptr);
  2188. setAttributes(0);
  2189. setGetter(nullptr);
  2190. setSetter(nullptr);
  2191. value().setUndefined();
  2192. }
  2193. void initFields(HandleObject obj, HandleValue v, unsigned attrs,
  2194. JSGetterOp getterOp, JSSetterOp setterOp) {
  2195. MOZ_ASSERT(getterOp != JS_PropertyStub);
  2196. MOZ_ASSERT(setterOp != JS_StrictPropertyStub);
  2197. object().set(obj);
  2198. value().set(v);
  2199. setAttributes(attrs);
  2200. setGetter(getterOp);
  2201. setSetter(setterOp);
  2202. }
  2203. void assign(PropertyDescriptor& other) {
  2204. object().set(other.obj);
  2205. setAttributes(other.attrs);
  2206. setGetter(other.getter);
  2207. setSetter(other.setter);
  2208. value().set(other.value);
  2209. }
  2210. void setDataDescriptor(HandleValue v, unsigned attrs) {
  2211. MOZ_ASSERT((attrs & ~(JSPROP_ENUMERATE |
  2212. JSPROP_PERMANENT |
  2213. JSPROP_READONLY |
  2214. JSPROP_IGNORE_ENUMERATE |
  2215. JSPROP_IGNORE_PERMANENT |
  2216. JSPROP_IGNORE_READONLY)) == 0);
  2217. object().set(nullptr);
  2218. setAttributes(attrs);
  2219. setGetter(nullptr);
  2220. setSetter(nullptr);
  2221. value().set(v);
  2222. }
  2223. JS::MutableHandleObject object() {
  2224. return JS::MutableHandleObject::fromMarkedLocation(&desc().obj);
  2225. }
  2226. unsigned& attributesRef() { return desc().attrs; }
  2227. JSGetterOp& getter() { return desc().getter; }
  2228. JSSetterOp& setter() { return desc().setter; }
  2229. JS::MutableHandleValue value() {
  2230. return JS::MutableHandleValue::fromMarkedLocation(&desc().value);
  2231. }
  2232. void setValue(JS::HandleValue v) {
  2233. MOZ_ASSERT(!(desc().attrs & (JSPROP_GETTER | JSPROP_SETTER)));
  2234. attributesRef() &= ~JSPROP_IGNORE_VALUE;
  2235. value().set(v);
  2236. }
  2237. void setConfigurable(bool configurable) {
  2238. setAttributes((desc().attrs & ~(JSPROP_IGNORE_PERMANENT | JSPROP_PERMANENT)) |
  2239. (configurable ? 0 : JSPROP_PERMANENT));
  2240. }
  2241. void setEnumerable(bool enumerable) {
  2242. setAttributes((desc().attrs & ~(JSPROP_IGNORE_ENUMERATE | JSPROP_ENUMERATE)) |
  2243. (enumerable ? JSPROP_ENUMERATE : 0));
  2244. }
  2245. void setWritable(bool writable) {
  2246. MOZ_ASSERT(!(desc().attrs & (JSPROP_GETTER | JSPROP_SETTER)));
  2247. setAttributes((desc().attrs & ~(JSPROP_IGNORE_READONLY | JSPROP_READONLY)) |
  2248. (writable ? 0 : JSPROP_READONLY));
  2249. }
  2250. void setAttributes(unsigned attrs) { desc().attrs = attrs; }
  2251. void setGetter(JSGetterOp op) {
  2252. MOZ_ASSERT(op != JS_PropertyStub);
  2253. desc().getter = op;
  2254. }
  2255. void setSetter(JSSetterOp op) {
  2256. MOZ_ASSERT(op != JS_StrictPropertyStub);
  2257. desc().setter = op;
  2258. }
  2259. void setGetterObject(JSObject* obj) {
  2260. desc().getter = reinterpret_cast<JSGetterOp>(obj);
  2261. desc().attrs &= ~(JSPROP_IGNORE_VALUE | JSPROP_IGNORE_READONLY | JSPROP_READONLY);
  2262. desc().attrs |= JSPROP_GETTER | JSPROP_SHARED;
  2263. }
  2264. void setSetterObject(JSObject* obj) {
  2265. desc().setter = reinterpret_cast<JSSetterOp>(obj);
  2266. desc().attrs &= ~(JSPROP_IGNORE_VALUE | JSPROP_IGNORE_READONLY | JSPROP_READONLY);
  2267. desc().attrs |= JSPROP_SETTER | JSPROP_SHARED;
  2268. }
  2269. JS::MutableHandleObject getterObject() {
  2270. MOZ_ASSERT(this->hasGetterObject());
  2271. return JS::MutableHandleObject::fromMarkedLocation(
  2272. reinterpret_cast<JSObject**>(&desc().getter));
  2273. }
  2274. JS::MutableHandleObject setterObject() {
  2275. MOZ_ASSERT(this->hasSetterObject());
  2276. return JS::MutableHandleObject::fromMarkedLocation(
  2277. reinterpret_cast<JSObject**>(&desc().setter));
  2278. }
  2279. };
  2280. } /* namespace JS */
  2281. namespace js {
  2282. template <>
  2283. class RootedBase<JS::PropertyDescriptor>
  2284. : public JS::MutablePropertyDescriptorOperations<JS::Rooted<JS::PropertyDescriptor>>
  2285. {};
  2286. template <>
  2287. class HandleBase<JS::PropertyDescriptor>
  2288. : public JS::PropertyDescriptorOperations<JS::Handle<JS::PropertyDescriptor>>
  2289. {};
  2290. template <>
  2291. class MutableHandleBase<JS::PropertyDescriptor>
  2292. : public JS::MutablePropertyDescriptorOperations<JS::MutableHandle<JS::PropertyDescriptor>>
  2293. {};
  2294. } /* namespace js */
  2295. namespace JS {
  2296. extern JS_PUBLIC_API(bool)
  2297. ObjectToCompletePropertyDescriptor(JSContext* cx,
  2298. JS::HandleObject obj,
  2299. JS::HandleValue descriptor,
  2300. JS::MutableHandle<PropertyDescriptor> desc);
  2301. /*
  2302. * ES6 draft rev 32 (2015 Feb 2) 6.2.4.4 FromPropertyDescriptor(Desc).
  2303. *
  2304. * If desc.object() is null, then vp is set to undefined.
  2305. */
  2306. extern JS_PUBLIC_API(bool)
  2307. FromPropertyDescriptor(JSContext* cx,
  2308. JS::Handle<JS::PropertyDescriptor> desc,
  2309. JS::MutableHandleValue vp);
  2310. } // namespace JS
  2311. /*** Standard internal methods ********************************************************************
  2312. *
  2313. * The functions below are the fundamental operations on objects.
  2314. *
  2315. * ES6 specifies 14 internal methods that define how objects behave. The
  2316. * standard is actually quite good on this topic, though you may have to read
  2317. * it a few times. See ES6 sections 6.1.7.2 and 6.1.7.3.
  2318. *
  2319. * When 'obj' is an ordinary object, these functions have boring standard
  2320. * behavior as specified by ES6 section 9.1; see the section about internal
  2321. * methods in js/src/vm/NativeObject.h.
  2322. *
  2323. * Proxies override the behavior of internal methods. So when 'obj' is a proxy,
  2324. * any one of the functions below could do just about anything. See
  2325. * js/public/Proxy.h.
  2326. */
  2327. /**
  2328. * Get the prototype of obj, storing it in result.
  2329. *
  2330. * Implements: ES6 [[GetPrototypeOf]] internal method.
  2331. */
  2332. extern JS_PUBLIC_API(bool)
  2333. JS_GetPrototype(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject result);
  2334. /**
  2335. * If |obj| (underneath any functionally-transparent wrapper proxies) has as
  2336. * its [[GetPrototypeOf]] trap the ordinary [[GetPrototypeOf]] behavior defined
  2337. * for ordinary objects, set |*isOrdinary = true| and store |obj|'s prototype
  2338. * in |result|. Otherwise set |*isOrdinary = false|. In case of error, both
  2339. * outparams have unspecified value.
  2340. */
  2341. extern JS_PUBLIC_API(bool)
  2342. JS_GetPrototypeIfOrdinary(JSContext* cx, JS::HandleObject obj, bool* isOrdinary,
  2343. JS::MutableHandleObject result);
  2344. /**
  2345. * Change the prototype of obj.
  2346. *
  2347. * Implements: ES6 [[SetPrototypeOf]] internal method.
  2348. *
  2349. * In cases where ES6 [[SetPrototypeOf]] returns false without an exception,
  2350. * JS_SetPrototype throws a TypeError and returns false.
  2351. *
  2352. * Performance warning: JS_SetPrototype is very bad for performance. It may
  2353. * cause compiled jit-code to be invalidated. It also causes not only obj but
  2354. * all other objects in the same "group" as obj to be permanently deoptimized.
  2355. * It's better to create the object with the right prototype from the start.
  2356. */
  2357. extern JS_PUBLIC_API(bool)
  2358. JS_SetPrototype(JSContext* cx, JS::HandleObject obj, JS::HandleObject proto);
  2359. /**
  2360. * Determine whether obj is extensible. Extensible objects can have new
  2361. * properties defined on them. Inextensible objects can't, and their
  2362. * [[Prototype]] slot is fixed as well.
  2363. *
  2364. * Implements: ES6 [[IsExtensible]] internal method.
  2365. */
  2366. extern JS_PUBLIC_API(bool)
  2367. JS_IsExtensible(JSContext* cx, JS::HandleObject obj, bool* extensible);
  2368. /**
  2369. * Attempt to make |obj| non-extensible.
  2370. *
  2371. * Not all failures are treated as errors. See the comment on
  2372. * JS::ObjectOpResult in js/public/Class.h.
  2373. *
  2374. * Implements: ES6 [[PreventExtensions]] internal method.
  2375. */
  2376. extern JS_PUBLIC_API(bool)
  2377. JS_PreventExtensions(JSContext* cx, JS::HandleObject obj, JS::ObjectOpResult& result);
  2378. /**
  2379. * Attempt to make the [[Prototype]] of |obj| immutable, such that any attempt
  2380. * to modify it will fail. If an error occurs during the attempt, return false
  2381. * (with a pending exception set, depending upon the nature of the error). If
  2382. * no error occurs, return true with |*succeeded| set to indicate whether the
  2383. * attempt successfully made the [[Prototype]] immutable.
  2384. *
  2385. * This is a nonstandard internal method.
  2386. */
  2387. extern JS_PUBLIC_API(bool)
  2388. JS_SetImmutablePrototype(JSContext* cx, JS::HandleObject obj, bool* succeeded);
  2389. /**
  2390. * Get a description of one of obj's own properties. If no such property exists
  2391. * on obj, return true with desc.object() set to null.
  2392. *
  2393. * Implements: ES6 [[GetOwnProperty]] internal method.
  2394. */
  2395. extern JS_PUBLIC_API(bool)
  2396. JS_GetOwnPropertyDescriptorById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
  2397. JS::MutableHandle<JS::PropertyDescriptor> desc);
  2398. extern JS_PUBLIC_API(bool)
  2399. JS_GetOwnPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char* name,
  2400. JS::MutableHandle<JS::PropertyDescriptor> desc);
  2401. extern JS_PUBLIC_API(bool)
  2402. JS_GetOwnUCPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char16_t* name,
  2403. JS::MutableHandle<JS::PropertyDescriptor> desc);
  2404. /**
  2405. * Like JS_GetOwnPropertyDescriptorById, but also searches the prototype chain
  2406. * if no own property is found directly on obj. The object on which the
  2407. * property is found is returned in desc.object(). If the property is not found
  2408. * on the prototype chain, this returns true with desc.object() set to null.
  2409. */
  2410. extern JS_PUBLIC_API(bool)
  2411. JS_GetPropertyDescriptorById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
  2412. JS::MutableHandle<JS::PropertyDescriptor> desc);
  2413. extern JS_PUBLIC_API(bool)
  2414. JS_GetPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char* name,
  2415. JS::MutableHandle<JS::PropertyDescriptor> desc);
  2416. /**
  2417. * Define a property on obj.
  2418. *
  2419. * This function uses JS::ObjectOpResult to indicate conditions that ES6
  2420. * specifies as non-error failures. This is inconvenient at best, so use this
  2421. * function only if you are implementing a proxy handler's defineProperty()
  2422. * method. For all other purposes, use one of the many DefineProperty functions
  2423. * below that throw an exception in all failure cases.
  2424. *
  2425. * Implements: ES6 [[DefineOwnProperty]] internal method.
  2426. */
  2427. extern JS_PUBLIC_API(bool)
  2428. JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
  2429. JS::Handle<JS::PropertyDescriptor> desc,
  2430. JS::ObjectOpResult& result);
  2431. /**
  2432. * Define a property on obj, throwing a TypeError if the attempt fails.
  2433. * This is the C++ equivalent of `Object.defineProperty(obj, id, desc)`.
  2434. */
  2435. extern JS_PUBLIC_API(bool)
  2436. JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
  2437. JS::Handle<JS::PropertyDescriptor> desc);
  2438. extern JS_PUBLIC_API(bool)
  2439. JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value,
  2440. unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
  2441. extern JS_PUBLIC_API(bool)
  2442. JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject value,
  2443. unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
  2444. extern JS_PUBLIC_API(bool)
  2445. JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleString value,
  2446. unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
  2447. extern JS_PUBLIC_API(bool)
  2448. JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, int32_t value,
  2449. unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
  2450. extern JS_PUBLIC_API(bool)
  2451. JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, uint32_t value,
  2452. unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
  2453. extern JS_PUBLIC_API(bool)
  2454. JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, double value,
  2455. unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
  2456. extern JS_PUBLIC_API(bool)
  2457. JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleValue value,
  2458. unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
  2459. extern JS_PUBLIC_API(bool)
  2460. JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleObject value,
  2461. unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
  2462. extern JS_PUBLIC_API(bool)
  2463. JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleString value,
  2464. unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
  2465. extern JS_PUBLIC_API(bool)
  2466. JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, int32_t value,
  2467. unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
  2468. extern JS_PUBLIC_API(bool)
  2469. JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, uint32_t value,
  2470. unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
  2471. extern JS_PUBLIC_API(bool)
  2472. JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, double value,
  2473. unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
  2474. extern JS_PUBLIC_API(bool)
  2475. JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
  2476. JS::Handle<JS::PropertyDescriptor> desc,
  2477. JS::ObjectOpResult& result);
  2478. extern JS_PUBLIC_API(bool)
  2479. JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
  2480. JS::Handle<JS::PropertyDescriptor> desc);
  2481. extern JS_PUBLIC_API(bool)
  2482. JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
  2483. JS::HandleValue value, unsigned attrs,
  2484. JSNative getter = nullptr, JSNative setter = nullptr);
  2485. extern JS_PUBLIC_API(bool)
  2486. JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
  2487. JS::HandleObject value, unsigned attrs,
  2488. JSNative getter = nullptr, JSNative setter = nullptr);
  2489. extern JS_PUBLIC_API(bool)
  2490. JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
  2491. JS::HandleString value, unsigned attrs,
  2492. JSNative getter = nullptr, JSNative setter = nullptr);
  2493. extern JS_PUBLIC_API(bool)
  2494. JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
  2495. int32_t value, unsigned attrs,
  2496. JSNative getter = nullptr, JSNative setter = nullptr);
  2497. extern JS_PUBLIC_API(bool)
  2498. JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
  2499. uint32_t value, unsigned attrs,
  2500. JSNative getter = nullptr, JSNative setter = nullptr);
  2501. extern JS_PUBLIC_API(bool)
  2502. JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
  2503. double value, unsigned attrs,
  2504. JSNative getter = nullptr, JSNative setter = nullptr);
  2505. extern JS_PUBLIC_API(bool)
  2506. JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleValue value,
  2507. unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
  2508. extern JS_PUBLIC_API(bool)
  2509. JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleObject value,
  2510. unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
  2511. extern JS_PUBLIC_API(bool)
  2512. JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleString value,
  2513. unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
  2514. extern JS_PUBLIC_API(bool)
  2515. JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, int32_t value,
  2516. unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
  2517. extern JS_PUBLIC_API(bool)
  2518. JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, uint32_t value,
  2519. unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
  2520. extern JS_PUBLIC_API(bool)
  2521. JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, double value,
  2522. unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
  2523. /**
  2524. * Compute the expression `id in obj`.
  2525. *
  2526. * If obj has an own or inherited property obj[id], set *foundp = true and
  2527. * return true. If not, set *foundp = false and return true. On error, return
  2528. * false with an exception pending.
  2529. *
  2530. * Implements: ES6 [[Has]] internal method.
  2531. */
  2532. extern JS_PUBLIC_API(bool)
  2533. JS_HasPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp);
  2534. extern JS_PUBLIC_API(bool)
  2535. JS_HasProperty(JSContext* cx, JS::HandleObject obj, const char* name, bool* foundp);
  2536. extern JS_PUBLIC_API(bool)
  2537. JS_HasUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
  2538. bool* vp);
  2539. extern JS_PUBLIC_API(bool)
  2540. JS_HasElement(JSContext* cx, JS::HandleObject obj, uint32_t index, bool* foundp);
  2541. /**
  2542. * Determine whether obj has an own property with the key `id`.
  2543. *
  2544. * Implements: ES6 7.3.11 HasOwnProperty(O, P).
  2545. */
  2546. extern JS_PUBLIC_API(bool)
  2547. JS_HasOwnPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp);
  2548. extern JS_PUBLIC_API(bool)
  2549. JS_HasOwnProperty(JSContext* cx, JS::HandleObject obj, const char* name, bool* foundp);
  2550. /**
  2551. * Get the value of the property `obj[id]`, or undefined if no such property
  2552. * exists. This is the C++ equivalent of `vp = Reflect.get(obj, id, receiver)`.
  2553. *
  2554. * Most callers don't need the `receiver` argument. Consider using
  2555. * JS_GetProperty instead. (But if you're implementing a proxy handler's set()
  2556. * method, it's often correct to call this function and pass the receiver
  2557. * through.)
  2558. *
  2559. * Implements: ES6 [[Get]] internal method.
  2560. */
  2561. extern JS_PUBLIC_API(bool)
  2562. JS_ForwardGetPropertyTo(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
  2563. JS::HandleValue receiver, JS::MutableHandleValue vp);
  2564. extern JS_PUBLIC_API(bool)
  2565. JS_ForwardGetElementTo(JSContext* cx, JS::HandleObject obj, uint32_t index,
  2566. JS::HandleObject receiver, JS::MutableHandleValue vp);
  2567. /**
  2568. * Get the value of the property `obj[id]`, or undefined if no such property
  2569. * exists. The result is stored in vp.
  2570. *
  2571. * Implements: ES6 7.3.1 Get(O, P).
  2572. */
  2573. extern JS_PUBLIC_API(bool)
  2574. JS_GetPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
  2575. JS::MutableHandleValue vp);
  2576. extern JS_PUBLIC_API(bool)
  2577. JS_GetProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::MutableHandleValue vp);
  2578. extern JS_PUBLIC_API(bool)
  2579. JS_GetUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
  2580. JS::MutableHandleValue vp);
  2581. extern JS_PUBLIC_API(bool)
  2582. JS_GetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp);
  2583. /**
  2584. * Perform the same property assignment as `Reflect.set(obj, id, v, receiver)`.
  2585. *
  2586. * This function has a `receiver` argument that most callers don't need.
  2587. * Consider using JS_SetProperty instead.
  2588. *
  2589. * Implements: ES6 [[Set]] internal method.
  2590. */
  2591. extern JS_PUBLIC_API(bool)
  2592. JS_ForwardSetPropertyTo(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v,
  2593. JS::HandleValue receiver, JS::ObjectOpResult& result);
  2594. /**
  2595. * Perform the assignment `obj[id] = v`.
  2596. *
  2597. * This function performs non-strict assignment, so if the property is
  2598. * read-only, nothing happens and no error is thrown.
  2599. */
  2600. extern JS_PUBLIC_API(bool)
  2601. JS_SetPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v);
  2602. extern JS_PUBLIC_API(bool)
  2603. JS_SetProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleValue v);
  2604. extern JS_PUBLIC_API(bool)
  2605. JS_SetUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
  2606. JS::HandleValue v);
  2607. extern JS_PUBLIC_API(bool)
  2608. JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleValue v);
  2609. extern JS_PUBLIC_API(bool)
  2610. JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleObject v);
  2611. extern JS_PUBLIC_API(bool)
  2612. JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleString v);
  2613. extern JS_PUBLIC_API(bool)
  2614. JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, int32_t v);
  2615. extern JS_PUBLIC_API(bool)
  2616. JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, uint32_t v);
  2617. extern JS_PUBLIC_API(bool)
  2618. JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, double v);
  2619. /**
  2620. * Delete a property. This is the C++ equivalent of
  2621. * `result = Reflect.deleteProperty(obj, id)`.
  2622. *
  2623. * This function has a `result` out parameter that most callers don't need.
  2624. * Unless you can pass through an ObjectOpResult provided by your caller, it's
  2625. * probably best to use the JS_DeletePropertyById signature with just 3
  2626. * arguments.
  2627. *
  2628. * Implements: ES6 [[Delete]] internal method.
  2629. */
  2630. extern JS_PUBLIC_API(bool)
  2631. JS_DeletePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
  2632. JS::ObjectOpResult& result);
  2633. extern JS_PUBLIC_API(bool)
  2634. JS_DeleteProperty(JSContext* cx, JS::HandleObject obj, const char* name,
  2635. JS::ObjectOpResult& result);
  2636. extern JS_PUBLIC_API(bool)
  2637. JS_DeleteUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
  2638. JS::ObjectOpResult& result);
  2639. extern JS_PUBLIC_API(bool)
  2640. JS_DeleteElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::ObjectOpResult& result);
  2641. /**
  2642. * Delete a property, ignoring strict failures. This is the C++ equivalent of
  2643. * the JS `delete obj[id]` in non-strict mode code.
  2644. */
  2645. extern JS_PUBLIC_API(bool)
  2646. JS_DeletePropertyById(JSContext* cx, JS::HandleObject obj, jsid id);
  2647. extern JS_PUBLIC_API(bool)
  2648. JS_DeleteProperty(JSContext* cx, JS::HandleObject obj, const char* name);
  2649. extern JS_PUBLIC_API(bool)
  2650. JS_DeleteElement(JSContext* cx, JS::HandleObject obj, uint32_t index);
  2651. /**
  2652. * Get an array of the non-symbol enumerable properties of obj.
  2653. * This function is roughly equivalent to:
  2654. *
  2655. * var result = [];
  2656. * for (key in obj)
  2657. * result.push(key);
  2658. * return result;
  2659. *
  2660. * This is the closest thing we currently have to the ES6 [[Enumerate]]
  2661. * internal method.
  2662. *
  2663. * The array of ids returned by JS_Enumerate must be rooted to protect its
  2664. * contents from garbage collection. Use JS::Rooted<JS::IdVector>.
  2665. */
  2666. extern JS_PUBLIC_API(bool)
  2667. JS_Enumerate(JSContext* cx, JS::HandleObject obj, JS::MutableHandle<JS::IdVector> props);
  2668. /*
  2669. * API for determining callability and constructability. [[Call]] and
  2670. * [[Construct]] are internal methods that aren't present on all objects, so it
  2671. * is useful to ask if they are there or not. The standard itself asks these
  2672. * questions routinely.
  2673. */
  2674. namespace JS {
  2675. /**
  2676. * Return true if the given object is callable. In ES6 terms, an object is
  2677. * callable if it has a [[Call]] internal method.
  2678. *
  2679. * Implements: ES6 7.2.3 IsCallable(argument).
  2680. *
  2681. * Functions are callable. A scripted proxy or wrapper is callable if its
  2682. * target is callable. Most other objects aren't callable.
  2683. */
  2684. extern JS_PUBLIC_API(bool)
  2685. IsCallable(JSObject* obj);
  2686. /**
  2687. * Return true if the given object is a constructor. In ES6 terms, an object is
  2688. * a constructor if it has a [[Construct]] internal method. The expression
  2689. * `new obj()` throws a TypeError if obj is not a constructor.
  2690. *
  2691. * Implements: ES6 7.2.4 IsConstructor(argument).
  2692. *
  2693. * JS functions and classes are constructors. Arrow functions and most builtin
  2694. * functions are not. A scripted proxy or wrapper is a constructor if its
  2695. * target is a constructor.
  2696. */
  2697. extern JS_PUBLIC_API(bool)
  2698. IsConstructor(JSObject* obj);
  2699. } /* namespace JS */
  2700. /**
  2701. * Call a function, passing a this-value and arguments. This is the C++
  2702. * equivalent of `rval = Reflect.apply(fun, obj, args)`.
  2703. *
  2704. * Implements: ES6 7.3.12 Call(F, V, [argumentsList]).
  2705. * Use this function to invoke the [[Call]] internal method.
  2706. */
  2707. extern JS_PUBLIC_API(bool)
  2708. JS_CallFunctionValue(JSContext* cx, JS::HandleObject obj, JS::HandleValue fval,
  2709. const JS::HandleValueArray& args, JS::MutableHandleValue rval);
  2710. extern JS_PUBLIC_API(bool)
  2711. JS_CallFunction(JSContext* cx, JS::HandleObject obj, JS::HandleFunction fun,
  2712. const JS::HandleValueArray& args, JS::MutableHandleValue rval);
  2713. /**
  2714. * Perform the method call `rval = obj[name](args)`.
  2715. */
  2716. extern JS_PUBLIC_API(bool)
  2717. JS_CallFunctionName(JSContext* cx, JS::HandleObject obj, const char* name,
  2718. const JS::HandleValueArray& args, JS::MutableHandleValue rval);
  2719. namespace JS {
  2720. static inline bool
  2721. Call(JSContext* cx, JS::HandleObject thisObj, JS::HandleFunction fun,
  2722. const JS::HandleValueArray& args, MutableHandleValue rval)
  2723. {
  2724. return !!JS_CallFunction(cx, thisObj, fun, args, rval);
  2725. }
  2726. static inline bool
  2727. Call(JSContext* cx, JS::HandleObject thisObj, JS::HandleValue fun, const JS::HandleValueArray& args,
  2728. MutableHandleValue rval)
  2729. {
  2730. return !!JS_CallFunctionValue(cx, thisObj, fun, args, rval);
  2731. }
  2732. static inline bool
  2733. Call(JSContext* cx, JS::HandleObject thisObj, const char* name, const JS::HandleValueArray& args,
  2734. MutableHandleValue rval)
  2735. {
  2736. return !!JS_CallFunctionName(cx, thisObj, name, args, rval);
  2737. }
  2738. extern JS_PUBLIC_API(bool)
  2739. Call(JSContext* cx, JS::HandleValue thisv, JS::HandleValue fun, const JS::HandleValueArray& args,
  2740. MutableHandleValue rval);
  2741. static inline bool
  2742. Call(JSContext* cx, JS::HandleValue thisv, JS::HandleObject funObj, const JS::HandleValueArray& args,
  2743. MutableHandleValue rval)
  2744. {
  2745. MOZ_ASSERT(funObj);
  2746. JS::RootedValue fun(cx, JS::ObjectValue(*funObj));
  2747. return Call(cx, thisv, fun, args, rval);
  2748. }
  2749. /**
  2750. * Invoke a constructor. This is the C++ equivalent of
  2751. * `rval = Reflect.construct(fun, args, newTarget)`.
  2752. *
  2753. * JS::Construct() takes a `newTarget` argument that most callers don't need.
  2754. * Consider using the four-argument Construct signature instead. (But if you're
  2755. * implementing a subclass or a proxy handler's construct() method, this is the
  2756. * right function to call.)
  2757. *
  2758. * Implements: ES6 7.3.13 Construct(F, [argumentsList], [newTarget]).
  2759. * Use this function to invoke the [[Construct]] internal method.
  2760. */
  2761. extern JS_PUBLIC_API(bool)
  2762. Construct(JSContext* cx, JS::HandleValue fun, HandleObject newTarget,
  2763. const JS::HandleValueArray &args, MutableHandleObject objp);
  2764. /**
  2765. * Invoke a constructor. This is the C++ equivalent of
  2766. * `rval = new fun(...args)`.
  2767. *
  2768. * Implements: ES6 7.3.13 Construct(F, [argumentsList], [newTarget]), when
  2769. * newTarget is omitted.
  2770. */
  2771. extern JS_PUBLIC_API(bool)
  2772. Construct(JSContext* cx, JS::HandleValue fun, const JS::HandleValueArray& args,
  2773. MutableHandleObject objp);
  2774. } /* namespace JS */
  2775. /**
  2776. * Invoke a constructor, like the JS expression `new ctor(...args)`. Returns
  2777. * the new object, or null on error.
  2778. */
  2779. extern JS_PUBLIC_API(JSObject*)
  2780. JS_New(JSContext* cx, JS::HandleObject ctor, const JS::HandleValueArray& args);
  2781. /*** Other property-defining functions ***********************************************************/
  2782. extern JS_PUBLIC_API(JSObject*)
  2783. JS_DefineObject(JSContext* cx, JS::HandleObject obj, const char* name,
  2784. const JSClass* clasp = nullptr, unsigned attrs = 0);
  2785. extern JS_PUBLIC_API(bool)
  2786. JS_DefineConstDoubles(JSContext* cx, JS::HandleObject obj, const JSConstDoubleSpec* cds);
  2787. extern JS_PUBLIC_API(bool)
  2788. JS_DefineConstIntegers(JSContext* cx, JS::HandleObject obj, const JSConstIntegerSpec* cis);
  2789. extern JS_PUBLIC_API(bool)
  2790. JS_DefineProperties(JSContext* cx, JS::HandleObject obj, const JSPropertySpec* ps);
  2791. /* * */
  2792. extern JS_PUBLIC_API(bool)
  2793. JS_AlreadyHasOwnPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
  2794. bool* foundp);
  2795. extern JS_PUBLIC_API(bool)
  2796. JS_AlreadyHasOwnProperty(JSContext* cx, JS::HandleObject obj, const char* name,
  2797. bool* foundp);
  2798. extern JS_PUBLIC_API(bool)
  2799. JS_AlreadyHasOwnUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name,
  2800. size_t namelen, bool* foundp);
  2801. extern JS_PUBLIC_API(bool)
  2802. JS_AlreadyHasOwnElement(JSContext* cx, JS::HandleObject obj, uint32_t index, bool* foundp);
  2803. extern JS_PUBLIC_API(JSObject*)
  2804. JS_NewArrayObject(JSContext* cx, const JS::HandleValueArray& contents);
  2805. extern JS_PUBLIC_API(JSObject*)
  2806. JS_NewArrayObject(JSContext* cx, size_t length);
  2807. /**
  2808. * Returns true and sets |*isArray| indicating whether |value| is an Array
  2809. * object or a wrapper around one, otherwise returns false on failure.
  2810. *
  2811. * This method returns true with |*isArray == false| when passed a proxy whose
  2812. * target is an Array, or when passed a revoked proxy.
  2813. */
  2814. extern JS_PUBLIC_API(bool)
  2815. JS_IsArrayObject(JSContext* cx, JS::HandleValue value, bool* isArray);
  2816. /**
  2817. * Returns true and sets |*isArray| indicating whether |obj| is an Array object
  2818. * or a wrapper around one, otherwise returns false on failure.
  2819. *
  2820. * This method returns true with |*isArray == false| when passed a proxy whose
  2821. * target is an Array, or when passed a revoked proxy.
  2822. */
  2823. extern JS_PUBLIC_API(bool)
  2824. JS_IsArrayObject(JSContext* cx, JS::HandleObject obj, bool* isArray);
  2825. extern JS_PUBLIC_API(bool)
  2826. JS_GetArrayLength(JSContext* cx, JS::Handle<JSObject*> obj, uint32_t* lengthp);
  2827. extern JS_PUBLIC_API(bool)
  2828. JS_SetArrayLength(JSContext* cx, JS::Handle<JSObject*> obj, uint32_t length);
  2829. namespace JS {
  2830. /**
  2831. * Returns true and sets |*isMap| indicating whether |obj| is an Map object
  2832. * or a wrapper around one, otherwise returns false on failure.
  2833. *
  2834. * This method returns true with |*isMap == false| when passed a proxy whose
  2835. * target is an Map, or when passed a revoked proxy.
  2836. */
  2837. extern JS_PUBLIC_API(bool)
  2838. IsMapObject(JSContext* cx, JS::HandleObject obj, bool* isMap);
  2839. /**
  2840. * Returns true and sets |*isSet| indicating whether |obj| is an Set object
  2841. * or a wrapper around one, otherwise returns false on failure.
  2842. *
  2843. * This method returns true with |*isSet == false| when passed a proxy whose
  2844. * target is an Set, or when passed a revoked proxy.
  2845. */
  2846. extern JS_PUBLIC_API(bool)
  2847. IsSetObject(JSContext* cx, JS::HandleObject obj, bool* isSet);
  2848. } /* namespace JS */
  2849. /**
  2850. * Assign 'undefined' to all of the object's non-reserved slots. Note: this is
  2851. * done for all slots, regardless of the associated property descriptor.
  2852. */
  2853. JS_PUBLIC_API(void)
  2854. JS_SetAllNonReservedSlotsToUndefined(JSContext* cx, JSObject* objArg);
  2855. /**
  2856. * Create a new array buffer with the given contents. It must be legal to pass
  2857. * these contents to free(). On success, the ownership is transferred to the
  2858. * new array buffer.
  2859. */
  2860. extern JS_PUBLIC_API(JSObject*)
  2861. JS_NewArrayBufferWithContents(JSContext* cx, size_t nbytes, void* contents);
  2862. /**
  2863. * Create a new array buffer with the given contents. The array buffer does not take ownership of
  2864. * contents, and JS_DetachArrayBuffer must be called before the contents are disposed of.
  2865. */
  2866. extern JS_PUBLIC_API(JSObject*)
  2867. JS_NewArrayBufferWithExternalContents(JSContext* cx, size_t nbytes, void* contents);
  2868. /**
  2869. * Steal the contents of the given array buffer. The array buffer has its
  2870. * length set to 0 and its contents array cleared. The caller takes ownership
  2871. * of the return value and must free it or transfer ownership via
  2872. * JS_NewArrayBufferWithContents when done using it.
  2873. */
  2874. extern JS_PUBLIC_API(void*)
  2875. JS_StealArrayBufferContents(JSContext* cx, JS::HandleObject obj);
  2876. /**
  2877. * Returns a pointer to the ArrayBuffer |obj|'s data. |obj| and its views will store and expose
  2878. * the data in the returned pointer: assigning into the returned pointer will affect values exposed
  2879. * by views of |obj| and vice versa.
  2880. *
  2881. * The caller must ultimately deallocate the returned pointer to avoid leaking. The memory is
  2882. * *not* garbage-collected with |obj|. These steps must be followed to deallocate:
  2883. *
  2884. * 1. The ArrayBuffer |obj| must be detached using JS_DetachArrayBuffer.
  2885. * 2. The returned pointer must be freed using JS_free.
  2886. *
  2887. * To perform step 1, callers *must* hold a reference to |obj| until they finish using the returned
  2888. * pointer. They *must not* attempt to let |obj| be GC'd, then JS_free the pointer.
  2889. *
  2890. * If |obj| isn't an ArrayBuffer, this function returns null and reports an error.
  2891. */
  2892. extern JS_PUBLIC_API(void*)
  2893. JS_ExternalizeArrayBufferContents(JSContext* cx, JS::HandleObject obj);
  2894. /**
  2895. * Create a new mapped array buffer with the given memory mapped contents. It
  2896. * must be legal to free the contents pointer by unmapping it. On success,
  2897. * ownership is transferred to the new mapped array buffer.
  2898. */
  2899. extern JS_PUBLIC_API(JSObject*)
  2900. JS_NewMappedArrayBufferWithContents(JSContext* cx, size_t nbytes, void* contents);
  2901. /**
  2902. * Create memory mapped array buffer contents.
  2903. * Caller must take care of closing fd after calling this function.
  2904. */
  2905. extern JS_PUBLIC_API(void*)
  2906. JS_CreateMappedArrayBufferContents(int fd, size_t offset, size_t length);
  2907. /**
  2908. * Release the allocated resource of mapped array buffer contents before the
  2909. * object is created.
  2910. * If a new object has been created by JS_NewMappedArrayBufferWithContents()
  2911. * with this content, then JS_DetachArrayBuffer() should be used instead to
  2912. * release the resource used by the object.
  2913. */
  2914. extern JS_PUBLIC_API(void)
  2915. JS_ReleaseMappedArrayBufferContents(void* contents, size_t length);
  2916. extern JS_PUBLIC_API(JS::Value)
  2917. JS_GetReservedSlot(JSObject* obj, uint32_t index);
  2918. extern JS_PUBLIC_API(void)
  2919. JS_SetReservedSlot(JSObject* obj, uint32_t index, const JS::Value& v);
  2920. /************************************************************************/
  2921. /*
  2922. * Functions and scripts.
  2923. */
  2924. extern JS_PUBLIC_API(JSFunction*)
  2925. JS_NewFunction(JSContext* cx, JSNative call, unsigned nargs, unsigned flags,
  2926. const char* name);
  2927. namespace JS {
  2928. extern JS_PUBLIC_API(JSFunction*)
  2929. GetSelfHostedFunction(JSContext* cx, const char* selfHostedName, HandleId id,
  2930. unsigned nargs);
  2931. /**
  2932. * Create a new function based on the given JSFunctionSpec, *fs.
  2933. * id is the result of a successful call to
  2934. * `PropertySpecNameToPermanentId(cx, fs->name, &id)`.
  2935. *
  2936. * Unlike JS_DefineFunctions, this does not treat fs as an array.
  2937. * *fs must not be JS_FS_END.
  2938. */
  2939. extern JS_PUBLIC_API(JSFunction*)
  2940. NewFunctionFromSpec(JSContext* cx, const JSFunctionSpec* fs, HandleId id);
  2941. } /* namespace JS */
  2942. extern JS_PUBLIC_API(JSObject*)
  2943. JS_GetFunctionObject(JSFunction* fun);
  2944. /**
  2945. * Return the function's identifier as a JSString, or null if fun is unnamed.
  2946. * The returned string lives as long as fun, so you don't need to root a saved
  2947. * reference to it if fun is well-connected or rooted, and provided you bound
  2948. * the use of the saved reference by fun's lifetime.
  2949. */
  2950. extern JS_PUBLIC_API(JSString*)
  2951. JS_GetFunctionId(JSFunction* fun);
  2952. /**
  2953. * Return a function's display name. This is the defined name if one was given
  2954. * where the function was defined, or it could be an inferred name by the JS
  2955. * engine in the case that the function was defined to be anonymous. This can
  2956. * still return nullptr if a useful display name could not be inferred. The
  2957. * same restrictions on rooting as those in JS_GetFunctionId apply.
  2958. */
  2959. extern JS_PUBLIC_API(JSString*)
  2960. JS_GetFunctionDisplayId(JSFunction* fun);
  2961. /*
  2962. * Return the arity (length) of fun.
  2963. */
  2964. extern JS_PUBLIC_API(uint16_t)
  2965. JS_GetFunctionArity(JSFunction* fun);
  2966. /**
  2967. * Infallible predicate to test whether obj is a function object (faster than
  2968. * comparing obj's class name to "Function", but equivalent unless someone has
  2969. * overwritten the "Function" identifier with a different constructor and then
  2970. * created instances using that constructor that might be passed in as obj).
  2971. */
  2972. extern JS_PUBLIC_API(bool)
  2973. JS_ObjectIsFunction(JSContext* cx, JSObject* obj);
  2974. extern JS_PUBLIC_API(bool)
  2975. JS_IsNativeFunction(JSObject* funobj, JSNative call);
  2976. /** Return whether the given function is a valid constructor. */
  2977. extern JS_PUBLIC_API(bool)
  2978. JS_IsConstructor(JSFunction* fun);
  2979. extern JS_PUBLIC_API(bool)
  2980. JS_DefineFunctions(JSContext* cx, JS::Handle<JSObject*> obj, const JSFunctionSpec* fs);
  2981. extern JS_PUBLIC_API(JSFunction*)
  2982. JS_DefineFunction(JSContext* cx, JS::Handle<JSObject*> obj, const char* name, JSNative call,
  2983. unsigned nargs, unsigned attrs);
  2984. extern JS_PUBLIC_API(JSFunction*)
  2985. JS_DefineUCFunction(JSContext* cx, JS::Handle<JSObject*> obj,
  2986. const char16_t* name, size_t namelen, JSNative call,
  2987. unsigned nargs, unsigned attrs);
  2988. extern JS_PUBLIC_API(JSFunction*)
  2989. JS_DefineFunctionById(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JSNative call,
  2990. unsigned nargs, unsigned attrs);
  2991. extern JS_PUBLIC_API(bool)
  2992. JS_IsFunctionBound(JSFunction* fun);
  2993. extern JS_PUBLIC_API(JSObject*)
  2994. JS_GetBoundFunctionTarget(JSFunction* fun);
  2995. namespace JS {
  2996. /**
  2997. * Clone a top-level function into cx's global. This function will dynamically
  2998. * fail if funobj was lexically nested inside some other function.
  2999. */
  3000. extern JS_PUBLIC_API(JSObject*)
  3001. CloneFunctionObject(JSContext* cx, HandleObject funobj);
  3002. /**
  3003. * As above, but providing an explicit scope chain. scopeChain must not include
  3004. * the global object on it; that's implicit. It needs to contain the other
  3005. * objects that should end up on the clone's scope chain.
  3006. */
  3007. extern JS_PUBLIC_API(JSObject*)
  3008. CloneFunctionObject(JSContext* cx, HandleObject funobj, AutoObjectVector& scopeChain);
  3009. } // namespace JS
  3010. /**
  3011. * Given a buffer, return false if the buffer might become a valid
  3012. * javascript statement with the addition of more lines. Otherwise return
  3013. * true. The intent is to support interactive compilation - accumulate
  3014. * lines in a buffer until JS_BufferIsCompilableUnit is true, then pass it to
  3015. * the compiler.
  3016. */
  3017. extern JS_PUBLIC_API(bool)
  3018. JS_BufferIsCompilableUnit(JSContext* cx, JS::Handle<JSObject*> obj, const char* utf8,
  3019. size_t length);
  3020. /**
  3021. * |script| will always be set. On failure, it will be set to nullptr.
  3022. */
  3023. extern JS_PUBLIC_API(bool)
  3024. JS_CompileScript(JSContext* cx, const char* ascii, size_t length,
  3025. const JS::CompileOptions& options,
  3026. JS::MutableHandleScript script);
  3027. /**
  3028. * |script| will always be set. On failure, it will be set to nullptr.
  3029. */
  3030. extern JS_PUBLIC_API(bool)
  3031. JS_CompileUCScript(JSContext* cx, const char16_t* chars, size_t length,
  3032. const JS::CompileOptions& options,
  3033. JS::MutableHandleScript script);
  3034. extern JS_PUBLIC_API(JSObject*)
  3035. JS_GetGlobalFromScript(JSScript* script);
  3036. extern JS_PUBLIC_API(const char*)
  3037. JS_GetScriptFilename(JSScript* script);
  3038. extern JS_PUBLIC_API(unsigned)
  3039. JS_GetScriptBaseLineNumber(JSContext* cx, JSScript* script);
  3040. extern JS_PUBLIC_API(JSScript*)
  3041. JS_GetFunctionScript(JSContext* cx, JS::HandleFunction fun);
  3042. namespace JS {
  3043. /* Options for JavaScript compilation. */
  3044. /*
  3045. * In the most common use case, a CompileOptions instance is allocated on the
  3046. * stack, and holds non-owning references to non-POD option values: strings;
  3047. * principals; objects; and so on. The code declaring the instance guarantees
  3048. * that such option values will outlive the CompileOptions itself: objects are
  3049. * otherwise rooted; principals have had their reference counts bumped; strings
  3050. * will not be freed until the CompileOptions goes out of scope. In this
  3051. * situation, CompileOptions only refers to things others own, so it can be
  3052. * lightweight.
  3053. *
  3054. * In some cases, however, we need to hold compilation options with a
  3055. * non-stack-like lifetime. For example, JS::CompileOffThread needs to save
  3056. * compilation options where a worker thread can find them, and then return
  3057. * immediately. The worker thread will come along at some later point, and use
  3058. * the options.
  3059. *
  3060. * The compiler itself just needs to be able to access a collection of options;
  3061. * it doesn't care who owns them, or what's keeping them alive. It does its own
  3062. * addrefs/copies/tracing/etc.
  3063. *
  3064. * Furthermore, in some cases compile options are propagated from one entity to
  3065. * another (e.g. from a scriipt to a function defined in that script). This
  3066. * involves copying over some, but not all, of the options.
  3067. *
  3068. * So, we have a class hierarchy that reflects these four use cases:
  3069. *
  3070. * - TransitiveCompileOptions is the common base class, representing options
  3071. * that should get propagated from a script to functions defined in that
  3072. * script. This is never instantiated directly.
  3073. *
  3074. * - ReadOnlyCompileOptions is the only subclass of TransitiveCompileOptions,
  3075. * representing a full set of compile options. It can be used by code that
  3076. * simply needs to access options set elsewhere, like the compiler. This,
  3077. * again, is never instantiated directly.
  3078. *
  3079. * - The usual CompileOptions class must be stack-allocated, and holds
  3080. * non-owning references to the filename, element, and so on. It's derived
  3081. * from ReadOnlyCompileOptions, so the compiler can use it.
  3082. *
  3083. * - OwningCompileOptions roots / copies / reference counts of all its values,
  3084. * and unroots / frees / releases them when it is destructed. It too is
  3085. * derived from ReadOnlyCompileOptions, so the compiler accepts it.
  3086. */
  3087. enum class AsmJSOption : uint8_t { Enabled, Disabled, DisabledByDebugger };
  3088. /**
  3089. * The common base class for the CompileOptions hierarchy.
  3090. *
  3091. * Use this in code that needs to propagate compile options from one compilation
  3092. * unit to another.
  3093. */
  3094. class JS_FRIEND_API(TransitiveCompileOptions)
  3095. {
  3096. protected:
  3097. // The Web Platform allows scripts to be loaded from arbitrary cross-origin
  3098. // sources. This allows an attack by which a malicious website loads a
  3099. // sensitive file (say, a bank statement) cross-origin (using the user's
  3100. // cookies), and sniffs the generated syntax errors (via a window.onerror
  3101. // handler) for juicy morsels of its contents.
  3102. //
  3103. // To counter this attack, HTML5 specifies that script errors should be
  3104. // sanitized ("muted") when the script is not same-origin with the global
  3105. // for which it is loaded. Callers should set this flag for cross-origin
  3106. // scripts, and it will be propagated appropriately to child scripts and
  3107. // passed back in JSErrorReports.
  3108. bool mutedErrors_;
  3109. const char* filename_;
  3110. const char* introducerFilename_;
  3111. const char16_t* sourceMapURL_;
  3112. // This constructor leaves 'version' set to JSVERSION_UNKNOWN. The structure
  3113. // is unusable until that's set to something more specific; the derived
  3114. // classes' constructors take care of that, in ways appropriate to their
  3115. // purpose.
  3116. TransitiveCompileOptions()
  3117. : mutedErrors_(false),
  3118. filename_(nullptr),
  3119. introducerFilename_(nullptr),
  3120. sourceMapURL_(nullptr),
  3121. version(JSVERSION_UNKNOWN),
  3122. versionSet(false),
  3123. utf8(false),
  3124. selfHostingMode(false),
  3125. canLazilyParse(true),
  3126. strictOption(false),
  3127. extraWarningsOption(false),
  3128. werrorOption(false),
  3129. asmJSOption(AsmJSOption::Disabled),
  3130. throwOnAsmJSValidationFailureOption(false),
  3131. forceAsync(false),
  3132. installedFile(false),
  3133. sourceIsLazy(false),
  3134. introductionType(nullptr),
  3135. introductionLineno(0),
  3136. introductionOffset(0),
  3137. hasIntroductionInfo(false)
  3138. { }
  3139. // Set all POD options (those not requiring reference counts, copies,
  3140. // rooting, or other hand-holding) to their values in |rhs|.
  3141. void copyPODTransitiveOptions(const TransitiveCompileOptions& rhs);
  3142. public:
  3143. // Read-only accessors for non-POD options. The proper way to set these
  3144. // depends on the derived type.
  3145. bool mutedErrors() const { return mutedErrors_; }
  3146. const char* filename() const { return filename_; }
  3147. const char* introducerFilename() const { return introducerFilename_; }
  3148. const char16_t* sourceMapURL() const { return sourceMapURL_; }
  3149. virtual JSObject* element() const = 0;
  3150. virtual JSString* elementAttributeName() const = 0;
  3151. virtual JSScript* introductionScript() const = 0;
  3152. // POD options.
  3153. JSVersion version;
  3154. bool versionSet;
  3155. bool utf8;
  3156. bool selfHostingMode;
  3157. bool canLazilyParse;
  3158. bool strictOption;
  3159. bool extraWarningsOption;
  3160. bool werrorOption;
  3161. AsmJSOption asmJSOption;
  3162. bool throwOnAsmJSValidationFailureOption;
  3163. bool forceAsync;
  3164. bool installedFile; // 'true' iff pre-compiling js file in packaged app
  3165. bool sourceIsLazy;
  3166. // |introductionType| is a statically allocated C string:
  3167. // one of "eval", "Function", or "GeneratorFunction".
  3168. const char* introductionType;
  3169. unsigned introductionLineno;
  3170. uint32_t introductionOffset;
  3171. bool hasIntroductionInfo;
  3172. private:
  3173. void operator=(const TransitiveCompileOptions&) = delete;
  3174. };
  3175. /**
  3176. * The class representing a full set of compile options.
  3177. *
  3178. * Use this in code that only needs to access compilation options created
  3179. * elsewhere, like the compiler. Don't instantiate this class (the constructor
  3180. * is protected anyway); instead, create instances only of the derived classes:
  3181. * CompileOptions and OwningCompileOptions.
  3182. */
  3183. class JS_FRIEND_API(ReadOnlyCompileOptions) : public TransitiveCompileOptions
  3184. {
  3185. friend class CompileOptions;
  3186. protected:
  3187. ReadOnlyCompileOptions()
  3188. : TransitiveCompileOptions(),
  3189. lineno(1),
  3190. column(0),
  3191. isRunOnce(false),
  3192. noScriptRval(false)
  3193. { }
  3194. // Set all POD options (those not requiring reference counts, copies,
  3195. // rooting, or other hand-holding) to their values in |rhs|.
  3196. void copyPODOptions(const ReadOnlyCompileOptions& rhs);
  3197. public:
  3198. // Read-only accessors for non-POD options. The proper way to set these
  3199. // depends on the derived type.
  3200. bool mutedErrors() const { return mutedErrors_; }
  3201. const char* filename() const { return filename_; }
  3202. const char* introducerFilename() const { return introducerFilename_; }
  3203. const char16_t* sourceMapURL() const { return sourceMapURL_; }
  3204. virtual JSObject* element() const = 0;
  3205. virtual JSString* elementAttributeName() const = 0;
  3206. virtual JSScript* introductionScript() const = 0;
  3207. // POD options.
  3208. unsigned lineno;
  3209. unsigned column;
  3210. // isRunOnce only applies to non-function scripts.
  3211. bool isRunOnce;
  3212. bool noScriptRval;
  3213. private:
  3214. void operator=(const ReadOnlyCompileOptions&) = delete;
  3215. };
  3216. /**
  3217. * Compilation options, with dynamic lifetime. An instance of this type
  3218. * makes a copy of / holds / roots all dynamically allocated resources
  3219. * (principals; elements; strings) that it refers to. Its destructor frees
  3220. * / drops / unroots them. This is heavier than CompileOptions, below, but
  3221. * unlike CompileOptions, it can outlive any given stack frame.
  3222. *
  3223. * Note that this *roots* any JS values it refers to - they're live
  3224. * unconditionally. Thus, instances of this type can't be owned, directly
  3225. * or indirectly, by a JavaScript object: if any value that this roots ever
  3226. * comes to refer to the object that owns this, then the whole cycle, and
  3227. * anything else it entrains, will never be freed.
  3228. */
  3229. class JS_FRIEND_API(OwningCompileOptions) : public ReadOnlyCompileOptions
  3230. {
  3231. PersistentRootedObject elementRoot;
  3232. PersistentRootedString elementAttributeNameRoot;
  3233. PersistentRootedScript introductionScriptRoot;
  3234. public:
  3235. // A minimal constructor, for use with OwningCompileOptions::copy. This
  3236. // leaves |this.version| set to JSVERSION_UNKNOWN; the instance
  3237. // shouldn't be used until we've set that to something real (as |copy|
  3238. // will).
  3239. explicit OwningCompileOptions(JSContext* cx);
  3240. ~OwningCompileOptions();
  3241. JSObject* element() const override { return elementRoot; }
  3242. JSString* elementAttributeName() const override { return elementAttributeNameRoot; }
  3243. JSScript* introductionScript() const override { return introductionScriptRoot; }
  3244. // Set this to a copy of |rhs|. Return false on OOM.
  3245. bool copy(JSContext* cx, const ReadOnlyCompileOptions& rhs);
  3246. /* These setters make copies of their string arguments, and are fallible. */
  3247. bool setFile(JSContext* cx, const char* f);
  3248. bool setFileAndLine(JSContext* cx, const char* f, unsigned l);
  3249. bool setSourceMapURL(JSContext* cx, const char16_t* s);
  3250. bool setIntroducerFilename(JSContext* cx, const char* s);
  3251. /* These setters are infallible, and can be chained. */
  3252. OwningCompileOptions& setLine(unsigned l) { lineno = l; return *this; }
  3253. OwningCompileOptions& setElement(JSObject* e) {
  3254. elementRoot = e;
  3255. return *this;
  3256. }
  3257. OwningCompileOptions& setElementAttributeName(JSString* p) {
  3258. elementAttributeNameRoot = p;
  3259. return *this;
  3260. }
  3261. OwningCompileOptions& setIntroductionScript(JSScript* s) {
  3262. introductionScriptRoot = s;
  3263. return *this;
  3264. }
  3265. OwningCompileOptions& setMutedErrors(bool mute) {
  3266. mutedErrors_ = mute;
  3267. return *this;
  3268. }
  3269. OwningCompileOptions& setVersion(JSVersion v) {
  3270. version = v;
  3271. versionSet = true;
  3272. return *this;
  3273. }
  3274. OwningCompileOptions& setUTF8(bool u) { utf8 = u; return *this; }
  3275. OwningCompileOptions& setColumn(unsigned c) { column = c; return *this; }
  3276. OwningCompileOptions& setIsRunOnce(bool once) { isRunOnce = once; return *this; }
  3277. OwningCompileOptions& setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; }
  3278. OwningCompileOptions& setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; }
  3279. OwningCompileOptions& setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; }
  3280. OwningCompileOptions& setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; }
  3281. OwningCompileOptions& setIntroductionType(const char* t) { introductionType = t; return *this; }
  3282. bool setIntroductionInfo(JSContext* cx, const char* introducerFn, const char* intro,
  3283. unsigned line, JSScript* script, uint32_t offset)
  3284. {
  3285. if (!setIntroducerFilename(cx, introducerFn))
  3286. return false;
  3287. introductionType = intro;
  3288. introductionLineno = line;
  3289. introductionScriptRoot = script;
  3290. introductionOffset = offset;
  3291. hasIntroductionInfo = true;
  3292. return true;
  3293. }
  3294. private:
  3295. void operator=(const CompileOptions& rhs) = delete;
  3296. };
  3297. /**
  3298. * Compilation options stored on the stack. An instance of this type
  3299. * simply holds references to dynamically allocated resources (element;
  3300. * filename; source map URL) that are owned by something else. If you
  3301. * create an instance of this type, it's up to you to guarantee that
  3302. * everything you store in it will outlive it.
  3303. */
  3304. class MOZ_STACK_CLASS JS_FRIEND_API(CompileOptions) final : public ReadOnlyCompileOptions
  3305. {
  3306. RootedObject elementRoot;
  3307. RootedString elementAttributeNameRoot;
  3308. RootedScript introductionScriptRoot;
  3309. public:
  3310. explicit CompileOptions(JSContext* cx, JSVersion version = JSVERSION_UNKNOWN);
  3311. CompileOptions(js::ContextFriendFields* cx, const ReadOnlyCompileOptions& rhs)
  3312. : ReadOnlyCompileOptions(), elementRoot(cx), elementAttributeNameRoot(cx),
  3313. introductionScriptRoot(cx)
  3314. {
  3315. copyPODOptions(rhs);
  3316. filename_ = rhs.filename();
  3317. introducerFilename_ = rhs.introducerFilename();
  3318. sourceMapURL_ = rhs.sourceMapURL();
  3319. elementRoot = rhs.element();
  3320. elementAttributeNameRoot = rhs.elementAttributeName();
  3321. introductionScriptRoot = rhs.introductionScript();
  3322. }
  3323. CompileOptions(js::ContextFriendFields* cx, const TransitiveCompileOptions& rhs)
  3324. : ReadOnlyCompileOptions(), elementRoot(cx), elementAttributeNameRoot(cx),
  3325. introductionScriptRoot(cx)
  3326. {
  3327. copyPODTransitiveOptions(rhs);
  3328. filename_ = rhs.filename();
  3329. introducerFilename_ = rhs.introducerFilename();
  3330. sourceMapURL_ = rhs.sourceMapURL();
  3331. elementRoot = rhs.element();
  3332. elementAttributeNameRoot = rhs.elementAttributeName();
  3333. introductionScriptRoot = rhs.introductionScript();
  3334. }
  3335. JSObject* element() const override { return elementRoot; }
  3336. JSString* elementAttributeName() const override { return elementAttributeNameRoot; }
  3337. JSScript* introductionScript() const override { return introductionScriptRoot; }
  3338. CompileOptions& setFile(const char* f) { filename_ = f; return *this; }
  3339. CompileOptions& setLine(unsigned l) { lineno = l; return *this; }
  3340. CompileOptions& setFileAndLine(const char* f, unsigned l) {
  3341. filename_ = f; lineno = l; return *this;
  3342. }
  3343. CompileOptions& setSourceMapURL(const char16_t* s) { sourceMapURL_ = s; return *this; }
  3344. CompileOptions& setElement(JSObject* e) { elementRoot = e; return *this; }
  3345. CompileOptions& setElementAttributeName(JSString* p) {
  3346. elementAttributeNameRoot = p;
  3347. return *this;
  3348. }
  3349. CompileOptions& setIntroductionScript(JSScript* s) {
  3350. introductionScriptRoot = s;
  3351. return *this;
  3352. }
  3353. CompileOptions& setMutedErrors(bool mute) {
  3354. mutedErrors_ = mute;
  3355. return *this;
  3356. }
  3357. CompileOptions& setVersion(JSVersion v) {
  3358. version = v;
  3359. versionSet = true;
  3360. return *this;
  3361. }
  3362. CompileOptions& setUTF8(bool u) { utf8 = u; return *this; }
  3363. CompileOptions& setColumn(unsigned c) { column = c; return *this; }
  3364. CompileOptions& setIsRunOnce(bool once) { isRunOnce = once; return *this; }
  3365. CompileOptions& setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; }
  3366. CompileOptions& setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; }
  3367. CompileOptions& setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; }
  3368. CompileOptions& setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; }
  3369. CompileOptions& setIntroductionType(const char* t) { introductionType = t; return *this; }
  3370. CompileOptions& setIntroductionInfo(const char* introducerFn, const char* intro,
  3371. unsigned line, JSScript* script, uint32_t offset)
  3372. {
  3373. introducerFilename_ = introducerFn;
  3374. introductionType = intro;
  3375. introductionLineno = line;
  3376. introductionScriptRoot = script;
  3377. introductionOffset = offset;
  3378. hasIntroductionInfo = true;
  3379. return *this;
  3380. }
  3381. CompileOptions& maybeMakeStrictMode(bool strict) {
  3382. strictOption = strictOption || strict;
  3383. return *this;
  3384. }
  3385. private:
  3386. void operator=(const CompileOptions& rhs) = delete;
  3387. };
  3388. /**
  3389. * |script| will always be set. On failure, it will be set to nullptr.
  3390. */
  3391. extern JS_PUBLIC_API(bool)
  3392. Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
  3393. SourceBufferHolder& srcBuf, JS::MutableHandleScript script);
  3394. extern JS_PUBLIC_API(bool)
  3395. Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
  3396. const char* bytes, size_t length, JS::MutableHandleScript script);
  3397. extern JS_PUBLIC_API(bool)
  3398. Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
  3399. const char16_t* chars, size_t length, JS::MutableHandleScript script);
  3400. extern JS_PUBLIC_API(bool)
  3401. Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
  3402. FILE* file, JS::MutableHandleScript script);
  3403. extern JS_PUBLIC_API(bool)
  3404. Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
  3405. const char* filename, JS::MutableHandleScript script);
  3406. extern JS_PUBLIC_API(bool)
  3407. CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
  3408. SourceBufferHolder& srcBuf, JS::MutableHandleScript script);
  3409. extern JS_PUBLIC_API(bool)
  3410. CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
  3411. const char* bytes, size_t length, JS::MutableHandleScript script);
  3412. extern JS_PUBLIC_API(bool)
  3413. CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
  3414. const char16_t* chars, size_t length, JS::MutableHandleScript script);
  3415. extern JS_PUBLIC_API(bool)
  3416. CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
  3417. FILE* file, JS::MutableHandleScript script);
  3418. extern JS_PUBLIC_API(bool)
  3419. CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
  3420. const char* filename, JS::MutableHandleScript script);
  3421. extern JS_PUBLIC_API(bool)
  3422. CanCompileOffThread(JSContext* cx, const ReadOnlyCompileOptions& options, size_t length);
  3423. /*
  3424. * Off thread compilation control flow.
  3425. *
  3426. * After successfully triggering an off thread compile of a script, the
  3427. * callback will eventually be invoked with the specified data and a token
  3428. * for the compilation. The callback will be invoked while off the main thread,
  3429. * so must ensure that its operations are thread safe. Afterwards, one of the
  3430. * following functions must be invoked on the main thread:
  3431. *
  3432. * - FinishOffThreadScript, to get the result script (or nullptr on failure).
  3433. * - CancelOffThreadScript, to free the resources without creating a script.
  3434. *
  3435. * The characters passed in to CompileOffThread must remain live until the
  3436. * callback is invoked, and the resulting script will be rooted until the call
  3437. * to FinishOffThreadScript.
  3438. */
  3439. extern JS_PUBLIC_API(bool)
  3440. CompileOffThread(JSContext* cx, const ReadOnlyCompileOptions& options,
  3441. const char16_t* chars, size_t length,
  3442. OffThreadCompileCallback callback, void* callbackData);
  3443. extern JS_PUBLIC_API(JSScript*)
  3444. FinishOffThreadScript(JSContext* cx, void* token);
  3445. extern JS_PUBLIC_API(void)
  3446. CancelOffThreadScript(JSContext* cx, void* token);
  3447. extern JS_PUBLIC_API(bool)
  3448. CompileOffThreadModule(JSContext* cx, const ReadOnlyCompileOptions& options,
  3449. const char16_t* chars, size_t length,
  3450. OffThreadCompileCallback callback, void* callbackData);
  3451. extern JS_PUBLIC_API(JSObject*)
  3452. FinishOffThreadModule(JSContext* cx, void* token);
  3453. extern JS_PUBLIC_API(void)
  3454. CancelOffThreadModule(JSContext* cx, void* token);
  3455. /**
  3456. * Compile a function with envChain plus the global as its scope chain.
  3457. * envChain must contain objects in the current compartment of cx. The actual
  3458. * scope chain used for the function will consist of With wrappers for those
  3459. * objects, followed by the current global of the compartment cx is in. This
  3460. * global must not be explicitly included in the scope chain.
  3461. */
  3462. extern JS_PUBLIC_API(bool)
  3463. CompileFunction(JSContext* cx, AutoObjectVector& envChain,
  3464. const ReadOnlyCompileOptions& options,
  3465. const char* name, unsigned nargs, const char* const* argnames,
  3466. const char16_t* chars, size_t length, JS::MutableHandleFunction fun);
  3467. /**
  3468. * Same as above, but taking a SourceBufferHolder for the function body.
  3469. */
  3470. extern JS_PUBLIC_API(bool)
  3471. CompileFunction(JSContext* cx, AutoObjectVector& envChain,
  3472. const ReadOnlyCompileOptions& options,
  3473. const char* name, unsigned nargs, const char* const* argnames,
  3474. SourceBufferHolder& srcBuf, JS::MutableHandleFunction fun);
  3475. /**
  3476. * Same as above, but taking a const char * for the function body.
  3477. */
  3478. extern JS_PUBLIC_API(bool)
  3479. CompileFunction(JSContext* cx, AutoObjectVector& envChain,
  3480. const ReadOnlyCompileOptions& options,
  3481. const char* name, unsigned nargs, const char* const* argnames,
  3482. const char* bytes, size_t length, JS::MutableHandleFunction fun);
  3483. } /* namespace JS */
  3484. extern JS_PUBLIC_API(JSString*)
  3485. JS_DecompileScript(JSContext* cx, JS::Handle<JSScript*> script, const char* name, unsigned indent);
  3486. /*
  3487. * API extension: OR this into indent to avoid pretty-printing the decompiled
  3488. * source resulting from JS_DecompileFunction.
  3489. */
  3490. #define JS_DONT_PRETTY_PRINT ((unsigned)0x8000)
  3491. extern JS_PUBLIC_API(JSString*)
  3492. JS_DecompileFunction(JSContext* cx, JS::Handle<JSFunction*> fun, unsigned indent);
  3493. /*
  3494. * NB: JS_ExecuteScript and the JS::Evaluate APIs come in two flavors: either
  3495. * they use the global as the scope, or they take an AutoObjectVector of objects
  3496. * to use as the scope chain. In the former case, the global is also used as
  3497. * the "this" keyword value and the variables object (ECMA parlance for where
  3498. * 'var' and 'function' bind names) of the execution context for script. In the
  3499. * latter case, the first object in the provided list is used, unless the list
  3500. * is empty, in which case the global is used.
  3501. *
  3502. * Why a runtime option? The alternative is to add APIs duplicating those
  3503. * for the other value of flags, and that doesn't seem worth the code bloat
  3504. * cost. Such new entry points would probably have less obvious names, too, so
  3505. * would not tend to be used. The ContextOptionsRef adjustment, OTOH, can be
  3506. * more easily hacked into existing code that does not depend on the bug; such
  3507. * code can continue to use the familiar JS::Evaluate, etc., entry points.
  3508. */
  3509. /**
  3510. * Evaluate a script in the scope of the current global of cx.
  3511. */
  3512. extern JS_PUBLIC_API(bool)
  3513. JS_ExecuteScript(JSContext* cx, JS::HandleScript script, JS::MutableHandleValue rval);
  3514. extern JS_PUBLIC_API(bool)
  3515. JS_ExecuteScript(JSContext* cx, JS::HandleScript script);
  3516. /**
  3517. * As above, but providing an explicit scope chain. envChain must not include
  3518. * the global object on it; that's implicit. It needs to contain the other
  3519. * objects that should end up on the script's scope chain.
  3520. */
  3521. extern JS_PUBLIC_API(bool)
  3522. JS_ExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain,
  3523. JS::HandleScript script, JS::MutableHandleValue rval);
  3524. extern JS_PUBLIC_API(bool)
  3525. JS_ExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain, JS::HandleScript script);
  3526. namespace JS {
  3527. /**
  3528. * Like the above, but handles a cross-compartment script. If the script is
  3529. * cross-compartment, it is cloned into the current compartment before executing.
  3530. */
  3531. extern JS_PUBLIC_API(bool)
  3532. CloneAndExecuteScript(JSContext* cx, JS::Handle<JSScript*> script,
  3533. JS::MutableHandleValue rval);
  3534. } /* namespace JS */
  3535. namespace JS {
  3536. /**
  3537. * Evaluate the given source buffer in the scope of the current global of cx.
  3538. */
  3539. extern JS_PUBLIC_API(bool)
  3540. Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
  3541. SourceBufferHolder& srcBuf, JS::MutableHandleValue rval);
  3542. /**
  3543. * As above, but providing an explicit scope chain. envChain must not include
  3544. * the global object on it; that's implicit. It needs to contain the other
  3545. * objects that should end up on the script's scope chain.
  3546. */
  3547. extern JS_PUBLIC_API(bool)
  3548. Evaluate(JSContext* cx, AutoObjectVector& envChain, const ReadOnlyCompileOptions& options,
  3549. SourceBufferHolder& srcBuf, JS::MutableHandleValue rval);
  3550. /**
  3551. * Evaluate the given character buffer in the scope of the current global of cx.
  3552. */
  3553. extern JS_PUBLIC_API(bool)
  3554. Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
  3555. const char16_t* chars, size_t length, JS::MutableHandleValue rval);
  3556. /**
  3557. * As above, but providing an explicit scope chain. envChain must not include
  3558. * the global object on it; that's implicit. It needs to contain the other
  3559. * objects that should end up on the script's scope chain.
  3560. */
  3561. extern JS_PUBLIC_API(bool)
  3562. Evaluate(JSContext* cx, AutoObjectVector& envChain, const ReadOnlyCompileOptions& options,
  3563. const char16_t* chars, size_t length, JS::MutableHandleValue rval);
  3564. /**
  3565. * Evaluate the given byte buffer in the scope of the current global of cx.
  3566. */
  3567. extern JS_PUBLIC_API(bool)
  3568. Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
  3569. const char* bytes, size_t length, JS::MutableHandleValue rval);
  3570. /**
  3571. * Evaluate the given file in the scope of the current global of cx.
  3572. */
  3573. extern JS_PUBLIC_API(bool)
  3574. Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
  3575. const char* filename, JS::MutableHandleValue rval);
  3576. /**
  3577. * Get the HostResolveImportedModule hook for a global.
  3578. */
  3579. extern JS_PUBLIC_API(JSFunction*)
  3580. GetModuleResolveHook(JSContext* cx);
  3581. /**
  3582. * Set the HostResolveImportedModule hook for a global to the given function.
  3583. */
  3584. extern JS_PUBLIC_API(void)
  3585. SetModuleResolveHook(JSContext* cx, JS::HandleFunction func);
  3586. /**
  3587. * Parse the given source buffer as a module in the scope of the current global
  3588. * of cx and return a source text module record.
  3589. */
  3590. extern JS_PUBLIC_API(bool)
  3591. CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options,
  3592. SourceBufferHolder& srcBuf, JS::MutableHandleObject moduleRecord);
  3593. /**
  3594. * Set the [[HostDefined]] field of a source text module record to the given
  3595. * value.
  3596. */
  3597. extern JS_PUBLIC_API(void)
  3598. SetModuleHostDefinedField(JSObject* module, const JS::Value& value);
  3599. /**
  3600. * Get the [[HostDefined]] field of a source text module record.
  3601. */
  3602. extern JS_PUBLIC_API(JS::Value)
  3603. GetModuleHostDefinedField(JSObject* module);
  3604. /*
  3605. * Perform the ModuleDeclarationInstantiation operation on on the give source
  3606. * text module record.
  3607. *
  3608. * This transitively resolves all module dependencies (calling the
  3609. * HostResolveImportedModule hook) and initializes the environment record for
  3610. * the module.
  3611. */
  3612. extern JS_PUBLIC_API(bool)
  3613. ModuleDeclarationInstantiation(JSContext* cx, JS::HandleObject moduleRecord);
  3614. /*
  3615. * Perform the ModuleEvaluation operation on on the give source text module
  3616. * record.
  3617. *
  3618. * This does nothing if this module has already been evaluated. Otherwise, it
  3619. * transitively evaluates all dependences of this module and then evaluates this
  3620. * module.
  3621. *
  3622. * ModuleDeclarationInstantiation must have completed prior to calling this.
  3623. */
  3624. extern JS_PUBLIC_API(bool)
  3625. ModuleEvaluation(JSContext* cx, JS::HandleObject moduleRecord);
  3626. /*
  3627. * Get a list of the module specifiers used by a source text module
  3628. * record to request importation of modules.
  3629. *
  3630. * The result is a JavaScript array of string values. To extract the individual
  3631. * values use only JS_GetArrayLength and JS_GetElement with indices 0 to
  3632. * length - 1.
  3633. */
  3634. extern JS_PUBLIC_API(JSObject*)
  3635. GetRequestedModules(JSContext* cx, JS::HandleObject moduleRecord);
  3636. /*
  3637. * Get the script associated with a module.
  3638. */
  3639. extern JS_PUBLIC_API(JSScript*)
  3640. GetModuleScript(JSContext* cx, JS::HandleObject moduleRecord);
  3641. } /* namespace JS */
  3642. extern JS_PUBLIC_API(bool)
  3643. JS_CheckForInterrupt(JSContext* cx);
  3644. /*
  3645. * These functions allow setting an interrupt callback that will be called
  3646. * from the JS thread some time after any thread triggered the callback using
  3647. * JS_RequestInterruptCallback(cx).
  3648. *
  3649. * To schedule the GC and for other activities the engine internally triggers
  3650. * interrupt callbacks. The embedding should thus not rely on callbacks being
  3651. * triggered through the external API only.
  3652. *
  3653. * Important note: Additional callbacks can occur inside the callback handler
  3654. * if it re-enters the JS engine. The embedding must ensure that the callback
  3655. * is disconnected before attempting such re-entry.
  3656. */
  3657. extern JS_PUBLIC_API(bool)
  3658. JS_AddInterruptCallback(JSContext* cx, JSInterruptCallback callback);
  3659. extern JS_PUBLIC_API(bool)
  3660. JS_DisableInterruptCallback(JSContext* cx);
  3661. extern JS_PUBLIC_API(void)
  3662. JS_ResetInterruptCallback(JSContext* cx, bool enable);
  3663. extern JS_PUBLIC_API(void)
  3664. JS_RequestInterruptCallback(JSContext* cx);
  3665. namespace JS {
  3666. /**
  3667. * Sets the callback that's invoked whenever an incumbent global is required.
  3668. *
  3669. * SpiderMonkey doesn't itself have a notion of incumbent globals as defined
  3670. * by the html spec, so we need the embedding to provide this.
  3671. * See dom/base/ScriptSettings.h for details.
  3672. */
  3673. extern JS_PUBLIC_API(void)
  3674. SetGetIncumbentGlobalCallback(JSContext* cx, JSGetIncumbentGlobalCallback callback);
  3675. /**
  3676. * Sets the callback that's invoked whenever a Promise job should be enqeued.
  3677. *
  3678. * SpiderMonkey doesn't schedule Promise resolution jobs itself; instead,
  3679. * using this function the embedding can provide a callback to do that
  3680. * scheduling. The provided `callback` is invoked with the promise job,
  3681. * the corresponding Promise's allocation stack, and the `data` pointer
  3682. * passed here as arguments.
  3683. */
  3684. extern JS_PUBLIC_API(void)
  3685. SetEnqueuePromiseJobCallback(JSContext* cx, JSEnqueuePromiseJobCallback callback,
  3686. void* data = nullptr);
  3687. /**
  3688. * Sets the callback that's invoked whenever a Promise is rejected without
  3689. * a rejection handler, and when a Promise that was previously rejected
  3690. * without a handler gets a handler attached.
  3691. */
  3692. extern JS_PUBLIC_API(void)
  3693. SetPromiseRejectionTrackerCallback(JSContext* cx, JSPromiseRejectionTrackerCallback callback,
  3694. void* data = nullptr);
  3695. /**
  3696. * Returns a new instance of the Promise builtin class in the current
  3697. * compartment, with the right slot layout. If a `proto` is passed, that gets
  3698. * set as the instance's [[Prototype]] instead of the original value of
  3699. * `Promise.prototype`.
  3700. */
  3701. extern JS_PUBLIC_API(JSObject*)
  3702. NewPromiseObject(JSContext* cx, JS::HandleObject executor, JS::HandleObject proto = nullptr);
  3703. /**
  3704. * Returns true if the given object is an unwrapped PromiseObject, false
  3705. * otherwise.
  3706. */
  3707. extern JS_PUBLIC_API(bool)
  3708. IsPromiseObject(JS::HandleObject obj);
  3709. /**
  3710. * Returns the current compartment's original Promise constructor.
  3711. */
  3712. extern JS_PUBLIC_API(JSObject*)
  3713. GetPromiseConstructor(JSContext* cx);
  3714. /**
  3715. * Returns the current compartment's original Promise.prototype.
  3716. */
  3717. extern JS_PUBLIC_API(JSObject*)
  3718. GetPromisePrototype(JSContext* cx);
  3719. // Keep this in sync with the PROMISE_STATE defines in SelfHostingDefines.h.
  3720. enum class PromiseState {
  3721. Pending,
  3722. Fulfilled,
  3723. Rejected
  3724. };
  3725. /**
  3726. * Returns the given Promise's state as a JS::PromiseState enum value.
  3727. */
  3728. extern JS_PUBLIC_API(PromiseState)
  3729. GetPromiseState(JS::HandleObject promise);
  3730. /**
  3731. * Returns the given Promise's process-unique ID.
  3732. */
  3733. JS_PUBLIC_API(uint64_t)
  3734. GetPromiseID(JS::HandleObject promise);
  3735. /**
  3736. * Returns the given Promise's result: either the resolution value for
  3737. * fulfilled promises, or the rejection reason for rejected ones.
  3738. */
  3739. extern JS_PUBLIC_API(JS::Value)
  3740. GetPromiseResult(JS::HandleObject promise);
  3741. /**
  3742. * Returns a js::SavedFrame linked list of the stack that lead to the given
  3743. * Promise's allocation.
  3744. */
  3745. extern JS_PUBLIC_API(JSObject*)
  3746. GetPromiseAllocationSite(JS::HandleObject promise);
  3747. extern JS_PUBLIC_API(JSObject*)
  3748. GetPromiseResolutionSite(JS::HandleObject promise);
  3749. #ifdef DEBUG
  3750. extern JS_PUBLIC_API(void)
  3751. DumpPromiseAllocationSite(JSContext* cx, JS::HandleObject promise);
  3752. extern JS_PUBLIC_API(void)
  3753. DumpPromiseResolutionSite(JSContext* cx, JS::HandleObject promise);
  3754. #endif
  3755. /**
  3756. * Calls the current compartment's original Promise.resolve on the original
  3757. * Promise constructor, with `resolutionValue` passed as an argument.
  3758. */
  3759. extern JS_PUBLIC_API(JSObject*)
  3760. CallOriginalPromiseResolve(JSContext* cx, JS::HandleValue resolutionValue);
  3761. /**
  3762. * Calls the current compartment's original Promise.reject on the original
  3763. * Promise constructor, with `resolutionValue` passed as an argument.
  3764. */
  3765. extern JS_PUBLIC_API(JSObject*)
  3766. CallOriginalPromiseReject(JSContext* cx, JS::HandleValue rejectionValue);
  3767. /**
  3768. * Resolves the given Promise with the given `resolutionValue`.
  3769. *
  3770. * Calls the `resolve` function that was passed to the executor function when
  3771. * the Promise was created.
  3772. */
  3773. extern JS_PUBLIC_API(bool)
  3774. ResolvePromise(JSContext* cx, JS::HandleObject promise, JS::HandleValue resolutionValue);
  3775. /**
  3776. * Rejects the given `promise` with the given `rejectionValue`.
  3777. *
  3778. * Calls the `reject` function that was passed to the executor function when
  3779. * the Promise was created.
  3780. */
  3781. extern JS_PUBLIC_API(bool)
  3782. RejectPromise(JSContext* cx, JS::HandleObject promise, JS::HandleValue rejectionValue);
  3783. /**
  3784. * Calls the current compartment's original Promise.prototype.then on the
  3785. * given `promise`, with `onResolve` and `onReject` passed as arguments.
  3786. *
  3787. * Asserts if the passed-in `promise` object isn't an unwrapped instance of
  3788. * `Promise` or a subclass or `onResolve` and `onReject` aren't both either
  3789. * `nullptr` or callable objects.
  3790. */
  3791. extern JS_PUBLIC_API(JSObject*)
  3792. CallOriginalPromiseThen(JSContext* cx, JS::HandleObject promise,
  3793. JS::HandleObject onResolve, JS::HandleObject onReject);
  3794. /**
  3795. * Unforgeable, optimized version of the JS builtin Promise.prototype.then.
  3796. *
  3797. * Takes a Promise instance and `onResolve`, `onReject` callables to enqueue
  3798. * as reactions for that promise. In difference to Promise.prototype.then,
  3799. * this doesn't create and return a new Promise instance.
  3800. *
  3801. * Asserts if the passed-in `promise` object isn't an unwrapped instance of
  3802. * `Promise` or a subclass or `onResolve` and `onReject` aren't both callable
  3803. * objects.
  3804. */
  3805. extern JS_PUBLIC_API(bool)
  3806. AddPromiseReactions(JSContext* cx, JS::HandleObject promise,
  3807. JS::HandleObject onResolve, JS::HandleObject onReject);
  3808. /**
  3809. * Unforgeable version of the JS builtin Promise.all.
  3810. *
  3811. * Takes an AutoObjectVector of Promise objects and returns a promise that's
  3812. * resolved with an array of resolution values when all those promises ahve
  3813. * been resolved, or rejected with the rejection value of the first rejected
  3814. * promise.
  3815. *
  3816. * Asserts if the array isn't dense or one of the entries isn't an unwrapped
  3817. * instance of Promise or a subclass.
  3818. */
  3819. extern JS_PUBLIC_API(JSObject*)
  3820. GetWaitForAllPromise(JSContext* cx, const JS::AutoObjectVector& promises);
  3821. /**
  3822. * An AsyncTask represents a SpiderMonkey-internal operation that starts on a
  3823. * JSContext's owner thread, possibly executes on other threads, completes, and
  3824. * then needs to be scheduled to run again on the JSContext's owner thread. The
  3825. * embedding provides for this final dispatch back to the JSContext's owner
  3826. * thread by calling methods on this interface when requested.
  3827. */
  3828. struct JS_PUBLIC_API(AsyncTask)
  3829. {
  3830. AsyncTask() : user(nullptr) {}
  3831. virtual ~AsyncTask() {}
  3832. /**
  3833. * After the FinishAsyncTaskCallback is called and succeeds, one of these
  3834. * two functions will be called on the original JSContext's owner thread.
  3835. */
  3836. virtual void finish(JSContext* cx) = 0;
  3837. virtual void cancel(JSContext* cx) = 0;
  3838. /* The embedding may use this field to attach arbitrary data to a task. */
  3839. void* user;
  3840. };
  3841. /**
  3842. * A new AsyncTask object, created inside SpiderMonkey on the JSContext's owner
  3843. * thread, will be passed to the StartAsyncTaskCallback before it is dispatched
  3844. * to another thread. The embedding may use the AsyncTask::user field to attach
  3845. * additional task state.
  3846. *
  3847. * If this function succeeds, SpiderMonkey will call the FinishAsyncTaskCallback
  3848. * at some point in the future. Otherwise, FinishAsyncTaskCallback will *not*
  3849. * be called. SpiderMonkey assumes that, if StartAsyncTaskCallback fails, it is
  3850. * because the JSContext is being shut down.
  3851. */
  3852. typedef bool
  3853. (*StartAsyncTaskCallback)(JSContext* cx, AsyncTask* task);
  3854. /**
  3855. * The FinishAsyncTaskCallback may be called from any thread and will only be
  3856. * passed AsyncTasks that have already been started via StartAsyncTaskCallback.
  3857. * If the embedding returns 'true', indicating success, the embedding must call
  3858. * either task->finish() or task->cancel() on the JSContext's owner thread at
  3859. * some point in the future.
  3860. */
  3861. typedef bool
  3862. (*FinishAsyncTaskCallback)(AsyncTask* task);
  3863. /**
  3864. * Set the above callbacks for the given context.
  3865. */
  3866. extern JS_PUBLIC_API(void)
  3867. SetAsyncTaskCallbacks(JSContext* cx, StartAsyncTaskCallback start, FinishAsyncTaskCallback finish);
  3868. } // namespace JS
  3869. extern JS_PUBLIC_API(bool)
  3870. JS_IsRunning(JSContext* cx);
  3871. namespace JS {
  3872. /**
  3873. * This class can be used to store a pointer to the youngest frame of a saved
  3874. * stack in the specified JSContext. This reference will be picked up by any new
  3875. * calls performed until the class is destroyed, with the specified asyncCause,
  3876. * that must not be empty.
  3877. *
  3878. * Any stack capture initiated during these new calls will go through the async
  3879. * stack instead of the current stack.
  3880. *
  3881. * Capturing the stack before a new call is performed will not be affected.
  3882. *
  3883. * The provided chain of SavedFrame objects can live in any compartment,
  3884. * although it will be copied to the compartment where the stack is captured.
  3885. *
  3886. * See also `js/src/doc/SavedFrame/SavedFrame.md` for documentation on async
  3887. * stack frames.
  3888. */
  3889. class MOZ_STACK_CLASS JS_PUBLIC_API(AutoSetAsyncStackForNewCalls)
  3890. {
  3891. JSContext* cx;
  3892. RootedObject oldAsyncStack;
  3893. const char* oldAsyncCause;
  3894. bool oldAsyncCallIsExplicit;
  3895. public:
  3896. enum class AsyncCallKind {
  3897. // The ordinary kind of call, where we may apply an async
  3898. // parent if there is no ordinary parent.
  3899. IMPLICIT,
  3900. // An explicit async parent, e.g., callFunctionWithAsyncStack,
  3901. // where we always want to override any ordinary parent.
  3902. EXPLICIT
  3903. };
  3904. // The stack parameter cannot be null by design, because it would be
  3905. // ambiguous whether that would clear any scheduled async stack and make the
  3906. // normal stack reappear in the new call, or just keep the async stack
  3907. // already scheduled for the new call, if any.
  3908. //
  3909. // asyncCause is owned by the caller and its lifetime must outlive the
  3910. // lifetime of the AutoSetAsyncStackForNewCalls object. It is strongly
  3911. // encouraged that asyncCause be a string constant or similar statically
  3912. // allocated string.
  3913. AutoSetAsyncStackForNewCalls(JSContext* cx, HandleObject stack,
  3914. const char* asyncCause,
  3915. AsyncCallKind kind = AsyncCallKind::IMPLICIT);
  3916. ~AutoSetAsyncStackForNewCalls();
  3917. };
  3918. } // namespace JS
  3919. /************************************************************************/
  3920. /*
  3921. * Strings.
  3922. *
  3923. * NB: JS_NewUCString takes ownership of bytes on success, avoiding a copy;
  3924. * but on error (signified by null return), it leaves chars owned by the
  3925. * caller. So the caller must free bytes in the error case, if it has no use
  3926. * for them. In contrast, all the JS_New*StringCopy* functions do not take
  3927. * ownership of the character memory passed to them -- they copy it.
  3928. */
  3929. extern JS_PUBLIC_API(JSString*)
  3930. JS_NewStringCopyN(JSContext* cx, const char* s, size_t n);
  3931. extern JS_PUBLIC_API(JSString*)
  3932. JS_NewStringCopyZ(JSContext* cx, const char* s);
  3933. extern JS_PUBLIC_API(JSString*)
  3934. JS_NewStringCopyUTF8Z(JSContext* cx, const JS::ConstUTF8CharsZ s);
  3935. extern JS_PUBLIC_API(JSString*)
  3936. JS_NewStringCopyUTF8N(JSContext* cx, const JS::UTF8Chars s);
  3937. extern JS_PUBLIC_API(JSString*)
  3938. JS_AtomizeAndPinJSString(JSContext* cx, JS::HandleString str);
  3939. extern JS_PUBLIC_API(JSString*)
  3940. JS_AtomizeStringN(JSContext* cx, const char* s, size_t length);
  3941. extern JS_PUBLIC_API(JSString*)
  3942. JS_AtomizeString(JSContext* cx, const char* s);
  3943. extern JS_PUBLIC_API(JSString*)
  3944. JS_AtomizeAndPinStringN(JSContext* cx, const char* s, size_t length);
  3945. extern JS_PUBLIC_API(JSString*)
  3946. JS_AtomizeAndPinString(JSContext* cx, const char* s);
  3947. extern JS_PUBLIC_API(JSString*)
  3948. JS_NewUCString(JSContext* cx, char16_t* chars, size_t length);
  3949. extern JS_PUBLIC_API(JSString*)
  3950. JS_NewUCStringCopyN(JSContext* cx, const char16_t* s, size_t n);
  3951. extern JS_PUBLIC_API(JSString*)
  3952. JS_NewUCStringCopyZ(JSContext* cx, const char16_t* s);
  3953. extern JS_PUBLIC_API(JSString*)
  3954. JS_AtomizeUCStringN(JSContext* cx, const char16_t* s, size_t length);
  3955. extern JS_PUBLIC_API(JSString*)
  3956. JS_AtomizeUCString(JSContext* cx, const char16_t* s);
  3957. extern JS_PUBLIC_API(JSString*)
  3958. JS_AtomizeAndPinUCStringN(JSContext* cx, const char16_t* s, size_t length);
  3959. extern JS_PUBLIC_API(JSString*)
  3960. JS_AtomizeAndPinUCString(JSContext* cx, const char16_t* s);
  3961. extern JS_PUBLIC_API(bool)
  3962. JS_CompareStrings(JSContext* cx, JSString* str1, JSString* str2, int32_t* result);
  3963. extern JS_PUBLIC_API(bool)
  3964. JS_StringEqualsAscii(JSContext* cx, JSString* str, const char* asciiBytes, bool* match);
  3965. extern JS_PUBLIC_API(size_t)
  3966. JS_PutEscapedString(JSContext* cx, char* buffer, size_t size, JSString* str, char quote);
  3967. extern JS_PUBLIC_API(bool)
  3968. JS_FileEscapedString(FILE* fp, JSString* str, char quote);
  3969. /*
  3970. * Extracting string characters and length.
  3971. *
  3972. * While getting the length of a string is infallible, getting the chars can
  3973. * fail. As indicated by the lack of a JSContext parameter, there are two
  3974. * special cases where getting the chars is infallible:
  3975. *
  3976. * The first case is for strings that have been atomized, e.g. directly by
  3977. * JS_AtomizeAndPinString or implicitly because it is stored in a jsid.
  3978. *
  3979. * The second case is "flat" strings that have been explicitly prepared in a
  3980. * fallible context by JS_FlattenString. To catch errors, a separate opaque
  3981. * JSFlatString type is returned by JS_FlattenString and expected by
  3982. * JS_GetFlatStringChars. Note, though, that this is purely a syntactic
  3983. * distinction: the input and output of JS_FlattenString are the same actual
  3984. * GC-thing. If a JSString is known to be flat, JS_ASSERT_STRING_IS_FLAT can be
  3985. * used to make a debug-checked cast. Example:
  3986. *
  3987. * // in a fallible context
  3988. * JSFlatString* fstr = JS_FlattenString(cx, str);
  3989. * if (!fstr)
  3990. * return false;
  3991. * MOZ_ASSERT(fstr == JS_ASSERT_STRING_IS_FLAT(str));
  3992. *
  3993. * // in an infallible context, for the same 'str'
  3994. * AutoCheckCannotGC nogc;
  3995. * const char16_t* chars = JS_GetTwoByteFlatStringChars(nogc, fstr)
  3996. * MOZ_ASSERT(chars);
  3997. *
  3998. * Flat strings and interned strings are always null-terminated, so
  3999. * JS_FlattenString can be used to get a null-terminated string.
  4000. *
  4001. * Additionally, string characters are stored as either Latin1Char (8-bit)
  4002. * or char16_t (16-bit). Clients can use JS_StringHasLatin1Chars and can then
  4003. * call either the Latin1* or TwoByte* functions. Some functions like
  4004. * JS_CopyStringChars and JS_GetStringCharAt accept both Latin1 and TwoByte
  4005. * strings.
  4006. */
  4007. extern JS_PUBLIC_API(size_t)
  4008. JS_GetStringLength(JSString* str);
  4009. extern JS_PUBLIC_API(bool)
  4010. JS_StringIsFlat(JSString* str);
  4011. /** Returns true iff the string's characters are stored as Latin1. */
  4012. extern JS_PUBLIC_API(bool)
  4013. JS_StringHasLatin1Chars(JSString* str);
  4014. extern JS_PUBLIC_API(const JS::Latin1Char*)
  4015. JS_GetLatin1StringCharsAndLength(JSContext* cx, const JS::AutoCheckCannotGC& nogc, JSString* str,
  4016. size_t* length);
  4017. extern JS_PUBLIC_API(const char16_t*)
  4018. JS_GetTwoByteStringCharsAndLength(JSContext* cx, const JS::AutoCheckCannotGC& nogc, JSString* str,
  4019. size_t* length);
  4020. extern JS_PUBLIC_API(bool)
  4021. JS_GetStringCharAt(JSContext* cx, JSString* str, size_t index, char16_t* res);
  4022. extern JS_PUBLIC_API(char16_t)
  4023. JS_GetFlatStringCharAt(JSFlatString* str, size_t index);
  4024. extern JS_PUBLIC_API(const char16_t*)
  4025. JS_GetTwoByteExternalStringChars(JSString* str);
  4026. extern JS_PUBLIC_API(bool)
  4027. JS_CopyStringChars(JSContext* cx, mozilla::Range<char16_t> dest, JSString* str);
  4028. extern JS_PUBLIC_API(JSFlatString*)
  4029. JS_FlattenString(JSContext* cx, JSString* str);
  4030. extern JS_PUBLIC_API(const JS::Latin1Char*)
  4031. JS_GetLatin1FlatStringChars(const JS::AutoCheckCannotGC& nogc, JSFlatString* str);
  4032. extern JS_PUBLIC_API(const char16_t*)
  4033. JS_GetTwoByteFlatStringChars(const JS::AutoCheckCannotGC& nogc, JSFlatString* str);
  4034. static MOZ_ALWAYS_INLINE JSFlatString*
  4035. JSID_TO_FLAT_STRING(jsid id)
  4036. {
  4037. MOZ_ASSERT(JSID_IS_STRING(id));
  4038. return (JSFlatString*)(JSID_BITS(id));
  4039. }
  4040. static MOZ_ALWAYS_INLINE JSFlatString*
  4041. JS_ASSERT_STRING_IS_FLAT(JSString* str)
  4042. {
  4043. MOZ_ASSERT(JS_StringIsFlat(str));
  4044. return (JSFlatString*)str;
  4045. }
  4046. static MOZ_ALWAYS_INLINE JSString*
  4047. JS_FORGET_STRING_FLATNESS(JSFlatString* fstr)
  4048. {
  4049. return (JSString*)fstr;
  4050. }
  4051. /*
  4052. * Additional APIs that avoid fallibility when given a flat string.
  4053. */
  4054. extern JS_PUBLIC_API(bool)
  4055. JS_FlatStringEqualsAscii(JSFlatString* str, const char* asciiBytes);
  4056. extern JS_PUBLIC_API(size_t)
  4057. JS_PutEscapedFlatString(char* buffer, size_t size, JSFlatString* str, char quote);
  4058. /**
  4059. * Create a dependent string, i.e., a string that owns no character storage,
  4060. * but that refers to a slice of another string's chars. Dependent strings
  4061. * are mutable by definition, so the thread safety comments above apply.
  4062. */
  4063. extern JS_PUBLIC_API(JSString*)
  4064. JS_NewDependentString(JSContext* cx, JS::HandleString str, size_t start,
  4065. size_t length);
  4066. /**
  4067. * Concatenate two strings, possibly resulting in a rope.
  4068. * See above for thread safety comments.
  4069. */
  4070. extern JS_PUBLIC_API(JSString*)
  4071. JS_ConcatStrings(JSContext* cx, JS::HandleString left, JS::HandleString right);
  4072. /**
  4073. * For JS_DecodeBytes, set *dstlenp to the size of the destination buffer before
  4074. * the call; on return, *dstlenp contains the number of characters actually
  4075. * stored. To determine the necessary destination buffer size, make a sizing
  4076. * call that passes nullptr for dst.
  4077. *
  4078. * On errors, the functions report the error. In that case, *dstlenp contains
  4079. * the number of characters or bytes transferred so far. If cx is nullptr, no
  4080. * error is reported on failure, and the functions simply return false.
  4081. *
  4082. * NB: This function does not store an additional zero byte or char16_t after the
  4083. * transcoded string.
  4084. */
  4085. JS_PUBLIC_API(bool)
  4086. JS_DecodeBytes(JSContext* cx, const char* src, size_t srclen, char16_t* dst,
  4087. size_t* dstlenp);
  4088. /**
  4089. * A variation on JS_EncodeCharacters where a null terminated string is
  4090. * returned that you are expected to call JS_free on when done.
  4091. */
  4092. JS_PUBLIC_API(char*)
  4093. JS_EncodeString(JSContext* cx, JSString* str);
  4094. /**
  4095. * Same behavior as JS_EncodeString(), but encode into UTF-8 string
  4096. */
  4097. JS_PUBLIC_API(char*)
  4098. JS_EncodeStringToUTF8(JSContext* cx, JS::HandleString str);
  4099. /**
  4100. * Get number of bytes in the string encoding (without accounting for a
  4101. * terminating zero bytes. The function returns (size_t) -1 if the string
  4102. * can not be encoded into bytes and reports an error using cx accordingly.
  4103. */
  4104. JS_PUBLIC_API(size_t)
  4105. JS_GetStringEncodingLength(JSContext* cx, JSString* str);
  4106. /**
  4107. * Encode string into a buffer. The function does not stores an additional
  4108. * zero byte. The function returns (size_t) -1 if the string can not be
  4109. * encoded into bytes with no error reported. Otherwise it returns the number
  4110. * of bytes that are necessary to encode the string. If that exceeds the
  4111. * length parameter, the string will be cut and only length bytes will be
  4112. * written into the buffer.
  4113. */
  4114. JS_PUBLIC_API(size_t)
  4115. JS_EncodeStringToBuffer(JSContext* cx, JSString* str, char* buffer, size_t length);
  4116. class MOZ_RAII JSAutoByteString
  4117. {
  4118. public:
  4119. JSAutoByteString(JSContext* cx, JSString* str
  4120. MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
  4121. : mBytes(JS_EncodeString(cx, str))
  4122. {
  4123. MOZ_ASSERT(cx);
  4124. MOZ_GUARD_OBJECT_NOTIFIER_INIT;
  4125. }
  4126. explicit JSAutoByteString(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
  4127. : mBytes(nullptr)
  4128. {
  4129. MOZ_GUARD_OBJECT_NOTIFIER_INIT;
  4130. }
  4131. ~JSAutoByteString() {
  4132. JS_free(nullptr, mBytes);
  4133. }
  4134. /* Take ownership of the given byte array. */
  4135. void initBytes(char* bytes) {
  4136. MOZ_ASSERT(!mBytes);
  4137. mBytes = bytes;
  4138. }
  4139. char* encodeLatin1(JSContext* cx, JSString* str) {
  4140. MOZ_ASSERT(!mBytes);
  4141. MOZ_ASSERT(cx);
  4142. mBytes = JS_EncodeString(cx, str);
  4143. return mBytes;
  4144. }
  4145. char* encodeLatin1(js::ExclusiveContext* cx, JSString* str);
  4146. char* encodeUtf8(JSContext* cx, JS::HandleString str) {
  4147. MOZ_ASSERT(!mBytes);
  4148. MOZ_ASSERT(cx);
  4149. mBytes = JS_EncodeStringToUTF8(cx, str);
  4150. return mBytes;
  4151. }
  4152. void clear() {
  4153. js_free(mBytes);
  4154. mBytes = nullptr;
  4155. }
  4156. char* ptr() const {
  4157. return mBytes;
  4158. }
  4159. bool operator!() const {
  4160. return !mBytes;
  4161. }
  4162. size_t length() const {
  4163. if (!mBytes)
  4164. return 0;
  4165. return strlen(mBytes);
  4166. }
  4167. private:
  4168. char* mBytes;
  4169. MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
  4170. /* Copy and assignment are not supported. */
  4171. JSAutoByteString(const JSAutoByteString& another);
  4172. JSAutoByteString& operator=(const JSAutoByteString& another);
  4173. };
  4174. namespace JS {
  4175. extern JS_PUBLIC_API(JSAddonId*)
  4176. NewAddonId(JSContext* cx, JS::HandleString str);
  4177. extern JS_PUBLIC_API(JSString*)
  4178. StringOfAddonId(JSAddonId* id);
  4179. extern JS_PUBLIC_API(JSAddonId*)
  4180. AddonIdOfObject(JSObject* obj);
  4181. } // namespace JS
  4182. /************************************************************************/
  4183. /*
  4184. * Symbols
  4185. */
  4186. namespace JS {
  4187. /**
  4188. * Create a new Symbol with the given description. This function never returns
  4189. * a Symbol that is in the Runtime-wide symbol registry.
  4190. *
  4191. * If description is null, the new Symbol's [[Description]] attribute is
  4192. * undefined.
  4193. */
  4194. JS_PUBLIC_API(Symbol*)
  4195. NewSymbol(JSContext* cx, HandleString description);
  4196. /**
  4197. * Symbol.for as specified in ES6.
  4198. *
  4199. * Get a Symbol with the description 'key' from the Runtime-wide symbol registry.
  4200. * If there is not already a Symbol with that description in the registry, a new
  4201. * Symbol is created and registered. 'key' must not be null.
  4202. */
  4203. JS_PUBLIC_API(Symbol*)
  4204. GetSymbolFor(JSContext* cx, HandleString key);
  4205. /**
  4206. * Get the [[Description]] attribute of the given symbol.
  4207. *
  4208. * This function is infallible. If it returns null, that means the symbol's
  4209. * [[Description]] is undefined.
  4210. */
  4211. JS_PUBLIC_API(JSString*)
  4212. GetSymbolDescription(HandleSymbol symbol);
  4213. /* Well-known symbols. */
  4214. #define JS_FOR_EACH_WELL_KNOWN_SYMBOL(macro) \
  4215. macro(isConcatSpreadable) \
  4216. macro(iterator) \
  4217. macro(match) \
  4218. macro(replace) \
  4219. macro(search) \
  4220. macro(species) \
  4221. macro(hasInstance) \
  4222. macro(split) \
  4223. macro(toPrimitive) \
  4224. macro(toStringTag) \
  4225. macro(unscopables)
  4226. enum class SymbolCode : uint32_t {
  4227. // There is one SymbolCode for each well-known symbol.
  4228. #define JS_DEFINE_SYMBOL_ENUM(name) name,
  4229. JS_FOR_EACH_WELL_KNOWN_SYMBOL(JS_DEFINE_SYMBOL_ENUM) // SymbolCode::iterator, etc.
  4230. #undef JS_DEFINE_SYMBOL_ENUM
  4231. Limit,
  4232. InSymbolRegistry = 0xfffffffe, // created by Symbol.for() or JS::GetSymbolFor()
  4233. UniqueSymbol = 0xffffffff // created by Symbol() or JS::NewSymbol()
  4234. };
  4235. /* For use in loops that iterate over the well-known symbols. */
  4236. const size_t WellKnownSymbolLimit = size_t(SymbolCode::Limit);
  4237. /**
  4238. * Return the SymbolCode telling what sort of symbol `symbol` is.
  4239. *
  4240. * A symbol's SymbolCode never changes once it is created.
  4241. */
  4242. JS_PUBLIC_API(SymbolCode)
  4243. GetSymbolCode(Handle<Symbol*> symbol);
  4244. /**
  4245. * Get one of the well-known symbols defined by ES6. A single set of well-known
  4246. * symbols is shared by all compartments in a JSRuntime.
  4247. *
  4248. * `which` must be in the range [0, WellKnownSymbolLimit).
  4249. */
  4250. JS_PUBLIC_API(Symbol*)
  4251. GetWellKnownSymbol(JSContext* cx, SymbolCode which);
  4252. /**
  4253. * Return true if the given JSPropertySpec::name or JSFunctionSpec::name value
  4254. * is actually a symbol code and not a string. See JS_SYM_FN.
  4255. */
  4256. inline bool
  4257. PropertySpecNameIsSymbol(const char* name)
  4258. {
  4259. uintptr_t u = reinterpret_cast<uintptr_t>(name);
  4260. return u != 0 && u - 1 < WellKnownSymbolLimit;
  4261. }
  4262. JS_PUBLIC_API(bool)
  4263. PropertySpecNameEqualsId(const char* name, HandleId id);
  4264. /**
  4265. * Create a jsid that does not need to be marked for GC.
  4266. *
  4267. * 'name' is a JSPropertySpec::name or JSFunctionSpec::name value. The
  4268. * resulting jsid, on success, is either an interned string or a well-known
  4269. * symbol; either way it is immune to GC so there is no need to visit *idp
  4270. * during GC marking.
  4271. */
  4272. JS_PUBLIC_API(bool)
  4273. PropertySpecNameToPermanentId(JSContext* cx, const char* name, jsid* idp);
  4274. } /* namespace JS */
  4275. /************************************************************************/
  4276. /*
  4277. * JSON functions
  4278. */
  4279. typedef bool (* JSONWriteCallback)(const char16_t* buf, uint32_t len, void* data);
  4280. /**
  4281. * JSON.stringify as specified by ES5.
  4282. */
  4283. JS_PUBLIC_API(bool)
  4284. JS_Stringify(JSContext* cx, JS::MutableHandleValue value, JS::HandleObject replacer,
  4285. JS::HandleValue space, JSONWriteCallback callback, void* data);
  4286. namespace JS {
  4287. /**
  4288. * An API akin to JS_Stringify but with the goal of not having observable
  4289. * side-effects when the stringification is performed. This means it does not
  4290. * allow a replacer or a custom space, and has the following constraints on its
  4291. * input:
  4292. *
  4293. * 1) The input must be a plain object or array, not an abitrary value.
  4294. * 2) Every value in the graph reached by the algorithm starting with this
  4295. * object must be one of the following: null, undefined, a string (NOT a
  4296. * string object!), a boolean, a finite number (i.e. no NaN or Infinity or
  4297. * -Infinity), a plain object with no accessor properties, or an Array with
  4298. * no holes.
  4299. *
  4300. * The actual behavior differs from JS_Stringify only in asserting the above and
  4301. * NOT attempting to get the "toJSON" property from things, since that could
  4302. * clearly have side-effects.
  4303. */
  4304. JS_PUBLIC_API(bool)
  4305. ToJSONMaybeSafely(JSContext* cx, JS::HandleObject input,
  4306. JSONWriteCallback callback, void* data);
  4307. } /* namespace JS */
  4308. /**
  4309. * JSON.parse as specified by ES5.
  4310. */
  4311. JS_PUBLIC_API(bool)
  4312. JS_ParseJSON(JSContext* cx, const char16_t* chars, uint32_t len, JS::MutableHandleValue vp);
  4313. JS_PUBLIC_API(bool)
  4314. JS_ParseJSON(JSContext* cx, JS::HandleString str, JS::MutableHandleValue vp);
  4315. JS_PUBLIC_API(bool)
  4316. JS_ParseJSONWithReviver(JSContext* cx, const char16_t* chars, uint32_t len, JS::HandleValue reviver,
  4317. JS::MutableHandleValue vp);
  4318. JS_PUBLIC_API(bool)
  4319. JS_ParseJSONWithReviver(JSContext* cx, JS::HandleString str, JS::HandleValue reviver,
  4320. JS::MutableHandleValue vp);
  4321. /************************************************************************/
  4322. /**
  4323. * The default locale for the ECMAScript Internationalization API
  4324. * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat).
  4325. * Note that the Internationalization API encourages clients to
  4326. * specify their own locales.
  4327. * The locale string remains owned by the caller.
  4328. */
  4329. extern JS_PUBLIC_API(bool)
  4330. JS_SetDefaultLocale(JSContext* cx, const char* locale);
  4331. /**
  4332. * Look up the default locale for the ECMAScript Internationalization API.
  4333. */
  4334. extern JS_PUBLIC_API(JS::UniqueChars)
  4335. JS_GetDefaultLocale(JSContext* cx);
  4336. /**
  4337. * Reset the default locale to OS defaults.
  4338. */
  4339. extern JS_PUBLIC_API(void)
  4340. JS_ResetDefaultLocale(JSContext* cx);
  4341. /**
  4342. * Locale specific string conversion and error message callbacks.
  4343. */
  4344. struct JSLocaleCallbacks {
  4345. JSLocaleToUpperCase localeToUpperCase;
  4346. JSLocaleToLowerCase localeToLowerCase;
  4347. JSLocaleCompare localeCompare; // not used #if EXPOSE_INTL_API
  4348. JSLocaleToUnicode localeToUnicode;
  4349. };
  4350. /**
  4351. * Establish locale callbacks. The pointer must persist as long as the
  4352. * JSContext. Passing nullptr restores the default behaviour.
  4353. */
  4354. extern JS_PUBLIC_API(void)
  4355. JS_SetLocaleCallbacks(JSContext* cx, const JSLocaleCallbacks* callbacks);
  4356. /**
  4357. * Return the address of the current locale callbacks struct, which may
  4358. * be nullptr.
  4359. */
  4360. extern JS_PUBLIC_API(const JSLocaleCallbacks*)
  4361. JS_GetLocaleCallbacks(JSContext* cx);
  4362. /************************************************************************/
  4363. /*
  4364. * Error reporting.
  4365. */
  4366. namespace JS {
  4367. const uint16_t MaxNumErrorArguments = 10;
  4368. };
  4369. /**
  4370. * Report an exception represented by the sprintf-like conversion of format
  4371. * and its arguments.
  4372. */
  4373. extern JS_PUBLIC_API(void)
  4374. JS_ReportErrorASCII(JSContext* cx, const char* format, ...)
  4375. MOZ_FORMAT_PRINTF(2, 3);
  4376. extern JS_PUBLIC_API(void)
  4377. JS_ReportErrorLatin1(JSContext* cx, const char* format, ...)
  4378. MOZ_FORMAT_PRINTF(2, 3);
  4379. extern JS_PUBLIC_API(void)
  4380. JS_ReportErrorUTF8(JSContext* cx, const char* format, ...)
  4381. MOZ_FORMAT_PRINTF(2, 3);
  4382. /*
  4383. * Use an errorNumber to retrieve the format string, args are char*
  4384. */
  4385. extern JS_PUBLIC_API(void)
  4386. JS_ReportErrorNumberASCII(JSContext* cx, JSErrorCallback errorCallback,
  4387. void* userRef, const unsigned errorNumber, ...);
  4388. extern JS_PUBLIC_API(void)
  4389. JS_ReportErrorNumberASCIIVA(JSContext* cx, JSErrorCallback errorCallback,
  4390. void* userRef, const unsigned errorNumber, va_list ap);
  4391. extern JS_PUBLIC_API(void)
  4392. JS_ReportErrorNumberLatin1(JSContext* cx, JSErrorCallback errorCallback,
  4393. void* userRef, const unsigned errorNumber, ...);
  4394. #ifdef va_start
  4395. extern JS_PUBLIC_API(void)
  4396. JS_ReportErrorNumberLatin1VA(JSContext* cx, JSErrorCallback errorCallback,
  4397. void* userRef, const unsigned errorNumber, va_list ap);
  4398. #endif
  4399. extern JS_PUBLIC_API(void)
  4400. JS_ReportErrorNumberUTF8(JSContext* cx, JSErrorCallback errorCallback,
  4401. void* userRef, const unsigned errorNumber, ...);
  4402. #ifdef va_start
  4403. extern JS_PUBLIC_API(void)
  4404. JS_ReportErrorNumberUTF8VA(JSContext* cx, JSErrorCallback errorCallback,
  4405. void* userRef, const unsigned errorNumber, va_list ap);
  4406. #endif
  4407. /*
  4408. * Use an errorNumber to retrieve the format string, args are char16_t*
  4409. */
  4410. extern JS_PUBLIC_API(void)
  4411. JS_ReportErrorNumberUC(JSContext* cx, JSErrorCallback errorCallback,
  4412. void* userRef, const unsigned errorNumber, ...);
  4413. extern JS_PUBLIC_API(void)
  4414. JS_ReportErrorNumberUCArray(JSContext* cx, JSErrorCallback errorCallback,
  4415. void* userRef, const unsigned errorNumber,
  4416. const char16_t** args);
  4417. /**
  4418. * As above, but report a warning instead (JSREPORT_IS_WARNING(report.flags)).
  4419. * Return true if there was no error trying to issue the warning, and if the
  4420. * warning was not converted into an error due to the JSOPTION_WERROR option
  4421. * being set, false otherwise.
  4422. */
  4423. extern JS_PUBLIC_API(bool)
  4424. JS_ReportWarningASCII(JSContext* cx, const char* format, ...)
  4425. MOZ_FORMAT_PRINTF(2, 3);
  4426. extern JS_PUBLIC_API(bool)
  4427. JS_ReportWarningLatin1(JSContext* cx, const char* format, ...)
  4428. MOZ_FORMAT_PRINTF(2, 3);
  4429. extern JS_PUBLIC_API(bool)
  4430. JS_ReportWarningUTF8(JSContext* cx, const char* format, ...)
  4431. MOZ_FORMAT_PRINTF(2, 3);
  4432. extern JS_PUBLIC_API(bool)
  4433. JS_ReportErrorFlagsAndNumberASCII(JSContext* cx, unsigned flags,
  4434. JSErrorCallback errorCallback, void* userRef,
  4435. const unsigned errorNumber, ...);
  4436. extern JS_PUBLIC_API(bool)
  4437. JS_ReportErrorFlagsAndNumberLatin1(JSContext* cx, unsigned flags,
  4438. JSErrorCallback errorCallback, void* userRef,
  4439. const unsigned errorNumber, ...);
  4440. extern JS_PUBLIC_API(bool)
  4441. JS_ReportErrorFlagsAndNumberUTF8(JSContext* cx, unsigned flags,
  4442. JSErrorCallback errorCallback, void* userRef,
  4443. const unsigned errorNumber, ...);
  4444. extern JS_PUBLIC_API(bool)
  4445. JS_ReportErrorFlagsAndNumberUC(JSContext* cx, unsigned flags,
  4446. JSErrorCallback errorCallback, void* userRef,
  4447. const unsigned errorNumber, ...);
  4448. /**
  4449. * Complain when out of memory.
  4450. */
  4451. extern JS_PUBLIC_API(void)
  4452. JS_ReportOutOfMemory(JSContext* cx);
  4453. /**
  4454. * Complain when an allocation size overflows the maximum supported limit.
  4455. */
  4456. extern JS_PUBLIC_API(void)
  4457. JS_ReportAllocationOverflow(JSContext* cx);
  4458. class JSErrorReport
  4459. {
  4460. // The (default) error message.
  4461. // If ownsMessage_ is true, the it is freed in destructor.
  4462. JS::ConstUTF8CharsZ message_;
  4463. // Offending source line without final '\n'.
  4464. // If ownsLinebuf__ is true, the buffer is freed in destructor.
  4465. const char16_t* linebuf_;
  4466. // Number of chars in linebuf_. Does not include trailing '\0'.
  4467. size_t linebufLength_;
  4468. // The 0-based offset of error token in linebuf_.
  4469. size_t tokenOffset_;
  4470. public:
  4471. JSErrorReport()
  4472. : linebuf_(nullptr), linebufLength_(0), tokenOffset_(0),
  4473. filename(nullptr), lineno(0), column(0),
  4474. flags(0), errorNumber(0),
  4475. exnType(0), isMuted(false),
  4476. ownsLinebuf_(false), ownsMessage_(false)
  4477. {}
  4478. ~JSErrorReport() {
  4479. freeLinebuf();
  4480. freeMessage();
  4481. }
  4482. const char* filename; /* source file name, URL, etc., or null */
  4483. unsigned lineno; /* source line number */
  4484. unsigned column; /* zero-based column index in line */
  4485. unsigned flags; /* error/warning, etc. */
  4486. unsigned errorNumber; /* the error number, e.g. see js.msg */
  4487. int16_t exnType; /* One of the JSExnType constants */
  4488. bool isMuted : 1; /* See the comment in ReadOnlyCompileOptions. */
  4489. private:
  4490. bool ownsLinebuf_ : 1;
  4491. bool ownsMessage_ : 1;
  4492. public:
  4493. const char16_t* linebuf() const {
  4494. return linebuf_;
  4495. }
  4496. size_t linebufLength() const {
  4497. return linebufLength_;
  4498. }
  4499. size_t tokenOffset() const {
  4500. return tokenOffset_;
  4501. }
  4502. void initOwnedLinebuf(const char16_t* linebufArg, size_t linebufLengthArg, size_t tokenOffsetArg) {
  4503. initBorrowedLinebuf(linebufArg, linebufLengthArg, tokenOffsetArg);
  4504. ownsLinebuf_ = true;
  4505. }
  4506. void initBorrowedLinebuf(const char16_t* linebufArg, size_t linebufLengthArg, size_t tokenOffsetArg);
  4507. void freeLinebuf();
  4508. const JS::ConstUTF8CharsZ message() const {
  4509. return message_;
  4510. }
  4511. void initOwnedMessage(const char* messageArg) {
  4512. initBorrowedMessage(messageArg);
  4513. ownsMessage_ = true;
  4514. }
  4515. void initBorrowedMessage(const char* messageArg) {
  4516. MOZ_ASSERT(!message_);
  4517. message_ = JS::ConstUTF8CharsZ(messageArg, strlen(messageArg));
  4518. }
  4519. JSString* newMessageString(JSContext* cx);
  4520. void freeMessage();
  4521. };
  4522. /*
  4523. * JSErrorReport flag values. These may be freely composed.
  4524. */
  4525. #define JSREPORT_ERROR 0x0 /* pseudo-flag for default case */
  4526. #define JSREPORT_WARNING 0x1 /* reported via JS_ReportWarning */
  4527. #define JSREPORT_EXCEPTION 0x2 /* exception was thrown */
  4528. #define JSREPORT_STRICT 0x4 /* error or warning due to strict option */
  4529. #define JSREPORT_USER_1 0x8 /* user-defined flag */
  4530. /*
  4531. * If JSREPORT_EXCEPTION is set, then a JavaScript-catchable exception
  4532. * has been thrown for this runtime error, and the host should ignore it.
  4533. * Exception-aware hosts should also check for JS_IsExceptionPending if
  4534. * JS_ExecuteScript returns failure, and signal or propagate the exception, as
  4535. * appropriate.
  4536. */
  4537. #define JSREPORT_IS_WARNING(flags) (((flags) & JSREPORT_WARNING) != 0)
  4538. #define JSREPORT_IS_EXCEPTION(flags) (((flags) & JSREPORT_EXCEPTION) != 0)
  4539. #define JSREPORT_IS_STRICT(flags) (((flags) & JSREPORT_STRICT) != 0)
  4540. namespace JS {
  4541. using WarningReporter = void (*)(JSContext* cx, JSErrorReport* report);
  4542. extern JS_PUBLIC_API(WarningReporter)
  4543. SetWarningReporter(JSContext* cx, WarningReporter reporter);
  4544. extern JS_PUBLIC_API(WarningReporter)
  4545. GetWarningReporter(JSContext* cx);
  4546. extern JS_PUBLIC_API(bool)
  4547. CreateError(JSContext* cx, JSExnType type, HandleObject stack,
  4548. HandleString fileName, uint32_t lineNumber, uint32_t columnNumber,
  4549. JSErrorReport* report, HandleString message, MutableHandleValue rval);
  4550. /************************************************************************/
  4551. /*
  4552. * Weak Maps.
  4553. */
  4554. extern JS_PUBLIC_API(JSObject*)
  4555. NewWeakMapObject(JSContext* cx);
  4556. extern JS_PUBLIC_API(bool)
  4557. IsWeakMapObject(JSObject* obj);
  4558. extern JS_PUBLIC_API(bool)
  4559. GetWeakMapEntry(JSContext* cx, JS::HandleObject mapObj, JS::HandleObject key,
  4560. JS::MutableHandleValue val);
  4561. extern JS_PUBLIC_API(bool)
  4562. SetWeakMapEntry(JSContext* cx, JS::HandleObject mapObj, JS::HandleObject key,
  4563. JS::HandleValue val);
  4564. /*
  4565. * Map
  4566. */
  4567. extern JS_PUBLIC_API(JSObject*)
  4568. NewMapObject(JSContext* cx);
  4569. extern JS_PUBLIC_API(uint32_t)
  4570. MapSize(JSContext* cx, HandleObject obj);
  4571. extern JS_PUBLIC_API(bool)
  4572. MapGet(JSContext* cx, HandleObject obj,
  4573. HandleValue key, MutableHandleValue rval);
  4574. extern JS_PUBLIC_API(bool)
  4575. MapHas(JSContext* cx, HandleObject obj, HandleValue key, bool* rval);
  4576. extern JS_PUBLIC_API(bool)
  4577. MapSet(JSContext* cx, HandleObject obj, HandleValue key, HandleValue val);
  4578. extern JS_PUBLIC_API(bool)
  4579. MapDelete(JSContext *cx, HandleObject obj, HandleValue key, bool *rval);
  4580. extern JS_PUBLIC_API(bool)
  4581. MapClear(JSContext* cx, HandleObject obj);
  4582. extern JS_PUBLIC_API(bool)
  4583. MapKeys(JSContext* cx, HandleObject obj, MutableHandleValue rval);
  4584. extern JS_PUBLIC_API(bool)
  4585. MapValues(JSContext* cx, HandleObject obj, MutableHandleValue rval);
  4586. extern JS_PUBLIC_API(bool)
  4587. MapEntries(JSContext* cx, HandleObject obj, MutableHandleValue rval);
  4588. extern JS_PUBLIC_API(bool)
  4589. MapForEach(JSContext *cx, HandleObject obj, HandleValue callbackFn, HandleValue thisVal);
  4590. /*
  4591. * Set
  4592. */
  4593. extern JS_PUBLIC_API(JSObject *)
  4594. NewSetObject(JSContext *cx);
  4595. extern JS_PUBLIC_API(uint32_t)
  4596. SetSize(JSContext *cx, HandleObject obj);
  4597. extern JS_PUBLIC_API(bool)
  4598. SetHas(JSContext *cx, HandleObject obj, HandleValue key, bool *rval);
  4599. extern JS_PUBLIC_API(bool)
  4600. SetDelete(JSContext *cx, HandleObject obj, HandleValue key, bool *rval);
  4601. extern JS_PUBLIC_API(bool)
  4602. SetAdd(JSContext *cx, HandleObject obj, HandleValue key);
  4603. extern JS_PUBLIC_API(bool)
  4604. SetClear(JSContext *cx, HandleObject obj);
  4605. extern JS_PUBLIC_API(bool)
  4606. SetKeys(JSContext *cx, HandleObject obj, MutableHandleValue rval);
  4607. extern JS_PUBLIC_API(bool)
  4608. SetValues(JSContext *cx, HandleObject obj, MutableHandleValue rval);
  4609. extern JS_PUBLIC_API(bool)
  4610. SetEntries(JSContext *cx, HandleObject obj, MutableHandleValue rval);
  4611. extern JS_PUBLIC_API(bool)
  4612. SetForEach(JSContext *cx, HandleObject obj, HandleValue callbackFn, HandleValue thisVal);
  4613. } /* namespace JS */
  4614. /*
  4615. * Dates.
  4616. */
  4617. extern JS_PUBLIC_API(JSObject*)
  4618. JS_NewDateObject(JSContext* cx, int year, int mon, int mday, int hour, int min, int sec);
  4619. /**
  4620. * Returns true and sets |*isDate| indicating whether |obj| is a Date object or
  4621. * a wrapper around one, otherwise returns false on failure.
  4622. *
  4623. * This method returns true with |*isDate == false| when passed a proxy whose
  4624. * target is a Date, or when passed a revoked proxy.
  4625. */
  4626. extern JS_PUBLIC_API(bool)
  4627. JS_ObjectIsDate(JSContext* cx, JS::HandleObject obj, bool* isDate);
  4628. /************************************************************************/
  4629. /*
  4630. * Regular Expressions.
  4631. */
  4632. #define JSREG_FOLD 0x01u /* fold uppercase to lowercase */
  4633. #define JSREG_GLOB 0x02u /* global exec, creates array of matches */
  4634. #define JSREG_MULTILINE 0x04u /* treat ^ and $ as begin and end of line */
  4635. #define JSREG_STICKY 0x08u /* only match starting at lastIndex */
  4636. #define JSREG_UNICODE 0x10u /* unicode */
  4637. extern JS_PUBLIC_API(JSObject*)
  4638. JS_NewRegExpObject(JSContext* cx, const char* bytes, size_t length, unsigned flags);
  4639. extern JS_PUBLIC_API(JSObject*)
  4640. JS_NewUCRegExpObject(JSContext* cx, const char16_t* chars, size_t length, unsigned flags);
  4641. extern JS_PUBLIC_API(bool)
  4642. JS_SetRegExpInput(JSContext* cx, JS::HandleObject obj, JS::HandleString input);
  4643. extern JS_PUBLIC_API(bool)
  4644. JS_ClearRegExpStatics(JSContext* cx, JS::HandleObject obj);
  4645. extern JS_PUBLIC_API(bool)
  4646. JS_ExecuteRegExp(JSContext* cx, JS::HandleObject obj, JS::HandleObject reobj,
  4647. char16_t* chars, size_t length, size_t* indexp, bool test,
  4648. JS::MutableHandleValue rval);
  4649. /* RegExp interface for clients without a global object. */
  4650. extern JS_PUBLIC_API(bool)
  4651. JS_ExecuteRegExpNoStatics(JSContext* cx, JS::HandleObject reobj, char16_t* chars, size_t length,
  4652. size_t* indexp, bool test, JS::MutableHandleValue rval);
  4653. /**
  4654. * Returns true and sets |*isRegExp| indicating whether |obj| is a RegExp
  4655. * object or a wrapper around one, otherwise returns false on failure.
  4656. *
  4657. * This method returns true with |*isRegExp == false| when passed a proxy whose
  4658. * target is a RegExp, or when passed a revoked proxy.
  4659. */
  4660. extern JS_PUBLIC_API(bool)
  4661. JS_ObjectIsRegExp(JSContext* cx, JS::HandleObject obj, bool* isRegExp);
  4662. extern JS_PUBLIC_API(unsigned)
  4663. JS_GetRegExpFlags(JSContext* cx, JS::HandleObject obj);
  4664. extern JS_PUBLIC_API(JSString*)
  4665. JS_GetRegExpSource(JSContext* cx, JS::HandleObject obj);
  4666. /************************************************************************/
  4667. extern JS_PUBLIC_API(bool)
  4668. JS_IsExceptionPending(JSContext* cx);
  4669. extern JS_PUBLIC_API(bool)
  4670. JS_GetPendingException(JSContext* cx, JS::MutableHandleValue vp);
  4671. extern JS_PUBLIC_API(void)
  4672. JS_SetPendingException(JSContext* cx, JS::HandleValue v);
  4673. extern JS_PUBLIC_API(void)
  4674. JS_ClearPendingException(JSContext* cx);
  4675. namespace JS {
  4676. /**
  4677. * Save and later restore the current exception state of a given JSContext.
  4678. * This is useful for implementing behavior in C++ that's like try/catch
  4679. * or try/finally in JS.
  4680. *
  4681. * Typical usage:
  4682. *
  4683. * bool ok = JS::Evaluate(cx, ...);
  4684. * AutoSaveExceptionState savedExc(cx);
  4685. * ... cleanup that might re-enter JS ...
  4686. * return ok;
  4687. */
  4688. class JS_PUBLIC_API(AutoSaveExceptionState)
  4689. {
  4690. private:
  4691. JSContext* context;
  4692. bool wasPropagatingForcedReturn;
  4693. bool wasOverRecursed;
  4694. bool wasThrowing;
  4695. RootedValue exceptionValue;
  4696. public:
  4697. /*
  4698. * Take a snapshot of cx's current exception state. Then clear any current
  4699. * pending exception in cx.
  4700. */
  4701. explicit AutoSaveExceptionState(JSContext* cx);
  4702. /*
  4703. * If neither drop() nor restore() was called, restore the exception
  4704. * state only if no exception is currently pending on cx.
  4705. */
  4706. ~AutoSaveExceptionState();
  4707. /*
  4708. * Discard any stored exception state.
  4709. * If this is called, the destructor is a no-op.
  4710. */
  4711. void drop() {
  4712. wasPropagatingForcedReturn = false;
  4713. wasOverRecursed = false;
  4714. wasThrowing = false;
  4715. exceptionValue.setUndefined();
  4716. }
  4717. /*
  4718. * Replace cx's exception state with the stored exception state. Then
  4719. * discard the stored exception state. If this is called, the
  4720. * destructor is a no-op.
  4721. */
  4722. void restore();
  4723. };
  4724. } /* namespace JS */
  4725. /* Deprecated API. Use AutoSaveExceptionState instead. */
  4726. extern JS_PUBLIC_API(JSExceptionState*)
  4727. JS_SaveExceptionState(JSContext* cx);
  4728. extern JS_PUBLIC_API(void)
  4729. JS_RestoreExceptionState(JSContext* cx, JSExceptionState* state);
  4730. extern JS_PUBLIC_API(void)
  4731. JS_DropExceptionState(JSContext* cx, JSExceptionState* state);
  4732. /**
  4733. * If the given object is an exception object, the exception will have (or be
  4734. * able to lazily create) an error report struct, and this function will return
  4735. * the address of that struct. Otherwise, it returns nullptr. The lifetime
  4736. * of the error report struct that might be returned is the same as the
  4737. * lifetime of the exception object.
  4738. */
  4739. extern JS_PUBLIC_API(JSErrorReport*)
  4740. JS_ErrorFromException(JSContext* cx, JS::HandleObject obj);
  4741. /**
  4742. * If the given object is an exception object (or an unwrappable
  4743. * cross-compartment wrapper for one), return the stack for that exception, if
  4744. * any. Will return null if the given object is not an exception object
  4745. * (including if it's null or a security wrapper that can't be unwrapped) or if
  4746. * the exception has no stack.
  4747. */
  4748. extern JS_PUBLIC_API(JSObject*)
  4749. ExceptionStackOrNull(JS::HandleObject obj);
  4750. /*
  4751. * Throws a StopIteration exception on cx.
  4752. */
  4753. extern JS_PUBLIC_API(bool)
  4754. JS_ThrowStopIteration(JSContext* cx);
  4755. extern JS_PUBLIC_API(bool)
  4756. JS_IsStopIteration(const JS::Value& v);
  4757. /**
  4758. * A JS context always has an "owner thread". The owner thread is set when the
  4759. * context is created (to the current thread) and practically all entry points
  4760. * into the JS engine check that a context (or anything contained in the
  4761. * context: runtime, compartment, object, etc) is only touched by its owner
  4762. * thread. Embeddings may check this invariant outside the JS engine by calling
  4763. * JS_AbortIfWrongThread (which will abort if not on the owner thread, even for
  4764. * non-debug builds).
  4765. */
  4766. extern JS_PUBLIC_API(void)
  4767. JS_AbortIfWrongThread(JSContext* cx);
  4768. /************************************************************************/
  4769. /**
  4770. * A constructor can request that the JS engine create a default new 'this'
  4771. * object of the given class, using the callee to determine parentage and
  4772. * [[Prototype]].
  4773. */
  4774. extern JS_PUBLIC_API(JSObject*)
  4775. JS_NewObjectForConstructor(JSContext* cx, const JSClass* clasp, const JS::CallArgs& args);
  4776. /************************************************************************/
  4777. #ifdef JS_GC_ZEAL
  4778. #define JS_DEFAULT_ZEAL_FREQ 100
  4779. extern JS_PUBLIC_API(void)
  4780. JS_GetGCZealBits(JSContext* cx, uint32_t* zealBits, uint32_t* frequency, uint32_t* nextScheduled);
  4781. extern JS_PUBLIC_API(void)
  4782. JS_SetGCZeal(JSContext* cx, uint8_t zeal, uint32_t frequency);
  4783. extern JS_PUBLIC_API(void)
  4784. JS_ScheduleGC(JSContext* cx, uint32_t count);
  4785. #endif
  4786. extern JS_PUBLIC_API(void)
  4787. JS_SetParallelParsingEnabled(JSContext* cx, bool enabled);
  4788. extern JS_PUBLIC_API(void)
  4789. JS_SetOffthreadIonCompilationEnabled(JSContext* cx, bool enabled);
  4790. #define JIT_COMPILER_OPTIONS(Register) \
  4791. Register(BASELINE_WARMUP_TRIGGER, "baseline.warmup.trigger") \
  4792. Register(ION_WARMUP_TRIGGER, "ion.warmup.trigger") \
  4793. Register(ION_GVN_ENABLE, "ion.gvn.enable") \
  4794. Register(ION_FORCE_IC, "ion.forceinlineCaches") \
  4795. Register(ION_ENABLE, "ion.enable") \
  4796. Register(ION_INTERRUPT_WITHOUT_SIGNAL, "ion.interrupt-without-signals") \
  4797. Register(ION_CHECK_RANGE_ANALYSIS, "ion.check-range-analysis") \
  4798. Register(BASELINE_ENABLE, "baseline.enable") \
  4799. Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable") \
  4800. Register(JUMP_THRESHOLD, "jump-threshold") \
  4801. Register(ASMJS_ATOMICS_ENABLE, "asmjs.atomics.enable") \
  4802. Register(WASM_TEST_MODE, "wasm.test-mode") \
  4803. Register(WASM_FOLD_OFFSETS, "wasm.fold-offsets")
  4804. typedef enum JSJitCompilerOption {
  4805. #define JIT_COMPILER_DECLARE(key, str) \
  4806. JSJITCOMPILER_ ## key,
  4807. JIT_COMPILER_OPTIONS(JIT_COMPILER_DECLARE)
  4808. #undef JIT_COMPILER_DECLARE
  4809. JSJITCOMPILER_NOT_AN_OPTION
  4810. } JSJitCompilerOption;
  4811. extern JS_PUBLIC_API(void)
  4812. JS_SetGlobalJitCompilerOption(JSContext* cx, JSJitCompilerOption opt, uint32_t value);
  4813. extern JS_PUBLIC_API(bool)
  4814. JS_GetGlobalJitCompilerOption(JSContext* cx, JSJitCompilerOption opt, uint32_t* valueOut);
  4815. /**
  4816. * Convert a uint32_t index into a jsid.
  4817. */
  4818. extern JS_PUBLIC_API(bool)
  4819. JS_IndexToId(JSContext* cx, uint32_t index, JS::MutableHandleId);
  4820. /**
  4821. * Convert chars into a jsid.
  4822. *
  4823. * |chars| may not be an index.
  4824. */
  4825. extern JS_PUBLIC_API(bool)
  4826. JS_CharsToId(JSContext* cx, JS::TwoByteChars chars, JS::MutableHandleId);
  4827. /**
  4828. * Test if the given string is a valid ECMAScript identifier
  4829. */
  4830. extern JS_PUBLIC_API(bool)
  4831. JS_IsIdentifier(JSContext* cx, JS::HandleString str, bool* isIdentifier);
  4832. /**
  4833. * Test whether the given chars + length are a valid ECMAScript identifier.
  4834. * This version is infallible, so just returns whether the chars are an
  4835. * identifier.
  4836. */
  4837. extern JS_PUBLIC_API(bool)
  4838. JS_IsIdentifier(const char16_t* chars, size_t length);
  4839. namespace js {
  4840. class ScriptSource;
  4841. } // namespace js
  4842. namespace JS {
  4843. class MOZ_RAII JS_PUBLIC_API(AutoFilename)
  4844. {
  4845. private:
  4846. js::ScriptSource* ss_;
  4847. mozilla::Variant<const char*, UniqueChars> filename_;
  4848. AutoFilename(const AutoFilename&) = delete;
  4849. AutoFilename& operator=(const AutoFilename&) = delete;
  4850. public:
  4851. AutoFilename()
  4852. : ss_(nullptr),
  4853. filename_(mozilla::AsVariant<const char*>(nullptr))
  4854. {}
  4855. ~AutoFilename() {
  4856. reset();
  4857. }
  4858. void reset();
  4859. void setOwned(UniqueChars&& filename);
  4860. void setUnowned(const char* filename);
  4861. void setScriptSource(js::ScriptSource* ss);
  4862. const char* get() const;
  4863. };
  4864. /**
  4865. * Return the current filename, line number and column number of the most
  4866. * currently running frame. Returns true if a scripted frame was found, false
  4867. * otherwise.
  4868. *
  4869. * If a the embedding has hidden the scripted caller for the topmost activation
  4870. * record, this will also return false.
  4871. */
  4872. extern JS_PUBLIC_API(bool)
  4873. DescribeScriptedCaller(JSContext* cx, AutoFilename* filename = nullptr,
  4874. unsigned* lineno = nullptr, unsigned* column = nullptr);
  4875. extern JS_PUBLIC_API(JSObject*)
  4876. GetScriptedCallerGlobal(JSContext* cx);
  4877. /**
  4878. * Informs the JS engine that the scripted caller should be hidden. This can be
  4879. * used by the embedding to maintain an override of the scripted caller in its
  4880. * calculations, by hiding the scripted caller in the JS engine and pushing data
  4881. * onto a separate stack, which it inspects when DescribeScriptedCaller returns
  4882. * null.
  4883. *
  4884. * We maintain a counter on each activation record. Add() increments the counter
  4885. * of the topmost activation, and Remove() decrements it. The count may never
  4886. * drop below zero, and must always be exactly zero when the activation is
  4887. * popped from the stack.
  4888. */
  4889. extern JS_PUBLIC_API(void)
  4890. HideScriptedCaller(JSContext* cx);
  4891. extern JS_PUBLIC_API(void)
  4892. UnhideScriptedCaller(JSContext* cx);
  4893. class MOZ_RAII AutoHideScriptedCaller
  4894. {
  4895. public:
  4896. explicit AutoHideScriptedCaller(JSContext* cx
  4897. MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
  4898. : mContext(cx)
  4899. {
  4900. MOZ_GUARD_OBJECT_NOTIFIER_INIT;
  4901. HideScriptedCaller(mContext);
  4902. }
  4903. ~AutoHideScriptedCaller() {
  4904. UnhideScriptedCaller(mContext);
  4905. }
  4906. protected:
  4907. JSContext* mContext;
  4908. MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
  4909. };
  4910. /*
  4911. * Encode/Decode interpreted scripts and functions to/from memory.
  4912. */
  4913. typedef mozilla::Vector<uint8_t> TranscodeBuffer;
  4914. enum TranscodeResult
  4915. {
  4916. // Successful encoding / decoding.
  4917. TranscodeResult_Ok = 0,
  4918. // A warning message, is set to the message out-param.
  4919. TranscodeResult_Failure = 0x100,
  4920. TranscodeResult_Failure_BadBuildId = TranscodeResult_Failure | 0x1,
  4921. TranscodeResult_Failure_RunOnceNotSupported = TranscodeResult_Failure | 0x2,
  4922. TranscodeResult_Failure_AsmJSNotSupported = TranscodeResult_Failure | 0x3,
  4923. TranscodeResult_Failure_UnknownClassKind = TranscodeResult_Failure | 0x4,
  4924. // A error, the JSContext has a pending exception.
  4925. TranscodeResult_Throw = 0x200
  4926. };
  4927. extern JS_PUBLIC_API(TranscodeResult)
  4928. EncodeScript(JSContext* cx, TranscodeBuffer& buffer, JS::HandleScript script);
  4929. extern JS_PUBLIC_API(TranscodeResult)
  4930. EncodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer, JS::HandleObject funobj);
  4931. extern JS_PUBLIC_API(TranscodeResult)
  4932. DecodeScript(JSContext* cx, TranscodeBuffer& buffer, JS::MutableHandleScript scriptp,
  4933. size_t cursorIndex = 0);
  4934. extern JS_PUBLIC_API(TranscodeResult)
  4935. DecodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer, JS::MutableHandleFunction funp,
  4936. size_t cursorIndex = 0);
  4937. } /* namespace JS */
  4938. namespace js {
  4939. enum class StackFormat { SpiderMonkey, V8, Default };
  4940. /*
  4941. * Sets the format used for stringifying Error stacks.
  4942. *
  4943. * The default format is StackFormat::SpiderMonkey. Use StackFormat::V8
  4944. * in order to emulate V8's stack formatting. StackFormat::Default can't be
  4945. * used here.
  4946. */
  4947. extern JS_PUBLIC_API(void)
  4948. SetStackFormat(JSContext* cx, StackFormat format);
  4949. extern JS_PUBLIC_API(StackFormat)
  4950. GetStackFormat(JSContext* cx);
  4951. }
  4952. namespace JS {
  4953. /*
  4954. * This callback represents a request by the JS engine to open for reading the
  4955. * existing cache entry for the given global and char range that may contain a
  4956. * module. If a cache entry exists, the callback shall return 'true' and return
  4957. * the size, base address and an opaque file handle as outparams. If the
  4958. * callback returns 'true', the JS engine guarantees a call to
  4959. * CloseAsmJSCacheEntryForReadOp, passing the same base address, size and
  4960. * handle.
  4961. */
  4962. typedef bool
  4963. (* OpenAsmJSCacheEntryForReadOp)(HandleObject global, const char16_t* begin, const char16_t* limit,
  4964. size_t* size, const uint8_t** memory, intptr_t* handle);
  4965. typedef void
  4966. (* CloseAsmJSCacheEntryForReadOp)(size_t size, const uint8_t* memory, intptr_t handle);
  4967. /** The list of reasons why an asm.js module may not be stored in the cache. */
  4968. enum AsmJSCacheResult
  4969. {
  4970. AsmJSCache_Success,
  4971. AsmJSCache_MIN = AsmJSCache_Success,
  4972. AsmJSCache_ModuleTooSmall,
  4973. AsmJSCache_SynchronousScript,
  4974. AsmJSCache_QuotaExceeded,
  4975. AsmJSCache_StorageInitFailure,
  4976. AsmJSCache_Disabled_Internal,
  4977. AsmJSCache_Disabled_ShellFlags,
  4978. AsmJSCache_Disabled_JitInspector,
  4979. AsmJSCache_InternalError,
  4980. AsmJSCache_Disabled_PrivateBrowsing,
  4981. AsmJSCache_LIMIT
  4982. };
  4983. /*
  4984. * This callback represents a request by the JS engine to open for writing a
  4985. * cache entry of the given size for the given global and char range containing
  4986. * the just-compiled module. If cache entry space is available, the callback
  4987. * shall return 'true' and return the base address and an opaque file handle as
  4988. * outparams. If the callback returns 'true', the JS engine guarantees a call
  4989. * to CloseAsmJSCacheEntryForWriteOp passing the same base address, size and
  4990. * handle.
  4991. *
  4992. * If 'installed' is true, then the cache entry is associated with a permanently
  4993. * installed JS file (e.g., in a packaged webapp). This information allows the
  4994. * embedding to store the cache entry in a installed location associated with
  4995. * the principal of 'global' where it will not be evicted until the associated
  4996. * installed JS file is removed.
  4997. */
  4998. typedef AsmJSCacheResult
  4999. (* OpenAsmJSCacheEntryForWriteOp)(HandleObject global, bool installed,
  5000. const char16_t* begin, const char16_t* end,
  5001. size_t size, uint8_t** memory, intptr_t* handle);
  5002. typedef void
  5003. (* CloseAsmJSCacheEntryForWriteOp)(size_t size, uint8_t* memory, intptr_t handle);
  5004. struct AsmJSCacheOps
  5005. {
  5006. OpenAsmJSCacheEntryForReadOp openEntryForRead;
  5007. CloseAsmJSCacheEntryForReadOp closeEntryForRead;
  5008. OpenAsmJSCacheEntryForWriteOp openEntryForWrite;
  5009. CloseAsmJSCacheEntryForWriteOp closeEntryForWrite;
  5010. };
  5011. extern JS_PUBLIC_API(void)
  5012. SetAsmJSCacheOps(JSContext* cx, const AsmJSCacheOps* callbacks);
  5013. /**
  5014. * Return the buildId (represented as a sequence of characters) associated with
  5015. * the currently-executing build. If the JS engine is embedded such that a
  5016. * single cache entry can be observed by different compiled versions of the JS
  5017. * engine, it is critical that the buildId shall change for each new build of
  5018. * the JS engine.
  5019. */
  5020. typedef js::Vector<char, 0, js::SystemAllocPolicy> BuildIdCharVector;
  5021. typedef bool
  5022. (* BuildIdOp)(BuildIdCharVector* buildId);
  5023. extern JS_PUBLIC_API(void)
  5024. SetBuildIdOp(JSContext* cx, BuildIdOp buildIdOp);
  5025. /**
  5026. * The WasmModule interface allows the embedding to hold a reference to the
  5027. * underying C++ implementation of a JS WebAssembly.Module object for purposes
  5028. * of (de)serialization off the object's JSRuntime's thread.
  5029. *
  5030. * - Serialization starts when WebAssembly.Module is passed to the
  5031. * structured-clone algorithm. JS::GetWasmModule is called on the JSRuntime
  5032. * thread that initiated the structured clone to get the JS::WasmModule.
  5033. * This interface is then taken to a background thread where serializedSize()
  5034. * and serialize() are called to write the object to two files: a bytecode file
  5035. * that always allows successful deserialization and a compiled-code file keyed
  5036. * on cpu- and build-id that may become invalid if either of these change between
  5037. * serialization and deserialization. After serialization, the reference is
  5038. * dropped from the background thread.
  5039. *
  5040. * - Deserialization starts when the structured clone algorithm encounters a
  5041. * serialized WebAssembly.Module. On a background thread, the compiled-code file
  5042. * is opened and CompiledWasmModuleAssumptionsMatch is called to see if it is
  5043. * still valid (as described above). DeserializeWasmModule is then called to
  5044. * construct a JS::WasmModule (also on the background thread), passing the
  5045. * bytecode file descriptor and, if valid, the compiled-code file descriptor.
  5046. * The JS::WasmObject is then transported to the JSRuntime thread (which
  5047. * originated the request) and the wrapping WebAssembly.Module object is created
  5048. * by calling createObject().
  5049. */
  5050. struct WasmModule : mozilla::external::AtomicRefCounted<WasmModule>
  5051. {
  5052. MOZ_DECLARE_REFCOUNTED_TYPENAME(WasmModule)
  5053. virtual ~WasmModule() {}
  5054. virtual void serializedSize(size_t* maybeBytecodeSize, size_t* maybeCompiledSize) const = 0;
  5055. virtual void serialize(uint8_t* maybeBytecodeBegin, size_t maybeBytecodeSize,
  5056. uint8_t* maybeCompiledBegin, size_t maybeCompiledSize) const = 0;
  5057. virtual JSObject* createObject(JSContext* cx) = 0;
  5058. };
  5059. extern JS_PUBLIC_API(bool)
  5060. IsWasmModuleObject(HandleObject obj);
  5061. extern JS_PUBLIC_API(RefPtr<WasmModule>)
  5062. GetWasmModule(HandleObject obj);
  5063. extern JS_PUBLIC_API(bool)
  5064. CompiledWasmModuleAssumptionsMatch(PRFileDesc* compiled, BuildIdCharVector&& buildId);
  5065. extern JS_PUBLIC_API(RefPtr<WasmModule>)
  5066. DeserializeWasmModule(PRFileDesc* bytecode, PRFileDesc* maybeCompiled, BuildIdCharVector&& buildId,
  5067. JS::UniqueChars filename, unsigned line, unsigned column);
  5068. /**
  5069. * Convenience class for imitating a JS level for-of loop. Typical usage:
  5070. *
  5071. * ForOfIterator it(cx);
  5072. * if (!it.init(iterable))
  5073. * return false;
  5074. * RootedValue val(cx);
  5075. * while (true) {
  5076. * bool done;
  5077. * if (!it.next(&val, &done))
  5078. * return false;
  5079. * if (done)
  5080. * break;
  5081. * if (!DoStuff(cx, val))
  5082. * return false;
  5083. * }
  5084. */
  5085. class MOZ_STACK_CLASS JS_PUBLIC_API(ForOfIterator) {
  5086. protected:
  5087. JSContext* cx_;
  5088. /*
  5089. * Use the ForOfPIC on the global object (see vm/GlobalObject.h) to try
  5090. * to optimize iteration across arrays.
  5091. *
  5092. * Case 1: Regular Iteration
  5093. * iterator - pointer to the iterator object.
  5094. * index - fixed to NOT_ARRAY (== UINT32_MAX)
  5095. *
  5096. * Case 2: Optimized Array Iteration
  5097. * iterator - pointer to the array object.
  5098. * index - current position in array.
  5099. *
  5100. * The cases are distinguished by whether or not |index| is equal to NOT_ARRAY.
  5101. */
  5102. JS::RootedObject iterator;
  5103. uint32_t index;
  5104. static const uint32_t NOT_ARRAY = UINT32_MAX;
  5105. ForOfIterator(const ForOfIterator&) = delete;
  5106. ForOfIterator& operator=(const ForOfIterator&) = delete;
  5107. public:
  5108. explicit ForOfIterator(JSContext* cx) : cx_(cx), iterator(cx_), index(NOT_ARRAY) { }
  5109. enum NonIterableBehavior {
  5110. ThrowOnNonIterable,
  5111. AllowNonIterable
  5112. };
  5113. /**
  5114. * Initialize the iterator. If AllowNonIterable is passed then if getting
  5115. * the @@iterator property from iterable returns undefined init() will just
  5116. * return true instead of throwing. Callers must then check
  5117. * valueIsIterable() before continuing with the iteration.
  5118. */
  5119. bool init(JS::HandleValue iterable,
  5120. NonIterableBehavior nonIterableBehavior = ThrowOnNonIterable);
  5121. /**
  5122. * Get the next value from the iterator. If false *done is true
  5123. * after this call, do not examine val.
  5124. */
  5125. bool next(JS::MutableHandleValue val, bool* done);
  5126. /**
  5127. * If initialized with throwOnNonCallable = false, check whether
  5128. * the value is iterable.
  5129. */
  5130. bool valueIsIterable() const {
  5131. return iterator;
  5132. }
  5133. private:
  5134. inline bool nextFromOptimizedArray(MutableHandleValue val, bool* done);
  5135. bool materializeArrayIterator();
  5136. };
  5137. /**
  5138. * If a large allocation fails when calling pod_{calloc,realloc}CanGC, the JS
  5139. * engine may call the large-allocation- failure callback, if set, to allow the
  5140. * embedding to flush caches, possibly perform shrinking GCs, etc. to make some
  5141. * room. The allocation will then be retried (and may still fail.)
  5142. */
  5143. typedef void
  5144. (* LargeAllocationFailureCallback)(void* data);
  5145. extern JS_PUBLIC_API(void)
  5146. SetLargeAllocationFailureCallback(JSContext* cx, LargeAllocationFailureCallback afc, void* data);
  5147. /**
  5148. * Unlike the error reporter, which is only called if the exception for an OOM
  5149. * bubbles up and is not caught, the OutOfMemoryCallback is called immediately
  5150. * at the OOM site to allow the embedding to capture the current state of heap
  5151. * allocation before anything is freed. If the large-allocation-failure callback
  5152. * is called at all (not all allocation sites call the large-allocation-failure
  5153. * callback on failure), it is called before the out-of-memory callback; the
  5154. * out-of-memory callback is only called if the allocation still fails after the
  5155. * large-allocation-failure callback has returned.
  5156. */
  5157. typedef void
  5158. (* OutOfMemoryCallback)(JSContext* cx, void* data);
  5159. extern JS_PUBLIC_API(void)
  5160. SetOutOfMemoryCallback(JSContext* cx, OutOfMemoryCallback cb, void* data);
  5161. /**
  5162. * Capture all frames.
  5163. */
  5164. struct AllFrames { };
  5165. /**
  5166. * Capture at most this many frames.
  5167. */
  5168. struct MaxFrames
  5169. {
  5170. uint32_t maxFrames;
  5171. explicit MaxFrames(uint32_t max)
  5172. : maxFrames(max)
  5173. {
  5174. MOZ_ASSERT(max > 0);
  5175. }
  5176. };
  5177. /**
  5178. * Capture the first frame with the given principals. By default, do not
  5179. * consider self-hosted frames with the given principals as satisfying the stack
  5180. * capture.
  5181. */
  5182. struct FirstSubsumedFrame
  5183. {
  5184. JSContext* cx;
  5185. JSPrincipals* principals;
  5186. bool ignoreSelfHosted;
  5187. /**
  5188. * Use the cx's current compartment's principals.
  5189. */
  5190. explicit FirstSubsumedFrame(JSContext* cx, bool ignoreSelfHostedFrames = true);
  5191. explicit FirstSubsumedFrame(JSContext* ctx, JSPrincipals* p, bool ignoreSelfHostedFrames = true)
  5192. : cx(ctx)
  5193. , principals(p)
  5194. , ignoreSelfHosted(ignoreSelfHostedFrames)
  5195. {
  5196. if (principals)
  5197. JS_HoldPrincipals(principals);
  5198. }
  5199. // No copying because we want to avoid holding and dropping principals
  5200. // unnecessarily.
  5201. FirstSubsumedFrame(const FirstSubsumedFrame&) = delete;
  5202. FirstSubsumedFrame& operator=(const FirstSubsumedFrame&) = delete;
  5203. FirstSubsumedFrame(FirstSubsumedFrame&& rhs)
  5204. : principals(rhs.principals)
  5205. , ignoreSelfHosted(rhs.ignoreSelfHosted)
  5206. {
  5207. MOZ_ASSERT(this != &rhs, "self move disallowed");
  5208. rhs.principals = nullptr;
  5209. }
  5210. FirstSubsumedFrame& operator=(FirstSubsumedFrame&& rhs) {
  5211. new (this) FirstSubsumedFrame(mozilla::Move(rhs));
  5212. return *this;
  5213. }
  5214. ~FirstSubsumedFrame() {
  5215. if (principals)
  5216. JS_DropPrincipals(cx, principals);
  5217. }
  5218. };
  5219. using StackCapture = mozilla::Variant<AllFrames, MaxFrames, FirstSubsumedFrame>;
  5220. /**
  5221. * Capture the current call stack as a chain of SavedFrame JSObjects, and set
  5222. * |stackp| to the SavedFrame for the youngest stack frame, or nullptr if there
  5223. * are no JS frames on the stack.
  5224. *
  5225. * The |capture| parameter describes the portion of the JS stack to capture:
  5226. *
  5227. * * |JS::AllFrames|: Capture all frames on the stack.
  5228. *
  5229. * * |JS::MaxFrames|: Capture no more than |JS::MaxFrames::maxFrames| from the
  5230. * stack.
  5231. *
  5232. * * |JS::FirstSubsumedFrame|: Capture the first frame whose principals are
  5233. * subsumed by |JS::FirstSubsumedFrame::principals|. By default, do not
  5234. * consider self-hosted frames; this can be controlled via the
  5235. * |JS::FirstSubsumedFrame::ignoreSelfHosted| flag. Do not capture any async
  5236. * stack.
  5237. */
  5238. extern JS_PUBLIC_API(bool)
  5239. CaptureCurrentStack(JSContext* cx, MutableHandleObject stackp,
  5240. StackCapture&& capture = StackCapture(AllFrames()));
  5241. /*
  5242. * This is a utility function for preparing an async stack to be used
  5243. * by some other object. This may be used when you need to treat a
  5244. * given stack trace as an async parent. If you just need to capture
  5245. * the current stack, async parents and all, use CaptureCurrentStack
  5246. * instead.
  5247. *
  5248. * Here |asyncStack| is the async stack to prepare. It is copied into
  5249. * |cx|'s current compartment, and the newest frame is given
  5250. * |asyncCause| as its asynchronous cause. If |maxFrameCount| is
  5251. * non-zero, capture at most the youngest |maxFrameCount| frames. The
  5252. * new stack object is written to |stackp|. Returns true on success,
  5253. * or sets an exception and returns |false| on error.
  5254. */
  5255. extern JS_PUBLIC_API(bool)
  5256. CopyAsyncStack(JSContext* cx, HandleObject asyncStack,
  5257. HandleString asyncCause, MutableHandleObject stackp,
  5258. unsigned maxFrameCount);
  5259. /*
  5260. * Accessors for working with SavedFrame JSObjects
  5261. *
  5262. * Each of these functions assert that if their `HandleObject savedFrame`
  5263. * argument is non-null, its JSClass is the SavedFrame class (or it is a
  5264. * cross-compartment or Xray wrapper around an object with the SavedFrame class)
  5265. * and the object is not the SavedFrame.prototype object.
  5266. *
  5267. * Each of these functions will find the first SavedFrame object in the chain
  5268. * whose underlying stack frame principals are subsumed by the cx's current
  5269. * compartment's principals, and operate on that SavedFrame object. This
  5270. * prevents leaking information about privileged frames to un-privileged
  5271. * callers. As a result, the SavedFrame in parameters do _NOT_ need to be in the
  5272. * same compartment as the cx, and the various out parameters are _NOT_
  5273. * guaranteed to be in the same compartment as cx.
  5274. *
  5275. * You may consider or skip over self-hosted frames by passing
  5276. * `SavedFrameSelfHosted::Include` or `SavedFrameSelfHosted::Exclude`
  5277. * respectively.
  5278. *
  5279. * Additionally, it may be the case that there is no such SavedFrame object
  5280. * whose captured frame's principals are subsumed by the caller's compartment's
  5281. * principals! If the `HandleObject savedFrame` argument is null, or the
  5282. * caller's principals do not subsume any of the chained SavedFrame object's
  5283. * principals, `SavedFrameResult::AccessDenied` is returned and a (hopefully)
  5284. * sane default value is chosen for the out param.
  5285. *
  5286. * See also `js/src/doc/SavedFrame/SavedFrame.md`.
  5287. */
  5288. enum class SavedFrameResult {
  5289. Ok,
  5290. AccessDenied
  5291. };
  5292. enum class SavedFrameSelfHosted {
  5293. Include,
  5294. Exclude
  5295. };
  5296. /**
  5297. * Given a SavedFrame JSObject, get its source property. Defaults to the empty
  5298. * string.
  5299. */
  5300. extern JS_PUBLIC_API(SavedFrameResult)
  5301. GetSavedFrameSource(JSContext* cx, HandleObject savedFrame, MutableHandleString sourcep,
  5302. SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
  5303. /**
  5304. * Given a SavedFrame JSObject, get its line property. Defaults to 0.
  5305. */
  5306. extern JS_PUBLIC_API(SavedFrameResult)
  5307. GetSavedFrameLine(JSContext* cx, HandleObject savedFrame, uint32_t* linep,
  5308. SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
  5309. /**
  5310. * Given a SavedFrame JSObject, get its column property. Defaults to 0.
  5311. */
  5312. extern JS_PUBLIC_API(SavedFrameResult)
  5313. GetSavedFrameColumn(JSContext* cx, HandleObject savedFrame, uint32_t* columnp,
  5314. SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
  5315. /**
  5316. * Given a SavedFrame JSObject, get its functionDisplayName string, or nullptr
  5317. * if SpiderMonkey was unable to infer a name for the captured frame's
  5318. * function. Defaults to nullptr.
  5319. */
  5320. extern JS_PUBLIC_API(SavedFrameResult)
  5321. GetSavedFrameFunctionDisplayName(JSContext* cx, HandleObject savedFrame, MutableHandleString namep,
  5322. SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
  5323. /**
  5324. * Given a SavedFrame JSObject, get its asyncCause string. Defaults to nullptr.
  5325. */
  5326. extern JS_PUBLIC_API(SavedFrameResult)
  5327. GetSavedFrameAsyncCause(JSContext* cx, HandleObject savedFrame, MutableHandleString asyncCausep,
  5328. SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
  5329. /**
  5330. * Given a SavedFrame JSObject, get its asyncParent SavedFrame object or nullptr
  5331. * if there is no asyncParent. The `asyncParentp` out parameter is _NOT_
  5332. * guaranteed to be in the cx's compartment. Defaults to nullptr.
  5333. */
  5334. extern JS_PUBLIC_API(SavedFrameResult)
  5335. GetSavedFrameAsyncParent(JSContext* cx, HandleObject savedFrame, MutableHandleObject asyncParentp,
  5336. SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
  5337. /**
  5338. * Given a SavedFrame JSObject, get its parent SavedFrame object or nullptr if
  5339. * it is the oldest frame in the stack. The `parentp` out parameter is _NOT_
  5340. * guaranteed to be in the cx's compartment. Defaults to nullptr.
  5341. */
  5342. extern JS_PUBLIC_API(SavedFrameResult)
  5343. GetSavedFrameParent(JSContext* cx, HandleObject savedFrame, MutableHandleObject parentp,
  5344. SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
  5345. /**
  5346. * Given a SavedFrame JSObject stack, stringify it in the same format as
  5347. * Error.prototype.stack. The stringified stack out parameter is placed in the
  5348. * cx's compartment. Defaults to the empty string.
  5349. *
  5350. * The same notes above about SavedFrame accessors applies here as well: cx
  5351. * doesn't need to be in stack's compartment, and stack can be null, a
  5352. * SavedFrame object, or a wrapper (CCW or Xray) around a SavedFrame object.
  5353. *
  5354. * Optional indent parameter specifies the number of white spaces to indent
  5355. * each line.
  5356. */
  5357. extern JS_PUBLIC_API(bool)
  5358. BuildStackString(JSContext* cx, HandleObject stack, MutableHandleString stringp,
  5359. size_t indent = 0, js::StackFormat stackFormat = js::StackFormat::Default);
  5360. /**
  5361. * Return true iff the given object is either a SavedFrame object or wrapper
  5362. * around a SavedFrame object, and it is not the SavedFrame.prototype object.
  5363. */
  5364. extern JS_PUBLIC_API(bool)
  5365. IsSavedFrame(JSObject* obj);
  5366. } /* namespace JS */
  5367. /* Stopwatch-based performance monitoring. */
  5368. namespace js {
  5369. class AutoStopwatch;
  5370. /**
  5371. * Abstract base class for a representation of the performance of a
  5372. * component. Embeddings interested in performance monitoring should
  5373. * provide a concrete implementation of this class, as well as the
  5374. * relevant callbacks (see below).
  5375. */
  5376. struct PerformanceGroup {
  5377. PerformanceGroup();
  5378. // The current iteration of the event loop.
  5379. uint64_t iteration() const;
  5380. // `true` if an instance of `AutoStopwatch` is already monitoring
  5381. // the performance of this performance group for this iteration
  5382. // of the event loop, `false` otherwise.
  5383. bool isAcquired(uint64_t it) const;
  5384. // `true` if a specific instance of `AutoStopwatch` is already monitoring
  5385. // the performance of this performance group for this iteration
  5386. // of the event loop, `false` otherwise.
  5387. bool isAcquired(uint64_t it, const AutoStopwatch* owner) const;
  5388. // Mark that an instance of `AutoStopwatch` is monitoring
  5389. // the performance of this group for a given iteration.
  5390. void acquire(uint64_t it, const AutoStopwatch* owner);
  5391. // Mark that no `AutoStopwatch` is monitoring the
  5392. // performance of this group for the iteration.
  5393. void release(uint64_t it, const AutoStopwatch* owner);
  5394. // The number of cycles spent in this group during this iteration
  5395. // of the event loop. Note that cycles are not a reliable measure,
  5396. // especially over short intervals. See Stopwatch.* for a more
  5397. // complete discussion on the imprecision of cycle measurement.
  5398. uint64_t recentCycles(uint64_t iteration) const;
  5399. void addRecentCycles(uint64_t iteration, uint64_t cycles);
  5400. // The number of times this group has been activated during this
  5401. // iteration of the event loop.
  5402. uint64_t recentTicks(uint64_t iteration) const;
  5403. void addRecentTicks(uint64_t iteration, uint64_t ticks);
  5404. // The number of microseconds spent doing CPOW during this
  5405. // iteration of the event loop.
  5406. uint64_t recentCPOW(uint64_t iteration) const;
  5407. void addRecentCPOW(uint64_t iteration, uint64_t CPOW);
  5408. // Get rid of any data that pretends to be recent.
  5409. void resetRecentData();
  5410. // `true` if new measures should be added to this group, `false`
  5411. // otherwise.
  5412. bool isActive() const;
  5413. void setIsActive(bool);
  5414. // `true` if this group has been used in the current iteration,
  5415. // `false` otherwise.
  5416. bool isUsedInThisIteration() const;
  5417. void setIsUsedInThisIteration(bool);
  5418. protected:
  5419. // An implementation of `delete` for this object. Must be provided
  5420. // by the embedding.
  5421. virtual void Delete() = 0;
  5422. private:
  5423. // The number of cycles spent in this group during this iteration
  5424. // of the event loop. Note that cycles are not a reliable measure,
  5425. // especially over short intervals. See Runtime.cpp for a more
  5426. // complete discussion on the imprecision of cycle measurement.
  5427. uint64_t recentCycles_;
  5428. // The number of times this group has been activated during this
  5429. // iteration of the event loop.
  5430. uint64_t recentTicks_;
  5431. // The number of microseconds spent doing CPOW during this
  5432. // iteration of the event loop.
  5433. uint64_t recentCPOW_;
  5434. // The current iteration of the event loop. If necessary,
  5435. // may safely overflow.
  5436. uint64_t iteration_;
  5437. // `true` if new measures should be added to this group, `false`
  5438. // otherwise.
  5439. bool isActive_;
  5440. // `true` if this group has been used in the current iteration,
  5441. // `false` otherwise.
  5442. bool isUsedInThisIteration_;
  5443. // The stopwatch currently monitoring the group,
  5444. // or `nullptr` if none. Used ony for comparison.
  5445. const AutoStopwatch* owner_;
  5446. public:
  5447. // Compatibility with RefPtr<>
  5448. void AddRef();
  5449. void Release();
  5450. uint64_t refCount_;
  5451. };
  5452. using PerformanceGroupVector = mozilla::Vector<RefPtr<js::PerformanceGroup>, 0, SystemAllocPolicy>;
  5453. /**
  5454. * Commit any Performance Monitoring data.
  5455. *
  5456. * Until `FlushMonitoring` has been called, all PerformanceMonitoring data is invisible
  5457. * to the outside world and can cancelled with a call to `ResetMonitoring`.
  5458. */
  5459. extern JS_PUBLIC_API(bool)
  5460. FlushPerformanceMonitoring(JSContext*);
  5461. /**
  5462. * Cancel any measurement that hasn't been committed.
  5463. */
  5464. extern JS_PUBLIC_API(void)
  5465. ResetPerformanceMonitoring(JSContext*);
  5466. /**
  5467. * Cleanup any memory used by performance monitoring.
  5468. */
  5469. extern JS_PUBLIC_API(void)
  5470. DisposePerformanceMonitoring(JSContext*);
  5471. /**
  5472. * Turn on/off stopwatch-based CPU monitoring.
  5473. *
  5474. * `SetStopwatchIsMonitoringCPOW` or `SetStopwatchIsMonitoringJank`
  5475. * may return `false` if monitoring could not be activated, which may
  5476. * happen if we are out of memory.
  5477. */
  5478. extern JS_PUBLIC_API(bool)
  5479. SetStopwatchIsMonitoringCPOW(JSContext*, bool);
  5480. extern JS_PUBLIC_API(bool)
  5481. GetStopwatchIsMonitoringCPOW(JSContext*);
  5482. extern JS_PUBLIC_API(bool)
  5483. SetStopwatchIsMonitoringJank(JSContext*, bool);
  5484. extern JS_PUBLIC_API(bool)
  5485. GetStopwatchIsMonitoringJank(JSContext*);
  5486. // Extract the CPU rescheduling data.
  5487. extern JS_PUBLIC_API(void)
  5488. GetPerfMonitoringTestCpuRescheduling(JSContext*, uint64_t* stayed, uint64_t* moved);
  5489. /**
  5490. * Add a number of microseconds to the time spent waiting on CPOWs
  5491. * since process start.
  5492. */
  5493. extern JS_PUBLIC_API(void)
  5494. AddCPOWPerformanceDelta(JSContext*, uint64_t delta);
  5495. typedef bool
  5496. (*StopwatchStartCallback)(uint64_t, void*);
  5497. extern JS_PUBLIC_API(bool)
  5498. SetStopwatchStartCallback(JSContext*, StopwatchStartCallback, void*);
  5499. typedef bool
  5500. (*StopwatchCommitCallback)(uint64_t, PerformanceGroupVector&, void*);
  5501. extern JS_PUBLIC_API(bool)
  5502. SetStopwatchCommitCallback(JSContext*, StopwatchCommitCallback, void*);
  5503. typedef bool
  5504. (*GetGroupsCallback)(JSContext*, PerformanceGroupVector&, void*);
  5505. extern JS_PUBLIC_API(bool)
  5506. SetGetPerformanceGroupsCallback(JSContext*, GetGroupsCallback, void*);
  5507. } /* namespace js */
  5508. #endif /* jsapi_h */