Parse.cpp 487 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "ParserPch.h"
  6. #include "FormalsUtil.h"
  7. #include "../Runtime/Language/SourceDynamicProfileManager.h"
  8. #include "ByteCode/ByteCodeSerializer.h"
  9. #if DBG_DUMP
  10. void PrintPnodeWIndent(ParseNode *pnode, int indentAmt);
  11. #endif
  12. const char* const nopNames[knopLim] = {
  13. #define PTNODE(nop,sn,pc,nk,grfnop,json) sn,
  14. #include "ptlist.h"
  15. };
  16. void printNop(int nop) {
  17. Output::Print(_u("%S\n"), nopNames[nop]);
  18. }
  19. const uint ParseNode::mpnopgrfnop[knopLim] =
  20. {
  21. #define PTNODE(nop,sn,pc,nk,grfnop,json) grfnop,
  22. #include "ptlist.h"
  23. };
  24. bool Parser::IsES6DestructuringEnabled() const
  25. {
  26. return m_scriptContext->GetConfig()->IsES6DestructuringEnabled();
  27. }
  28. struct BlockInfoStack
  29. {
  30. StmtNest pstmt;
  31. ParseNodeBlock *pnodeBlock;
  32. ParseNodePtr *m_ppnodeLex; // lexical variable list tail
  33. BlockInfoStack *pBlockInfoOuter; // containing block's BlockInfoStack
  34. BlockInfoStack *pBlockInfoFunction; // nearest function's BlockInfoStack (if pnodeBlock is a function, this points to itself)
  35. };
  36. #if DEBUG
  37. Parser::Parser(Js::ScriptContext* scriptContext, BOOL strictMode, PageAllocator *alloc, bool isBackground, size_t size)
  38. #else
  39. Parser::Parser(Js::ScriptContext* scriptContext, BOOL strictMode, PageAllocator *alloc, bool isBackground)
  40. #endif
  41. : m_nodeAllocator(_u("Parser"), alloc ? alloc : scriptContext->GetThreadContext()->GetPageAllocator(), Parser::OutOfMemory),
  42. m_cactIdentToNodeLookup(0),
  43. m_grfscr(fscrNil),
  44. m_length(0),
  45. m_originalLength(0),
  46. m_nextFunctionId(nullptr),
  47. m_sourceContextInfo(nullptr),
  48. #if ENABLE_BACKGROUND_PARSING
  49. m_isInBackground(isBackground),
  50. m_hasParallelJob(false),
  51. m_doingFastScan(false),
  52. #endif
  53. m_nextBlockId(0),
  54. m_tempGuestArenaReleased(false),
  55. m_tempGuestArena(scriptContext->GetTemporaryGuestAllocator(_u("ParserRegex")), scriptContext->GetRecycler()),
  56. // use the GuestArena directly for keeping the RegexPattern* alive during byte code generation
  57. m_registeredRegexPatterns(m_tempGuestArena->GetAllocator()),
  58. m_scriptContext(scriptContext),
  59. m_token(), // should initialize to 0/nullptrs
  60. m_scan(this, &m_token, scriptContext),
  61. m_currentNodeNonLambdaFunc(nullptr),
  62. m_currentNodeNonLambdaDeferredFunc(nullptr),
  63. m_currentNodeFunc(nullptr),
  64. m_currentNodeDeferredFunc(nullptr),
  65. m_currentNodeProg(nullptr),
  66. m_currDeferredStub(nullptr),
  67. m_currDeferredStubCount(0),
  68. m_pCurrentAstSize(nullptr),
  69. m_ppnodeScope(nullptr),
  70. m_ppnodeExprScope(nullptr),
  71. m_ppnodeVar(nullptr),
  72. m_inDeferredNestedFunc(false),
  73. m_reparsingLambdaParams(false),
  74. m_disallowImportExportStmt(false),
  75. m_isInParsingArgList(false),
  76. m_hasDestructuringPattern(false),
  77. m_hasDeferredShorthandInitError(false),
  78. m_deferCommaError(false),
  79. m_pnestedCount(nullptr),
  80. wellKnownPropertyPids(), // should initialize to nullptrs
  81. m_sourceLim(0),
  82. m_functionBody(nullptr),
  83. m_parseType(ParseType_Upfront),
  84. m_arrayDepth(0),
  85. m_funcInArrayDepth(0),
  86. m_funcInArray(0),
  87. m_scopeCountNoAst(0),
  88. m_funcParenExprDepth(0),
  89. m_deferEllipsisError(false),
  90. m_deferEllipsisErrorLoc(), // calls default initializer
  91. m_deferCommaErrorLoc(),
  92. m_tryCatchOrFinallyDepth(0),
  93. m_pstmtCur(nullptr),
  94. m_currentBlockInfo(nullptr),
  95. m_currentScope(nullptr),
  96. currBackgroundParseItem(nullptr),
  97. backgroundParseItems(nullptr),
  98. fastScannedRegExpNodes(nullptr),
  99. m_currentDynamicBlock(nullptr),
  100. m_UsesArgumentsAtGlobal(false),
  101. m_fUseStrictMode(strictMode),
  102. m_InAsmMode(false),
  103. m_deferAsmJs(true),
  104. m_fExpectExternalSource(FALSE),
  105. m_deferringAST(FALSE),
  106. m_stoppedDeferredParse(FALSE)
  107. {
  108. AssertMsg(size == sizeof(Parser), "verify conditionals affecting the size of Parser agree");
  109. Assert(scriptContext != nullptr);
  110. // init PID members
  111. InitPids();
  112. }
  113. Parser::~Parser(void)
  114. {
  115. this->ReleaseTemporaryGuestArena();
  116. #if ENABLE_BACKGROUND_PARSING
  117. if (this->m_hasParallelJob)
  118. {
  119. // Let the background threads know that they can decommit their arena pages.
  120. BackgroundParser *bgp = m_scriptContext->GetBackgroundParser();
  121. Assert(bgp);
  122. if (bgp->Processor()->ProcessesInBackground())
  123. {
  124. JsUtil::BackgroundJobProcessor *processor = static_cast<JsUtil::BackgroundJobProcessor*>(bgp->Processor());
  125. bool result = processor->IterateBackgroundThreads([&](JsUtil::ParallelThreadData *threadData)->bool {
  126. threadData->canDecommit = true;
  127. return false;
  128. });
  129. Assert(result);
  130. }
  131. }
  132. #endif
  133. }
  134. void Parser::OutOfMemory()
  135. {
  136. throw ParseExceptionObject(ERRnoMemory);
  137. }
  138. void Parser::Error(HRESULT hr)
  139. {
  140. throw ParseExceptionObject(hr);
  141. }
  142. void Parser::Error(HRESULT hr, ParseNodePtr pnode)
  143. {
  144. if (pnode && pnode->ichLim)
  145. {
  146. Error(hr, pnode->ichMin, pnode->ichLim);
  147. }
  148. else
  149. {
  150. Error(hr);
  151. }
  152. }
  153. void Parser::Error(HRESULT hr, charcount_t ichMin, charcount_t ichLim)
  154. {
  155. this->GetScanner()->SetErrorPosition(ichMin, ichLim);
  156. Error(hr);
  157. }
  158. void Parser::IdentifierExpectedError(const Token& token)
  159. {
  160. Assert(token.tk != tkID);
  161. HRESULT hr;
  162. if (token.IsReservedWord())
  163. {
  164. if (token.IsKeyword())
  165. {
  166. hr = ERRKeywordNotId;
  167. }
  168. else
  169. {
  170. Assert(token.IsFutureReservedWord(true));
  171. if (token.IsFutureReservedWord(false))
  172. {
  173. // Future reserved word in strict and non-strict modes
  174. hr = ERRFutureReservedWordNotId;
  175. }
  176. else
  177. {
  178. // Future reserved word only in strict mode. The token would have been converted to tkID by the scanner if not
  179. // in strict mode.
  180. Assert(IsStrictMode());
  181. hr = ERRFutureReservedWordInStrictModeNotId;
  182. }
  183. }
  184. }
  185. else
  186. {
  187. hr = ERRnoIdent;
  188. }
  189. Error(hr);
  190. }
  191. HRESULT Parser::ValidateSyntax(LPCUTF8 pszSrc, size_t encodedCharCount, bool isGenerator, bool isAsync, CompileScriptException *pse, void (Parser::*validateFunction)())
  192. {
  193. Assert(pszSrc);
  194. PROBE_STACK_NO_DISPOSE(m_scriptContext, Js::Constants::MinStackDefault);
  195. HRESULT hr;
  196. SmartFPUControl smartFpuControl;
  197. BOOL fDeferSave = m_deferringAST;
  198. try
  199. {
  200. hr = NOERROR;
  201. m_length = encodedCharCount;
  202. m_originalLength = encodedCharCount;
  203. // make sure deferred parsing is turned off
  204. ULONG grfscr = fscrNil;
  205. // Give the scanner the source and get the first token
  206. this->GetScanner()->SetText(pszSrc, 0, encodedCharCount, 0, false, grfscr);
  207. this->GetScanner()->SetYieldIsKeywordRegion(isGenerator);
  208. this->GetScanner()->SetAwaitIsKeywordRegion(isAsync);
  209. this->GetScanner()->Scan();
  210. uint nestedCount = 0;
  211. m_pnestedCount = &nestedCount;
  212. ParseNodePtr pnodeScope = nullptr;
  213. m_ppnodeScope = &pnodeScope;
  214. m_ppnodeExprScope = nullptr;
  215. uint nextFunctionId = 0;
  216. m_nextFunctionId = &nextFunctionId;
  217. m_inDeferredNestedFunc = false;
  218. m_deferringAST = true;
  219. m_nextBlockId = 0;
  220. ParseNodeFnc *pnodeFnc = CreateAllowDeferNodeForOpT<knopFncDecl>();
  221. pnodeFnc->SetIsGenerator(isGenerator);
  222. pnodeFnc->SetIsAsync(isAsync);
  223. m_ppnodeVar = &pnodeFnc->pnodeVars;
  224. m_currentNodeFunc = pnodeFnc;
  225. m_currentNodeDeferredFunc = NULL;
  226. m_sourceContextInfo = nullptr;
  227. AssertMsg(m_pstmtCur == NULL, "Statement stack should be empty when we start parse function body");
  228. ParseNodeBlock * block = StartParseBlock<false>(PnodeBlockType::Function, ScopeType_FunctionBody);
  229. (this->*validateFunction)();
  230. FinishParseBlock(block);
  231. pnodeFnc->ichLim = this->GetScanner()->IchLimTok();
  232. pnodeFnc->cbLim = this->GetScanner()->IecpLimTok();
  233. pnodeFnc->pnodeVars = nullptr;
  234. // there should be nothing after successful parsing for a given construct
  235. if (m_token.tk != tkEOF)
  236. Error(ERRsyntax);
  237. m_deferringAST = fDeferSave;
  238. }
  239. catch (ParseExceptionObject& e)
  240. {
  241. m_deferringAST = fDeferSave;
  242. hr = e.GetError();
  243. }
  244. if (nullptr != pse && FAILED(hr))
  245. {
  246. hr = pse->ProcessError(this->GetScanner(), hr, /* pnodeBase */ NULL);
  247. }
  248. return hr;
  249. }
  250. HRESULT Parser::ParseSourceInternal(
  251. __out ParseNodeProg ** parseTree, LPCUTF8 pszSrc, size_t offsetInBytes, size_t encodedCharCount, charcount_t offsetInChars,
  252. bool isUtf8, ULONG grfscr, CompileScriptException *pse, Js::LocalFunctionId * nextFunctionId, ULONG lineNumber, SourceContextInfo * sourceContextInfo)
  253. {
  254. Assert(parseTree);
  255. Assert(pszSrc);
  256. if (this->IsBackgroundParser())
  257. {
  258. PROBE_STACK_NO_DISPOSE(m_scriptContext, Js::Constants::MinStackDefault);
  259. }
  260. else
  261. {
  262. PROBE_STACK(m_scriptContext, Js::Constants::MinStackDefault);
  263. }
  264. #ifdef PROFILE_EXEC
  265. m_scriptContext->ProfileBegin(Js::ParsePhase);
  266. #endif
  267. JS_ETW_INTERNAL(EventWriteJSCRIPT_PARSE_START(m_scriptContext, 0));
  268. *parseTree = NULL;
  269. m_sourceLim = 0;
  270. m_grfscr = grfscr;
  271. m_sourceContextInfo = sourceContextInfo;
  272. ParseNodeProg * pnodeBase = NULL;
  273. HRESULT hr;
  274. SmartFPUControl smartFpuControl;
  275. try
  276. {
  277. if ((grfscr & fscrIsModuleCode) != 0)
  278. {
  279. // Module source flag should not be enabled unless module is enabled
  280. Assert(m_scriptContext->GetConfig()->IsES6ModuleEnabled());
  281. // Module code is always strict mode code.
  282. this->m_fUseStrictMode = TRUE;
  283. }
  284. // parse the source
  285. pnodeBase = Parse(pszSrc, offsetInBytes, encodedCharCount, offsetInChars, isUtf8, grfscr, lineNumber, nextFunctionId, pse);
  286. Assert(pnodeBase);
  287. // Record the actual number of words parsed.
  288. m_sourceLim = pnodeBase->ichLim - offsetInChars;
  289. // TODO: The assert can be false positive in some scenarios and chuckj to fix it later
  290. // Assert(utf8::ByteIndexIntoCharacterIndex(pszSrc + offsetInBytes, encodedCharCount, isUtf8 ? utf8::doDefault : utf8::doAllowThreeByteSurrogates) == m_sourceLim);
  291. #if DBG_DUMP
  292. if (Js::Configuration::Global.flags.Trace.IsEnabled(Js::ParsePhase))
  293. {
  294. PrintPnodeWIndent(pnodeBase, 4);
  295. fflush(stdout);
  296. }
  297. #endif
  298. *parseTree = pnodeBase;
  299. hr = NOERROR;
  300. }
  301. catch (ParseExceptionObject& e)
  302. {
  303. hr = e.GetError();
  304. }
  305. catch (Js::AsmJsParseException&)
  306. {
  307. hr = JSERR_AsmJsCompileError;
  308. }
  309. if (FAILED(hr))
  310. {
  311. hr = pse->ProcessError(this->GetScanner(), hr, pnodeBase);
  312. }
  313. #if ENABLE_BACKGROUND_PARSING
  314. if (this->m_hasParallelJob)
  315. {
  316. ///// Wait here for remaining jobs to finish. Then look for errors, do final const bindings.
  317. // pleath TODO: If there are remaining jobs, let the main thread help finish them.
  318. BackgroundParser *bgp = m_scriptContext->GetBackgroundParser();
  319. Assert(bgp);
  320. CompileScriptException se;
  321. this->WaitForBackgroundJobs(bgp, &se);
  322. BackgroundParseItem *failedItem = bgp->GetFailedBackgroundParseItem();
  323. if (failedItem)
  324. {
  325. CompileScriptException *bgPse = failedItem->GetPSE();
  326. Assert(bgPse);
  327. *pse = *bgPse;
  328. hr = failedItem->GetHR();
  329. bgp->SetFailedBackgroundParseItem(nullptr);
  330. }
  331. if (this->fastScannedRegExpNodes != nullptr)
  332. {
  333. this->FinishBackgroundRegExpNodes();
  334. }
  335. for (BackgroundParseItem *item = this->backgroundParseItems; item; item = item->GetNext())
  336. {
  337. Parser *parser = item->GetParser();
  338. parser->FinishBackgroundPidRefs(item, this != parser);
  339. }
  340. }
  341. #endif
  342. // done with the scanner
  343. this->GetScanner()->Clear();
  344. #ifdef PROFILE_EXEC
  345. m_scriptContext->ProfileEnd(Js::ParsePhase);
  346. #endif
  347. JS_ETW_INTERNAL(EventWriteJSCRIPT_PARSE_STOP(m_scriptContext, 0));
  348. return hr;
  349. }
  350. #if ENABLE_BACKGROUND_PARSING
  351. void Parser::WaitForBackgroundJobs(BackgroundParser *bgp, CompileScriptException *pse)
  352. {
  353. // The scan of the script is done, but there may be unfinished background jobs in the queue.
  354. // Enlist the main thread to help with those.
  355. BackgroundParseItem *item;
  356. if (!*bgp->GetPendingBackgroundItemsPtr())
  357. {
  358. // We're done.
  359. return;
  360. }
  361. // Save parser state, since we'll need to restore it in order to bind references correctly later.
  362. this->m_isInBackground = true;
  363. this->SetCurrBackgroundParseItem(nullptr);
  364. uint blockIdSave = this->m_nextBlockId;
  365. uint functionIdSave = *this->m_nextFunctionId;
  366. StmtNest *pstmtSave = this->m_pstmtCur;
  367. if (!bgp->Processor()->ProcessesInBackground())
  368. {
  369. // No background thread. Just walk the jobs with no locking and process them.
  370. for (item = bgp->GetNextUnprocessedItem(); item; item = bgp->GetNextUnprocessedItem())
  371. {
  372. bgp->Processor()->RemoveJob(item);
  373. bool succeeded = bgp->Process(item, this, pse);
  374. bgp->JobProcessed(item, succeeded);
  375. }
  376. Assert(!*bgp->GetPendingBackgroundItemsPtr());
  377. }
  378. else
  379. {
  380. // Background threads. We need to have the critical section in order to:
  381. // - Check for unprocessed jobs;
  382. // - Remove jobs from the processor queue;
  383. // - Do JobsProcessed work (such as removing jobs from the BackgroundParser's unprocessed list).
  384. CriticalSection *pcs = static_cast<JsUtil::BackgroundJobProcessor*>(bgp->Processor())->GetCriticalSection();
  385. pcs->Enter();
  386. for (;;)
  387. {
  388. // Grab a job (in lock)
  389. item = bgp->GetNextUnprocessedItem();
  390. if (item == nullptr)
  391. {
  392. break;
  393. }
  394. bgp->Processor()->RemoveJob(item);
  395. pcs->Leave();
  396. // Process job (if there is one) (outside lock)
  397. bool succeeded = bgp->Process(item, this, pse);
  398. pcs->Enter();
  399. bgp->JobProcessed(item, succeeded);
  400. }
  401. pcs->Leave();
  402. // Wait for the background threads to finish jobs they're already processing (if any).
  403. // TODO: Replace with a proper semaphore.
  404. while (*bgp->GetPendingBackgroundItemsPtr());
  405. }
  406. Assert(!*bgp->GetPendingBackgroundItemsPtr());
  407. // Restore parser state.
  408. this->m_pstmtCur = pstmtSave;
  409. this->m_isInBackground = false;
  410. this->m_nextBlockId = blockIdSave;
  411. *this->m_nextFunctionId = functionIdSave;
  412. }
  413. void Parser::FinishBackgroundPidRefs(BackgroundParseItem *item, bool isOtherParser)
  414. {
  415. for (BlockInfoStack *blockInfo = item->GetParseContext()->currentBlockInfo; blockInfo; blockInfo = blockInfo->pBlockInfoOuter)
  416. {
  417. if (isOtherParser)
  418. {
  419. this->BindPidRefs<true>(blockInfo, item->GetMaxBlockId());
  420. }
  421. else
  422. {
  423. this->BindPidRefs<false>(blockInfo, item->GetMaxBlockId());
  424. }
  425. }
  426. }
  427. void Parser::FinishBackgroundRegExpNodes()
  428. {
  429. // We have a list of RegExp nodes that we saw on the UI thread in functions we're parallel parsing,
  430. // and for each background job we have a list of RegExp nodes for which we couldn't allocate patterns.
  431. // We need to copy the pattern pointers from the UI thread nodes to the corresponding nodes on the
  432. // background nodes.
  433. // There may be UI thread nodes for which there are no background thread equivalents, because the UI thread
  434. // has to assume that the background thread won't defer anything.
  435. // Note that because these lists (and the list of background jobs) are SList's built by prepending, they are
  436. // all in reverse lexical order.
  437. Assert(!this->IsBackgroundParser());
  438. Assert(this->fastScannedRegExpNodes);
  439. Assert(this->backgroundParseItems != nullptr);
  440. BackgroundParseItem *currBackgroundItem;
  441. #if DBG
  442. for (currBackgroundItem = this->backgroundParseItems;
  443. currBackgroundItem;
  444. currBackgroundItem = currBackgroundItem->GetNext())
  445. {
  446. if (currBackgroundItem->RegExpNodeList())
  447. {
  448. FOREACH_DLIST_ENTRY(ParseNodePtr, ArenaAllocator, pnode, currBackgroundItem->RegExpNodeList())
  449. {
  450. Assert(pnode->AsParseNodeRegExp()->regexPattern == nullptr);
  451. }
  452. NEXT_DLIST_ENTRY;
  453. }
  454. }
  455. #endif
  456. // Hook up the patterns allocated on the main thread to the nodes created on the background thread.
  457. // Walk the list of foreground nodes, advancing through the work items and looking up each item.
  458. // Note that the background thread may have chosen to defer a given RegEx literal, so not every foreground
  459. // node will have a matching background node. Doesn't matter for correctness.
  460. // (It's inefficient, of course, to have to restart the inner loop from the beginning of the work item's
  461. // list, but it should be unusual to have many RegExes in a single work item's chunk of code. Figure out how
  462. // to start the inner loop from a known internal node within the list if that turns out to be important.)
  463. currBackgroundItem = this->backgroundParseItems;
  464. FOREACH_DLIST_ENTRY(ParseNodePtr, ArenaAllocator, pnodeFgnd, this->fastScannedRegExpNodes)
  465. {
  466. Assert(pnodeFgnd->nop == knopRegExp);
  467. Assert(pnodeFgnd->AsParseNodeRegExp()->regexPattern != nullptr);
  468. bool quit = false;
  469. while (!quit)
  470. {
  471. // Find the next work item with a RegEx in it.
  472. while (currBackgroundItem && currBackgroundItem->RegExpNodeList() == nullptr)
  473. {
  474. currBackgroundItem = currBackgroundItem->GetNext();
  475. }
  476. if (!currBackgroundItem)
  477. {
  478. break;
  479. }
  480. // Walk the RegExps in the work item.
  481. FOREACH_DLIST_ENTRY(ParseNodePtr, ArenaAllocator, pnodeBgnd, currBackgroundItem->RegExpNodeList())
  482. {
  483. Assert(pnodeBgnd->nop == knopRegExp);
  484. if (pnodeFgnd->ichMin <= pnodeBgnd->ichMin)
  485. {
  486. // Either we found a match, or the next background node is past the foreground node.
  487. // In any case, we can stop searching.
  488. if (pnodeFgnd->ichMin == pnodeBgnd->ichMin)
  489. {
  490. Assert(pnodeFgnd->ichLim == pnodeBgnd->ichLim);
  491. pnodeBgnd->AsParseNodeRegExp()->regexPattern = pnodeFgnd->AsParseNodeRegExp()->regexPattern;
  492. }
  493. quit = true;
  494. break;
  495. }
  496. }
  497. NEXT_DLIST_ENTRY;
  498. if (!quit)
  499. {
  500. // Need to advance to the next work item.
  501. currBackgroundItem = currBackgroundItem->GetNext();
  502. }
  503. }
  504. }
  505. NEXT_DLIST_ENTRY;
  506. #if DBG
  507. for (currBackgroundItem = this->backgroundParseItems;
  508. currBackgroundItem;
  509. currBackgroundItem = currBackgroundItem->GetNext())
  510. {
  511. if (currBackgroundItem->RegExpNodeList())
  512. {
  513. FOREACH_DLIST_ENTRY(ParseNodePtr, ArenaAllocator, pnode, currBackgroundItem->RegExpNodeList())
  514. {
  515. Assert(pnode->AsParseNodeRegExp()->regexPattern != nullptr);
  516. }
  517. NEXT_DLIST_ENTRY;
  518. }
  519. }
  520. #endif
  521. }
  522. #endif
  523. LabelId* Parser::CreateLabelId(IdentPtr pid)
  524. {
  525. LabelId* pLabelId;
  526. pLabelId = (LabelId*)m_nodeAllocator.Alloc(sizeof(LabelId));
  527. if (NULL == pLabelId)
  528. Error(ERRnoMemory);
  529. pLabelId->pid = pid;
  530. pLabelId->next = NULL;
  531. return pLabelId;
  532. }
  533. /*****************************************************************************
  534. The following set of routines allocate parse tree nodes of various kinds.
  535. They catch an exception on out of memory.
  536. *****************************************************************************/
  537. void
  538. Parser::AddAstSize(int size)
  539. {
  540. Assert(!this->m_deferringAST);
  541. Assert(m_pCurrentAstSize != NULL);
  542. *m_pCurrentAstSize += size;
  543. }
  544. void
  545. Parser::AddAstSizeAllowDefer(int size)
  546. {
  547. if (!this->m_deferringAST)
  548. {
  549. AddAstSize(size);
  550. }
  551. }
  552. // StaticCreate
  553. ParseNodeVar * Parser::StaticCreateTempNode(ParseNode* initExpr, ArenaAllocator * alloc)
  554. {
  555. ParseNodeVar * pnode = Anew(alloc, ParseNodeVar, knopTemp, 0, 0, nullptr);
  556. pnode->pnodeInit = initExpr;
  557. return pnode;
  558. }
  559. ParseNodeUni * Parser::StaticCreateTempRef(ParseNode* tempNode, ArenaAllocator * alloc)
  560. {
  561. return Anew(alloc, ParseNodeUni, knopTempRef, 0, 0, tempNode);
  562. }
  563. // Create Node with limit
  564. template <OpCode nop>
  565. typename OpCodeTrait<nop>::ParseNodeType * Parser::CreateNodeForOpT(charcount_t ichMin, charcount_t ichLim)
  566. {
  567. Assert(!this->m_deferringAST);
  568. typename OpCodeTrait<nop>::ParseNodeType * pnode = StaticCreateNodeT<nop>(&m_nodeAllocator, ichMin, ichLim);
  569. AddAstSize(sizeof(typename OpCodeTrait<nop>::ParseNodeType));
  570. return pnode;
  571. }
  572. template <OpCode nop>
  573. typename OpCodeTrait<nop>::ParseNodeType * Parser::CreateAllowDeferNodeForOpT(charcount_t ichMin, charcount_t ichLim)
  574. {
  575. CompileAssert(OpCodeTrait<nop>::AllowDefer);
  576. typename OpCodeTrait<nop>::ParseNodeType * pnode = StaticCreateNodeT<nop>(&m_nodeAllocator, ichMin, ichLim);
  577. AddAstSizeAllowDefer(sizeof(typename OpCodeTrait<nop>::ParseNodeType));
  578. return pnode;
  579. }
  580. #if DBG
  581. static const int g_mpnopcbNode[] =
  582. {
  583. #define PTNODE(nop,sn,pc,nk,ok,json) sizeof(ParseNode##nk),
  584. #include "ptlist.h"
  585. };
  586. void VerifyNodeSize(OpCode nop, int size)
  587. {
  588. Assert(nop >= 0 && nop < knopLim);
  589. __analysis_assume(nop < knopLim);
  590. Assert(g_mpnopcbNode[nop] == size);
  591. }
  592. #endif
  593. // Create ParseNodeUni
  594. ParseNodeUni * Parser::CreateUniNode(OpCode nop, ParseNodePtr pnode1)
  595. {
  596. charcount_t ichMin;
  597. charcount_t ichLim;
  598. if (nullptr == pnode1)
  599. {
  600. // no ops
  601. ichMin = this->GetScanner()->IchMinTok();
  602. ichLim = this->GetScanner()->IchLimTok();
  603. }
  604. else
  605. {
  606. // 1 op
  607. ichMin = pnode1->ichMin;
  608. ichLim = pnode1->ichLim;
  609. this->CheckArguments(pnode1);
  610. }
  611. return CreateUniNode(nop, pnode1, ichMin, ichLim);
  612. }
  613. ParseNodeUni * Parser::CreateUniNode(OpCode nop, ParseNodePtr pnode1, charcount_t ichMin, charcount_t ichLim)
  614. {
  615. Assert(!this->m_deferringAST);
  616. DebugOnly(VerifyNodeSize(nop, sizeof(ParseNodeUni)));
  617. ParseNodeUni * pnode = Anew(&m_nodeAllocator, ParseNodeUni, nop, ichMin, ichLim, pnode1);
  618. AddAstSize(sizeof(ParseNodeUni));
  619. return pnode;
  620. }
  621. // Create ParseNodeBin
  622. ParseNodeBin * Parser::StaticCreateBinNode(OpCode nop, ParseNodePtr pnode1, ParseNodePtr pnode2, ArenaAllocator* alloc, charcount_t ichMin, charcount_t ichLim)
  623. {
  624. DebugOnly(VerifyNodeSize(nop, sizeof(ParseNodeBin)));
  625. return Anew(alloc, ParseNodeBin, nop, ichMin, ichLim, pnode1, pnode2);
  626. }
  627. ParseNodeBin * Parser::CreateBinNode(OpCode nop, ParseNodePtr pnode1, ParseNodePtr pnode2)
  628. {
  629. Assert(!this->m_deferringAST);
  630. charcount_t ichMin;
  631. charcount_t ichLim;
  632. if (nullptr == pnode1)
  633. {
  634. // no ops
  635. Assert(nullptr == pnode2);
  636. ichMin = this->GetScanner()->IchMinTok();
  637. ichLim = this->GetScanner()->IchLimTok();
  638. }
  639. else
  640. {
  641. if (nullptr == pnode2)
  642. {
  643. // 1 op
  644. ichMin = pnode1->ichMin;
  645. ichLim = pnode1->ichLim;
  646. }
  647. else
  648. {
  649. // 2 ops
  650. ichMin = pnode1->ichMin;
  651. ichLim = pnode2->ichLim;
  652. if (nop != knopDot && nop != knopIndex)
  653. {
  654. this->CheckArguments(pnode2);
  655. }
  656. }
  657. if (nop != knopDot && nop != knopIndex)
  658. {
  659. this->CheckArguments(pnode1);
  660. }
  661. }
  662. return CreateBinNode(nop, pnode1, pnode2, ichMin, ichLim);
  663. }
  664. ParseNodeBin * Parser::CreateBinNode(OpCode nop, ParseNodePtr pnode1,
  665. ParseNodePtr pnode2, charcount_t ichMin, charcount_t ichLim)
  666. {
  667. Assert(!this->m_deferringAST);
  668. ParseNodeBin * pnode = StaticCreateBinNode(nop, pnode1, pnode2, &m_nodeAllocator, ichMin, ichLim);
  669. AddAstSize(sizeof(ParseNodeBin));
  670. return pnode;
  671. }
  672. // Create ParseNodeTri
  673. ParseNodeTri * Parser::CreateTriNode(OpCode nop, ParseNodePtr pnode1,
  674. ParseNodePtr pnode2, ParseNodePtr pnode3)
  675. {
  676. charcount_t ichMin;
  677. charcount_t ichLim;
  678. if (nullptr == pnode1)
  679. {
  680. // no ops
  681. Assert(nullptr == pnode2);
  682. Assert(nullptr == pnode3);
  683. ichMin = this->GetScanner()->IchMinTok();
  684. ichLim = this->GetScanner()->IchLimTok();
  685. }
  686. else if (nullptr == pnode2)
  687. {
  688. // 1 op
  689. Assert(nullptr == pnode3);
  690. ichMin = pnode1->ichMin;
  691. ichLim = pnode1->ichLim;
  692. }
  693. else if (nullptr == pnode3)
  694. {
  695. // 2 op
  696. ichMin = pnode1->ichMin;
  697. ichLim = pnode2->ichLim;
  698. }
  699. else
  700. {
  701. // 3 ops
  702. ichMin = pnode1->ichMin;
  703. ichLim = pnode3->ichLim;
  704. }
  705. return CreateTriNode(nop, pnode1, pnode2, pnode3, ichMin, ichLim);
  706. }
  707. ParseNodeTri * Parser::CreateTriNode(OpCode nop, ParseNodePtr pnode1,
  708. ParseNodePtr pnode2, ParseNodePtr pnode3,
  709. charcount_t ichMin, charcount_t ichLim)
  710. {
  711. Assert(!this->m_deferringAST);
  712. DebugOnly(VerifyNodeSize(nop, sizeof(ParseNodeTri)));
  713. ParseNodeTri * pnode = Anew(&m_nodeAllocator, ParseNodeTri, nop, ichMin, ichLim);
  714. AddAstSize(sizeof(ParseNodeTri));
  715. pnode->pnode1 = pnode1;
  716. pnode->pnode2 = pnode2;
  717. pnode->pnode3 = pnode3;
  718. return pnode;
  719. }
  720. // Create ParseNodeBlock
  721. ParseNodeBlock *
  722. Parser::StaticCreateBlockNode(ArenaAllocator* alloc, charcount_t ichMin, charcount_t ichLim, int blockId, PnodeBlockType blockType)
  723. {
  724. return Anew(alloc, ParseNodeBlock, ichMin, ichLim, blockId, blockType);
  725. }
  726. ParseNodeBlock * Parser::CreateBlockNode(PnodeBlockType blockType)
  727. {
  728. return CreateBlockNode(this->GetScanner()->IchMinTok(), this->GetScanner()->IchLimTok(), blockType);
  729. }
  730. ParseNodeBlock * Parser::CreateBlockNode(charcount_t ichMin, charcount_t ichLim, PnodeBlockType blockType)
  731. {
  732. Assert(OpCodeTrait<knopBlock>::AllowDefer);
  733. ParseNodeBlock * pnode = StaticCreateBlockNode(&m_nodeAllocator, ichMin, ichLim, this->m_nextBlockId++, blockType);
  734. AddAstSizeAllowDefer(sizeof(ParseNodeBlock));
  735. return pnode;
  736. }
  737. // Create ParseNodeVar
  738. ParseNodeVar * Parser::CreateDeclNode(OpCode nop, IdentPtr pid, SymbolType symbolType, bool errorOnRedecl)
  739. {
  740. Assert(nop == knopVarDecl || nop == knopLetDecl || nop == knopConstDecl);
  741. ParseNodeVar * pnode = Anew(&m_nodeAllocator, ParseNodeVar, nop, this->GetScanner()->IchMinTok(), this->GetScanner()->IchLimTok(), pid);
  742. if (symbolType != STUnknown)
  743. {
  744. pnode->sym = AddDeclForPid(pnode, pid, symbolType, errorOnRedecl);
  745. }
  746. return pnode;
  747. }
  748. ParseNodeInt * Parser::CreateIntNode(int32 lw)
  749. {
  750. Assert(!this->m_deferringAST);
  751. ParseNodeInt * pnode = Anew(&m_nodeAllocator, ParseNodeInt, this->GetScanner()->IchMinTok(), this->GetScanner()->IchLimTok(), lw);
  752. AddAstSize(sizeof(ParseNodeInt));
  753. return pnode;
  754. }
  755. ParseNodeStr * Parser::CreateStrNode(IdentPtr pid)
  756. {
  757. Assert(!this->m_deferringAST);
  758. ParseNodeStr * pnode = Anew(&m_nodeAllocator, ParseNodeStr, this->GetScanner()->IchMinTok(), this->GetScanner()->IchLimTok(), pid);
  759. pnode->grfpn |= PNodeFlags::fpnCanFlattenConcatExpr;
  760. AddAstSize(sizeof(ParseNodeStr));
  761. return pnode;
  762. }
  763. ParseNodeName * Parser::CreateNameNode(IdentPtr pid)
  764. {
  765. ParseNodeName * pnode = Anew(&m_nodeAllocator, ParseNodeName, this->GetScanner()->IchMinTok(), this->GetScanner()->IchLimTok(), pid);
  766. AddAstSizeAllowDefer(sizeof(ParseNodeName));
  767. return pnode;
  768. }
  769. ParseNodeName * Parser::CreateNameNode(IdentPtr pid, PidRefStack * ref, charcount_t ichMin, charcount_t ichLim)
  770. {
  771. ParseNodeName * pnode = Anew(&m_nodeAllocator, ParseNodeName, ichMin, ichLim, pid);
  772. pnode->SetSymRef(ref);
  773. AddAstSize(sizeof(ParseNodeName));
  774. return pnode;
  775. }
  776. ParseNodeSpecialName * Parser::CreateSpecialNameNode(IdentPtr pid, PidRefStack * ref, charcount_t ichMin, charcount_t ichLim)
  777. {
  778. Assert(!this->m_deferringAST);
  779. ParseNodeSpecialName * pnode = Anew(&m_nodeAllocator, ParseNodeSpecialName, ichMin, ichLim, pid);
  780. pnode->SetSymRef(ref);
  781. if (pid == wellKnownPropertyPids._this)
  782. {
  783. pnode->isThis = true;
  784. }
  785. else if (pid == wellKnownPropertyPids._super || pid == wellKnownPropertyPids._superConstructor)
  786. {
  787. pnode->isSuper = true;
  788. }
  789. AddAstSize(sizeof(ParseNodeSpecialName));
  790. return pnode;
  791. }
  792. ParseNodeSuperReference * Parser::CreateSuperReferenceNode(OpCode nop, ParseNodeSpecialName * pnode1, ParseNodePtr pnode2)
  793. {
  794. Assert(!this->m_deferringAST);
  795. Assert(pnode1 && pnode1->isSuper);
  796. Assert(pnode2 != nullptr);
  797. Assert(nop == knopDot || nop == knopIndex);
  798. ParseNodeSuperReference * pnode = Anew(&m_nodeAllocator, ParseNodeSuperReference, nop, pnode1->ichMin, pnode2->ichLim, pnode1, pnode2);
  799. AddAstSize(sizeof(ParseNodeSuperReference));
  800. return pnode;
  801. }
  802. ParseNodeProg * Parser::CreateProgNode(bool isModuleSource, ULONG lineNumber)
  803. {
  804. ParseNodeProg * pnodeProg;
  805. if (isModuleSource)
  806. {
  807. pnodeProg = CreateNodeForOpT<knopModule>();
  808. // knopModule is not actually handled anywhere since we would need to handle it everywhere we could
  809. // have knopProg and it would be treated exactly the same except for import/export statements.
  810. // We are only using it as a way to get the correct size for PnModule.
  811. // Consider: Should we add a flag to PnProg which is false but set to true in PnModule?
  812. // If we do, it can't be a virtual method since the parse nodes are all in a union.
  813. pnodeProg->nop = knopProg;
  814. }
  815. else
  816. {
  817. pnodeProg = CreateNodeForOpT<knopProg>();
  818. }
  819. pnodeProg->cbMin = this->GetScanner()->IecpMinTok();
  820. pnodeProg->cbStringMin = pnodeProg->cbMin;
  821. pnodeProg->lineNumber = lineNumber;
  822. pnodeProg->homeObjLocation = Js::Constants::NoRegister;
  823. pnodeProg->superRestrictionState = SuperRestrictionState::Disallowed;
  824. return pnodeProg;
  825. }
  826. ParseNodeCall * Parser::CreateCallNode(OpCode nop, ParseNodePtr pnode1, ParseNodePtr pnode2)
  827. {
  828. charcount_t ichMin;
  829. charcount_t ichLim;
  830. if (nullptr == pnode1)
  831. {
  832. Assert(nullptr == pnode2);
  833. ichMin = this->GetScanner()->IchMinTok();
  834. ichLim = this->GetScanner()->IchLimTok();
  835. }
  836. else
  837. {
  838. ichMin = pnode1->ichMin;
  839. ichLim = pnode2 == nullptr ? pnode1->ichLim : pnode2->ichLim;
  840. if (pnode1->nop == knopDot || pnode1->nop == knopIndex)
  841. {
  842. this->CheckArguments(pnode1->AsParseNodeBin()->pnode1);
  843. }
  844. }
  845. return CreateCallNode(nop, pnode1, pnode2, ichMin, ichLim);
  846. }
  847. ParseNodeCall * Parser::CreateCallNode(OpCode nop, ParseNodePtr pnode1, ParseNodePtr pnode2, charcount_t ichMin, charcount_t ichLim)
  848. {
  849. Assert(!this->m_deferringAST);
  850. // Classes, derived from ParseNodeCall, can be created here as well,
  851. // as long as their size matches kcbPnCall (that is, they don't add
  852. // any data members of their own).
  853. DebugOnly(VerifyNodeSize(nop, sizeof(ParseNodeCall)));
  854. ParseNodeCall* pnode = Anew(&m_nodeAllocator, ParseNodeCall, nop, ichMin, ichLim, pnode1, pnode2);
  855. AddAstSize(sizeof(ParseNodeCall));
  856. return pnode;
  857. }
  858. ParseNodeSuperCall * Parser::CreateSuperCallNode(ParseNodeSpecialName * pnode1, ParseNodePtr pnode2)
  859. {
  860. Assert(!this->m_deferringAST);
  861. Assert(pnode1 && pnode1->isSuper);
  862. ParseNodeSuperCall* pnode = Anew(&m_nodeAllocator, ParseNodeSuperCall, knopCall, pnode1->ichMin, pnode2 == nullptr ? pnode1->ichLim : pnode2->ichLim, pnode1, pnode2);
  863. AddAstSize(sizeof(ParseNodeSuperCall));
  864. return pnode;
  865. }
  866. ParseNodeParamPattern * Parser::CreateParamPatternNode(ParseNode * pnode1)
  867. {
  868. ParseNodeParamPattern * paramPatternNode = CreateNodeForOpT<knopParamPattern>(pnode1->ichMin, pnode1->ichLim);
  869. paramPatternNode->pnode1 = pnode1;
  870. paramPatternNode->pnodeNext = nullptr;
  871. paramPatternNode->location = Js::Constants::NoRegister;
  872. return paramPatternNode;
  873. }
  874. ParseNodeParamPattern * Parser::CreateDummyParamPatternNode(charcount_t ichMin)
  875. {
  876. ParseNodeParamPattern * paramPatternNode = CreateNodeForOpT<knopParamPattern>(ichMin);
  877. paramPatternNode->pnode1 = nullptr;
  878. paramPatternNode->pnodeNext = nullptr;
  879. paramPatternNode->location = Js::Constants::NoRegister;
  880. return paramPatternNode;
  881. }
  882. ParseNodeObjLit * Parser::CreateObjectPatternNode(ParseNodePtr pnodeMemberList, charcount_t ichMin, charcount_t ichLim, bool convertToPattern) {
  883. // Count the number of non-rest members in the object
  884. uint32 staticCount = 0;
  885. uint32 computedCount = 0;
  886. bool hasRest = false;
  887. ParseNodePtr pnodeMemberNodeList = convertToPattern ? nullptr : pnodeMemberList;
  888. if (pnodeMemberList != nullptr)
  889. {
  890. Assert(pnodeMemberList->nop == knopList ||
  891. (!convertToPattern && pnodeMemberList->nop == knopObjectPatternMember) ||
  892. convertToPattern ||
  893. pnodeMemberList->nop == knopEllipsis);
  894. ForEachItemInList(pnodeMemberList, [&](ParseNodePtr item) {
  895. ParseNodePtr memberNode = convertToPattern ? ConvertMemberToMemberPattern(item) : item;
  896. if (convertToPattern)
  897. {
  898. AppendToList(&pnodeMemberNodeList, memberNode);
  899. }
  900. if (memberNode->nop != knopEllipsis)
  901. {
  902. ParseNodePtr nameNode = memberNode->AsParseNodeBin()->pnode1;
  903. Assert(nameNode->nop == knopComputedName || nameNode->nop == knopStr);
  904. if (nameNode->nop == knopComputedName)
  905. {
  906. computedCount++;
  907. }
  908. else
  909. {
  910. staticCount++;
  911. }
  912. }
  913. else
  914. {
  915. hasRest = true;
  916. }
  917. });
  918. }
  919. ParseNodeObjLit * objectPatternNode = CreateNodeForOpT<knopObjectPattern>(ichMin, ichLim);
  920. objectPatternNode->pnode1 = pnodeMemberNodeList;
  921. objectPatternNode->computedCount = computedCount;
  922. objectPatternNode->staticCount = staticCount;
  923. objectPatternNode->hasRest = hasRest;
  924. return objectPatternNode;
  925. }
  926. Symbol* Parser::AddDeclForPid(ParseNodeVar * pnodeVar, IdentPtr pid, SymbolType symbolType, bool errorOnRedecl)
  927. {
  928. Assert(pnodeVar->IsVarLetOrConst());
  929. PidRefStack *refForUse = nullptr, *refForDecl = nullptr;
  930. BlockInfoStack *blockInfo;
  931. bool fBlockScope = false;
  932. if (pnodeVar->nop != knopVarDecl || symbolType == STFunction)
  933. {
  934. Assert(m_pstmtCur);
  935. if (m_pstmtCur->GetNop() != knopBlock)
  936. {
  937. // Let/const declared in a bare statement context.
  938. Error(ERRDeclOutOfStmt);
  939. }
  940. if (m_pstmtCur->pstmtOuter && m_pstmtCur->pstmtOuter->GetNop() == knopSwitch)
  941. {
  942. // Let/const declared inside a switch block (requiring conservative use-before-decl check).
  943. pnodeVar->isSwitchStmtDecl = true;
  944. }
  945. fBlockScope = pnodeVar->nop != knopVarDecl ||
  946. (
  947. !GetCurrentBlockInfo()->pnodeBlock->scope ||
  948. GetCurrentBlockInfo()->pnodeBlock->scope->GetScopeType() != ScopeType_GlobalEvalBlock
  949. );
  950. }
  951. if (fBlockScope)
  952. {
  953. blockInfo = GetCurrentBlockInfo();
  954. }
  955. else
  956. {
  957. blockInfo = GetCurrentFunctionBlockInfo();
  958. }
  959. refForDecl = this->FindOrAddPidRef(pid, blockInfo->pnodeBlock->blockId, GetCurrentFunctionNode()->functionId);
  960. if (refForDecl == nullptr)
  961. {
  962. Error(ERRnoMemory);
  963. }
  964. if (refForDecl->funcId != GetCurrentFunctionNode()->functionId)
  965. {
  966. // Fix up the function id, which is incorrect if we're reparsing lambda parameters
  967. Assert(this->m_reparsingLambdaParams);
  968. refForDecl->funcId = GetCurrentFunctionNode()->functionId;
  969. }
  970. if (blockInfo == GetCurrentBlockInfo())
  971. {
  972. refForUse = refForDecl;
  973. }
  974. else
  975. {
  976. refForUse = this->PushPidRef(pid);
  977. }
  978. pnodeVar->symRef = refForUse->GetSymRef();
  979. Symbol *sym = refForDecl->GetSym();
  980. if (sym != nullptr)
  981. {
  982. // Multiple declarations in the same scope. 3 possibilities: error, existing one wins, new one wins.
  983. switch (pnodeVar->nop)
  984. {
  985. case knopLetDecl:
  986. case knopConstDecl:
  987. if (!sym->GetDecl()->AsParseNodeVar()->isBlockScopeFncDeclVar && !sym->IsArguments())
  988. {
  989. // If the built-in arguments is shadowed then don't throw
  990. Assert(errorOnRedecl);
  991. // Redeclaration error.
  992. Error(ERRRedeclaration);
  993. }
  994. else
  995. {
  996. // (New) let/const hides the (old) var
  997. sym->SetSymbolType(symbolType);
  998. sym->SetDecl(pnodeVar);
  999. }
  1000. break;
  1001. case knopVarDecl:
  1002. if (m_currentScope->GetScopeType() == ScopeType_Parameter && !sym->IsArguments())
  1003. {
  1004. // If this is a parameter list, mark the scope to indicate that it has duplicate definition unless it is shadowing the default arguments symbol.
  1005. // If later this turns out to be a non-simple param list (like function f(a, a, c = 1) {}) then it is a SyntaxError to have duplicate formals.
  1006. m_currentScope->SetHasDuplicateFormals();
  1007. }
  1008. if (sym->GetDecl() == nullptr)
  1009. {
  1010. sym->SetDecl(pnodeVar);
  1011. break;
  1012. }
  1013. switch (sym->GetDecl()->nop)
  1014. {
  1015. case knopLetDecl:
  1016. case knopConstDecl:
  1017. // Destructuring made possible to have the formals to be the let bind. But that shouldn't throw the error.
  1018. if (errorOnRedecl && (!IsES6DestructuringEnabled() || sym->GetSymbolType() != STFormal))
  1019. {
  1020. Error(ERRRedeclaration);
  1021. }
  1022. // If !errorOnRedecl, (old) let/const hides the (new) var, so do nothing.
  1023. break;
  1024. case knopVarDecl:
  1025. // Legal redeclaration. Who wins?
  1026. if (errorOnRedecl || sym->GetDecl()->AsParseNodeVar()->isBlockScopeFncDeclVar || sym->IsArguments())
  1027. {
  1028. if (symbolType == STFormal ||
  1029. (symbolType == STFunction && sym->GetSymbolType() != STFormal) ||
  1030. sym->GetSymbolType() == STVariable)
  1031. {
  1032. // New decl wins.
  1033. sym->SetSymbolType(symbolType);
  1034. sym->SetDecl(pnodeVar);
  1035. }
  1036. }
  1037. break;
  1038. }
  1039. break;
  1040. }
  1041. }
  1042. else
  1043. {
  1044. Scope *scope = blockInfo->pnodeBlock->scope;
  1045. if (scope == nullptr)
  1046. {
  1047. Assert(blockInfo->pnodeBlock->blockType == PnodeBlockType::Regular);
  1048. scope = Anew(&m_nodeAllocator, Scope, &m_nodeAllocator, ScopeType_Block);
  1049. if (this->IsCurBlockInLoop())
  1050. {
  1051. scope->SetIsBlockInLoop();
  1052. }
  1053. blockInfo->pnodeBlock->scope = scope;
  1054. PushScope(scope);
  1055. }
  1056. ParseNodeFnc * pnodeFnc = GetCurrentFunctionNode();
  1057. if (scope->GetScopeType() == ScopeType_GlobalEvalBlock)
  1058. {
  1059. Assert(fBlockScope);
  1060. Assert(scope->GetEnclosingScope() == m_currentNodeProg->scope);
  1061. // Check for same-named decl in Global scope.
  1062. CheckRedeclarationErrorForBlockId(pid, 0);
  1063. }
  1064. else if (scope->GetScopeType() == ScopeType_Global && (this->m_grfscr & fscrEvalCode) &&
  1065. !(m_functionBody && m_functionBody->GetScopeInfo()))
  1066. {
  1067. // Check for same-named decl in GlobalEvalBlock scope. Note that this is not necessary
  1068. // if we're compiling a deferred nested function and the global scope was restored from cached info,
  1069. // because in that case we don't need a GlobalEvalScope.
  1070. Assert(!fBlockScope || (this->m_grfscr & fscrConsoleScopeEval) == fscrConsoleScopeEval);
  1071. CheckRedeclarationErrorForBlockId(pid, 1);
  1072. }
  1073. else if (!pnodeFnc->IsBodyAndParamScopeMerged()
  1074. && scope->GetScopeType() == ScopeType_FunctionBody
  1075. && (pnodeVar->nop == knopLetDecl || pnodeVar->nop == knopConstDecl))
  1076. {
  1077. // In case of split scope function when we add a new let or const declaration to the body
  1078. // we have to check whether the param scope already has the same symbol defined.
  1079. CheckRedeclarationErrorForBlockId(pid, pnodeFnc->pnodeScopes->blockId);
  1080. }
  1081. if (!sym)
  1082. {
  1083. const char16 *name = reinterpret_cast<const char16*>(pid->Psz());
  1084. int nameLength = pid->Cch();
  1085. SymbolName const symName(name, nameLength);
  1086. Assert(!scope->FindLocalSymbol(symName));
  1087. sym = Anew(&m_nodeAllocator, Symbol, symName, pnodeVar, symbolType);
  1088. scope->AddNewSymbol(sym);
  1089. sym->SetPid(pid);
  1090. }
  1091. refForDecl->SetSym(sym);
  1092. }
  1093. return sym;
  1094. }
  1095. void Parser::CheckRedeclarationErrorForBlockId(IdentPtr pid, int blockId)
  1096. {
  1097. // If the ref stack entry for the blockId contains a sym then throw redeclaration error
  1098. PidRefStack *pidRefOld = pid->GetPidRefForScopeId(blockId);
  1099. if (pidRefOld && pidRefOld->GetSym() && !pidRefOld->GetSym()->IsArguments())
  1100. {
  1101. Error(ERRRedeclaration);
  1102. }
  1103. }
  1104. bool Parser::IsCurBlockInLoop() const
  1105. {
  1106. for (StmtNest *stmt = this->m_pstmtCur; stmt != nullptr; stmt = stmt->pstmtOuter)
  1107. {
  1108. OpCode nop = stmt->GetNop();
  1109. if (ParseNode::Grfnop(nop) & fnopContinue)
  1110. {
  1111. return true;
  1112. }
  1113. if (nop == knopFncDecl)
  1114. {
  1115. return false;
  1116. }
  1117. }
  1118. return false;
  1119. }
  1120. void Parser::RestorePidRefForSym(Symbol *sym)
  1121. {
  1122. IdentPtr pid = this->GetHashTbl()->PidHashNameLen(sym->GetName().GetBuffer(), sym->GetName().GetLength());
  1123. Assert(pid);
  1124. sym->SetPid(pid);
  1125. PidRefStack *ref = this->PushPidRef(pid);
  1126. ref->SetSym(sym);
  1127. }
  1128. void Parser::CheckPidIsValid(IdentPtr pid, bool autoArgumentsObject)
  1129. {
  1130. if (IsStrictMode())
  1131. {
  1132. // in strict mode, variable named 'eval' cannot be created
  1133. if (pid == wellKnownPropertyPids.eval)
  1134. {
  1135. Error(ERREvalUsage);
  1136. }
  1137. else if (pid == wellKnownPropertyPids.arguments && !autoArgumentsObject)
  1138. {
  1139. Error(ERRArgsUsage);
  1140. }
  1141. }
  1142. }
  1143. // CreateVarDecl needs m_ppnodeVar to be pointing to the right function.
  1144. // Post-parsing rewriting during bytecode gen may have m_ppnodeVar pointing to the last parsed function.
  1145. // This function sets up m_ppnodeVar to point to the given pnodeFnc and creates the new var declaration.
  1146. // This prevents accidentally adding var declarations to the last parsed function.
  1147. ParseNodeVar * Parser::AddVarDeclNode(IdentPtr pid, ParseNodeFnc * pnodeFnc)
  1148. {
  1149. AnalysisAssert(pnodeFnc);
  1150. ParseNodePtr *const ppnodeVarSave = m_ppnodeVar;
  1151. m_ppnodeVar = &pnodeFnc->pnodeVars;
  1152. while (*m_ppnodeVar != nullptr)
  1153. {
  1154. m_ppnodeVar = &(*m_ppnodeVar)->AsParseNodeVar()->pnodeNext;
  1155. }
  1156. ParseNodeVar * pnode = CreateVarDeclNode(pid, STUnknown, false, 0, /* checkReDecl = */ false);
  1157. m_ppnodeVar = ppnodeVarSave;
  1158. return pnode;
  1159. }
  1160. ParseNodeVar * Parser::CreateModuleImportDeclNode(IdentPtr localName)
  1161. {
  1162. ParseNodeVar * declNode = CreateBlockScopedDeclNode(localName, knopConstDecl);
  1163. Symbol* sym = declNode->sym;
  1164. sym->SetIsModuleExportStorage(true);
  1165. sym->SetIsModuleImport(true);
  1166. return declNode;
  1167. }
  1168. ParseNodeVar * Parser::CreateVarDeclNode(IdentPtr pid, SymbolType symbolType, bool autoArgumentsObject, ParseNodePtr pnodeFnc, bool errorOnRedecl)
  1169. {
  1170. ParseNodeVar * pnode = CreateDeclNode(knopVarDecl, pid, symbolType, errorOnRedecl);
  1171. // Append the variable to the end of the current variable list.
  1172. Assert(m_ppnodeVar);
  1173. pnode->pnodeNext = *m_ppnodeVar;
  1174. *m_ppnodeVar = pnode;
  1175. if (nullptr != pid)
  1176. {
  1177. // this is not a temp - make sure temps go after this node
  1178. Assert(pid);
  1179. m_ppnodeVar = &pnode->pnodeNext;
  1180. CheckPidIsValid(pid, autoArgumentsObject);
  1181. }
  1182. return pnode;
  1183. }
  1184. ParseNodeVar * Parser::CreateBlockScopedDeclNode(IdentPtr pid, OpCode nodeType)
  1185. {
  1186. Assert(nodeType == knopConstDecl || nodeType == knopLetDecl);
  1187. ParseNodeVar * pnode = CreateDeclNode(nodeType, pid, STVariable, true);
  1188. if (nullptr != pid)
  1189. {
  1190. Assert(pid);
  1191. AddVarDeclToBlock(pnode);
  1192. CheckPidIsValid(pid);
  1193. }
  1194. return pnode;
  1195. }
  1196. void Parser::AddVarDeclToBlock(ParseNodeVar *pnode)
  1197. {
  1198. Assert(pnode->nop == knopConstDecl || pnode->nop == knopLetDecl);
  1199. // Maintain a combined list of let and const declarations to keep
  1200. // track of declaration order.
  1201. Assert(m_currentBlockInfo->m_ppnodeLex);
  1202. *m_currentBlockInfo->m_ppnodeLex = pnode;
  1203. m_currentBlockInfo->m_ppnodeLex = &pnode->pnodeNext;
  1204. pnode->pnodeNext = nullptr;
  1205. }
  1206. void Parser::SetCurrentStatement(StmtNest *stmt)
  1207. {
  1208. m_pstmtCur = stmt;
  1209. }
  1210. template<bool buildAST>
  1211. ParseNodeBlock * Parser::StartParseBlockWithCapacity(PnodeBlockType blockType, ScopeType scopeType, int capacity)
  1212. {
  1213. Scope *scope = nullptr;
  1214. // Block scopes are not created lazily in the case where we're repopulating a persisted scope.
  1215. scope = Anew(&m_nodeAllocator, Scope, &m_nodeAllocator, scopeType, capacity);
  1216. PushScope(scope);
  1217. return StartParseBlockHelper<buildAST>(blockType, scope, nullptr);
  1218. }
  1219. template<bool buildAST>
  1220. ParseNodeBlock * Parser::StartParseBlock(PnodeBlockType blockType, ScopeType scopeType, LabelId* pLabelId)
  1221. {
  1222. Scope *scope = nullptr;
  1223. // Block scopes are created lazily when we discover block-scoped content.
  1224. if (scopeType != ScopeType_Unknown && scopeType != ScopeType_Block)
  1225. {
  1226. scope = Anew(&m_nodeAllocator, Scope, &m_nodeAllocator, scopeType);
  1227. PushScope(scope);
  1228. }
  1229. return StartParseBlockHelper<buildAST>(blockType, scope, pLabelId);
  1230. }
  1231. template<bool buildAST>
  1232. ParseNodeBlock * Parser::StartParseBlockHelper(PnodeBlockType blockType, Scope *scope, LabelId* pLabelId)
  1233. {
  1234. ParseNodeBlock * pnodeBlock = CreateBlockNode(blockType);
  1235. pnodeBlock->scope = scope;
  1236. BlockInfoStack *newBlockInfo = PushBlockInfo(pnodeBlock);
  1237. PushStmt<buildAST>(&newBlockInfo->pstmt, pnodeBlock, knopBlock, pLabelId);
  1238. return pnodeBlock;
  1239. }
  1240. void Parser::PushScope(Scope *scope)
  1241. {
  1242. Assert(scope);
  1243. scope->SetEnclosingScope(m_currentScope);
  1244. m_currentScope = scope;
  1245. }
  1246. void Parser::PopScope(Scope *scope)
  1247. {
  1248. Assert(scope == m_currentScope);
  1249. m_currentScope = scope->GetEnclosingScope();
  1250. scope->SetEnclosingScope(nullptr);
  1251. }
  1252. void Parser::PushFuncBlockScope(ParseNodeBlock * pnodeBlock, ParseNodePtr **ppnodeScopeSave, ParseNodePtr **ppnodeExprScopeSave)
  1253. {
  1254. // Maintain the scope tree.
  1255. pnodeBlock->pnodeScopes = nullptr;
  1256. pnodeBlock->pnodeNext = nullptr;
  1257. // Insert this block into the active list of scopes (m_ppnodeExprScope or m_ppnodeScope).
  1258. // Save the current block's "next" pointer as the new endpoint of that list.
  1259. if (m_ppnodeExprScope)
  1260. {
  1261. *ppnodeScopeSave = m_ppnodeScope;
  1262. Assert(*m_ppnodeExprScope == nullptr);
  1263. *m_ppnodeExprScope = pnodeBlock;
  1264. *ppnodeExprScopeSave = &pnodeBlock->pnodeNext;
  1265. }
  1266. else
  1267. {
  1268. Assert(m_ppnodeScope);
  1269. Assert(*m_ppnodeScope == nullptr);
  1270. *m_ppnodeScope = pnodeBlock;
  1271. *ppnodeScopeSave = &pnodeBlock->pnodeNext;
  1272. *ppnodeExprScopeSave = m_ppnodeExprScope;
  1273. }
  1274. // Advance the global scope list pointer to the new block's child list.
  1275. m_ppnodeScope = &pnodeBlock->pnodeScopes;
  1276. // Set m_ppnodeExprScope to NULL to make that list inactive.
  1277. m_ppnodeExprScope = nullptr;
  1278. }
  1279. void Parser::PopFuncBlockScope(ParseNodePtr *ppnodeScopeSave, ParseNodePtr *ppnodeExprScopeSave)
  1280. {
  1281. Assert(m_ppnodeExprScope == nullptr || *m_ppnodeExprScope == nullptr);
  1282. m_ppnodeExprScope = ppnodeExprScopeSave;
  1283. Assert(m_ppnodeScope);
  1284. Assert(nullptr == *m_ppnodeScope);
  1285. m_ppnodeScope = ppnodeScopeSave;
  1286. }
  1287. template<bool buildAST>
  1288. ParseNodeBlock * Parser::ParseBlock(LabelId* pLabelId)
  1289. {
  1290. ParseNodeBlock * pnodeBlock = nullptr;
  1291. ParseNodePtr *ppnodeScopeSave = nullptr;
  1292. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  1293. pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Regular, ScopeType_Block, pLabelId);
  1294. BlockInfoStack* outerBlockInfo = m_currentBlockInfo->pBlockInfoOuter;
  1295. if (outerBlockInfo != nullptr && outerBlockInfo->pnodeBlock != nullptr
  1296. && outerBlockInfo->pnodeBlock->scope != nullptr
  1297. && outerBlockInfo->pnodeBlock->scope->GetScopeType() == ScopeType_CatchParamPattern)
  1298. {
  1299. // If we are parsing the catch block then destructured params can have let declarations. Let's add them to the new block.
  1300. for (ParseNodePtr pnode = m_currentBlockInfo->pBlockInfoOuter->pnodeBlock->pnodeLexVars; pnode; pnode = pnode->AsParseNodeVar()->pnodeNext)
  1301. {
  1302. PidRefStack* ref = PushPidRef(pnode->AsParseNodeVar()->sym->GetPid());
  1303. ref->SetSym(pnode->AsParseNodeVar()->sym);
  1304. }
  1305. }
  1306. ChkCurTok(tkLCurly, ERRnoLcurly);
  1307. ParseNodePtr * ppnodeList = nullptr;
  1308. if (buildAST)
  1309. {
  1310. PushFuncBlockScope(pnodeBlock, &ppnodeScopeSave, &ppnodeExprScopeSave);
  1311. ppnodeList = &pnodeBlock->pnodeStmt;
  1312. }
  1313. ParseStmtList<buildAST>(ppnodeList);
  1314. if (buildAST)
  1315. {
  1316. PopFuncBlockScope(ppnodeScopeSave, ppnodeExprScopeSave);
  1317. }
  1318. FinishParseBlock(pnodeBlock);
  1319. ChkCurTok(tkRCurly, ERRnoRcurly);
  1320. return pnodeBlock;
  1321. }
  1322. bool Parser::IsSpecialName(IdentPtr pid)
  1323. {
  1324. return pid == wellKnownPropertyPids._this ||
  1325. pid == wellKnownPropertyPids._super ||
  1326. pid == wellKnownPropertyPids._superConstructor ||
  1327. pid == wellKnownPropertyPids._newTarget;
  1328. }
  1329. ParseNodeSpecialName * Parser::ReferenceSpecialName(IdentPtr pid, charcount_t ichMin, charcount_t ichLim, bool createNode)
  1330. {
  1331. PidRefStack* ref = this->PushPidRef(pid);
  1332. if (!createNode)
  1333. {
  1334. return nullptr;
  1335. }
  1336. return CreateSpecialNameNode(pid, ref, ichMin, ichLim);
  1337. }
  1338. ParseNodeVar * Parser::CreateSpecialVarDeclIfNeeded(ParseNodeFnc * pnodeFnc, IdentPtr pid, bool forceCreate)
  1339. {
  1340. Assert(pid != nullptr);
  1341. PidRefStack* ref = pid->GetTopRef();
  1342. // If the function has a reference to pid or we set forceCreate, make a special var decl
  1343. if (forceCreate || (ref && ref->GetScopeId() >= m_currentBlockInfo->pnodeBlock->blockId))
  1344. {
  1345. return this->CreateSpecialVarDeclNode(pnodeFnc, pid);
  1346. }
  1347. return nullptr;
  1348. }
  1349. void Parser::CreateSpecialSymbolDeclarations(ParseNodeFnc * pnodeFnc)
  1350. {
  1351. // Lambda function cannot have any special bindings.
  1352. if (pnodeFnc->IsLambda())
  1353. {
  1354. return;
  1355. }
  1356. bool isTopLevelEventHandler = (this->m_grfscr & fscrImplicitThis) && !pnodeFnc->IsNested();
  1357. // Create a 'this' symbol for non-lambda functions with references to 'this', and all class constructors and top level event hanlders.
  1358. ParseNodePtr varDeclNode = CreateSpecialVarDeclIfNeeded(pnodeFnc, wellKnownPropertyPids._this, pnodeFnc->IsClassConstructor() || isTopLevelEventHandler);
  1359. if (varDeclNode)
  1360. {
  1361. varDeclNode->AsParseNodeVar()->sym->SetIsThis(true);
  1362. if (pnodeFnc->IsDerivedClassConstructor())
  1363. {
  1364. varDeclNode->AsParseNodeVar()->sym->SetNeedDeclaration(true);
  1365. }
  1366. }
  1367. // Create a 'new.target' symbol for any ordinary function with a reference and all class constructors.
  1368. varDeclNode = CreateSpecialVarDeclIfNeeded(pnodeFnc, wellKnownPropertyPids._newTarget, pnodeFnc->IsClassConstructor());
  1369. if (varDeclNode)
  1370. {
  1371. varDeclNode->AsParseNodeVar()->sym->SetIsNewTarget(true);
  1372. }
  1373. // Create a 'super' (as a reference) symbol.
  1374. varDeclNode = CreateSpecialVarDeclIfNeeded(pnodeFnc, wellKnownPropertyPids._super);
  1375. if (varDeclNode)
  1376. {
  1377. varDeclNode->AsParseNodeVar()->sym->SetIsSuper(true);
  1378. }
  1379. // Create a 'super' (as the call target for super()) symbol only for derived class constructors.
  1380. varDeclNode = CreateSpecialVarDeclIfNeeded(pnodeFnc, wellKnownPropertyPids._superConstructor);
  1381. if (varDeclNode)
  1382. {
  1383. varDeclNode->AsParseNodeVar()->sym->SetIsSuperConstructor(true);
  1384. }
  1385. }
  1386. void Parser::FinishParseBlock(ParseNodeBlock *pnodeBlock, bool needScanRCurly)
  1387. {
  1388. Assert(m_currentBlockInfo != nullptr && pnodeBlock == m_currentBlockInfo->pnodeBlock);
  1389. if (needScanRCurly)
  1390. {
  1391. // Only update the ichLim if we were expecting an RCurly. If there is an
  1392. // expression body without a necessary RCurly, the correct ichLim will
  1393. // have been set already.
  1394. pnodeBlock->ichLim = this->GetScanner()->IchLimTok();
  1395. }
  1396. BindPidRefs<false>(GetCurrentBlockInfo(), m_nextBlockId - 1);
  1397. PopStmt(&m_currentBlockInfo->pstmt);
  1398. PopBlockInfo();
  1399. Scope *scope = pnodeBlock->scope;
  1400. if (scope)
  1401. {
  1402. PopScope(scope);
  1403. }
  1404. }
  1405. void Parser::FinishParseFncExprScope(ParseNodeFnc * pnodeFnc, ParseNodeBlock * pnodeFncExprScope)
  1406. {
  1407. int fncExprScopeId = pnodeFncExprScope->blockId;
  1408. ParseNodePtr pnodeName = pnodeFnc->pnodeName;
  1409. if (pnodeName)
  1410. {
  1411. Assert(pnodeName->nop == knopVarDecl);
  1412. BindPidRefsInScope(pnodeName->AsParseNodeVar()->pid, pnodeName->AsParseNodeVar()->sym, fncExprScopeId, m_nextBlockId - 1);
  1413. }
  1414. FinishParseBlock(pnodeFncExprScope);
  1415. }
  1416. template <const bool backgroundPidRef>
  1417. void Parser::BindPidRefs(BlockInfoStack *blockInfo, uint maxBlockId)
  1418. {
  1419. // We need to bind all assignments in order to emit assignment to 'const' error
  1420. int blockId = blockInfo->pnodeBlock->blockId;
  1421. Scope *scope = blockInfo->pnodeBlock->scope;
  1422. if (scope)
  1423. {
  1424. auto bindPidRefs = [blockId, maxBlockId, this](Symbol *sym)
  1425. {
  1426. ParseNodePtr pnode = sym->GetDecl();
  1427. IdentPtr pid;
  1428. #if PROFILE_DICTIONARY
  1429. int depth = 0;
  1430. #endif
  1431. Assert(pnode);
  1432. switch (pnode->nop)
  1433. {
  1434. case knopVarDecl:
  1435. case knopLetDecl:
  1436. case knopConstDecl:
  1437. pid = pnode->AsParseNodeVar()->pid;
  1438. if (backgroundPidRef)
  1439. {
  1440. pid = this->GetHashTbl()->FindExistingPid(pid->Psz(), pid->Psz() + pid->Cch(), pid->Cch(), pid->Hash(), nullptr, nullptr
  1441. #if PROFILE_DICTIONARY
  1442. , depth
  1443. #endif
  1444. );
  1445. if (pid == nullptr)
  1446. {
  1447. break;
  1448. }
  1449. }
  1450. this->BindPidRefsInScope(pid, sym, blockId, maxBlockId);
  1451. break;
  1452. case knopName:
  1453. pid = pnode->AsParseNodeName()->pid;
  1454. if (backgroundPidRef)
  1455. {
  1456. pid = this->GetHashTbl()->FindExistingPid(pid->Psz(), pid->Psz() + pid->Cch(), pid->Cch(), pid->Hash(), nullptr, nullptr
  1457. #if PROFILE_DICTIONARY
  1458. , depth
  1459. #endif
  1460. );
  1461. if (pid == nullptr)
  1462. {
  1463. break;
  1464. }
  1465. }
  1466. this->BindPidRefsInScope(pid, sym, blockId, maxBlockId);
  1467. break;
  1468. default:
  1469. Assert(0);
  1470. break;
  1471. }
  1472. };
  1473. scope->ForEachSymbol(bindPidRefs);
  1474. }
  1475. }
  1476. void Parser::BindPidRefsInScope(IdentPtr pid, Symbol *sym, int blockId, uint maxBlockId)
  1477. {
  1478. PidRefStack *ref, *nextRef, *lastRef = nullptr;
  1479. Js::LocalFunctionId funcId = GetCurrentFunctionNode()->functionId;
  1480. Assert(sym);
  1481. if (pid->GetIsModuleExport() && IsTopLevelModuleFunc())
  1482. {
  1483. sym->SetIsModuleExportStorage(true);
  1484. }
  1485. bool hasFuncAssignment = sym->GetHasFuncAssignment();
  1486. bool doesEscape = false;
  1487. for (ref = pid->GetTopRef(); ref && ref->GetScopeId() >= blockId; ref = nextRef)
  1488. {
  1489. // Fix up sym* on PID ref.
  1490. Assert(!ref->GetSym() || ref->GetSym() == sym);
  1491. nextRef = ref->prev;
  1492. Assert(ref->GetScopeId() >= 0);
  1493. if ((uint)ref->GetScopeId() > maxBlockId)
  1494. {
  1495. lastRef = ref;
  1496. continue;
  1497. }
  1498. ref->SetSym(sym);
  1499. this->RemovePrevPidRef(pid, lastRef);
  1500. if (ref->IsUsedInLdElem())
  1501. {
  1502. sym->SetIsUsedInLdElem(true);
  1503. }
  1504. if (ref->IsAssignment())
  1505. {
  1506. sym->PromoteAssignmentState();
  1507. if (sym->GetIsFormal())
  1508. {
  1509. GetCurrentFunctionNode()->SetHasAnyWriteToFormals(true);
  1510. }
  1511. }
  1512. if (ref->GetFuncScopeId() != funcId && !sym->GetIsGlobal() && !sym->GetIsModuleExportStorage())
  1513. {
  1514. Assert(ref->GetFuncScopeId() > funcId);
  1515. sym->SetHasNonLocalReference();
  1516. if (ref->IsDynamicBinding())
  1517. {
  1518. sym->SetNeedsScopeObject();
  1519. }
  1520. }
  1521. if (ref->IsFuncAssignment())
  1522. {
  1523. hasFuncAssignment = true;
  1524. }
  1525. if (ref->IsEscape())
  1526. {
  1527. doesEscape = true;
  1528. }
  1529. if (m_currentNodeFunc && doesEscape && hasFuncAssignment)
  1530. {
  1531. if (m_sourceContextInfo ?
  1532. !PHASE_OFF_RAW(Js::DisableStackFuncOnDeferredEscapePhase, m_sourceContextInfo->sourceContextId, m_currentNodeFunc->functionId) :
  1533. !PHASE_OFF1(Js::DisableStackFuncOnDeferredEscapePhase))
  1534. {
  1535. m_currentNodeFunc->SetNestedFuncEscapes();
  1536. }
  1537. }
  1538. if (ref->GetScopeId() == blockId)
  1539. {
  1540. break;
  1541. }
  1542. }
  1543. }
  1544. void Parser::MarkEscapingRef(ParseNodePtr pnode, IdentToken *pToken)
  1545. {
  1546. if (m_currentNodeFunc == nullptr)
  1547. {
  1548. return;
  1549. }
  1550. if (pnode && pnode->nop == knopFncDecl)
  1551. {
  1552. this->SetNestedFuncEscapes();
  1553. }
  1554. else if (pToken->pid)
  1555. {
  1556. PidRefStack *pidRef = pToken->pid->GetTopRef();
  1557. if (pidRef->sym)
  1558. {
  1559. if (pidRef->sym->GetSymbolType() == STFunction)
  1560. {
  1561. this->SetNestedFuncEscapes();
  1562. }
  1563. }
  1564. else
  1565. {
  1566. pidRef->isEscape = true;
  1567. }
  1568. }
  1569. }
  1570. void Parser::SetNestedFuncEscapes() const
  1571. {
  1572. if (m_sourceContextInfo ?
  1573. !PHASE_OFF_RAW(Js::DisableStackFuncOnDeferredEscapePhase, m_sourceContextInfo->sourceContextId, m_currentNodeFunc->functionId) :
  1574. !PHASE_OFF1(Js::DisableStackFuncOnDeferredEscapePhase))
  1575. {
  1576. m_currentNodeFunc->SetNestedFuncEscapes();
  1577. }
  1578. }
  1579. void Parser::PopStmt(StmtNest *pStmt)
  1580. {
  1581. Assert(pStmt == m_pstmtCur);
  1582. SetCurrentStatement(m_pstmtCur->pstmtOuter);
  1583. }
  1584. BlockInfoStack *Parser::PushBlockInfo(ParseNodeBlock * pnodeBlock)
  1585. {
  1586. BlockInfoStack *newBlockInfo = (BlockInfoStack *)m_nodeAllocator.Alloc(sizeof(BlockInfoStack));
  1587. Assert(nullptr != newBlockInfo);
  1588. newBlockInfo->pnodeBlock = pnodeBlock;
  1589. newBlockInfo->pBlockInfoOuter = m_currentBlockInfo;
  1590. newBlockInfo->m_ppnodeLex = &pnodeBlock->pnodeLexVars;
  1591. if (pnodeBlock->blockType != PnodeBlockType::Regular)
  1592. {
  1593. newBlockInfo->pBlockInfoFunction = newBlockInfo;
  1594. }
  1595. else
  1596. {
  1597. Assert(m_currentBlockInfo);
  1598. newBlockInfo->pBlockInfoFunction = m_currentBlockInfo->pBlockInfoFunction;
  1599. }
  1600. m_currentBlockInfo = newBlockInfo;
  1601. return newBlockInfo;
  1602. }
  1603. void Parser::PopBlockInfo()
  1604. {
  1605. Assert(m_currentBlockInfo);
  1606. PopDynamicBlock();
  1607. m_currentBlockInfo = m_currentBlockInfo->pBlockInfoOuter;
  1608. }
  1609. void Parser::PushDynamicBlock()
  1610. {
  1611. Assert(GetCurrentBlock());
  1612. int blockId = GetCurrentBlock()->blockId;
  1613. if (m_currentDynamicBlock && m_currentDynamicBlock->id == blockId)
  1614. {
  1615. return;
  1616. }
  1617. BlockIdsStack *info = (BlockIdsStack *)m_nodeAllocator.Alloc(sizeof(BlockIdsStack));
  1618. if (nullptr == info)
  1619. {
  1620. Error(ERRnoMemory);
  1621. }
  1622. info->id = blockId;
  1623. info->prev = m_currentDynamicBlock;
  1624. m_currentDynamicBlock = info;
  1625. }
  1626. void Parser::PopDynamicBlock()
  1627. {
  1628. int blockId = GetCurrentDynamicBlockId();
  1629. if (GetCurrentBlock()->blockId != blockId || blockId == -1)
  1630. {
  1631. return;
  1632. }
  1633. Assert(m_currentDynamicBlock);
  1634. this->GetHashTbl()->VisitPids([&](IdentPtr pid) {
  1635. for (PidRefStack *ref = pid->GetTopRef(); ref && ref->GetScopeId() >= blockId; ref = ref->prev)
  1636. {
  1637. ref->SetDynamicBinding();
  1638. }
  1639. });
  1640. m_currentDynamicBlock = m_currentDynamicBlock->prev;
  1641. }
  1642. int Parser::GetCurrentDynamicBlockId() const
  1643. {
  1644. return m_currentDynamicBlock ? m_currentDynamicBlock->id : -1;
  1645. }
  1646. ParseNodeFnc *Parser::GetCurrentFunctionNode()
  1647. {
  1648. if (m_currentNodeDeferredFunc != nullptr)
  1649. {
  1650. return m_currentNodeDeferredFunc;
  1651. }
  1652. else if (m_currentNodeFunc != nullptr)
  1653. {
  1654. return m_currentNodeFunc;
  1655. }
  1656. else
  1657. {
  1658. AssertMsg(GetFunctionBlock()->blockType == PnodeBlockType::Global,
  1659. "Most likely we are trying to find a syntax error, related to 'let' or 'const' in deferred parsing mode with disabled support of 'let' and 'const'");
  1660. return m_currentNodeProg;
  1661. }
  1662. }
  1663. ParseNodeFnc *Parser::GetCurrentNonLambdaFunctionNode()
  1664. {
  1665. if (m_currentNodeNonLambdaDeferredFunc != nullptr)
  1666. {
  1667. return m_currentNodeNonLambdaDeferredFunc;
  1668. }
  1669. return m_currentNodeNonLambdaFunc;
  1670. }
  1671. void Parser::RegisterRegexPattern(UnifiedRegex::RegexPattern *const regexPattern)
  1672. {
  1673. Assert(regexPattern);
  1674. // ensure a no-throw add behavior here, to catch out of memory exceptions, using the guest arena allocator
  1675. if (!m_registeredRegexPatterns.PrependNoThrow(m_tempGuestArena->GetAllocator(), regexPattern))
  1676. {
  1677. Parser::Error(ERRnoMemory);
  1678. }
  1679. }
  1680. void Parser::CaptureState(ParserState *state)
  1681. {
  1682. Assert(state != nullptr);
  1683. state->m_funcInArraySave = m_funcInArray;
  1684. state->m_funcInArrayDepthSave = m_funcInArrayDepth;
  1685. state->m_nestedCountSave = *m_pnestedCount;
  1686. state->m_ppnodeScopeSave = m_ppnodeScope;
  1687. state->m_ppnodeExprScopeSave = m_ppnodeExprScope;
  1688. state->m_pCurrentAstSizeSave = m_pCurrentAstSize;
  1689. state->m_nextBlockId = m_nextBlockId;
  1690. Assert(state->m_ppnodeScopeSave == nullptr || *state->m_ppnodeScopeSave == nullptr);
  1691. Assert(state->m_ppnodeExprScopeSave == nullptr || *state->m_ppnodeExprScopeSave == nullptr);
  1692. #if DEBUG
  1693. state->m_currentBlockInfo = m_currentBlockInfo;
  1694. #endif
  1695. }
  1696. void Parser::RestoreStateFrom(ParserState *state)
  1697. {
  1698. Assert(state != nullptr);
  1699. Assert(state->m_currentBlockInfo == m_currentBlockInfo);
  1700. m_funcInArray = state->m_funcInArraySave;
  1701. m_funcInArrayDepth = state->m_funcInArrayDepthSave;
  1702. *m_pnestedCount = state->m_nestedCountSave;
  1703. m_pCurrentAstSize = state->m_pCurrentAstSizeSave;
  1704. m_nextBlockId = state->m_nextBlockId;
  1705. if (state->m_ppnodeScopeSave != nullptr)
  1706. {
  1707. *state->m_ppnodeScopeSave = nullptr;
  1708. }
  1709. if (state->m_ppnodeExprScopeSave != nullptr)
  1710. {
  1711. *state->m_ppnodeExprScopeSave = nullptr;
  1712. }
  1713. m_ppnodeScope = state->m_ppnodeScopeSave;
  1714. m_ppnodeExprScope = state->m_ppnodeExprScopeSave;
  1715. }
  1716. void Parser::AddToNodeListEscapedUse(ParseNode ** ppnodeList, ParseNode *** pppnodeLast,
  1717. ParseNode * pnodeAdd)
  1718. {
  1719. AddToNodeList(ppnodeList, pppnodeLast, pnodeAdd);
  1720. pnodeAdd->SetIsInList();
  1721. }
  1722. void Parser::AddToNodeList(ParseNode ** ppnodeList, ParseNode *** pppnodeLast,
  1723. ParseNode * pnodeAdd)
  1724. {
  1725. Assert(!this->m_deferringAST);
  1726. if (nullptr == *pppnodeLast)
  1727. {
  1728. // should be an empty list
  1729. Assert(nullptr == *ppnodeList);
  1730. *ppnodeList = pnodeAdd;
  1731. *pppnodeLast = ppnodeList;
  1732. }
  1733. else
  1734. {
  1735. //
  1736. Assert(*ppnodeList);
  1737. Assert(**pppnodeLast);
  1738. ParseNode *pnodeT = CreateBinNode(knopList, **pppnodeLast, pnodeAdd);
  1739. **pppnodeLast = pnodeT;
  1740. *pppnodeLast = &pnodeT->AsParseNodeBin()->pnode2;
  1741. }
  1742. }
  1743. // Check reference to "arguments" that indicates the object may escape.
  1744. void Parser::CheckArguments(ParseNodePtr pnode)
  1745. {
  1746. if (m_currentNodeFunc && this->NodeIsIdent(pnode, wellKnownPropertyPids.arguments))
  1747. {
  1748. m_currentNodeFunc->SetHasHeapArguments();
  1749. }
  1750. }
  1751. // Check use of "arguments" that requires instantiation of the object.
  1752. void Parser::CheckArgumentsUse(IdentPtr pid, ParseNodeFnc * pnodeFnc)
  1753. {
  1754. if (pid == wellKnownPropertyPids.arguments)
  1755. {
  1756. if (pnodeFnc != nullptr && pnodeFnc != m_currentNodeProg)
  1757. {
  1758. pnodeFnc->SetUsesArguments(TRUE);
  1759. }
  1760. else
  1761. {
  1762. m_UsesArgumentsAtGlobal = true;
  1763. }
  1764. }
  1765. }
  1766. void Parser::CheckStrictModeEvalArgumentsUsage(IdentPtr pid, ParseNodePtr pnode)
  1767. {
  1768. if (pid != nullptr)
  1769. {
  1770. // In strict mode, 'eval' / 'arguments' cannot be assigned to.
  1771. if (pid == wellKnownPropertyPids.eval)
  1772. {
  1773. Error(ERREvalUsage, pnode);
  1774. }
  1775. if (pid == wellKnownPropertyPids.arguments)
  1776. {
  1777. Error(ERRArgsUsage, pnode);
  1778. }
  1779. }
  1780. }
  1781. void Parser::ReduceDeferredScriptLength(size_t chars)
  1782. {
  1783. // If we're in deferred mode, subtract the given char count from the total length,
  1784. // and see if this puts us under the deferral threshold.
  1785. if (((m_grfscr & (fscrCanDeferFncParse | fscrWillDeferFncParse)) == (fscrCanDeferFncParse | fscrWillDeferFncParse)) &&
  1786. (
  1787. PHASE_OFF1(Js::DeferEventHandlersPhase) ||
  1788. (m_grfscr & fscrGlobalCode)
  1789. )
  1790. )
  1791. {
  1792. if (m_length > chars)
  1793. {
  1794. m_length -= chars;
  1795. }
  1796. else
  1797. {
  1798. m_length = 0;
  1799. }
  1800. if (m_length < Parser::GetDeferralThreshold(this->m_sourceContextInfo->IsSourceProfileLoaded()))
  1801. {
  1802. // Stop deferring.
  1803. m_grfscr &= ~fscrWillDeferFncParse;
  1804. m_stoppedDeferredParse = TRUE;
  1805. }
  1806. }
  1807. }
  1808. void Parser::EnsureStackAvailable()
  1809. {
  1810. bool isInterrupt = false;
  1811. if (!m_scriptContext->GetThreadContext()->IsStackAvailable(Js::Constants::MinStackCompile, &isInterrupt))
  1812. {
  1813. Error(isInterrupt ? E_ABORT : VBSERR_OutOfStack);
  1814. }
  1815. }
  1816. void Parser::ThrowNewTargetSyntaxErrForGlobalScope()
  1817. {
  1818. // If we are parsing a previously deferred function, we can skip throwing the SyntaxError for `new.target` at global scope.
  1819. // If we are at global scope, we would have thrown a SyntaxError when we did the Upfront parse pass and we would not have
  1820. // deferred the function in order to come back now and reparse it.
  1821. if (m_parseType == ParseType_Deferred)
  1822. {
  1823. return;
  1824. }
  1825. if (GetCurrentNonLambdaFunctionNode() != nullptr)
  1826. {
  1827. return;
  1828. }
  1829. if ((this->m_grfscr & fscrEval) != 0)
  1830. {
  1831. Js::JavascriptFunction * caller = nullptr;
  1832. if (Js::JavascriptStackWalker::GetCaller(&caller, m_scriptContext))
  1833. {
  1834. Js::FunctionBody * callerBody = caller->GetFunctionBody();
  1835. Assert(callerBody);
  1836. if (!callerBody->GetIsGlobalFunc() && !(callerBody->IsLambda() && callerBody->GetEnclosedByGlobalFunc()))
  1837. {
  1838. return;
  1839. }
  1840. }
  1841. }
  1842. Error(ERRInvalidNewTarget);
  1843. }
  1844. template<bool buildAST>
  1845. IdentPtr Parser::ParseMetaProperty(tokens metaParentKeyword, charcount_t ichMin, _Out_opt_ BOOL* pfCanAssign)
  1846. {
  1847. AssertMsg(metaParentKeyword == tkNEW, "Only supported for tkNEW parent keywords");
  1848. AssertMsg(this->m_token.tk == tkDot, "We must be currently sitting on the dot after the parent keyword");
  1849. this->GetScanner()->Scan();
  1850. if (this->m_token.tk == tkID && this->m_token.GetIdentifier(this->GetHashTbl()) == this->GetTargetPid())
  1851. {
  1852. ThrowNewTargetSyntaxErrForGlobalScope();
  1853. if (pfCanAssign)
  1854. {
  1855. *pfCanAssign = FALSE;
  1856. }
  1857. return wellKnownPropertyPids._newTarget;
  1858. }
  1859. else
  1860. {
  1861. Error(ERRsyntax);
  1862. }
  1863. }
  1864. template<bool buildAST>
  1865. void Parser::ParseNamedImportOrExportClause(ModuleImportOrExportEntryList* importOrExportEntryList, bool isExportClause)
  1866. {
  1867. Assert(m_token.tk == tkLCurly);
  1868. Assert(importOrExportEntryList != nullptr);
  1869. this->GetScanner()->Scan();
  1870. while (m_token.tk != tkRCurly && m_token.tk != tkEOF)
  1871. {
  1872. tokens firstToken = m_token.tk;
  1873. if (!(m_token.IsIdentifier() || m_token.IsReservedWord()))
  1874. {
  1875. Error(ERRsyntax);
  1876. }
  1877. IdentPtr identifierName = m_token.GetIdentifier(this->GetHashTbl());
  1878. IdentPtr identifierAs = identifierName;
  1879. this->GetScanner()->Scan();
  1880. if (m_token.tk == tkID)
  1881. {
  1882. // We have the pattern "IdentifierName as"
  1883. if (wellKnownPropertyPids.as != m_token.GetIdentifier(this->GetHashTbl()))
  1884. {
  1885. Error(ERRsyntax);
  1886. }
  1887. this->GetScanner()->Scan();
  1888. // If we are parsing an import statement, the token after 'as' must be a BindingIdentifier.
  1889. if (!isExportClause)
  1890. {
  1891. ChkCurTokNoScan(tkID, ERRsyntax);
  1892. }
  1893. if (!(m_token.IsIdentifier() || m_token.IsReservedWord()))
  1894. {
  1895. Error(ERRsyntax);
  1896. }
  1897. identifierAs = m_token.GetIdentifier(this->GetHashTbl());
  1898. // Scan to the next token.
  1899. this->GetScanner()->Scan();
  1900. }
  1901. else if (!isExportClause && firstToken != tkID)
  1902. {
  1903. // If we are parsing an import statement and this ImportSpecifier clause did not have
  1904. // 'as ImportedBinding' at the end of it, identifierName must be a BindingIdentifier.
  1905. Error(ERRsyntax);
  1906. }
  1907. if (m_token.tk == tkComma)
  1908. {
  1909. // Consume a trailing comma
  1910. this->GetScanner()->Scan();
  1911. }
  1912. if (buildAST)
  1913. {
  1914. // The name we will use 'as' this import/export is a binding identifier in import statements.
  1915. if (!isExportClause)
  1916. {
  1917. CreateModuleImportDeclNode(identifierAs);
  1918. AddModuleImportOrExportEntry(importOrExportEntryList, identifierName, identifierAs, nullptr, nullptr);
  1919. }
  1920. else
  1921. {
  1922. identifierName->SetIsModuleExport();
  1923. AddModuleImportOrExportEntry(importOrExportEntryList, nullptr, identifierName, identifierAs, nullptr);
  1924. }
  1925. }
  1926. }
  1927. // Final token in a named import or export clause must be a '}'
  1928. ChkCurTokNoScan(tkRCurly, ERRsyntax);
  1929. }
  1930. IdentPtrList* Parser::GetRequestedModulesList()
  1931. {
  1932. return m_currentNodeProg->AsParseNodeModule()->requestedModules;
  1933. }
  1934. ModuleImportOrExportEntryList* Parser::GetModuleImportEntryList()
  1935. {
  1936. return m_currentNodeProg->AsParseNodeModule()->importEntries;
  1937. }
  1938. ModuleImportOrExportEntryList* Parser::GetModuleLocalExportEntryList()
  1939. {
  1940. return m_currentNodeProg->AsParseNodeModule()->localExportEntries;
  1941. }
  1942. ModuleImportOrExportEntryList* Parser::GetModuleIndirectExportEntryList()
  1943. {
  1944. return m_currentNodeProg->AsParseNodeModule()->indirectExportEntries;
  1945. }
  1946. ModuleImportOrExportEntryList* Parser::GetModuleStarExportEntryList()
  1947. {
  1948. return m_currentNodeProg->AsParseNodeModule()->starExportEntries;
  1949. }
  1950. IdentPtrList* Parser::EnsureRequestedModulesList()
  1951. {
  1952. if (m_currentNodeProg->AsParseNodeModule()->requestedModules == nullptr)
  1953. {
  1954. m_currentNodeProg->AsParseNodeModule()->requestedModules = Anew(&m_nodeAllocator, IdentPtrList, &m_nodeAllocator);
  1955. }
  1956. return m_currentNodeProg->AsParseNodeModule()->requestedModules;
  1957. }
  1958. ModuleImportOrExportEntryList* Parser::EnsureModuleImportEntryList()
  1959. {
  1960. if (m_currentNodeProg->AsParseNodeModule()->importEntries == nullptr)
  1961. {
  1962. m_currentNodeProg->AsParseNodeModule()->importEntries = Anew(&m_nodeAllocator, ModuleImportOrExportEntryList, &m_nodeAllocator);
  1963. }
  1964. return m_currentNodeProg->AsParseNodeModule()->importEntries;
  1965. }
  1966. ModuleImportOrExportEntryList* Parser::EnsureModuleLocalExportEntryList()
  1967. {
  1968. if (m_currentNodeProg->AsParseNodeModule()->localExportEntries == nullptr)
  1969. {
  1970. m_currentNodeProg->AsParseNodeModule()->localExportEntries = Anew(&m_nodeAllocator, ModuleImportOrExportEntryList, &m_nodeAllocator);
  1971. }
  1972. return m_currentNodeProg->AsParseNodeModule()->localExportEntries;
  1973. }
  1974. ModuleImportOrExportEntryList* Parser::EnsureModuleIndirectExportEntryList()
  1975. {
  1976. if (m_currentNodeProg->AsParseNodeModule()->indirectExportEntries == nullptr)
  1977. {
  1978. m_currentNodeProg->AsParseNodeModule()->indirectExportEntries = Anew(&m_nodeAllocator, ModuleImportOrExportEntryList, &m_nodeAllocator);
  1979. }
  1980. return m_currentNodeProg->AsParseNodeModule()->indirectExportEntries;
  1981. }
  1982. ModuleImportOrExportEntryList* Parser::EnsureModuleStarExportEntryList()
  1983. {
  1984. if (m_currentNodeProg->AsParseNodeModule()->starExportEntries == nullptr)
  1985. {
  1986. m_currentNodeProg->AsParseNodeModule()->starExportEntries = Anew(&m_nodeAllocator, ModuleImportOrExportEntryList, &m_nodeAllocator);
  1987. }
  1988. return m_currentNodeProg->AsParseNodeModule()->starExportEntries;
  1989. }
  1990. void Parser::AddModuleSpecifier(IdentPtr moduleRequest)
  1991. {
  1992. IdentPtrList* requestedModulesList = EnsureRequestedModulesList();
  1993. if (!requestedModulesList->Has(moduleRequest))
  1994. {
  1995. requestedModulesList->Prepend(moduleRequest);
  1996. }
  1997. }
  1998. ModuleImportOrExportEntry* Parser::AddModuleImportOrExportEntry(ModuleImportOrExportEntryList* importOrExportEntryList, ModuleImportOrExportEntry* importOrExportEntry)
  1999. {
  2000. if (importOrExportEntry->exportName != nullptr)
  2001. {
  2002. CheckForDuplicateExportEntry(importOrExportEntryList, importOrExportEntry->exportName);
  2003. }
  2004. importOrExportEntryList->Prepend(*importOrExportEntry);
  2005. return importOrExportEntry;
  2006. }
  2007. ModuleImportOrExportEntry* Parser::AddModuleImportOrExportEntry(ModuleImportOrExportEntryList* importOrExportEntryList, IdentPtr importName, IdentPtr localName, IdentPtr exportName, IdentPtr moduleRequest)
  2008. {
  2009. ModuleImportOrExportEntry* importOrExportEntry = Anew(&m_nodeAllocator, ModuleImportOrExportEntry);
  2010. importOrExportEntry->importName = importName;
  2011. importOrExportEntry->localName = localName;
  2012. importOrExportEntry->exportName = exportName;
  2013. importOrExportEntry->moduleRequest = moduleRequest;
  2014. return AddModuleImportOrExportEntry(importOrExportEntryList, importOrExportEntry);
  2015. }
  2016. void Parser::AddModuleLocalExportEntry(ParseNodePtr varDeclNode)
  2017. {
  2018. AssertOrFailFast(varDeclNode->nop == knopVarDecl || varDeclNode->nop == knopLetDecl || varDeclNode->nop == knopConstDecl);
  2019. IdentPtr localName = varDeclNode->AsParseNodeVar()->pid;
  2020. varDeclNode->AsParseNodeVar()->sym->SetIsModuleExportStorage(true);
  2021. AddModuleImportOrExportEntry(EnsureModuleLocalExportEntryList(), nullptr, localName, localName, nullptr);
  2022. }
  2023. void Parser::CheckForDuplicateExportEntry(ModuleImportOrExportEntryList* exportEntryList, IdentPtr exportName)
  2024. {
  2025. ModuleImportOrExportEntry* findResult = exportEntryList->Find([&](ModuleImportOrExportEntry exportEntry)
  2026. {
  2027. if (exportName == exportEntry.exportName)
  2028. {
  2029. return true;
  2030. }
  2031. return false;
  2032. });
  2033. if (findResult != nullptr)
  2034. {
  2035. Error(ERRsyntax);
  2036. }
  2037. }
  2038. template<bool buildAST>
  2039. void Parser::ParseImportClause(ModuleImportOrExportEntryList* importEntryList, bool parsingAfterComma)
  2040. {
  2041. bool parsedNamespaceOrNamedImport = false;
  2042. switch (m_token.tk)
  2043. {
  2044. case tkID:
  2045. // This is the default binding identifier.
  2046. // If we already saw a comma in the import clause, this is a syntax error.
  2047. if (parsingAfterComma)
  2048. {
  2049. Error(ERRsyntax);
  2050. }
  2051. if (buildAST)
  2052. {
  2053. IdentPtr localName = m_token.GetIdentifier(this->GetHashTbl());
  2054. IdentPtr importName = wellKnownPropertyPids._default;
  2055. CreateModuleImportDeclNode(localName);
  2056. AddModuleImportOrExportEntry(importEntryList, importName, localName, nullptr, nullptr);
  2057. }
  2058. break;
  2059. case tkLCurly:
  2060. // This begins a list of named imports.
  2061. ParseNamedImportOrExportClause<buildAST>(importEntryList, false);
  2062. parsedNamespaceOrNamedImport = true;
  2063. break;
  2064. case tkStar:
  2065. // This begins a namespace import clause.
  2066. // "* as ImportedBinding"
  2067. // Token following * must be the identifier 'as'
  2068. this->GetScanner()->Scan();
  2069. if (m_token.tk != tkID || wellKnownPropertyPids.as != m_token.GetIdentifier(this->GetHashTbl()))
  2070. {
  2071. Error(ERRsyntax);
  2072. }
  2073. // Token following 'as' must be a binding identifier.
  2074. this->GetScanner()->Scan();
  2075. ChkCurTokNoScan(tkID, ERRsyntax);
  2076. if (buildAST)
  2077. {
  2078. IdentPtr localName = m_token.GetIdentifier(this->GetHashTbl());
  2079. IdentPtr importName = wellKnownPropertyPids._star;
  2080. CreateModuleImportDeclNode(localName);
  2081. AddModuleImportOrExportEntry(importEntryList, importName, localName, nullptr, nullptr);
  2082. }
  2083. parsedNamespaceOrNamedImport = true;
  2084. break;
  2085. default:
  2086. Error(ERRsyntax);
  2087. }
  2088. this->GetScanner()->Scan();
  2089. if (m_token.tk == tkComma)
  2090. {
  2091. // There cannot be more than one comma in a module import clause.
  2092. // There cannot be a namespace import or named imports list on the left of the comma in a module import clause.
  2093. if (parsingAfterComma || parsedNamespaceOrNamedImport)
  2094. {
  2095. Error(ERRsyntax);
  2096. }
  2097. this->GetScanner()->Scan();
  2098. ParseImportClause<buildAST>(importEntryList, true);
  2099. }
  2100. }
  2101. bool Parser::IsImportOrExportStatementValidHere()
  2102. {
  2103. ParseNodeFnc * curFunc = GetCurrentFunctionNode();
  2104. // Import must be located in the top scope of the module body.
  2105. return curFunc->nop == knopFncDecl
  2106. && curFunc->IsModule()
  2107. && this->m_currentBlockInfo->pnodeBlock == curFunc->pnodeBodyScope
  2108. && (this->m_grfscr & fscrEvalCode) != fscrEvalCode
  2109. && this->m_tryCatchOrFinallyDepth == 0
  2110. && !this->m_disallowImportExportStmt;
  2111. }
  2112. bool Parser::IsTopLevelModuleFunc()
  2113. {
  2114. ParseNodeFnc * curFunc = GetCurrentFunctionNode();
  2115. return curFunc->nop == knopFncDecl && curFunc->IsModule();
  2116. }
  2117. template<bool buildAST> ParseNodePtr Parser::ParseImportCall()
  2118. {
  2119. this->GetScanner()->Scan();
  2120. ParseNodePtr specifier = ParseExpr<buildAST>(koplCma, nullptr, /* fAllowIn */FALSE, /* fAllowEllipsis */FALSE);
  2121. if (m_token.tk != tkRParen)
  2122. {
  2123. Error(ERRnoRparen);
  2124. }
  2125. this->GetScanner()->Scan();
  2126. return buildAST ? CreateCallNode(knopCall, CreateNodeForOpT<knopImport>(), specifier) : nullptr;
  2127. }
  2128. template<bool buildAST>
  2129. ParseNodePtr Parser::ParseImport()
  2130. {
  2131. Assert(m_scriptContext->GetConfig()->IsES6ModuleEnabled());
  2132. Assert(m_token.tk == tkIMPORT);
  2133. RestorePoint parsedImport;
  2134. this->GetScanner()->Capture(&parsedImport);
  2135. this->GetScanner()->Scan();
  2136. // import()
  2137. if (m_token.tk == tkLParen)
  2138. {
  2139. if (!m_scriptContext->GetConfig()->IsESDynamicImportEnabled())
  2140. {
  2141. Error(ERRsyntax);
  2142. }
  2143. ParseNodePtr pnode = ParseImportCall<buildAST>();
  2144. BOOL fCanAssign;
  2145. IdentToken token;
  2146. return ParsePostfixOperators<buildAST>(pnode, TRUE, FALSE, FALSE, TRUE, &fCanAssign, &token);
  2147. }
  2148. this->GetScanner()->SeekTo(parsedImport);
  2149. if (!IsImportOrExportStatementValidHere())
  2150. {
  2151. Error(ERRInvalidModuleImportOrExport);
  2152. }
  2153. // We just parsed an import token. Next valid token is *, {, string constant, or binding identifier.
  2154. this->GetScanner()->Scan();
  2155. if (m_token.tk == tkStrCon)
  2156. {
  2157. // This import declaration has no import clause.
  2158. // "import ModuleSpecifier;"
  2159. if (buildAST)
  2160. {
  2161. AddModuleSpecifier(m_token.GetStr());
  2162. }
  2163. // Scan past the module identifier.
  2164. this->GetScanner()->Scan();
  2165. }
  2166. else
  2167. {
  2168. ModuleImportOrExportEntryList importEntryList(&m_nodeAllocator);
  2169. // Parse the import clause (default binding can only exist before the comma).
  2170. ParseImportClause<buildAST>(&importEntryList);
  2171. // Token following import clause must be the identifier 'from'
  2172. IdentPtr moduleSpecifier = ParseImportOrExportFromClause<buildAST>(true);
  2173. if (buildAST)
  2174. {
  2175. Assert(moduleSpecifier != nullptr);
  2176. AddModuleSpecifier(moduleSpecifier);
  2177. importEntryList.Map([this, moduleSpecifier](ModuleImportOrExportEntry& importEntry) {
  2178. importEntry.moduleRequest = moduleSpecifier;
  2179. AddModuleImportOrExportEntry(EnsureModuleImportEntryList(), &importEntry);
  2180. });
  2181. }
  2182. importEntryList.Clear();
  2183. }
  2184. // Import statement is actually a nop, we hoist all the imported bindings to the top of the module.
  2185. return nullptr;
  2186. }
  2187. template<bool buildAST>
  2188. IdentPtr Parser::ParseImportOrExportFromClause(bool throwIfNotFound)
  2189. {
  2190. IdentPtr moduleSpecifier = nullptr;
  2191. if (m_token.tk == tkID && wellKnownPropertyPids.from == m_token.GetIdentifier(this->GetHashTbl()))
  2192. {
  2193. this->GetScanner()->Scan();
  2194. // Token following the 'from' token must be a string constant - the module specifier.
  2195. ChkCurTokNoScan(tkStrCon, ERRsyntax);
  2196. if (buildAST)
  2197. {
  2198. moduleSpecifier = m_token.GetStr();
  2199. }
  2200. this->GetScanner()->Scan();
  2201. }
  2202. else if (throwIfNotFound)
  2203. {
  2204. Error(ERRsyntax);
  2205. }
  2206. return moduleSpecifier;
  2207. }
  2208. template<bool buildAST>
  2209. ParseNodePtr Parser::ParseDefaultExportClause()
  2210. {
  2211. Assert(m_token.tk == tkDEFAULT);
  2212. this->GetScanner()->Scan();
  2213. ParseNodePtr pnode = nullptr;
  2214. ushort flags = fFncNoFlgs;
  2215. switch (m_token.tk)
  2216. {
  2217. case tkCLASS:
  2218. {
  2219. if (!m_scriptContext->GetConfig()->IsES6ClassAndExtendsEnabled())
  2220. {
  2221. goto LDefault;
  2222. }
  2223. // Before we parse the class itself we need to know if the class has an identifier name.
  2224. // If it does, we'll treat this class as an ordinary class declaration which will bind
  2225. // it to that name. Otherwise the class should parse as a nameless class expression and
  2226. // bind only to the export binding.
  2227. BOOL classHasName = false;
  2228. RestorePoint parsedClass;
  2229. this->GetScanner()->Capture(&parsedClass);
  2230. this->GetScanner()->Scan();
  2231. if (m_token.tk == tkID)
  2232. {
  2233. classHasName = true;
  2234. }
  2235. this->GetScanner()->SeekTo(parsedClass);
  2236. ParseNodeClass * pnodeClass;
  2237. pnode = pnodeClass = ParseClassDecl<buildAST>(classHasName, nullptr, nullptr, nullptr);
  2238. if (buildAST)
  2239. {
  2240. AnalysisAssert(pnode != nullptr);
  2241. Assert(pnode->nop == knopClassDecl);
  2242. pnodeClass->SetIsDefaultModuleExport(true);
  2243. }
  2244. break;
  2245. }
  2246. case tkID:
  2247. // If we parsed an async token, it could either modify the next token (if it is a
  2248. // function token) or it could be an identifier (let async = 0; export default async;).
  2249. // To handle both cases, when we parse an async token we need to keep the parser state
  2250. // and rewind if the next token is not function.
  2251. if (wellKnownPropertyPids.async == m_token.GetIdentifier(this->GetHashTbl()))
  2252. {
  2253. RestorePoint parsedAsync;
  2254. this->GetScanner()->Capture(&parsedAsync);
  2255. this->GetScanner()->Scan();
  2256. if (m_token.tk == tkFUNCTION)
  2257. {
  2258. // Token after async is function, consume the async token and continue to parse the
  2259. // function as an async function.
  2260. flags |= fFncAsync;
  2261. goto LFunction;
  2262. }
  2263. // Token after async is not function, no idea what the async token is supposed to mean
  2264. // so rewind and let the default case handle it.
  2265. this->GetScanner()->SeekTo(parsedAsync);
  2266. }
  2267. goto LDefault;
  2268. break;
  2269. case tkFUNCTION:
  2270. {
  2271. LFunction:
  2272. // We just parsed a function token but we need to figure out if the function
  2273. // has an identifier name or not before we call the helper.
  2274. RestorePoint parsedFunction;
  2275. this->GetScanner()->Capture(&parsedFunction);
  2276. this->GetScanner()->Scan();
  2277. if (m_token.tk == tkStar)
  2278. {
  2279. // If we saw 'function*' that indicates we are going to parse a generator,
  2280. // but doesn't tell us if the generator has an identifier or not.
  2281. // Skip the '*' token for now as it doesn't matter yet.
  2282. this->GetScanner()->Scan();
  2283. }
  2284. // We say that if the function has an identifier name, it is a 'normal' declaration
  2285. // and should create a binding to that identifier as well as one for our default export.
  2286. if (m_token.tk == tkID)
  2287. {
  2288. flags |= fFncDeclaration;
  2289. }
  2290. else
  2291. {
  2292. flags |= fFncNoName;
  2293. }
  2294. // Rewind back to the function token and let the helper handle the parsing.
  2295. this->GetScanner()->SeekTo(parsedFunction);
  2296. pnode = ParseFncDeclCheckScope<buildAST>(flags);
  2297. if (buildAST)
  2298. {
  2299. AnalysisAssert(pnode != nullptr);
  2300. Assert(pnode->nop == knopFncDecl);
  2301. pnode->AsParseNodeFnc()->SetIsDefaultModuleExport(true);
  2302. }
  2303. break;
  2304. }
  2305. default:
  2306. LDefault:
  2307. {
  2308. ParseNodePtr pnodeExpression = ParseExpr<buildAST>();
  2309. // Consider: Can we detect this syntax error earlier?
  2310. if (pnodeExpression && pnodeExpression->nop == knopComma)
  2311. {
  2312. Error(ERRsyntax);
  2313. }
  2314. if (buildAST)
  2315. {
  2316. AnalysisAssert(pnodeExpression != nullptr);
  2317. // Mark this node as the default module export. We need to make sure it is put into the correct
  2318. // module export slot when we emit the node.
  2319. ParseNodeExportDefault * pnodeExportDefault;
  2320. pnode = pnodeExportDefault = CreateNodeForOpT<knopExportDefault>();
  2321. pnode->AsParseNodeExportDefault()->pnodeExpr = pnodeExpression;
  2322. }
  2323. break;
  2324. }
  2325. }
  2326. IdentPtr exportName = wellKnownPropertyPids._default;
  2327. IdentPtr localName = wellKnownPropertyPids._starDefaultStar;
  2328. AddModuleImportOrExportEntry(EnsureModuleLocalExportEntryList(), nullptr, localName, exportName, nullptr);
  2329. return pnode;
  2330. }
  2331. template<bool buildAST>
  2332. ParseNodePtr Parser::ParseExportDeclaration(bool *needTerminator)
  2333. {
  2334. Assert(m_scriptContext->GetConfig()->IsES6ModuleEnabled());
  2335. Assert(m_token.tk == tkEXPORT);
  2336. if (!IsImportOrExportStatementValidHere())
  2337. {
  2338. Error(ERRInvalidModuleImportOrExport);
  2339. }
  2340. ParseNodePtr pnode = nullptr;
  2341. IdentPtr moduleIdentifier = nullptr;
  2342. tokens declarationType;
  2343. if (needTerminator != nullptr)
  2344. {
  2345. *needTerminator = false;
  2346. }
  2347. // We just parsed an export token. Next valid tokens are *, {, var, let, const, async, function, class, default.
  2348. this->GetScanner()->Scan();
  2349. switch (m_token.tk)
  2350. {
  2351. case tkStar:
  2352. this->GetScanner()->Scan();
  2353. // A star token in an export declaration must be followed by a from clause which begins with a token 'from'.
  2354. moduleIdentifier = ParseImportOrExportFromClause<buildAST>(true);
  2355. if (buildAST)
  2356. {
  2357. Assert(moduleIdentifier != nullptr);
  2358. AddModuleSpecifier(moduleIdentifier);
  2359. IdentPtr importName = wellKnownPropertyPids._star;
  2360. AddModuleImportOrExportEntry(EnsureModuleStarExportEntryList(), importName, nullptr, nullptr, moduleIdentifier);
  2361. }
  2362. if (needTerminator != nullptr)
  2363. {
  2364. *needTerminator = true;
  2365. }
  2366. break;
  2367. case tkLCurly:
  2368. {
  2369. ModuleImportOrExportEntryList exportEntryList(&m_nodeAllocator);
  2370. ParseNamedImportOrExportClause<buildAST>(&exportEntryList, true);
  2371. this->GetScanner()->Scan();
  2372. // Export clause may be followed by a from clause.
  2373. moduleIdentifier = ParseImportOrExportFromClause<buildAST>(false);
  2374. if (buildAST)
  2375. {
  2376. if (moduleIdentifier != nullptr)
  2377. {
  2378. AddModuleSpecifier(moduleIdentifier);
  2379. }
  2380. exportEntryList.Map([this, moduleIdentifier](ModuleImportOrExportEntry& exportEntry) {
  2381. if (moduleIdentifier != nullptr)
  2382. {
  2383. exportEntry.moduleRequest = moduleIdentifier;
  2384. // We need to swap localname and importname when this is a re-export.
  2385. exportEntry.importName = exportEntry.localName;
  2386. exportEntry.localName = nullptr;
  2387. AddModuleImportOrExportEntry(EnsureModuleIndirectExportEntryList(), &exportEntry);
  2388. }
  2389. else
  2390. {
  2391. AddModuleImportOrExportEntry(EnsureModuleLocalExportEntryList(), &exportEntry);
  2392. }
  2393. });
  2394. exportEntryList.Clear();
  2395. }
  2396. }
  2397. if (needTerminator != nullptr)
  2398. {
  2399. *needTerminator = true;
  2400. }
  2401. break;
  2402. case tkID:
  2403. {
  2404. IdentPtr pid = m_token.GetIdentifier(this->GetHashTbl());
  2405. if (wellKnownPropertyPids.let == pid)
  2406. {
  2407. declarationType = tkLET;
  2408. goto ParseVarDecl;
  2409. }
  2410. if (wellKnownPropertyPids.async == pid && m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
  2411. {
  2412. // In module export statements, async token is only valid if it's followed by function.
  2413. // We need to check here because ParseStatement would think 'async = 20' is a var decl.
  2414. RestorePoint parsedAsync;
  2415. this->GetScanner()->Capture(&parsedAsync);
  2416. this->GetScanner()->Scan();
  2417. if (m_token.tk == tkFUNCTION)
  2418. {
  2419. // Token after async is function, rewind to the async token and let ParseStatement handle it.
  2420. this->GetScanner()->SeekTo(parsedAsync);
  2421. goto ParseFunctionDecl;
  2422. }
  2423. // Token after async is not function, it's a syntax error.
  2424. }
  2425. goto ErrorToken;
  2426. }
  2427. case tkVAR:
  2428. case tkLET:
  2429. case tkCONST:
  2430. {
  2431. declarationType = m_token.tk;
  2432. ParseVarDecl:
  2433. this->GetScanner()->Scan();
  2434. pnode = ParseVariableDeclaration<buildAST>(declarationType, this->GetScanner()->IchMinTok());
  2435. if (buildAST)
  2436. {
  2437. ForEachItemInList(pnode, [&](ParseNodePtr item) {
  2438. if (item->nop == knopAsg)
  2439. {
  2440. Parser::MapBindIdentifier(item, [&](ParseNodePtr subItem)
  2441. {
  2442. AddModuleLocalExportEntry(subItem);
  2443. });
  2444. }
  2445. else
  2446. {
  2447. AddModuleLocalExportEntry(item);
  2448. }
  2449. });
  2450. }
  2451. }
  2452. break;
  2453. case tkFUNCTION:
  2454. case tkCLASS:
  2455. {
  2456. ParseFunctionDecl:
  2457. pnode = ParseStatement<buildAST>();
  2458. if (buildAST)
  2459. {
  2460. IdentPtr localName;
  2461. if (pnode->nop == knopClassDecl)
  2462. {
  2463. ParseNodeClass * pnodeClass = pnode->AsParseNodeClass();
  2464. pnodeClass->pnodeDeclName->sym->SetIsModuleExportStorage(true);
  2465. localName = pnodeClass->pnodeName->pid;
  2466. }
  2467. else
  2468. {
  2469. Assert(pnode->nop == knopFncDecl);
  2470. ParseNodeFnc * pnodeFnc = pnode->AsParseNodeFnc();
  2471. pnodeFnc->GetFuncSymbol()->SetIsModuleExportStorage(true);
  2472. localName = pnodeFnc->pid;
  2473. }
  2474. Assert(localName != nullptr);
  2475. AddModuleImportOrExportEntry(EnsureModuleLocalExportEntryList(), nullptr, localName, localName, nullptr);
  2476. }
  2477. }
  2478. break;
  2479. case tkDEFAULT:
  2480. {
  2481. pnode = ParseDefaultExportClause<buildAST>();
  2482. }
  2483. break;
  2484. default:
  2485. {
  2486. ErrorToken:
  2487. Error(ERRsyntax);
  2488. }
  2489. }
  2490. return pnode;
  2491. }
  2492. /***************************************************************************
  2493. Parse an expression term.
  2494. ***************************************************************************/
  2495. template<bool buildAST>
  2496. ParseNodePtr Parser::ParseTerm(BOOL fAllowCall,
  2497. LPCOLESTR pNameHint,
  2498. uint32 *pHintLength,
  2499. uint32 *pShortNameOffset,
  2500. _Inout_opt_ IdentToken* pToken /*= nullptr*/,
  2501. bool fUnaryOrParen /*= false*/,
  2502. BOOL fCanAssignToCall /*= TRUE*/,
  2503. _Out_opt_ BOOL* pfCanAssign /*= nullptr*/,
  2504. _Inout_opt_ BOOL* pfLikelyPattern /*= nullptr*/,
  2505. _Out_opt_ bool* pfIsDotOrIndex /*= nullptr*/,
  2506. _Inout_opt_ charcount_t *plastRParen /*= nullptr*/)
  2507. {
  2508. ParseNodePtr pnode = nullptr;
  2509. PidRefStack *savedTopAsyncRef = nullptr;
  2510. charcount_t ichMin = 0;
  2511. charcount_t ichLim = 0;
  2512. size_t iecpMin = 0;
  2513. size_t iecpLim = 0;
  2514. size_t iuMin;
  2515. IdentToken term;
  2516. BOOL fInNew = FALSE;
  2517. BOOL fCanAssign = TRUE;
  2518. bool isAsyncExpr = false;
  2519. bool isLambdaExpr = false;
  2520. bool isSpecialName = false;
  2521. IdentPtr pid = nullptr;
  2522. Assert(pToken == nullptr || pToken->tk == tkNone); // Must be empty initially
  2523. PROBE_STACK_NO_DISPOSE(m_scriptContext, Js::Constants::MinStackParseOneTerm);
  2524. switch (m_token.tk)
  2525. {
  2526. case tkID:
  2527. {
  2528. pid = m_token.GetIdentifier(this->GetHashTbl());
  2529. ichMin = this->GetScanner()->IchMinTok();
  2530. iecpMin = this->GetScanner()->IecpMinTok();
  2531. ichLim = this->GetScanner()->IchLimTok();
  2532. iecpLim = this->GetScanner()->IecpLimTok();
  2533. if (pid == wellKnownPropertyPids.async &&
  2534. m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
  2535. {
  2536. isAsyncExpr = true;
  2537. }
  2538. // Put this into a block to avoid previousAwaitIsKeyword being not initialized after jump to LIdentifier
  2539. {
  2540. bool previousAwaitIsKeyword = this->GetScanner()->SetAwaitIsKeywordRegion(isAsyncExpr);
  2541. this->GetScanner()->Scan();
  2542. this->GetScanner()->SetAwaitIsKeywordRegion(previousAwaitIsKeyword);
  2543. }
  2544. // We search for an Async expression (a function declaration or an async lambda expression)
  2545. if (isAsyncExpr && !this->GetScanner()->FHadNewLine())
  2546. {
  2547. if (m_token.tk == tkFUNCTION)
  2548. {
  2549. goto LFunction;
  2550. }
  2551. else if (m_token.tk == tkID || m_token.tk == tkAWAIT)
  2552. {
  2553. isLambdaExpr = true;
  2554. goto LFunction;
  2555. }
  2556. else if (m_token.tk == tkLParen)
  2557. {
  2558. // This is potentially an async arrow function. Save the state of the async references
  2559. // in case it needs to be restored. (Note that the case of a single parameter with no ()'s
  2560. // is detected upstream and need not be handled here.)
  2561. savedTopAsyncRef = pid->GetTopRef();
  2562. }
  2563. }
  2564. CheckArgumentsUse(pid, GetCurrentFunctionNode());
  2565. // Assume this pid is not special - overwrite when we parse a special name
  2566. isSpecialName = false;
  2567. LIdentifier:
  2568. PidRefStack * ref = nullptr;
  2569. // Don't push a reference if this is a single lambda parameter, because we'll reparse with
  2570. // a correct function ID.
  2571. if (m_token.tk != tkDArrow)
  2572. {
  2573. ref = this->PushPidRef(pid);
  2574. }
  2575. if (buildAST)
  2576. {
  2577. if (isSpecialName)
  2578. {
  2579. pnode = CreateSpecialNameNode(pid, ref, ichMin, ichLim);
  2580. }
  2581. else
  2582. {
  2583. pnode = CreateNameNode(pid, ref, ichMin, ichLim);
  2584. }
  2585. }
  2586. else
  2587. {
  2588. // Remember the identifier start and end in case it turns out to be a statement label.
  2589. term.tk = tkID;
  2590. term.pid = pid; // Record the identifier for detection of eval
  2591. term.ichMin = static_cast<charcount_t>(iecpMin);
  2592. term.ichLim = static_cast<charcount_t>(iecpLim);
  2593. }
  2594. break;
  2595. }
  2596. case tkSUPER:
  2597. ichMin = this->GetScanner()->IchMinTok();
  2598. iecpMin = this->GetScanner()->IecpMinTok();
  2599. ichLim = this->GetScanner()->IchLimTok();
  2600. iecpLim = this->GetScanner()->IecpLimTok();
  2601. if (!m_scriptContext->GetConfig()->IsES6ClassAndExtendsEnabled())
  2602. {
  2603. goto LUnknown;
  2604. }
  2605. this->GetScanner()->Scan();
  2606. pid = ParseSuper<buildAST>(!!fAllowCall);
  2607. isSpecialName = true;
  2608. // Super reference and super call need to push a pid ref to 'this' even when not building an AST
  2609. ReferenceSpecialName(wellKnownPropertyPids._this, ichMin, ichLim);
  2610. // Super call needs to reference 'new.target'
  2611. if (pid == wellKnownPropertyPids._superConstructor)
  2612. {
  2613. ReferenceSpecialName(wellKnownPropertyPids._newTarget, ichMin, ichLim);
  2614. }
  2615. goto LIdentifier;
  2616. case tkTHIS:
  2617. ichMin = this->GetScanner()->IchMinTok();
  2618. iecpMin = this->GetScanner()->IecpMinTok();
  2619. ichLim = this->GetScanner()->IchLimTok();
  2620. iecpLim = this->GetScanner()->IecpLimTok();
  2621. pid = wellKnownPropertyPids._this;
  2622. this->GetScanner()->Scan();
  2623. isSpecialName = true;
  2624. goto LIdentifier;
  2625. case tkLParen:
  2626. {
  2627. ichMin = this->GetScanner()->IchMinTok();
  2628. iuMin = this->GetScanner()->IecpMinTok();
  2629. // If we are undeferring a function which has deferred stubs, we can check to see if the next deferred stub
  2630. // is a lambda at the current character. If it is, we know this LParen is the beginning of a lambda nested
  2631. // function and we can avoid parsing the next series of tokens as a parenthetical expression and reparsing
  2632. // after finding the => token.
  2633. if (buildAST && m_currDeferredStub != nullptr && GetCurrentFunctionNode() != nullptr && GetCurrentFunctionNode()->nestedCount < m_currDeferredStubCount)
  2634. {
  2635. DeferredFunctionStub* stub = m_currDeferredStub + GetCurrentFunctionNode()->nestedCount;
  2636. if (stub->ichMin == ichMin)
  2637. {
  2638. Assert((stub->fncFlags & kFunctionIsLambda) == kFunctionIsLambda);
  2639. pnode = ParseFncDeclCheckScope<true>(fFncLambda);
  2640. break;
  2641. }
  2642. }
  2643. this->GetScanner()->Scan();
  2644. if (m_token.tk == tkRParen)
  2645. {
  2646. // Empty parens can only be legal as an empty parameter list to a lambda declaration.
  2647. // We're in a lambda if the next token is =>.
  2648. fAllowCall = FALSE;
  2649. this->GetScanner()->Scan();
  2650. // If the token after the right paren is not => or if there was a newline between () and => this is a syntax error
  2651. if (!IsDoingFastScan() && (m_token.tk != tkDArrow || this->GetScanner()->FHadNewLine()))
  2652. {
  2653. Error(ERRsyntax);
  2654. }
  2655. if (buildAST)
  2656. {
  2657. pnode = CreateNodeForOpT<knopEmpty>();
  2658. }
  2659. break;
  2660. }
  2661. // Advance the block ID here in case this parenthetical expression turns out to be a lambda parameter list.
  2662. // That way the pid ref stacks will be created in their correct final form, and we can simply fix
  2663. // up function ID's.
  2664. uint saveNextBlockId = m_nextBlockId;
  2665. uint saveCurrBlockId = GetCurrentBlock()->blockId;
  2666. GetCurrentBlock()->blockId = m_nextBlockId++;
  2667. AutoDeferErrorsRestore deferErrorRestore(this);
  2668. this->m_funcParenExprDepth++;
  2669. pnode = ParseExpr<buildAST>(koplNo, &fCanAssign, TRUE, FALSE, nullptr, nullptr /*nameLength*/, nullptr /*pShortNameOffset*/, &term, true, nullptr, plastRParen);
  2670. this->m_funcParenExprDepth--;
  2671. if (buildAST && plastRParen)
  2672. {
  2673. *plastRParen = this->GetScanner()->IchLimTok();
  2674. }
  2675. ChkCurTok(tkRParen, ERRnoRparen);
  2676. GetCurrentBlock()->blockId = saveCurrBlockId;
  2677. if (m_token.tk == tkDArrow)
  2678. {
  2679. // We're going to rewind and reinterpret the expression as a parameter list.
  2680. // Put back the original next-block-ID so the existing pid ref stacks will be correct.
  2681. m_nextBlockId = saveNextBlockId;
  2682. }
  2683. else
  2684. {
  2685. // Emit a deferred ... error if one was parsed.
  2686. if (m_deferEllipsisError)
  2687. {
  2688. this->GetScanner()->SeekTo(m_deferEllipsisErrorLoc);
  2689. Error(ERRInvalidSpreadUse);
  2690. }
  2691. else if (m_deferCommaError)
  2692. {
  2693. // Emit a comma error if that was deferred.
  2694. this->GetScanner()->SeekTo(m_deferCommaErrorLoc);
  2695. Error(ERRsyntax);
  2696. }
  2697. }
  2698. break;
  2699. }
  2700. case tkIntCon:
  2701. if (IsStrictMode() && this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
  2702. {
  2703. Error(ERRES5NoOctal);
  2704. }
  2705. if (buildAST)
  2706. {
  2707. pnode = CreateIntNode(m_token.GetLong());
  2708. }
  2709. fCanAssign = FALSE;
  2710. this->GetScanner()->Scan();
  2711. break;
  2712. case tkFltCon:
  2713. if (IsStrictMode() && this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
  2714. {
  2715. Error(ERRES5NoOctal);
  2716. }
  2717. if (buildAST)
  2718. {
  2719. ParseNodeFloat * pnodeFloat;
  2720. pnode = pnodeFloat = CreateNodeForOpT<knopFlt>();
  2721. pnodeFloat->dbl = m_token.GetDouble();
  2722. pnodeFloat->maybeInt = m_token.GetDoubleMayBeInt();
  2723. }
  2724. fCanAssign = FALSE;
  2725. this->GetScanner()->Scan();
  2726. break;
  2727. case tkStrCon:
  2728. if (IsStrictMode() && this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
  2729. {
  2730. Error(ERRES5NoOctal);
  2731. }
  2732. if (buildAST)
  2733. {
  2734. pnode = CreateStrNode(m_token.GetStr());
  2735. }
  2736. else
  2737. {
  2738. // Subtract the string literal length from the total char count for the purpose
  2739. // of deciding whether to defer parsing and byte code generation.
  2740. this->ReduceDeferredScriptLength(this->GetScanner()->IchLimTok() - this->GetScanner()->IchMinTok());
  2741. }
  2742. fCanAssign = FALSE;
  2743. this->GetScanner()->Scan();
  2744. break;
  2745. case tkTRUE:
  2746. if (buildAST)
  2747. {
  2748. pnode = CreateNodeForOpT<knopTrue>();
  2749. }
  2750. fCanAssign = FALSE;
  2751. this->GetScanner()->Scan();
  2752. break;
  2753. case tkFALSE:
  2754. if (buildAST)
  2755. {
  2756. pnode = CreateNodeForOpT<knopFalse>();
  2757. }
  2758. fCanAssign = FALSE;
  2759. this->GetScanner()->Scan();
  2760. break;
  2761. case tkNULL:
  2762. if (buildAST)
  2763. {
  2764. pnode = CreateNodeForOpT<knopNull>();
  2765. }
  2766. fCanAssign = FALSE;
  2767. this->GetScanner()->Scan();
  2768. break;
  2769. case tkDiv:
  2770. case tkAsgDiv:
  2771. pnode = ParseRegExp<buildAST>();
  2772. fCanAssign = FALSE;
  2773. this->GetScanner()->Scan();
  2774. break;
  2775. case tkNEW:
  2776. {
  2777. ichMin = this->GetScanner()->IchMinTok();
  2778. iecpMin = this->GetScanner()->IecpMinTok();
  2779. this->GetScanner()->Scan();
  2780. if (m_token.tk == tkDot && m_scriptContext->GetConfig()->IsES6ClassAndExtendsEnabled())
  2781. {
  2782. pid = ParseMetaProperty<buildAST>(tkNEW, ichMin, &fCanAssign);
  2783. ichLim = this->GetScanner()->IchLimTok();
  2784. iecpLim = this->GetScanner()->IecpLimTok();
  2785. this->GetScanner()->Scan();
  2786. isSpecialName = true;
  2787. goto LIdentifier;
  2788. }
  2789. else
  2790. {
  2791. ParseNodePtr pnodeExpr = ParseTerm<buildAST>(FALSE, pNameHint, pHintLength, pShortNameOffset, nullptr, false, TRUE, nullptr, nullptr, nullptr, plastRParen);
  2792. if (buildAST)
  2793. {
  2794. pnode = CreateCallNode(knopNew, pnodeExpr, nullptr);
  2795. pnode->ichMin = ichMin;
  2796. }
  2797. fInNew = TRUE;
  2798. fCanAssign = FALSE;
  2799. }
  2800. break;
  2801. }
  2802. case tkLBrack:
  2803. {
  2804. ichMin = this->GetScanner()->IchMinTok();
  2805. this->GetScanner()->Scan();
  2806. pnode = ParseArrayLiteral<buildAST>();
  2807. if (buildAST)
  2808. {
  2809. pnode->ichMin = ichMin;
  2810. pnode->ichLim = this->GetScanner()->IchLimTok();
  2811. }
  2812. if (this->m_arrayDepth == 0)
  2813. {
  2814. Assert(this->GetScanner()->IchLimTok() - ichMin > m_funcInArray);
  2815. this->ReduceDeferredScriptLength(this->GetScanner()->IchLimTok() - ichMin - this->m_funcInArray);
  2816. this->m_funcInArray = 0;
  2817. this->m_funcInArrayDepth = 0;
  2818. }
  2819. ChkCurTok(tkRBrack, ERRnoRbrack);
  2820. if (!IsES6DestructuringEnabled())
  2821. {
  2822. fCanAssign = FALSE;
  2823. }
  2824. else if (pfLikelyPattern != nullptr && !IsPostFixOperators())
  2825. {
  2826. *pfLikelyPattern = TRUE;
  2827. }
  2828. break;
  2829. }
  2830. case tkLCurly:
  2831. {
  2832. ichMin = this->GetScanner()->IchMinTok();
  2833. this->GetScanner()->ScanForcingPid();
  2834. ParseNodePtr pnodeMemberList = ParseMemberList<buildAST>(pNameHint, pHintLength);
  2835. if (buildAST)
  2836. {
  2837. pnode = CreateUniNode(knopObject, pnodeMemberList);
  2838. pnode->ichMin = ichMin;
  2839. pnode->ichLim = this->GetScanner()->IchLimTok();
  2840. }
  2841. ChkCurTok(tkRCurly, ERRnoRcurly);
  2842. if (!IsES6DestructuringEnabled())
  2843. {
  2844. fCanAssign = FALSE;
  2845. }
  2846. else if (pfLikelyPattern != nullptr && !IsPostFixOperators())
  2847. {
  2848. *pfLikelyPattern = TRUE;
  2849. }
  2850. break;
  2851. }
  2852. case tkFUNCTION:
  2853. {
  2854. LFunction:
  2855. if (m_grfscr & fscrDeferredFncExpression)
  2856. {
  2857. // The top-level deferred function body was defined by a function expression whose parsing was deferred. We are now
  2858. // parsing it, so unset the flag so that any nested functions are parsed normally. This flag is only applicable the
  2859. // first time we see it.
  2860. //
  2861. // Normally, deferred functions will be parsed in ParseStatement upon encountering the 'function' token. The first
  2862. // token of the source code of the function may not a 'function' token though, so we still need to reset this flag
  2863. // for the first function we parse. This can happen in compat modes, for instance, for a function expression enclosed
  2864. // in parentheses, where the legacy behavior was to include the parentheses in the function's source code.
  2865. m_grfscr &= ~fscrDeferredFncExpression;
  2866. }
  2867. ushort flags = fFncNoFlgs;
  2868. if (isLambdaExpr)
  2869. {
  2870. flags |= fFncLambda;
  2871. }
  2872. if (isAsyncExpr)
  2873. {
  2874. flags |= fFncAsync;
  2875. }
  2876. pnode = ParseFncDeclNoCheckScope<buildAST>(flags, SuperRestrictionState::Disallowed, pNameHint, /* needsPIDOnRCurlyScan */ false, fUnaryOrParen);
  2877. if (isAsyncExpr)
  2878. {
  2879. pnode->AsParseNodeFnc()->cbStringMin = iecpMin;
  2880. }
  2881. fCanAssign = FALSE;
  2882. break;
  2883. }
  2884. case tkCLASS:
  2885. if (m_scriptContext->GetConfig()->IsES6ClassAndExtendsEnabled())
  2886. {
  2887. pnode = ParseClassDecl<buildAST>(FALSE, pNameHint, pHintLength, pShortNameOffset);
  2888. }
  2889. else
  2890. {
  2891. goto LUnknown;
  2892. }
  2893. fCanAssign = FALSE;
  2894. break;
  2895. case tkStrTmplBasic:
  2896. case tkStrTmplBegin:
  2897. pnode = ParseStringTemplateDecl<buildAST>(nullptr);
  2898. fCanAssign = FALSE;
  2899. break;
  2900. case tkIMPORT:
  2901. if (m_scriptContext->GetConfig()->IsES6ModuleEnabled() && m_scriptContext->GetConfig()->IsESDynamicImportEnabled())
  2902. {
  2903. this->GetScanner()->Scan();
  2904. ChkCurTokNoScan(tkLParen, ERRnoLparen);
  2905. pnode = ParseImportCall<buildAST>();
  2906. }
  2907. else
  2908. {
  2909. goto LUnknown;
  2910. }
  2911. break;
  2912. #if ENABLE_BACKGROUND_PARSING
  2913. case tkCASE:
  2914. {
  2915. if (!m_doingFastScan)
  2916. {
  2917. goto LUnknown;
  2918. }
  2919. ParseNodePtr pnodeUnused;
  2920. pnode = ParseCase<buildAST>(&pnodeUnused);
  2921. break;
  2922. }
  2923. case tkELSE:
  2924. if (!m_doingFastScan)
  2925. {
  2926. goto LUnknown;
  2927. }
  2928. this->GetScanner()->Scan();
  2929. ParseStatement<buildAST>();
  2930. break;
  2931. #endif
  2932. default:
  2933. LUnknown:
  2934. Error(ERRsyntax);
  2935. break;
  2936. }
  2937. pnode = ParsePostfixOperators<buildAST>(pnode, fAllowCall, fInNew, isAsyncExpr, fCanAssignToCall, &fCanAssign, &term, pfIsDotOrIndex);
  2938. if (savedTopAsyncRef != nullptr &&
  2939. this->m_token.tk == tkDArrow)
  2940. {
  2941. // This is an async arrow function; we're going to back up and reparse it.
  2942. // Make sure we don't leave behind a bogus reference to the 'async' identifier.
  2943. for (pid = wellKnownPropertyPids.async; pid->GetTopRef() != savedTopAsyncRef;)
  2944. {
  2945. Assert(pid->GetTopRef() != nullptr);
  2946. pid->RemovePrevPidRef(nullptr);
  2947. }
  2948. }
  2949. // Pass back identifier if requested
  2950. if (pToken && term.tk == tkID)
  2951. {
  2952. *pToken = term;
  2953. }
  2954. if (pfCanAssign)
  2955. {
  2956. *pfCanAssign = fCanAssign;
  2957. }
  2958. return pnode;
  2959. }
  2960. template <bool buildAST>
  2961. ParseNodeRegExp * Parser::ParseRegExp()
  2962. {
  2963. ParseNodeRegExp * pnode = nullptr;
  2964. if (buildAST || IsDoingFastScan())
  2965. {
  2966. this->GetScanner()->RescanRegExp();
  2967. #if ENABLE_BACKGROUND_PARSING
  2968. BOOL saveDeferringAST = this->m_deferringAST;
  2969. if (m_doingFastScan)
  2970. {
  2971. this->m_deferringAST = false;
  2972. }
  2973. #endif
  2974. pnode = CreateNodeForOpT<knopRegExp>();
  2975. pnode->regexPattern = m_token.GetRegex();
  2976. #if ENABLE_BACKGROUND_PARSING
  2977. if (m_doingFastScan)
  2978. {
  2979. this->m_deferringAST = saveDeferringAST;
  2980. this->AddFastScannedRegExpNode(pnode);
  2981. if (!buildAST)
  2982. {
  2983. pnode = nullptr;
  2984. }
  2985. }
  2986. else if (this->IsBackgroundParser())
  2987. {
  2988. Assert(pnode->regexPattern == nullptr);
  2989. this->AddBackgroundRegExpNode(pnode);
  2990. }
  2991. #endif
  2992. }
  2993. else
  2994. {
  2995. this->GetScanner()->RescanRegExpNoAST();
  2996. }
  2997. Assert(m_token.tk == tkRegExp);
  2998. return pnode;
  2999. }
  3000. BOOL Parser::NodeIsEvalName(ParseNodePtr pnode)
  3001. {
  3002. //WOOB 1107758 Special case of indirect eval binds to local scope in standards mode
  3003. return pnode->nop == knopName && (pnode->AsParseNodeName()->pid == wellKnownPropertyPids.eval);
  3004. }
  3005. BOOL Parser::NodeIsSuperName(ParseNodePtr pnode)
  3006. {
  3007. return pnode->nop == knopName && (pnode->AsParseNodeName()->pid == wellKnownPropertyPids._superConstructor);
  3008. }
  3009. BOOL Parser::NodeEqualsName(ParseNodePtr pnode, LPCOLESTR sz, uint32 cch)
  3010. {
  3011. return pnode->nop == knopName &&
  3012. pnode->AsParseNodeName()->pid->Cch() == cch &&
  3013. !wmemcmp(pnode->AsParseNodeName()->pid->Psz(), sz, cch);
  3014. }
  3015. BOOL Parser::NodeIsIdent(ParseNodePtr pnode, IdentPtr pid)
  3016. {
  3017. for (;;)
  3018. {
  3019. switch (pnode->nop)
  3020. {
  3021. case knopName:
  3022. return (pnode->AsParseNodeName()->pid == pid);
  3023. case knopComma:
  3024. pnode = pnode->AsParseNodeBin()->pnode2;
  3025. break;
  3026. default:
  3027. return FALSE;
  3028. }
  3029. }
  3030. }
  3031. template<bool buildAST>
  3032. ParseNodePtr Parser::ParsePostfixOperators(
  3033. ParseNodePtr pnode,
  3034. BOOL fAllowCall,
  3035. BOOL fInNew,
  3036. BOOL isAsyncExpr,
  3037. BOOL fCanAssignToCallResult,
  3038. BOOL *pfCanAssign,
  3039. _Inout_ IdentToken* pToken,
  3040. _Out_opt_ bool* pfIsDotOrIndex /*= nullptr */)
  3041. {
  3042. uint16 count = 0;
  3043. bool callOfConstants = false;
  3044. if (pfIsDotOrIndex)
  3045. {
  3046. *pfIsDotOrIndex = false;
  3047. }
  3048. for (;;)
  3049. {
  3050. uint16 spreadArgCount = 0;
  3051. switch (m_token.tk)
  3052. {
  3053. case tkLParen:
  3054. {
  3055. AutoMarkInParsingArgs autoMarkInParsingArgs(this);
  3056. if (fInNew)
  3057. {
  3058. ParseNodePtr pnodeArgs = ParseArgList<buildAST>(&callOfConstants, &spreadArgCount, &count);
  3059. if (buildAST)
  3060. {
  3061. Assert(pnode->nop == knopNew);
  3062. Assert(pnode->AsParseNodeCall()->pnodeArgs == nullptr);
  3063. pnode->AsParseNodeCall()->pnodeArgs = pnodeArgs;
  3064. pnode->AsParseNodeCall()->callOfConstants = callOfConstants;
  3065. pnode->AsParseNodeCall()->isApplyCall = false;
  3066. pnode->AsParseNodeCall()->isEvalCall = false;
  3067. pnode->AsParseNodeCall()->isSuperCall = false;
  3068. pnode->AsParseNodeCall()->hasDestructuring = m_hasDestructuringPattern;
  3069. Assert(!m_hasDestructuringPattern || count > 0);
  3070. pnode->AsParseNodeCall()->argCount = count;
  3071. pnode->AsParseNodeCall()->spreadArgCount = spreadArgCount;
  3072. pnode->ichLim = this->GetScanner()->IchLimTok();
  3073. }
  3074. else
  3075. {
  3076. pnode = nullptr;
  3077. pToken->tk = tkNone; // This is no longer an identifier
  3078. }
  3079. fInNew = FALSE;
  3080. ChkCurTok(tkRParen, ERRnoRparen);
  3081. }
  3082. else
  3083. {
  3084. if (!fAllowCall)
  3085. {
  3086. return pnode;
  3087. }
  3088. uint saveNextBlockId = m_nextBlockId;
  3089. uint saveCurrBlockId = GetCurrentBlock()->blockId;
  3090. if (isAsyncExpr)
  3091. {
  3092. // Advance the block ID here in case this parenthetical expression turns out to be a lambda parameter list.
  3093. // That way the pid ref stacks will be created in their correct final form, and we can simply fix
  3094. // up function ID's.
  3095. GetCurrentBlock()->blockId = m_nextBlockId++;
  3096. }
  3097. ParseNodePtr pnodeArgs = ParseArgList<buildAST>(&callOfConstants, &spreadArgCount, &count);
  3098. // We used to un-defer a deferred function body here if it was called as part of the expression that declared it.
  3099. // We now detect this case up front in ParseFncDecl, which is cheaper and simpler.
  3100. if (buildAST)
  3101. {
  3102. bool fCallIsEval = false;
  3103. // Detect super()
  3104. if (this->NodeIsSuperName(pnode))
  3105. {
  3106. pnode = CreateSuperCallNode(pnode->AsParseNodeSpecialName(), pnodeArgs);
  3107. Assert(pnode);
  3108. pnode->AsParseNodeSuperCall()->pnodeThis = ReferenceSpecialName(wellKnownPropertyPids._this, pnode->ichMin, this->GetScanner()->IchLimTok(), true);
  3109. pnode->AsParseNodeSuperCall()->pnodeNewTarget = ReferenceSpecialName(wellKnownPropertyPids._newTarget, pnode->ichMin, this->GetScanner()->IchLimTok(), true);
  3110. }
  3111. else
  3112. {
  3113. pnode = CreateCallNode(knopCall, pnode, pnodeArgs);
  3114. Assert(pnode);
  3115. }
  3116. // Detect call to "eval" and record it on the function.
  3117. // Note: we used to leave it up to the byte code generator to detect eval calls
  3118. // at global scope, but now it relies on the flag the parser sets, so set it here.
  3119. if (count > 0 && this->NodeIsEvalName(pnode->AsParseNodeCall()->pnodeTarget))
  3120. {
  3121. this->MarkEvalCaller();
  3122. fCallIsEval = true;
  3123. // Eval may reference any of the special symbols so we need to push refs to them here.
  3124. ReferenceSpecialName(wellKnownPropertyPids._this);
  3125. ReferenceSpecialName(wellKnownPropertyPids._newTarget);
  3126. ReferenceSpecialName(wellKnownPropertyPids._super);
  3127. ReferenceSpecialName(wellKnownPropertyPids._superConstructor);
  3128. ReferenceSpecialName(wellKnownPropertyPids.arguments);
  3129. }
  3130. pnode->AsParseNodeCall()->callOfConstants = callOfConstants;
  3131. pnode->AsParseNodeCall()->spreadArgCount = spreadArgCount;
  3132. pnode->AsParseNodeCall()->isApplyCall = false;
  3133. pnode->AsParseNodeCall()->isEvalCall = fCallIsEval;
  3134. pnode->AsParseNodeCall()->hasDestructuring = m_hasDestructuringPattern;
  3135. Assert(!m_hasDestructuringPattern || count > 0);
  3136. pnode->AsParseNodeCall()->argCount = count;
  3137. pnode->ichLim = this->GetScanner()->IchLimTok();
  3138. }
  3139. else
  3140. {
  3141. pnode = nullptr;
  3142. if (pToken->tk == tkID && pToken->pid == wellKnownPropertyPids.eval && count > 0) // Detect eval
  3143. {
  3144. this->MarkEvalCaller();
  3145. ReferenceSpecialName(wellKnownPropertyPids._this);
  3146. ReferenceSpecialName(wellKnownPropertyPids._newTarget);
  3147. ReferenceSpecialName(wellKnownPropertyPids._super);
  3148. ReferenceSpecialName(wellKnownPropertyPids._superConstructor);
  3149. ReferenceSpecialName(wellKnownPropertyPids.arguments);
  3150. }
  3151. pToken->tk = tkNone; // This is no longer an identifier
  3152. }
  3153. ChkCurTok(tkRParen, ERRnoRparen);
  3154. if (isAsyncExpr)
  3155. {
  3156. GetCurrentBlock()->blockId = saveCurrBlockId;
  3157. if (m_token.tk == tkDArrow)
  3158. {
  3159. // We're going to rewind and reinterpret the expression as a parameter list.
  3160. // Put back the original next-block-ID so the existing pid ref stacks will be correct.
  3161. m_nextBlockId = saveNextBlockId;
  3162. }
  3163. }
  3164. }
  3165. if (pfCanAssign)
  3166. {
  3167. *pfCanAssign = fCanAssignToCallResult &&
  3168. (m_sourceContextInfo ?
  3169. !PHASE_ON_RAW(Js::EarlyErrorOnAssignToCallPhase, m_sourceContextInfo->sourceContextId, GetCurrentFunctionNode()->functionId) :
  3170. !PHASE_ON1(Js::EarlyErrorOnAssignToCallPhase));
  3171. }
  3172. if (pfIsDotOrIndex)
  3173. {
  3174. *pfIsDotOrIndex = false;
  3175. }
  3176. break;
  3177. }
  3178. case tkLBrack:
  3179. {
  3180. this->GetScanner()->Scan();
  3181. IdentToken tok;
  3182. ParseNodePtr pnodeExpr = ParseExpr<buildAST>(0, FALSE, TRUE, FALSE, nullptr, nullptr, nullptr, &tok);
  3183. if (buildAST)
  3184. {
  3185. AnalysisAssert(pnodeExpr);
  3186. if (pnode && pnode->nop == knopName && pnode->AsParseNodeName()->IsSpecialName() && pnode->AsParseNodeSpecialName()->isSuper)
  3187. {
  3188. pnode = CreateSuperReferenceNode(knopIndex, pnode->AsParseNodeSpecialName(), pnodeExpr);
  3189. pnode->AsParseNodeSuperReference()->pnodeThis = ReferenceSpecialName(wellKnownPropertyPids._this, pnode->ichMin, pnode->ichLim, true);
  3190. }
  3191. else
  3192. {
  3193. pnode = CreateBinNode(knopIndex, pnode, pnodeExpr);
  3194. }
  3195. AnalysisAssert(pnode);
  3196. pnode->ichLim = this->GetScanner()->IchLimTok();
  3197. }
  3198. else
  3199. {
  3200. pnode = nullptr;
  3201. pToken->tk = tkNone; // This is no longer an identifier
  3202. }
  3203. ChkCurTok(tkRBrack, ERRnoRbrack);
  3204. if (pfCanAssign)
  3205. {
  3206. *pfCanAssign = TRUE;
  3207. }
  3208. if (pfIsDotOrIndex)
  3209. {
  3210. *pfIsDotOrIndex = true;
  3211. }
  3212. PidRefStack * topPidRef = nullptr;
  3213. if (buildAST)
  3214. {
  3215. if (pnodeExpr && pnodeExpr->nop == knopName)
  3216. {
  3217. topPidRef = pnodeExpr->AsParseNodeName()->pid->GetTopRef();
  3218. }
  3219. }
  3220. else if (tok.tk == tkID)
  3221. {
  3222. topPidRef = tok.pid->GetTopRef();
  3223. }
  3224. if (topPidRef)
  3225. {
  3226. topPidRef->SetIsUsedInLdElem(true);
  3227. }
  3228. if (!buildAST)
  3229. {
  3230. break;
  3231. }
  3232. bool shouldConvertToDot = false;
  3233. if (pnode->AsParseNodeBin()->pnode2->nop == knopStr)
  3234. {
  3235. // if the string is empty or contains escape character, we will not convert them to dot node
  3236. shouldConvertToDot = pnode->AsParseNodeBin()->pnode2->AsParseNodeStr()->pid->Cch() > 0 && !this->GetScanner()->IsEscapeOnLastTkStrCon();
  3237. }
  3238. if (shouldConvertToDot)
  3239. {
  3240. LPCOLESTR str = pnode->AsParseNodeBin()->pnode2->AsParseNodeStr()->pid->Psz();
  3241. // See if we can convert o["p"] into o.p and o["0"] into o[0] since they're equivalent and the latter forms
  3242. // are faster
  3243. uint32 uintValue;
  3244. if (Js::JavascriptOperators::TryConvertToUInt32(
  3245. str,
  3246. pnode->AsParseNodeBin()->pnode2->AsParseNodeStr()->pid->Cch(),
  3247. &uintValue) &&
  3248. !Js::TaggedInt::IsOverflow(uintValue)) // the optimization is not very useful if the number can't be represented as a TaggedInt
  3249. {
  3250. // No need to verify that uintValue != JavascriptArray::InvalidIndex since all nonnegative TaggedInts are valid indexes
  3251. auto intNode = CreateIntNode(uintValue); // implicit conversion from uint32 to int32
  3252. pnode->AsParseNodeBin()->pnode2 = intNode;
  3253. }
  3254. // Field optimization (see GlobOpt::KillLiveElems) checks for value being a Number,
  3255. // and since NaN/Infinity is a number it won't kill o.NaN/o.Infinity which would cause a problem
  3256. // if we decide to hoist o.NaN/o.Infinity.
  3257. // We need to keep o["NaN"] and o["+/-Infinity"] as array element access (we don't hoist that but we may hoist field access),
  3258. // so no matter if it's killed by o[x] inside a loop, we make sure that we never hoist these.
  3259. // We need to follow same logic for strings that convert to a floating point number.
  3260. else
  3261. {
  3262. bool doConvertToProperty = false; // Convert a["x"] -> a.x.
  3263. if (!Parser::IsNaNOrInfinityLiteral<true>(str))
  3264. {
  3265. const OLECHAR* terminalChar;
  3266. double dbl = Js::NumberUtilities::StrToDbl(str, &terminalChar, m_scriptContext);
  3267. bool convertsToFloat = !Js::NumberUtilities::IsNan(dbl);
  3268. doConvertToProperty = !convertsToFloat;
  3269. }
  3270. if (doConvertToProperty)
  3271. {
  3272. ParseNodeName * pnodeNewExpr = CreateNameNode(pnodeExpr->AsParseNodeStr()->pid);
  3273. pnodeNewExpr->ichMin = pnodeExpr->ichMin;
  3274. pnodeNewExpr->ichLim = pnodeExpr->ichLim;
  3275. pnode->AsParseNodeBin()->pnode2 = pnodeNewExpr;
  3276. pnode->nop = knopDot;
  3277. pnode->grfpn |= PNodeFlags::fpnIndexOperator;
  3278. }
  3279. }
  3280. }
  3281. }
  3282. break;
  3283. case tkDot:
  3284. {
  3285. ParseNodePtr name = nullptr;
  3286. OpCode opCode = knopDot;
  3287. this->GetScanner()->Scan();
  3288. if (!m_token.IsIdentifier())
  3289. {
  3290. //allow reserved words in ES5 mode
  3291. if (!(m_token.IsReservedWord()))
  3292. {
  3293. IdentifierExpectedError(m_token);
  3294. }
  3295. }
  3296. // Note: see comment above about field optimization WRT NaN/Infinity/-Infinity.
  3297. // Convert a.Nan, a.Infinity into a["NaN"], a["Infinity"].
  3298. // We don't care about -Infinity case here because x.-Infinity is invalid in JavaScript.
  3299. // Both NaN and Infinity are identifiers.
  3300. else if (buildAST && Parser::IsNaNOrInfinityLiteral<false>(m_token.GetIdentifier(this->GetHashTbl())->Psz()))
  3301. {
  3302. opCode = knopIndex;
  3303. }
  3304. if (buildAST)
  3305. {
  3306. if (opCode == knopDot)
  3307. {
  3308. name = CreateNameNode(m_token.GetIdentifier(this->GetHashTbl()));
  3309. }
  3310. else
  3311. {
  3312. Assert(opCode == knopIndex);
  3313. name = CreateStrNode(m_token.GetIdentifier(this->GetHashTbl()));
  3314. }
  3315. if (pnode && pnode->nop == knopName && pnode->AsParseNodeName()->IsSpecialName() && pnode->AsParseNodeSpecialName()->isSuper)
  3316. {
  3317. pnode = CreateSuperReferenceNode(opCode, pnode->AsParseNodeSpecialName(), name);
  3318. pnode->AsParseNodeSuperReference()->pnodeThis = ReferenceSpecialName(wellKnownPropertyPids._this, pnode->ichMin, pnode->ichLim, true);
  3319. }
  3320. else
  3321. {
  3322. pnode = CreateBinNode(opCode, pnode, name);
  3323. }
  3324. }
  3325. else
  3326. {
  3327. pnode = nullptr;
  3328. pToken->tk = tkNone;
  3329. }
  3330. if (pfCanAssign)
  3331. {
  3332. *pfCanAssign = TRUE;
  3333. }
  3334. if (pfIsDotOrIndex)
  3335. {
  3336. *pfIsDotOrIndex = true;
  3337. }
  3338. this->GetScanner()->Scan();
  3339. break;
  3340. }
  3341. case tkStrTmplBasic:
  3342. case tkStrTmplBegin:
  3343. {
  3344. ParseNode* templateNode = nullptr;
  3345. if (pnode != nullptr)
  3346. {
  3347. AutoMarkInParsingArgs autoMarkInParsingArgs(this);
  3348. templateNode = ParseStringTemplateDecl<buildAST>(pnode);
  3349. }
  3350. else
  3351. {
  3352. templateNode = ParseStringTemplateDecl<buildAST>(pnode);
  3353. }
  3354. if (!buildAST)
  3355. {
  3356. pToken->tk = tkNone; // This is no longer an identifier
  3357. }
  3358. pnode = templateNode;
  3359. if (pfCanAssign)
  3360. {
  3361. *pfCanAssign = FALSE;
  3362. }
  3363. if (pfIsDotOrIndex)
  3364. {
  3365. *pfIsDotOrIndex = false;
  3366. }
  3367. break;
  3368. }
  3369. default:
  3370. return pnode;
  3371. }
  3372. }
  3373. }
  3374. /***************************************************************************
  3375. Look for an existing label with the given name.
  3376. ***************************************************************************/
  3377. bool Parser::LabelExists(IdentPtr pid, LabelId* pLabelIdList)
  3378. {
  3379. StmtNest dummy;
  3380. dummy.pLabelId = pLabelIdList;
  3381. dummy.pstmtOuter = m_pstmtCur;
  3382. // Look through each label list for the current stack of statements
  3383. for (StmtNest* pStmt = &dummy; pStmt != nullptr; pStmt = pStmt->pstmtOuter)
  3384. {
  3385. for (LabelId* pLabelId = pStmt->pLabelId; pLabelId != nullptr; pLabelId = pLabelId->next)
  3386. {
  3387. if (pLabelId->pid == pid)
  3388. return true;
  3389. }
  3390. }
  3391. return false;
  3392. }
  3393. // Currently only ints and floats are treated as constants in function call
  3394. // TODO: Check if we need for other constants as well
  3395. BOOL Parser::IsConstantInFunctionCall(ParseNodePtr pnode)
  3396. {
  3397. if (pnode->nop == knopInt && !Js::TaggedInt::IsOverflow(pnode->AsParseNodeInt()->lw))
  3398. {
  3399. return TRUE;
  3400. }
  3401. if (pnode->nop == knopFlt)
  3402. {
  3403. return TRUE;
  3404. }
  3405. return FALSE;
  3406. }
  3407. /***************************************************************************
  3408. Parse a list of arguments.
  3409. ***************************************************************************/
  3410. template<bool buildAST>
  3411. ParseNodePtr Parser::ParseArgList(bool *pCallOfConstants, uint16 *pSpreadArgCount, uint16 * pCount)
  3412. {
  3413. ParseNodePtr pnodeArg;
  3414. ParseNodePtr pnodeList = nullptr;
  3415. ParseNodePtr *lastNodeRef = nullptr;
  3416. // Check for an empty list
  3417. Assert(m_token.tk == tkLParen);
  3418. if (this->GetScanner()->Scan() == tkRParen)
  3419. {
  3420. return nullptr;
  3421. }
  3422. *pCallOfConstants = true;
  3423. *pSpreadArgCount = 0;
  3424. int count = 0;
  3425. while (true)
  3426. {
  3427. if (count >= Js::Constants::MaxAllowedArgs)
  3428. {
  3429. Error(ERRTooManyArgs);
  3430. }
  3431. // Allow spread in argument lists.
  3432. IdentToken token;
  3433. pnodeArg = ParseExpr<buildAST>(koplCma, nullptr, TRUE, /* fAllowEllipsis */TRUE, NULL, nullptr, nullptr, &token);
  3434. ++count;
  3435. this->MarkEscapingRef(pnodeArg, &token);
  3436. if (buildAST)
  3437. {
  3438. this->CheckArguments(pnodeArg);
  3439. if (*pCallOfConstants && !IsConstantInFunctionCall(pnodeArg))
  3440. {
  3441. *pCallOfConstants = false;
  3442. }
  3443. if (pnodeArg->nop == knopEllipsis)
  3444. {
  3445. (*pSpreadArgCount)++;
  3446. }
  3447. AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeArg);
  3448. }
  3449. if (m_token.tk != tkComma)
  3450. {
  3451. break;
  3452. }
  3453. this->GetScanner()->Scan();
  3454. if (m_token.tk == tkRParen && m_scriptContext->GetConfig()->IsES7TrailingCommaEnabled())
  3455. {
  3456. break;
  3457. }
  3458. }
  3459. if (pSpreadArgCount != nullptr && (*pSpreadArgCount) > 0) {
  3460. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, SpreadFeature, m_scriptContext);
  3461. }
  3462. *pCount = static_cast<uint16>(count);
  3463. if (buildAST)
  3464. {
  3465. Assert(lastNodeRef);
  3466. Assert(*lastNodeRef);
  3467. pnodeList->ichLim = (*lastNodeRef)->ichLim;
  3468. }
  3469. return pnodeList;
  3470. }
  3471. // Currently only ints are treated as constants in ArrayLiterals
  3472. BOOL Parser::IsConstantInArrayLiteral(ParseNodePtr pnode)
  3473. {
  3474. if (pnode->nop == knopInt && !Js::TaggedInt::IsOverflow(pnode->AsParseNodeInt()->lw))
  3475. {
  3476. return TRUE;
  3477. }
  3478. return FALSE;
  3479. }
  3480. template<bool buildAST>
  3481. ParseNodeArrLit * Parser::ParseArrayLiteral()
  3482. {
  3483. ParseNodeArrLit * pnode = nullptr;
  3484. bool arrayOfTaggedInts = false;
  3485. bool arrayOfInts = false;
  3486. bool arrayOfNumbers = false;
  3487. bool hasMissingValues = false;
  3488. uint count = 0;
  3489. uint spreadCount = 0;
  3490. ParseNodePtr pnode1 = ParseArrayList<buildAST>(&arrayOfTaggedInts, &arrayOfInts, &arrayOfNumbers, &hasMissingValues, &count, &spreadCount);
  3491. if (buildAST)
  3492. {
  3493. pnode = CreateNodeForOpT<knopArray>();
  3494. pnode->pnode1 = pnode1;
  3495. pnode->arrayOfTaggedInts = arrayOfTaggedInts;
  3496. pnode->arrayOfInts = arrayOfInts;
  3497. pnode->arrayOfNumbers = arrayOfNumbers;
  3498. pnode->hasMissingValues = hasMissingValues;
  3499. pnode->count = count;
  3500. pnode->spreadCount = spreadCount;
  3501. if (pnode->pnode1)
  3502. {
  3503. this->CheckArguments(pnode->pnode1);
  3504. }
  3505. }
  3506. return pnode;
  3507. }
  3508. /***************************************************************************
  3509. Create an ArrayLiteral node
  3510. Parse a list of array elements. [ a, b, , c, ]
  3511. ***************************************************************************/
  3512. template<bool buildAST>
  3513. ParseNodePtr Parser::ParseArrayList(bool *pArrayOfTaggedInts, bool *pArrayOfInts, bool *pArrayOfNumbers, bool *pHasMissingValues, uint *count, uint *spreadCount)
  3514. {
  3515. ParseNodePtr pnodeArg = nullptr;
  3516. ParseNodePtr pnodeList = nullptr;
  3517. ParseNodePtr *lastNodeRef = nullptr;
  3518. *count = 0;
  3519. // Check for an empty list
  3520. if (tkRBrack == m_token.tk)
  3521. {
  3522. return nullptr;
  3523. }
  3524. this->m_arrayDepth++;
  3525. bool arrayOfTaggedInts = buildAST;
  3526. bool arrayOfInts = buildAST;
  3527. bool arrayOfNumbers = buildAST;
  3528. bool arrayOfVarInts = false;
  3529. bool hasMissingValues = false;
  3530. for (;;)
  3531. {
  3532. (*count)++;
  3533. if (tkComma == m_token.tk || tkRBrack == m_token.tk)
  3534. {
  3535. hasMissingValues = true;
  3536. arrayOfTaggedInts = false;
  3537. arrayOfInts = false;
  3538. arrayOfNumbers = false;
  3539. if (buildAST)
  3540. {
  3541. pnodeArg = CreateNodeForOpT<knopEmpty>();
  3542. }
  3543. }
  3544. else
  3545. {
  3546. // Allow Spread in array literals.
  3547. pnodeArg = ParseExpr<buildAST>(koplCma, nullptr, TRUE, /* fAllowEllipsis */ TRUE);
  3548. if (buildAST)
  3549. {
  3550. if (pnodeArg->nop == knopEllipsis)
  3551. {
  3552. (*spreadCount)++;
  3553. }
  3554. this->CheckArguments(pnodeArg);
  3555. }
  3556. }
  3557. #if DEBUG
  3558. if (m_grfscr & fscrEnforceJSON && !IsJSONValid(pnodeArg))
  3559. {
  3560. Error(ERRsyntax);
  3561. }
  3562. #endif
  3563. if (buildAST)
  3564. {
  3565. if (arrayOfNumbers)
  3566. {
  3567. if (pnodeArg->nop != knopInt)
  3568. {
  3569. arrayOfTaggedInts = false;
  3570. if (pnodeArg->nop != knopFlt)
  3571. {
  3572. // Not an array of constants.
  3573. arrayOfInts = false;
  3574. arrayOfNumbers = false;
  3575. }
  3576. else if (arrayOfInts && Js::JavascriptNumber::IsInt32OrUInt32(pnodeArg->AsParseNodeFloat()->dbl) && (!Js::JavascriptNumber::IsInt32(pnodeArg->AsParseNodeFloat()->dbl) || pnodeArg->AsParseNodeFloat()->dbl == -2147483648.0))
  3577. {
  3578. // We've seen nothing but ints, and this is a uint32 but not an int32.
  3579. // Unless we see an actual float at some point, we want an array of vars
  3580. // so we can work with tagged ints.
  3581. arrayOfVarInts = true;
  3582. }
  3583. else
  3584. {
  3585. // Not an int array, but it may still be a float array.
  3586. arrayOfInts = false;
  3587. }
  3588. }
  3589. else
  3590. {
  3591. if (Js::SparseArraySegment<int32>::IsMissingItem((int32*)&pnodeArg->AsParseNodeInt()->lw))
  3592. {
  3593. arrayOfInts = false;
  3594. }
  3595. if (Js::TaggedInt::IsOverflow(pnodeArg->AsParseNodeInt()->lw))
  3596. {
  3597. arrayOfTaggedInts = false;
  3598. }
  3599. }
  3600. }
  3601. AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeArg);
  3602. }
  3603. if (tkComma != m_token.tk)
  3604. {
  3605. break;
  3606. }
  3607. this->GetScanner()->Scan();
  3608. if (tkRBrack == m_token.tk)
  3609. {
  3610. break;
  3611. }
  3612. }
  3613. if (spreadCount != nullptr && *spreadCount > 0) {
  3614. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, SpreadFeature, m_scriptContext);
  3615. }
  3616. if (buildAST)
  3617. {
  3618. Assert(lastNodeRef);
  3619. Assert(*lastNodeRef);
  3620. pnodeList->ichLim = (*lastNodeRef)->ichLim;
  3621. if (arrayOfVarInts && arrayOfInts)
  3622. {
  3623. arrayOfInts = false;
  3624. arrayOfNumbers = false;
  3625. }
  3626. *pArrayOfTaggedInts = arrayOfTaggedInts;
  3627. *pArrayOfInts = arrayOfInts;
  3628. *pArrayOfNumbers = arrayOfNumbers;
  3629. *pHasMissingValues = hasMissingValues;
  3630. }
  3631. this->m_arrayDepth--;
  3632. return pnodeList;
  3633. }
  3634. Parser::MemberNameToTypeMap* Parser::CreateMemberNameMap(ArenaAllocator* pAllocator)
  3635. {
  3636. Assert(pAllocator);
  3637. return Anew(pAllocator, MemberNameToTypeMap, pAllocator, 5);
  3638. }
  3639. template<bool buildAST> void Parser::ParseComputedName(ParseNodePtr* ppnodeName, LPCOLESTR* ppNameHint, LPCOLESTR* ppFullNameHint, uint32 *pNameLength, uint32 *pShortNameOffset)
  3640. {
  3641. this->GetScanner()->Scan();
  3642. ParseNodePtr pnodeNameExpr = ParseExpr<buildAST>(koplCma, nullptr, TRUE, FALSE, *ppNameHint, pNameLength, pShortNameOffset);
  3643. if (buildAST)
  3644. {
  3645. *ppnodeName = CreateUniNode(knopComputedName, pnodeNameExpr, pnodeNameExpr->ichMin, pnodeNameExpr->ichLim);
  3646. }
  3647. if (ppFullNameHint && buildAST && CONFIG_FLAG(UseFullName))
  3648. {
  3649. *ppFullNameHint = FormatPropertyString(*ppNameHint, pnodeNameExpr, pNameLength, pShortNameOffset);
  3650. }
  3651. ChkCurTokNoScan(tkRBrack, ERRnoRbrack);
  3652. }
  3653. /***************************************************************************
  3654. Parse a list of object set/get members, e.g.:
  3655. { get foo(){ ... }, set bar(arg) { ... } }
  3656. ***************************************************************************/
  3657. template<bool buildAST>
  3658. ParseNodeBin * Parser::ParseMemberGetSet(OpCode nop, LPCOLESTR* ppNameHint, size_t iecpMin, charcount_t ichMin)
  3659. {
  3660. ParseNodePtr pnodeName = nullptr;
  3661. Assert(nop == knopGetMember || nop == knopSetMember);
  3662. Assert(ppNameHint);
  3663. IdentPtr pid = nullptr;
  3664. bool isComputedName = false;
  3665. *ppNameHint = nullptr;
  3666. switch (m_token.tk)
  3667. {
  3668. default:
  3669. if (!m_token.IsReservedWord())
  3670. {
  3671. Error(ERRnoMemberIdent);
  3672. }
  3673. // fall through
  3674. case tkID:
  3675. pid = m_token.GetIdentifier(this->GetHashTbl());
  3676. *ppNameHint = pid->Psz();
  3677. if (buildAST)
  3678. {
  3679. pnodeName = CreateStrNode(pid);
  3680. }
  3681. break;
  3682. case tkStrCon:
  3683. if (IsStrictMode() && this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
  3684. {
  3685. Error(ERRES5NoOctal);
  3686. }
  3687. pid = m_token.GetStr();
  3688. *ppNameHint = pid->Psz();
  3689. if (buildAST)
  3690. {
  3691. pnodeName = CreateStrNode(pid);
  3692. }
  3693. break;
  3694. case tkIntCon:
  3695. if (IsStrictMode() && this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
  3696. {
  3697. Error(ERRES5NoOctal);
  3698. }
  3699. pid = this->GetScanner()->PidFromLong(m_token.GetLong());
  3700. if (buildAST)
  3701. {
  3702. pnodeName = CreateStrNode(pid);
  3703. }
  3704. break;
  3705. case tkFltCon:
  3706. if (IsStrictMode() && this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
  3707. {
  3708. Error(ERRES5NoOctal);
  3709. }
  3710. pid = this->GetScanner()->PidFromDbl(m_token.GetDouble());
  3711. if (buildAST)
  3712. {
  3713. pnodeName = CreateStrNode(pid);
  3714. }
  3715. break;
  3716. case tkLBrack:
  3717. // Computed property name: get|set [expr] () { }
  3718. if (!m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
  3719. {
  3720. Error(ERRnoMemberIdent);
  3721. }
  3722. LPCOLESTR emptyHint = nullptr;
  3723. uint32 offset = 0;
  3724. ParseComputedName<buildAST>(&pnodeName, &emptyHint, ppNameHint, &offset);
  3725. isComputedName = true;
  3726. break;
  3727. }
  3728. MemberType memberType;
  3729. ushort flags = fFncMethod | fFncNoName;
  3730. if (nop == knopGetMember)
  3731. {
  3732. memberType = MemberTypeGetter;
  3733. flags |= fFncNoArg;
  3734. }
  3735. else
  3736. {
  3737. Assert(nop == knopSetMember);
  3738. memberType = MemberTypeSetter;
  3739. flags |= fFncOneArg;
  3740. }
  3741. ParseNodeFnc * pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(flags, SuperRestrictionState::PropertyAllowed, *ppNameHint,
  3742. /*needsPIDOnRCurlyScan*/ false);
  3743. pnodeFnc->cbStringMin = iecpMin;
  3744. if (isComputedName)
  3745. {
  3746. pnodeFnc->SetHasComputedName();
  3747. }
  3748. pnodeFnc->SetHasHomeObj();
  3749. pnodeFnc->SetIsAccessor();
  3750. if (buildAST)
  3751. {
  3752. return CreateBinNode(nop, pnodeName, pnodeFnc);
  3753. }
  3754. else
  3755. {
  3756. return nullptr;
  3757. }
  3758. }
  3759. /***************************************************************************
  3760. Parse a list of object members. e.g. { x:foo, 'y me':bar }
  3761. ***************************************************************************/
  3762. template<bool buildAST>
  3763. ParseNodePtr Parser::ParseMemberList(LPCOLESTR pNameHint, uint32* pNameHintLength, tokens declarationType)
  3764. {
  3765. ParseNodeBin * pnodeArg = nullptr;
  3766. ParseNodePtr pnodeEllipsis = nullptr;
  3767. ParseNodePtr pnodeName = nullptr;
  3768. ParseNodePtr pnodeList = nullptr;
  3769. ParseNodePtr *lastNodeRef = nullptr;
  3770. LPCOLESTR pFullNameHint = nullptr; // A calculated full name
  3771. uint32 fullNameHintLength = pNameHintLength ? *pNameHintLength : 0;
  3772. uint32 shortNameOffset = 0;
  3773. bool isProtoDeclared = false;
  3774. bool seenRest = false;
  3775. // we get declaration tkLCurly - when the possible object pattern found under the expression.
  3776. bool isObjectPattern = (declarationType == tkVAR || declarationType == tkLET || declarationType == tkCONST || declarationType == tkLCurly) && IsES6DestructuringEnabled();
  3777. // Check for an empty list
  3778. if (tkRCurly == m_token.tk)
  3779. {
  3780. return nullptr;
  3781. }
  3782. ArenaAllocator tempAllocator(_u("MemberNames"), m_nodeAllocator.GetPageAllocator(), Parser::OutOfMemory);
  3783. bool hasDeferredInitError = false;
  3784. for (;;)
  3785. {
  3786. bool isComputedName = false;
  3787. #if DEBUG
  3788. if ((m_grfscr & fscrEnforceJSON) && (tkStrCon != m_token.tk || !(this->GetScanner()->IsDoubleQuoteOnLastTkStrCon())))
  3789. {
  3790. Error(ERRsyntax);
  3791. }
  3792. #endif
  3793. bool isAsyncMethod = false;
  3794. charcount_t ichMin = this->GetScanner()->IchMinTok();
  3795. size_t iecpMin = this->GetScanner()->IecpMinTok();
  3796. if (m_token.tk == tkID && m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.async && m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
  3797. {
  3798. RestorePoint parsedAsync;
  3799. this->GetScanner()->Capture(&parsedAsync);
  3800. ichMin = this->GetScanner()->IchMinTok();
  3801. iecpMin = this->GetScanner()->IecpMinTok();
  3802. this->GetScanner()->ScanForcingPid();
  3803. if (m_token.tk == tkLParen || m_token.tk == tkColon || m_token.tk == tkRCurly || this->GetScanner()->FHadNewLine() || m_token.tk == tkComma)
  3804. {
  3805. this->GetScanner()->SeekTo(parsedAsync);
  3806. }
  3807. else
  3808. {
  3809. isAsyncMethod = true;
  3810. }
  3811. }
  3812. bool isGenerator = m_scriptContext->GetConfig()->IsES6GeneratorsEnabled() &&
  3813. m_token.tk == tkStar;
  3814. ushort fncDeclFlags = fFncNoName | fFncMethod;
  3815. if (isGenerator)
  3816. {
  3817. if (isAsyncMethod)
  3818. {
  3819. Error(ERRsyntax);
  3820. }
  3821. // Include star character in the function extents
  3822. ichMin = this->GetScanner()->IchMinTok();
  3823. iecpMin = this->GetScanner()->IecpMinTok();
  3824. this->GetScanner()->ScanForcingPid();
  3825. fncDeclFlags |= fFncGenerator;
  3826. }
  3827. IdentPtr pidHint = nullptr; // A name scoped to current expression
  3828. Token tkHint = m_token;
  3829. charcount_t idHintIchMin = static_cast<charcount_t>(this->GetScanner()->IecpMinTok());
  3830. charcount_t idHintIchLim = static_cast<charcount_t>(this->GetScanner()->IecpLimTok());
  3831. bool wrapInBrackets = false;
  3832. bool seenEllipsis = false;
  3833. switch (m_token.tk)
  3834. {
  3835. default:
  3836. if (!m_token.IsReservedWord())
  3837. {
  3838. Error(ERRnoMemberIdent);
  3839. }
  3840. // allow reserved words
  3841. wrapInBrackets = true;
  3842. // fall-through
  3843. case tkID:
  3844. pidHint = m_token.GetIdentifier(this->GetHashTbl());
  3845. if (buildAST)
  3846. {
  3847. pnodeName = CreateStrNode(pidHint);
  3848. }
  3849. break;
  3850. case tkStrCon:
  3851. if (IsStrictMode() && this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
  3852. {
  3853. Error(ERRES5NoOctal);
  3854. }
  3855. wrapInBrackets = true;
  3856. pidHint = m_token.GetStr();
  3857. if (buildAST)
  3858. {
  3859. pnodeName = CreateStrNode(pidHint);
  3860. }
  3861. break;
  3862. case tkIntCon:
  3863. // Object initializers with numeric labels allowed in JS6
  3864. if (IsStrictMode() && this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
  3865. {
  3866. Error(ERRES5NoOctal);
  3867. }
  3868. pidHint = this->GetScanner()->PidFromLong(m_token.GetLong());
  3869. if (buildAST)
  3870. {
  3871. pnodeName = CreateStrNode(pidHint);
  3872. }
  3873. break;
  3874. case tkFltCon:
  3875. if (IsStrictMode() && this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
  3876. {
  3877. Error(ERRES5NoOctal);
  3878. }
  3879. pidHint = this->GetScanner()->PidFromDbl(m_token.GetDouble());
  3880. if (buildAST)
  3881. {
  3882. pnodeName = CreateStrNode(pidHint);
  3883. }
  3884. wrapInBrackets = true;
  3885. break;
  3886. case tkLBrack:
  3887. // Computed property name: [expr] : value
  3888. if (!m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
  3889. {
  3890. Error(ERRnoMemberIdent);
  3891. }
  3892. ParseComputedName<buildAST>(&pnodeName, &pNameHint, &pFullNameHint, &fullNameHintLength, &shortNameOffset);
  3893. isComputedName = true;
  3894. break;
  3895. case tkEllipsis:
  3896. if (CONFIG_FLAG(ES2018ObjectRestSpread))
  3897. {
  3898. seenEllipsis = true;
  3899. }
  3900. else
  3901. {
  3902. Error(ERRnoMemberIdent);
  3903. }
  3904. break;
  3905. }
  3906. if (pFullNameHint == nullptr)
  3907. {
  3908. if (CONFIG_FLAG(UseFullName))
  3909. {
  3910. pFullNameHint = AppendNameHints(pNameHint, pidHint, &fullNameHintLength, &shortNameOffset, false, wrapInBrackets);
  3911. }
  3912. else
  3913. {
  3914. pFullNameHint = pidHint ? pidHint->Psz() : nullptr;
  3915. fullNameHintLength = pidHint ? pidHint->Cch() : 0;
  3916. shortNameOffset = 0;
  3917. }
  3918. }
  3919. RestorePoint atPid;
  3920. // Only move to next token if spread op was not seen
  3921. if (!seenEllipsis)
  3922. {
  3923. this->GetScanner()->Capture(&atPid);
  3924. this->GetScanner()->ScanForcingPid();
  3925. }
  3926. if (isGenerator && m_token.tk != tkLParen)
  3927. {
  3928. Error(ERRnoLparen);
  3929. }
  3930. if (tkColon == m_token.tk)
  3931. {
  3932. // It is a syntax error if the production of the form __proto__ : <> occurs more than once. From B.3.1 in spec.
  3933. // Note that previous scan is important because only after that we can determine we have a variable.
  3934. if (!isComputedName && pidHint == wellKnownPropertyPids.__proto__)
  3935. {
  3936. if (isProtoDeclared)
  3937. {
  3938. Error(ERRsyntax);
  3939. }
  3940. else
  3941. {
  3942. isProtoDeclared = true;
  3943. }
  3944. }
  3945. this->GetScanner()->Scan();
  3946. ParseNodePtr pnodeExpr = nullptr;
  3947. if (isObjectPattern)
  3948. {
  3949. if (m_token.tk == tkEllipsis)
  3950. {
  3951. Error(ERRUnexpectedEllipsis);
  3952. }
  3953. RestorePoint atExpression;
  3954. if (!buildAST && declarationType == tkLCurly && IsPossiblePatternStart())
  3955. {
  3956. this->GetScanner()->Capture(&atExpression);
  3957. int saveNextBlockId = m_nextBlockId;
  3958. // It is possible that we might encounter the shorthand init error. Lets find that out.
  3959. bool savedDeferredInitError = m_hasDeferredShorthandInitError;
  3960. m_hasDeferredShorthandInitError = false;
  3961. IdentToken token;
  3962. BOOL fLikelyPattern = false;
  3963. // First identify that the current expression is indeed the object/array literal. Otherwise we will just use the ParsrExpr to parse that.
  3964. ParseTerm<buildAST>(/* fAllowCall */ m_token.tk != tkSUPER, nullptr /*pNameHint*/, nullptr /*pHintLength*/, nullptr /*pShortNameOffset*/, &token, false /*fUnaryOrParen*/,
  3965. TRUE, nullptr /*pfCanAssign*/, &fLikelyPattern);
  3966. m_nextBlockId = saveNextBlockId;
  3967. this->GetScanner()->SeekTo(atExpression);
  3968. if (fLikelyPattern)
  3969. {
  3970. pnodeExpr = ParseDestructuredVarDecl<buildAST>(declarationType, declarationType != tkLCurly, &seenRest/* *hasSeenRest*/, false /*topLevel*/, false /*allowEmptyExpression*/, true /*isObjectPattern*/);
  3971. if (m_token.tk != tkComma && m_token.tk != tkRCurly)
  3972. {
  3973. if (m_token.IsOperator())
  3974. {
  3975. Error(ERRDestructNoOper);
  3976. }
  3977. Error(ERRsyntax);
  3978. }
  3979. }
  3980. else
  3981. {
  3982. if (m_hasDeferredShorthandInitError)
  3983. {
  3984. Error(ERRnoColon);
  3985. }
  3986. pnodeExpr = ParseExpr<buildAST>(koplCma, nullptr/*pfCantAssign*/, TRUE/*fAllowIn*/, FALSE/*fAllowEllipsis*/, pFullNameHint, &fullNameHintLength, &shortNameOffset);
  3987. }
  3988. m_hasDeferredShorthandInitError = savedDeferredInitError;
  3989. }
  3990. else
  3991. {
  3992. pnodeExpr = ParseDestructuredVarDecl<buildAST>(declarationType, declarationType != tkLCurly, &seenRest/* *hasSeenRest*/, false /*topLevel*/, false /*allowEmptyExpression*/, true /*isObjectPattern*/);
  3993. if (m_token.tk != tkComma && m_token.tk != tkRCurly)
  3994. {
  3995. if (m_token.IsOperator())
  3996. {
  3997. Error(ERRDestructNoOper);
  3998. }
  3999. Error(ERRsyntax);
  4000. }
  4001. }
  4002. }
  4003. else
  4004. {
  4005. pnodeExpr = ParseExpr<buildAST>(koplCma, nullptr/*pfCantAssign*/, TRUE/*fAllowIn*/, FALSE/*fAllowEllipsis*/, pFullNameHint, &fullNameHintLength, &shortNameOffset);
  4006. if (pnodeExpr && pnodeExpr->nop == knopFncDecl)
  4007. {
  4008. ParseNodeFnc* funcNode = pnodeExpr->AsParseNodeFnc();
  4009. if (isComputedName)
  4010. {
  4011. funcNode->SetHasComputedName();
  4012. }
  4013. funcNode->SetHasHomeObj();
  4014. }
  4015. }
  4016. #if DEBUG
  4017. if ((m_grfscr & fscrEnforceJSON) && !IsJSONValid(pnodeExpr))
  4018. {
  4019. Error(ERRsyntax);
  4020. }
  4021. #endif
  4022. if (buildAST)
  4023. {
  4024. pnodeArg = CreateBinNode(isObjectPattern ? knopObjectPatternMember : knopMember, pnodeName, pnodeExpr);
  4025. if (pnodeArg->pnode1->nop == knopStr)
  4026. {
  4027. pnodeArg->pnode1->AsParseNodeStr()->pid->PromoteAssignmentState();
  4028. }
  4029. }
  4030. }
  4031. else if (m_token.tk == tkLParen && m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
  4032. {
  4033. if (isObjectPattern)
  4034. {
  4035. Error(ERRInvalidAssignmentTarget);
  4036. }
  4037. // Shorthand syntax: foo() {} -> foo: function() {}
  4038. // Rewind to the PID and parse a function expression.
  4039. this->GetScanner()->SeekTo(atPid);
  4040. ParseNodeFnc * pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(fncDeclFlags | (isAsyncMethod ? fFncAsync : fFncNoFlgs), SuperRestrictionState::PropertyAllowed, pFullNameHint,
  4041. /*needsPIDOnRCurlyScan*/ false);
  4042. if (isAsyncMethod || isGenerator)
  4043. {
  4044. pnodeFnc->cbStringMin = iecpMin;
  4045. }
  4046. if (isComputedName)
  4047. {
  4048. pnodeFnc->SetHasComputedName();
  4049. pnodeFnc->cbStringMin = iecpMin;
  4050. }
  4051. pnodeFnc->SetHasHomeObj();
  4052. if (buildAST)
  4053. {
  4054. pnodeArg = CreateBinNode(knopMember, pnodeName, pnodeFnc);
  4055. }
  4056. }
  4057. else if (seenEllipsis)
  4058. {
  4059. if (!isObjectPattern)
  4060. {
  4061. pnodeEllipsis = ParseExpr<buildAST>(koplCma, nullptr, TRUE, /* fAllowEllipsis */ TRUE);
  4062. }
  4063. else
  4064. {
  4065. pnodeEllipsis = ParseDestructuredVarDecl<buildAST>(declarationType, declarationType != tkLCurly, &seenRest/* *hasSeenRest*/, false /*topLevel*/, false /*allowEmptyExpression*/, true /*isObjectPattern*/);
  4066. }
  4067. if (buildAST)
  4068. {
  4069. this->CheckArguments(pnodeEllipsis);
  4070. }
  4071. }
  4072. else if (nullptr != pidHint) //It's either tkID/tkStrCon/tkFloatCon/tkIntCon
  4073. {
  4074. Assert(pidHint->Psz() != nullptr);
  4075. if ((pidHint == wellKnownPropertyPids.get || pidHint == wellKnownPropertyPids.set) &&
  4076. // get/set are only pseudo keywords when they are identifiers (i.e. not strings)
  4077. tkHint.tk == tkID && NextTokenIsPropertyNameStart())
  4078. {
  4079. if (isObjectPattern)
  4080. {
  4081. Error(ERRInvalidAssignmentTarget);
  4082. }
  4083. LPCOLESTR pNameGetOrSet = nullptr;
  4084. OpCode op = pidHint == wellKnownPropertyPids.get ? knopGetMember : knopSetMember;
  4085. pnodeArg = ParseMemberGetSet<buildAST>(op, &pNameGetOrSet, iecpMin, ichMin);
  4086. if (CONFIG_FLAG(UseFullName) && buildAST && pnodeArg->pnode2->nop == knopFncDecl)
  4087. {
  4088. // displays as "get object.funcname" or "set object.funcname"
  4089. uint32 getOrSetOffset = 0;
  4090. LPCOLESTR intermediateHint = AppendNameHints(pNameHint, pNameGetOrSet, &fullNameHintLength, &shortNameOffset);
  4091. pFullNameHint = AppendNameHints(pidHint, intermediateHint, &fullNameHintLength, &getOrSetOffset, true);
  4092. shortNameOffset += getOrSetOffset;
  4093. }
  4094. }
  4095. else if ((m_token.tk == tkRCurly || m_token.tk == tkComma || m_token.tk == tkAsg) && m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
  4096. {
  4097. // Shorthand {foo} -> {foo:foo} syntax.
  4098. // {foo = <initializer>} supported only when on object pattern rules are being applied
  4099. if (tkHint.tk != tkID)
  4100. {
  4101. Assert(tkHint.IsReservedWord()
  4102. || tkHint.tk == tkIntCon || tkHint.tk == tkFltCon || tkHint.tk == tkStrCon);
  4103. // All keywords are banned in non-strict mode.
  4104. // Future reserved words are banned in strict mode.
  4105. if (IsStrictMode() || !tkHint.IsFutureReservedWord(true))
  4106. {
  4107. IdentifierExpectedError(tkHint);
  4108. }
  4109. }
  4110. if (buildAST)
  4111. {
  4112. CheckArgumentsUse(pidHint, GetCurrentFunctionNode());
  4113. }
  4114. bool couldBeObjectPattern = !isObjectPattern && m_token.tk == tkAsg;
  4115. // Saving the current state as we may change the isObjectPattern down below.
  4116. bool oldState = isObjectPattern;
  4117. if (couldBeObjectPattern)
  4118. {
  4119. declarationType = tkLCurly;
  4120. isObjectPattern = true;
  4121. // This may be an error but we are deferring for favouring destructuring.
  4122. hasDeferredInitError = true;
  4123. }
  4124. ParseNodePtr pnodeIdent = nullptr;
  4125. if (isObjectPattern)
  4126. {
  4127. this->GetScanner()->SeekTo(atPid);
  4128. pnodeIdent = ParseDestructuredVarDecl<buildAST>(declarationType, declarationType != tkLCurly, &seenRest/* *hasSeenRest*/, false /*topLevel*/, false /*allowEmptyExpression*/, true /*isObjectPattern*/);
  4129. if (m_token.tk != tkComma && m_token.tk != tkRCurly)
  4130. {
  4131. if (m_token.IsOperator())
  4132. {
  4133. Error(ERRDestructNoOper);
  4134. }
  4135. Error(ERRsyntax);
  4136. }
  4137. }
  4138. else
  4139. {
  4140. // Add a reference to the hinted name so we can bind it properly.
  4141. PidRefStack *ref = PushPidRef(pidHint);
  4142. if (buildAST)
  4143. {
  4144. pnodeIdent = CreateNameNode(pidHint, ref, idHintIchMin, idHintIchLim);
  4145. }
  4146. }
  4147. if (buildAST)
  4148. {
  4149. pnodeArg = CreateBinNode(isObjectPattern && !couldBeObjectPattern ? knopObjectPatternMember : knopMemberShort, pnodeName, pnodeIdent);
  4150. }
  4151. isObjectPattern = oldState;
  4152. }
  4153. else
  4154. {
  4155. Error(ERRnoColon);
  4156. }
  4157. }
  4158. else
  4159. {
  4160. Error(ERRnoColon);
  4161. }
  4162. if (buildAST)
  4163. {
  4164. if (seenEllipsis)
  4165. {
  4166. Assert(pnodeEllipsis != nullptr);
  4167. AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeEllipsis);
  4168. }
  4169. else
  4170. {
  4171. Assert(pnodeArg->pnode2 != nullptr);
  4172. if (pnodeArg->pnode2->nop == knopFncDecl)
  4173. {
  4174. Assert(fullNameHintLength >= shortNameOffset);
  4175. ParseNodeFnc * pnodeFunc = pnodeArg->pnode2->AsParseNodeFnc();
  4176. pnodeFunc->hint = pFullNameHint;
  4177. pnodeFunc->hintLength = fullNameHintLength;
  4178. pnodeFunc->hintOffset = shortNameOffset;
  4179. }
  4180. AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeArg);
  4181. }
  4182. }
  4183. pidHint = nullptr;
  4184. pFullNameHint = nullptr;
  4185. if (tkComma != m_token.tk)
  4186. {
  4187. break;
  4188. }
  4189. this->GetScanner()->ScanForcingPid();
  4190. if (tkRCurly == m_token.tk)
  4191. {
  4192. break;
  4193. }
  4194. if (seenRest) // Rest must be in the last position.
  4195. {
  4196. Error(ERRDestructRestLast);
  4197. }
  4198. }
  4199. m_hasDeferredShorthandInitError = m_hasDeferredShorthandInitError || hasDeferredInitError;
  4200. if (buildAST)
  4201. {
  4202. Assert(lastNodeRef);
  4203. Assert(*lastNodeRef);
  4204. pnodeList->ichLim = (*lastNodeRef)->ichLim;
  4205. }
  4206. return pnodeList;
  4207. }
  4208. BOOL Parser::WillDeferParse(Js::LocalFunctionId functionId)
  4209. {
  4210. if ((m_grfscr & fscrWillDeferFncParse) != 0)
  4211. {
  4212. if (m_stoppedDeferredParse)
  4213. {
  4214. return false;
  4215. }
  4216. if (!PHASE_ENABLED_RAW(DeferParsePhase, m_sourceContextInfo->sourceContextId, functionId))
  4217. {
  4218. return false;
  4219. }
  4220. if (PHASE_FORCE_RAW(Js::DeferParsePhase, m_sourceContextInfo->sourceContextId, functionId)
  4221. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  4222. || Js::Configuration::Global.flags.IsEnabled(Js::ForceUndoDeferFlag)
  4223. #endif
  4224. )
  4225. {
  4226. return true;
  4227. }
  4228. #if ENABLE_PROFILE_INFO
  4229. #ifndef DISABLE_DYNAMIC_PROFILE_DEFER_PARSE
  4230. if (m_sourceContextInfo->sourceDynamicProfileManager != nullptr)
  4231. {
  4232. Js::ExecutionFlags flags = m_sourceContextInfo->sourceDynamicProfileManager->IsFunctionExecuted(functionId);
  4233. return flags != Js::ExecutionFlags_Executed;
  4234. }
  4235. #endif
  4236. #endif
  4237. return true;
  4238. }
  4239. return false;
  4240. }
  4241. //
  4242. // Call this in ParseFncDecl only to check (and reset) if ParseFncDecl is re-parsing a deferred
  4243. // function body. If a deferred function is called and being re-parsed, it shouldn't be deferred again.
  4244. //
  4245. BOOL Parser::IsDeferredFnc()
  4246. {
  4247. if (m_grfscr & fscrDeferredFnc)
  4248. {
  4249. m_grfscr &= ~fscrDeferredFnc;
  4250. return true;
  4251. }
  4252. return false;
  4253. }
  4254. template<bool buildAST>
  4255. ParseNode * Parser::ParseFncDeclCheckScope(ushort flags, bool fAllowIn)
  4256. {
  4257. ParseNodeBlock * pnodeFncBlockScope = nullptr;
  4258. ParseNodePtr *ppnodeScopeSave = nullptr;
  4259. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  4260. bool fDeclaration = flags & fFncDeclaration;
  4261. bool noStmtContext = false;
  4262. if (fDeclaration)
  4263. {
  4264. noStmtContext = m_pstmtCur->GetNop() != knopBlock;
  4265. if (noStmtContext)
  4266. {
  4267. // We have a function declaration like "if (a) function f() {}". We didn't see
  4268. // a block scope on the way in, so we need to pretend we did. Note that this is a syntax error
  4269. // in strict mode.
  4270. if (!this->FncDeclAllowedWithoutContext(flags))
  4271. {
  4272. Error(ERRsyntax);
  4273. }
  4274. pnodeFncBlockScope = StartParseBlock<buildAST>(PnodeBlockType::Regular, ScopeType_Block);
  4275. if (buildAST)
  4276. {
  4277. PushFuncBlockScope(pnodeFncBlockScope, &ppnodeScopeSave, &ppnodeExprScopeSave);
  4278. }
  4279. }
  4280. }
  4281. ParseNodeFnc * pnodeFnc = ParseFncDeclInternal<buildAST>(flags, nullptr, /* needsPIDOnRCurlyScan */ false, /* fUnaryOrParen */ false, noStmtContext, SuperRestrictionState::Disallowed, fAllowIn);
  4282. if (pnodeFncBlockScope)
  4283. {
  4284. Assert(pnodeFncBlockScope->pnodeStmt == nullptr);
  4285. pnodeFncBlockScope->pnodeStmt = pnodeFnc;
  4286. if (buildAST)
  4287. {
  4288. PopFuncBlockScope(ppnodeScopeSave, ppnodeExprScopeSave);
  4289. }
  4290. FinishParseBlock(pnodeFncBlockScope);
  4291. return pnodeFncBlockScope;
  4292. }
  4293. return pnodeFnc;
  4294. }
  4295. template<bool buildAST>
  4296. ParseNodeFnc * Parser::ParseFncDeclNoCheckScope(ushort flags, SuperRestrictionState::State superRestrictionState, LPCOLESTR pNameHint, const bool needsPIDOnRCurlyScan, bool fUnaryOrParen, bool fAllowIn)
  4297. {
  4298. Assert((flags & fFncDeclaration) == 0);
  4299. return ParseFncDeclInternal<buildAST>(flags, pNameHint, needsPIDOnRCurlyScan, fUnaryOrParen, /* noStmtContext */ false, superRestrictionState, fAllowIn);
  4300. }
  4301. template<bool buildAST>
  4302. ParseNodeFnc * Parser::ParseFncDeclInternal(ushort flags, LPCOLESTR pNameHint, const bool needsPIDOnRCurlyScan, bool fUnaryOrParen, bool noStmtContext, SuperRestrictionState::State superRestrictionState, bool fAllowIn)
  4303. {
  4304. ParseNodeFnc * pnodeFnc = nullptr;
  4305. ParseNodePtr *ppnodeVarSave = nullptr;
  4306. bool fDeclaration = flags & fFncDeclaration;
  4307. bool fModule = (flags & fFncModule) != 0;
  4308. bool fLambda = (flags & fFncLambda) != 0;
  4309. charcount_t ichMin = this->GetScanner()->IchMinTok();
  4310. bool wasInDeferredNestedFunc = false;
  4311. uint tryCatchOrFinallyDepthSave = this->m_tryCatchOrFinallyDepth;
  4312. this->m_tryCatchOrFinallyDepth = 0;
  4313. if (this->m_arrayDepth)
  4314. {
  4315. this->m_funcInArrayDepth++; // Count function depth within array literal
  4316. }
  4317. // Update the count of functions nested in the current parent.
  4318. Assert(m_pnestedCount || !buildAST);
  4319. uint *pnestedCountSave = m_pnestedCount;
  4320. if (buildAST || m_pnestedCount)
  4321. {
  4322. (*m_pnestedCount)++;
  4323. }
  4324. uint scopeCountNoAstSave = m_scopeCountNoAst;
  4325. m_scopeCountNoAst = 0;
  4326. // Create the node.
  4327. pnodeFnc = CreateAllowDeferNodeForOpT<knopFncDecl>();
  4328. pnodeFnc->SetDeclaration(fDeclaration);
  4329. pnodeFnc->nestedFuncEscapes = false;
  4330. pnodeFnc->cbMin = this->GetScanner()->IecpMinTok();
  4331. pnodeFnc->cbStringMin = pnodeFnc->cbMin;
  4332. pnodeFnc->functionId = (*m_nextFunctionId)++;
  4333. pnodeFnc->superRestrictionState = superRestrictionState;
  4334. // Push new parser state with this new function node
  4335. AppendFunctionToScopeList(fDeclaration, pnodeFnc);
  4336. // Start the argument list.
  4337. ppnodeVarSave = m_ppnodeVar;
  4338. if (buildAST)
  4339. {
  4340. pnodeFnc->lineNumber = this->GetScanner()->LineCur();
  4341. pnodeFnc->columnNumber = CalculateFunctionColumnNumber();
  4342. pnodeFnc->SetNested(m_currentNodeFunc != nullptr); // If there is a current function, then we're a nested function.
  4343. pnodeFnc->SetStrictMode(IsStrictMode()); // Inherit current strict mode -- may be overridden by the function itself if it contains a strict mode directive.
  4344. m_pCurrentAstSize = &pnodeFnc->astSize;
  4345. }
  4346. else // if !buildAST
  4347. {
  4348. wasInDeferredNestedFunc = m_inDeferredNestedFunc;
  4349. m_inDeferredNestedFunc = true;
  4350. }
  4351. m_pnestedCount = &pnodeFnc->nestedCount;
  4352. AnalysisAssert(pnodeFnc);
  4353. pnodeFnc->SetIsAsync((flags & fFncAsync) != 0);
  4354. pnodeFnc->SetIsLambda(fLambda);
  4355. pnodeFnc->SetIsMethod((flags & fFncMethod) != 0);
  4356. pnodeFnc->SetIsClassMember((flags & fFncClassMember) != 0);
  4357. pnodeFnc->SetIsModule(fModule);
  4358. pnodeFnc->SetIsClassConstructor((flags & fFncClassConstructor) != 0);
  4359. pnodeFnc->SetIsBaseClassConstructor((flags & fFncBaseClassConstructor) != 0);
  4360. pnodeFnc->SetHomeObjLocation(Js::Constants::NoRegister);
  4361. IdentPtr pFncNamePid = nullptr;
  4362. bool needScanRCurly = true;
  4363. ParseFncDeclHelper<buildAST>(pnodeFnc, pNameHint, flags, fUnaryOrParen, noStmtContext, &needScanRCurly, fModule, &pFncNamePid, fAllowIn);
  4364. AddNestedCapturedNames(pnodeFnc);
  4365. AnalysisAssert(pnodeFnc);
  4366. *m_ppnodeVar = nullptr;
  4367. m_ppnodeVar = ppnodeVarSave;
  4368. if (m_currentNodeFunc && (pnodeFnc->CallsEval() || pnodeFnc->ChildCallsEval()))
  4369. {
  4370. GetCurrentFunctionNode()->SetChildCallsEval(true);
  4371. }
  4372. // Lambdas do not have "arguments" and instead capture their parent's
  4373. // binding of "arguments. To ensure the arguments object of the enclosing
  4374. // non-lambda function is loaded propagate the UsesArguments flag up to
  4375. // the parent function
  4376. if (fLambda && (pnodeFnc->UsesArguments() || pnodeFnc->CallsEval()))
  4377. {
  4378. ParseNodeFnc * pnodeFncParent = GetCurrentFunctionNode();
  4379. if (pnodeFncParent != nullptr)
  4380. {
  4381. pnodeFncParent->SetUsesArguments();
  4382. }
  4383. else
  4384. {
  4385. m_UsesArgumentsAtGlobal = true;
  4386. }
  4387. }
  4388. if (needScanRCurly && !fModule)
  4389. {
  4390. // Consume the next token now that we're back in the enclosing function (whose strictness may be
  4391. // different from the function we just finished).
  4392. #if DBG
  4393. bool expectedTokenValid = m_token.tk == tkRCurly;
  4394. AssertMsg(expectedTokenValid, "Invalid token expected for RCurly match");
  4395. #endif
  4396. // The next token may need to have a PID created in !buildAST mode, as we may be parsing a method with a string name.
  4397. if (needsPIDOnRCurlyScan)
  4398. {
  4399. this->GetScanner()->ScanForcingPid();
  4400. }
  4401. else
  4402. {
  4403. this->GetScanner()->Scan();
  4404. }
  4405. }
  4406. m_pnestedCount = pnestedCountSave;
  4407. Assert(!buildAST || !wasInDeferredNestedFunc);
  4408. m_inDeferredNestedFunc = wasInDeferredNestedFunc;
  4409. if (this->m_arrayDepth)
  4410. {
  4411. this->m_funcInArrayDepth--;
  4412. if (this->m_funcInArrayDepth == 0)
  4413. {
  4414. // We disable deferred parsing if array literals dominate.
  4415. // But don't do this if the array literal is dominated by function bodies.
  4416. if (flags & (fFncMethod | fFncClassMember) && m_token.tk != tkSColon)
  4417. {
  4418. // Class member methods have optional separators. We need to check whether we are
  4419. // getting the IchLim of the correct token.
  4420. Assert(this->GetScanner()->m_tkPrevious == tkRCurly && needScanRCurly);
  4421. this->m_funcInArray += this->GetScanner()->IchMinTok() - /*tkRCurly*/ 1 - ichMin;
  4422. }
  4423. else
  4424. {
  4425. this->m_funcInArray += this->GetScanner()->IchLimTok() - ichMin;
  4426. }
  4427. }
  4428. }
  4429. m_scopeCountNoAst = scopeCountNoAstSave;
  4430. if (fDeclaration && !IsStrictMode())
  4431. {
  4432. if (pFncNamePid != nullptr &&
  4433. GetCurrentBlock() &&
  4434. GetCurrentBlock()->blockType == PnodeBlockType::Regular)
  4435. {
  4436. // Add a function-scoped VarDecl with the same name as the function for
  4437. // back compat with pre-ES6 code that declares functions in blocks. The
  4438. // idea is that the last executed declaration wins at the function scope
  4439. // level and we accomplish this by having each block scoped function
  4440. // declaration assign to both the block scoped "let" binding, as well
  4441. // as the function scoped "var" binding.
  4442. ParseNodeVar * vardecl = CreateVarDeclNode(pFncNamePid, STVariable, false, nullptr, false);
  4443. vardecl->isBlockScopeFncDeclVar = true;
  4444. if (GetCurrentFunctionNode() && vardecl->sym->GetIsFormal())
  4445. {
  4446. GetCurrentFunctionNode()->SetHasAnyWriteToFormals(true);
  4447. }
  4448. }
  4449. }
  4450. if (buildAST && fDeclaration)
  4451. {
  4452. Symbol* funcSym = pnodeFnc->GetFuncSymbol();
  4453. if (funcSym->GetIsFormal())
  4454. {
  4455. GetCurrentFunctionNode()->SetHasAnyWriteToFormals(true);
  4456. }
  4457. } this->m_tryCatchOrFinallyDepth = tryCatchOrFinallyDepthSave;
  4458. return pnodeFnc;
  4459. }
  4460. bool Parser::FncDeclAllowedWithoutContext(ushort flags)
  4461. {
  4462. // Statement context required for strict mode, async functions, and generators.
  4463. // Note that generators aren't detected yet when this method is called; they're checked elsewhere.
  4464. return !IsStrictMode() && !(flags & fFncAsync);
  4465. }
  4466. uint Parser::CalculateFunctionColumnNumber()
  4467. {
  4468. uint columnNumber;
  4469. charcount_t ichMinTok = this->GetScanner()->IchMinTok();
  4470. charcount_t ichMinLine = this->GetScanner()->IchMinLine();
  4471. if (ichMinTok >= ichMinLine)
  4472. {
  4473. // In scenarios involving defer parse IchMinLine() can be incorrect for the first line after defer parse
  4474. columnNumber = ichMinTok - ichMinLine;
  4475. if (m_functionBody != nullptr && m_functionBody->GetRelativeLineNumber() == this->GetScanner()->LineCur())
  4476. {
  4477. // Adjust the column if it falls on the first line, where the re-parse is happening.
  4478. columnNumber += m_functionBody->GetRelativeColumnNumber();
  4479. }
  4480. }
  4481. else if (m_currentNodeFunc)
  4482. {
  4483. // For the first line after defer parse, compute the column relative to the column number
  4484. // of the lexically parent function.
  4485. ULONG offsetFromCurrentFunction = ichMinTok - m_currentNodeFunc->ichMin;
  4486. columnNumber = m_currentNodeFunc->columnNumber + offsetFromCurrentFunction;
  4487. }
  4488. else
  4489. {
  4490. // if there is no current function, lets give a default of 0.
  4491. columnNumber = 0;
  4492. }
  4493. return columnNumber;
  4494. }
  4495. void Parser::AppendFunctionToScopeList(bool fDeclaration, ParseNodeFnc * pnodeFnc)
  4496. {
  4497. if (!fDeclaration && m_ppnodeExprScope)
  4498. {
  4499. // We're tracking function expressions separately from declarations in this scope
  4500. // (e.g., inside a catch scope in standards mode).
  4501. Assert(*m_ppnodeExprScope == nullptr);
  4502. *m_ppnodeExprScope = pnodeFnc;
  4503. m_ppnodeExprScope = &pnodeFnc->pnodeNext;
  4504. }
  4505. else
  4506. {
  4507. Assert(*m_ppnodeScope == nullptr);
  4508. *m_ppnodeScope = pnodeFnc;
  4509. m_ppnodeScope = &pnodeFnc->pnodeNext;
  4510. }
  4511. }
  4512. /***************************************************************************
  4513. Parse a function definition.
  4514. ***************************************************************************/
  4515. template<bool buildAST>
  4516. void Parser::ParseFncDeclHelper(ParseNodeFnc * pnodeFnc, LPCOLESTR pNameHint, ushort flags, bool fUnaryOrParen, bool noStmtContext, bool *pNeedScanRCurly, bool skipFormals, IdentPtr* pFncNamePid, bool fAllowIn)
  4517. {
  4518. Assert(pnodeFnc);
  4519. ParseNodeFnc * pnodeFncParent = GetCurrentFunctionNode();
  4520. // is the following correct? When buildAST is false, m_currentNodeDeferredFunc can be nullptr on transition to deferred parse from non-deferred
  4521. ParseNodeFnc * pnodeFncSave = buildAST ? m_currentNodeFunc : m_currentNodeDeferredFunc;
  4522. ParseNodeFnc * pnodeFncSaveNonLambda = buildAST ? m_currentNodeNonLambdaFunc : m_currentNodeNonLambdaDeferredFunc;
  4523. int32* pAstSizeSave = m_pCurrentAstSize;
  4524. bool fDeclaration = (flags & fFncDeclaration) != 0;
  4525. bool fLambda = (flags & fFncLambda) != 0;
  4526. bool fAsync = (flags & fFncAsync) != 0;
  4527. bool fModule = (flags & fFncModule) != 0;
  4528. bool fDeferred = false;
  4529. StmtNest *pstmtSave;
  4530. bool fFunctionInBlock = false;
  4531. if (buildAST)
  4532. {
  4533. fFunctionInBlock = GetCurrentBlockInfo() != GetCurrentFunctionBlockInfo() &&
  4534. (GetCurrentBlockInfo()->pnodeBlock->scope == nullptr ||
  4535. GetCurrentBlockInfo()->pnodeBlock->scope->GetScopeType() != ScopeType_GlobalEvalBlock);
  4536. }
  4537. // Save the position of the scanner in case we need to inspect the name hint later
  4538. RestorePoint beginNameHint;
  4539. this->GetScanner()->Capture(&beginNameHint);
  4540. ParseNodeBlock * pnodeFncExprScope = nullptr;
  4541. Scope *fncExprScope = nullptr;
  4542. if (!fDeclaration)
  4543. {
  4544. if (!fLambda)
  4545. {
  4546. pnodeFncExprScope = StartParseBlock<buildAST>(PnodeBlockType::Function, ScopeType_FuncExpr);
  4547. fncExprScope = pnodeFncExprScope->scope;
  4548. }
  4549. // Function expression: push the new function onto the stack now so that the name (if any) will be
  4550. // local to the new function.
  4551. this->UpdateCurrentNodeFunc<buildAST>(pnodeFnc, fLambda);
  4552. }
  4553. if (!fLambda && !fModule)
  4554. {
  4555. this->ParseFncName<buildAST>(pnodeFnc, flags, pFncNamePid);
  4556. }
  4557. if (fDeclaration)
  4558. {
  4559. // Declaration statement: push the new function now, after parsing the name, so the name is local to the
  4560. // enclosing function.
  4561. this->UpdateCurrentNodeFunc<buildAST>(pnodeFnc, fLambda);
  4562. }
  4563. if (noStmtContext && pnodeFnc->IsGenerator())
  4564. {
  4565. // Generator decl not allowed outside stmt context. (We have to wait until we've parsed the '*' to
  4566. // detect generator.)
  4567. Error(ERRsyntax, pnodeFnc);
  4568. }
  4569. // switch scanner to treat 'yield' as keyword in generator functions
  4570. // or as an identifier in non-generator functions
  4571. bool fPreviousYieldIsKeyword = this->GetScanner()->SetYieldIsKeywordRegion(pnodeFnc->IsGenerator());
  4572. bool fPreviousAwaitIsKeyword = this->GetScanner()->SetAwaitIsKeywordRegion(fAsync);
  4573. if (pnodeFnc->IsGenerator())
  4574. {
  4575. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, Generator, m_scriptContext);
  4576. }
  4577. if (fncExprScope && pnodeFnc->pnodeName == nullptr)
  4578. {
  4579. FinishParseBlock(pnodeFncExprScope);
  4580. m_nextBlockId--;
  4581. Adelete(&m_nodeAllocator, fncExprScope);
  4582. fncExprScope = nullptr;
  4583. pnodeFncExprScope = nullptr;
  4584. }
  4585. pnodeFnc->scope = fncExprScope;
  4586. // Start a new statement stack.
  4587. bool topLevelStmt =
  4588. buildAST &&
  4589. !fFunctionInBlock &&
  4590. (this->m_pstmtCur == nullptr || this->m_pstmtCur->pnodeStmt->nop == knopBlock);
  4591. pstmtSave = m_pstmtCur;
  4592. SetCurrentStatement(nullptr);
  4593. RestorePoint beginFormals;
  4594. this->GetScanner()->Capture(&beginFormals);
  4595. BOOL fWasAlreadyStrictMode = IsStrictMode();
  4596. BOOL oldStrictMode = this->m_fUseStrictMode;
  4597. if (fLambda)
  4598. {
  4599. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, Lambda, m_scriptContext);
  4600. }
  4601. uint uCanDeferSave = m_grfscr & fscrCanDeferFncParse;
  4602. uint uDeferSave = m_grfscr & fscrWillDeferFncParse;
  4603. if (flags & fFncClassMember)
  4604. {
  4605. // Disable deferral on class members or other construct with unusual text bounds
  4606. // as these are usually trivial, and re-parsing is problematic.
  4607. // NOTE: It is probably worth supporting these cases for memory and load-time purposes,
  4608. // especially as they become more and more common.
  4609. m_grfscr &= ~(fscrCanDeferFncParse | fscrWillDeferFncParse);
  4610. }
  4611. bool isTopLevelDeferredFunc = false;
  4612. #if ENABLE_BACKGROUND_PARSING
  4613. struct AutoFastScanFlag {
  4614. bool savedDoingFastScan;
  4615. AutoFastScanFlag(Parser *parser) : m_parser(parser) { savedDoingFastScan = m_parser->m_doingFastScan; }
  4616. ~AutoFastScanFlag() { m_parser->m_doingFastScan = savedDoingFastScan; }
  4617. Parser *m_parser;
  4618. } flag(this);
  4619. #endif
  4620. bool doParallel = false;
  4621. #if ENABLE_BACKGROUND_PARSING
  4622. bool parallelJobStarted = false;
  4623. #endif
  4624. if (buildAST)
  4625. {
  4626. bool isLikelyIIFE = !fDeclaration && fUnaryOrParen;
  4627. BOOL isDeferredFnc = IsDeferredFnc();
  4628. // These are the conditions that prohibit upfront deferral *and* redeferral.
  4629. isTopLevelDeferredFunc =
  4630. (m_grfscr & fscrCanDeferFncParse)
  4631. && !m_InAsmMode
  4632. // Don't defer a module function wrapper because we need to do export resolution at parse time
  4633. && !fModule;
  4634. pnodeFnc->SetCanBeDeferred(isTopLevelDeferredFunc && ParseNodeFnc::CanBeRedeferred(pnodeFnc->fncFlags));
  4635. // These are heuristic conditions that prohibit upfront deferral but not redeferral.
  4636. isTopLevelDeferredFunc = isTopLevelDeferredFunc && !isDeferredFnc && WillDeferParse(pnodeFnc->functionId) &&
  4637. (!isLikelyIIFE || !topLevelStmt || PHASE_FORCE_RAW(Js::DeferParsePhase, m_sourceContextInfo->sourceContextId, pnodeFnc->functionId));
  4638. #if ENABLE_BACKGROUND_PARSING
  4639. if (!fLambda &&
  4640. !isDeferredFnc &&
  4641. !isLikelyIIFE &&
  4642. !this->IsBackgroundParser() &&
  4643. !this->m_doingFastScan &&
  4644. !(pnodeFncSave && m_currDeferredStub) &&
  4645. !(this->m_parseType == ParseType_Deferred && this->m_functionBody && this->m_functionBody->GetScopeInfo() && !isTopLevelDeferredFunc))
  4646. {
  4647. doParallel = DoParallelParse(pnodeFnc);
  4648. if (doParallel)
  4649. {
  4650. BackgroundParser *bgp = m_scriptContext->GetBackgroundParser();
  4651. Assert(bgp);
  4652. if (bgp->HasFailedBackgroundParseItem())
  4653. {
  4654. Error(ERRsyntax);
  4655. }
  4656. doParallel = bgp->ParseBackgroundItem(this, pnodeFnc, isTopLevelDeferredFunc);
  4657. if (doParallel)
  4658. {
  4659. parallelJobStarted = true;
  4660. this->m_hasParallelJob = true;
  4661. this->m_doingFastScan = true;
  4662. doParallel = FastScanFormalsAndBody();
  4663. if (doParallel)
  4664. {
  4665. // Let the foreground thread take care of marking the limit on the function node,
  4666. // because in some cases this function's caller will want to change that limit,
  4667. // so we don't want the background thread to try and touch it.
  4668. pnodeFnc->ichLim = this->GetScanner()->IchLimTok();
  4669. pnodeFnc->cbLim = this->GetScanner()->IecpLimTok();
  4670. }
  4671. }
  4672. }
  4673. }
  4674. #endif
  4675. }
  4676. if (!doParallel)
  4677. {
  4678. #if ENABLE_BACKGROUND_PARSING
  4679. // We don't want to, or couldn't, let the main thread scan past this function body, so parse
  4680. // it for real.
  4681. ParseNodeFnc * pnodeRealFnc = pnodeFnc;
  4682. if (parallelJobStarted)
  4683. {
  4684. // We have to deal with a failure to fast-scan the function (due to syntax error? "/"?) when
  4685. // a background thread may already have begun to work on the job. Both threads can't be allowed to
  4686. // operate on the same node.
  4687. pnodeFnc = CreateDummyFuncNode(fDeclaration);
  4688. }
  4689. #endif
  4690. AnalysisAssert(pnodeFnc);
  4691. ParseNodeBlock * pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Parameter, ScopeType_Parameter);
  4692. AnalysisAssert(pnodeBlock != nullptr);
  4693. pnodeFnc->pnodeScopes = pnodeBlock;
  4694. m_ppnodeVar = &pnodeFnc->pnodeParams;
  4695. pnodeFnc->pnodeVars = nullptr;
  4696. ParseNodePtr* varNodesList = &pnodeFnc->pnodeVars;
  4697. ParseNodeVar * argNode = nullptr;
  4698. if (!fModule && !fLambda)
  4699. {
  4700. ParseNodePtr *const ppnodeVarSave = m_ppnodeVar;
  4701. m_ppnodeVar = &pnodeFnc->pnodeVars;
  4702. // Create the built-in arguments symbol
  4703. argNode = this->AddArgumentsNodeToVars(pnodeFnc);
  4704. // Save the updated var list
  4705. varNodesList = m_ppnodeVar;
  4706. m_ppnodeVar = ppnodeVarSave;
  4707. }
  4708. ParseNodePtr *ppnodeScopeSave = nullptr;
  4709. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  4710. ppnodeScopeSave = m_ppnodeScope;
  4711. if (pnodeBlock)
  4712. {
  4713. // This synthetic block scope will contain all the nested scopes.
  4714. m_ppnodeScope = &pnodeBlock->pnodeScopes;
  4715. pnodeBlock->pnodeStmt = pnodeFnc;
  4716. }
  4717. // Keep nested function declarations and expressions in the same list at function scope.
  4718. // (Indicate this by nulling out the current function expressions list.)
  4719. ppnodeExprScopeSave = m_ppnodeExprScope;
  4720. m_ppnodeExprScope = nullptr;
  4721. uint parenExprDepthSave = m_funcParenExprDepth;
  4722. m_funcParenExprDepth = 0;
  4723. if (!skipFormals)
  4724. {
  4725. bool fLambdaParamsSave = m_reparsingLambdaParams;
  4726. if (fLambda)
  4727. {
  4728. m_reparsingLambdaParams = true;
  4729. }
  4730. uint savedStubCount = m_currDeferredStubCount;
  4731. DeferredFunctionStub* savedStub = m_currDeferredStub;
  4732. ShiftCurrDeferredStubToChildFunction(pnodeFnc, pnodeFncParent);
  4733. this->ParseFncFormals<buildAST>(pnodeFnc, pnodeFncParent, flags, isTopLevelDeferredFunc);
  4734. m_currDeferredStub = savedStub;
  4735. m_currDeferredStubCount = savedStubCount;
  4736. m_reparsingLambdaParams = fLambdaParamsSave;
  4737. }
  4738. // Create function body scope
  4739. ParseNodeBlock * pnodeInnerBlock = StartParseBlock<buildAST>(PnodeBlockType::Function, ScopeType_FunctionBody);
  4740. // Set the parameter block's child to the function body block.
  4741. // The pnodeFnc->pnodeScopes list is constructed in such a way that it includes all the scopes in this list.
  4742. // For example if the param scope has one function and body scope has one function then the list will look like below,
  4743. // param scope block -> function decl from param scope -> body socpe block -> function decl from body scope.
  4744. *m_ppnodeScope = pnodeInnerBlock;
  4745. pnodeFnc->pnodeBodyScope = pnodeInnerBlock;
  4746. // This synthetic block scope will contain all the nested scopes.
  4747. m_ppnodeScope = &pnodeInnerBlock->pnodeScopes;
  4748. pnodeInnerBlock->pnodeStmt = pnodeFnc;
  4749. // DEFER: Begin deferral here (after names are parsed and name nodes created).
  4750. // Create no more AST nodes until we're done.
  4751. // Try to defer this func if all these are true:
  4752. // 0. We are not already in deferred parsing (i.e. buildAST is true)
  4753. // 1. We are not re-parsing a deferred func which is being invoked.
  4754. // 2. Dynamic profile suggests this func can be deferred (and deferred parse is on).
  4755. // 3. This func is top level or defer nested func is on.
  4756. // 4. Optionally, the function is non-nested and not in eval, or the deferral decision was based on cached profile info,
  4757. // or the function is sufficiently long. (I.e., don't defer little nested functions unless we're
  4758. // confident they'll never be executed, because un-deferring nested functions is more expensive.)
  4759. // NOTE: I'm disabling #4 by default, because we've found other ways to reduce the cost of un-deferral,
  4760. // and we don't want to create function bodies aggressively for little functions.
  4761. // We will also temporarily defer all asm.js functions, except for the asm.js
  4762. // module itself, which we will never defer
  4763. bool strictModeTurnedOn = false;
  4764. if (isTopLevelDeferredFunc &&
  4765. !(this->m_grfscr & fscrEvalCode) &&
  4766. pnodeFnc->IsNested() &&
  4767. #ifndef DISABLE_DYNAMIC_PROFILE_DEFER_PARSE
  4768. m_sourceContextInfo->sourceDynamicProfileManager == nullptr &&
  4769. #endif
  4770. PHASE_ON_RAW(Js::ScanAheadPhase, m_sourceContextInfo->sourceContextId, pnodeFnc->functionId) &&
  4771. (
  4772. !PHASE_FORCE_RAW(Js::DeferParsePhase, m_sourceContextInfo->sourceContextId, pnodeFnc->functionId) ||
  4773. PHASE_FORCE_RAW(Js::ScanAheadPhase, m_sourceContextInfo->sourceContextId, pnodeFnc->functionId)
  4774. ))
  4775. {
  4776. // Try to scan ahead to the end of the function. If we get there before we've scanned a minimum
  4777. // number of tokens, don't bother deferring, because it's too small.
  4778. if (this->ScanAheadToFunctionEnd(CONFIG_FLAG(MinDeferredFuncTokenCount)))
  4779. {
  4780. isTopLevelDeferredFunc = false;
  4781. }
  4782. }
  4783. Scope* paramScope = pnodeFnc->pnodeScopes ? pnodeFnc->pnodeScopes->scope : nullptr;
  4784. if (paramScope != nullptr)
  4785. {
  4786. if (CONFIG_FLAG(ForceSplitScope))
  4787. {
  4788. pnodeFnc->ResetBodyAndParamScopeMerged();
  4789. }
  4790. else if (pnodeFnc->HasNonSimpleParameterList() && pnodeFnc->IsBodyAndParamScopeMerged())
  4791. {
  4792. paramScope->ForEachSymbolUntil([this, paramScope, pnodeFnc](Symbol* sym) {
  4793. if (sym->GetPid()->GetTopRef()->GetFuncScopeId() > pnodeFnc->functionId)
  4794. {
  4795. // One of the symbol has non local reference. Mark the param scope as we can't merge it with body scope.
  4796. pnodeFnc->ResetBodyAndParamScopeMerged();
  4797. return true;
  4798. }
  4799. return false;
  4800. });
  4801. if (pnodeFnc->IsBodyAndParamScopeMerged() && !fDeclaration && pnodeFnc->pnodeName != nullptr)
  4802. {
  4803. Assert(pnodeFnc->pnodeName->nop == knopVarDecl);
  4804. Symbol* funcSym = pnodeFnc->pnodeName->sym;
  4805. if (funcSym->GetPid()->GetTopRef()->GetFuncScopeId() > pnodeFnc->functionId)
  4806. {
  4807. // This is a function expression with name captured in the param scope. In non-eval, non-split cases the function
  4808. // name symbol is added to the body scope to make it accessible in the body. But if there is a function or var
  4809. // declaration with the same name in the body then adding to the body will fail. So in this case we have to add
  4810. // the name symbol to the param scope by splitting it.
  4811. pnodeFnc->ResetBodyAndParamScopeMerged();
  4812. }
  4813. }
  4814. }
  4815. }
  4816. // If the param scope is merged with the body scope we want to use the param scope symbols in the body scope.
  4817. // So add a pid ref for the body using the param scope symbol. Note that in this case the same symbol will occur twice
  4818. // in the same pid ref stack.
  4819. if (paramScope != nullptr && pnodeFnc->IsBodyAndParamScopeMerged())
  4820. {
  4821. paramScope->ForEachSymbol([this](Symbol* paramSym)
  4822. {
  4823. PidRefStack* ref = PushPidRef(paramSym->GetPid());
  4824. ref->SetSym(paramSym);
  4825. });
  4826. }
  4827. AssertMsg(m_funcParenExprDepth == 0, "Paren exprs should have been resolved by the time we finish function formals");
  4828. if (fLambda)
  4829. {
  4830. #ifdef ASMJS_PLAT
  4831. if (m_InAsmMode && (isTopLevelDeferredFunc && m_deferAsmJs))
  4832. {
  4833. // asm.js doesn't support lambda functions
  4834. Js::AsmJSCompiler::OutputError(m_scriptContext, _u("Lambda functions are not supported."));
  4835. Js::AsmJSCompiler::OutputError(m_scriptContext, _u("Asm.js compilation failed."));
  4836. throw Js::AsmJsParseException();
  4837. }
  4838. #endif
  4839. }
  4840. if (m_token.tk == tkRParen)
  4841. {
  4842. this->GetScanner()->Scan();
  4843. }
  4844. if (fLambda)
  4845. {
  4846. BOOL hadNewLine = this->GetScanner()->FHadNewLine();
  4847. // it can be the case we do not have a fat arrow here if there is a valid expression on the left hand side
  4848. // of the fat arrow, but that expression does not parse as a parameter list. E.g.
  4849. // a.x => { }
  4850. // Therefore check for it and error if not found.
  4851. ChkCurTok(tkDArrow, ERRnoDArrow);
  4852. // Newline character between arrow parameters and fat arrow is a syntax error but we want to check for
  4853. // this after verifying there was a => token. Otherwise we would throw the wrong error.
  4854. if (hadNewLine)
  4855. {
  4856. Error(ERRsyntax);
  4857. }
  4858. }
  4859. if (isTopLevelDeferredFunc || (m_InAsmMode && m_deferAsmJs))
  4860. {
  4861. fDeferred = true;
  4862. this->ParseTopLevelDeferredFunc(pnodeFnc, pnodeFncSave, pNameHint, fLambda, pNeedScanRCurly, fAllowIn);
  4863. }
  4864. else
  4865. {
  4866. AnalysisAssert(pnodeFnc);
  4867. // Shouldn't be any temps in the arg list.
  4868. Assert(*m_ppnodeVar == nullptr);
  4869. // Start the var list.
  4870. m_ppnodeVar = varNodesList;
  4871. if (!pnodeFnc->IsBodyAndParamScopeMerged())
  4872. {
  4873. OUTPUT_TRACE_DEBUGONLY(Js::ParsePhase, _u("The param and body scope of the function %s cannot be merged\n"), pnodeFnc->pnodeName ? pnodeFnc->pnodeName->pid->Psz() : _u("Anonymous function"));
  4874. }
  4875. // Keep nested function declarations and expressions in the same list at function scope.
  4876. // (Indicate this by nulling out the current function expressions list.)
  4877. m_ppnodeExprScope = nullptr;
  4878. if (buildAST)
  4879. {
  4880. if (m_token.tk != tkLCurly && fLambda)
  4881. {
  4882. *pNeedScanRCurly = false;
  4883. }
  4884. uint savedStubCount = m_currDeferredStubCount;
  4885. DeferredFunctionStub* savedStub = m_currDeferredStub;
  4886. ShiftCurrDeferredStubToChildFunction(pnodeFnc, pnodeFncSave);
  4887. this->FinishFncDecl(pnodeFnc, pNameHint, fLambda, skipFormals, fAllowIn);
  4888. m_currDeferredStub = savedStub;
  4889. m_currDeferredStubCount = savedStubCount;
  4890. }
  4891. else
  4892. {
  4893. this->ParseNestedDeferredFunc(pnodeFnc, fLambda, pNeedScanRCurly, &strictModeTurnedOn, fAllowIn);
  4894. }
  4895. }
  4896. // Restore the paren count for any outer spread/rest error checking.
  4897. m_funcParenExprDepth = parenExprDepthSave;
  4898. if (pnodeInnerBlock)
  4899. {
  4900. FinishParseBlock(pnodeInnerBlock, *pNeedScanRCurly);
  4901. }
  4902. if (!fModule && (m_token.tk == tkLCurly || !fLambda))
  4903. {
  4904. UpdateArgumentsNode(pnodeFnc, argNode);
  4905. }
  4906. CreateSpecialSymbolDeclarations(pnodeFnc);
  4907. // Restore the lists of scopes that contain function expressions.
  4908. Assert(m_ppnodeExprScope == nullptr || *m_ppnodeExprScope == nullptr);
  4909. m_ppnodeExprScope = ppnodeExprScopeSave;
  4910. Assert(m_ppnodeScope);
  4911. Assert(nullptr == *m_ppnodeScope);
  4912. m_ppnodeScope = ppnodeScopeSave;
  4913. if (pnodeBlock)
  4914. {
  4915. FinishParseBlock(pnodeBlock, *pNeedScanRCurly);
  4916. }
  4917. if (IsStrictMode() || strictModeTurnedOn)
  4918. {
  4919. this->m_fUseStrictMode = TRUE; // Now we know this function is in strict mode
  4920. if (!fWasAlreadyStrictMode)
  4921. {
  4922. // If this function turned on strict mode then we didn't check the formal
  4923. // parameters or function name hint for future reserved word usage. So do that now.
  4924. RestorePoint afterFnc;
  4925. this->GetScanner()->Capture(&afterFnc);
  4926. if (pnodeFnc->pnodeName != nullptr)
  4927. {
  4928. // Rewind to the function name hint and check if the token is a reserved word.
  4929. this->GetScanner()->SeekTo(beginNameHint);
  4930. this->GetScanner()->Scan();
  4931. if (pnodeFnc->IsGenerator())
  4932. {
  4933. Assert(m_token.tk == tkStar);
  4934. Assert(m_scriptContext->GetConfig()->IsES6GeneratorsEnabled());
  4935. Assert(!(flags & fFncClassMember));
  4936. this->GetScanner()->Scan();
  4937. }
  4938. if (m_token.IsReservedWord())
  4939. {
  4940. IdentifierExpectedError(m_token);
  4941. }
  4942. CheckStrictModeEvalArgumentsUsage(m_token.GetIdentifier(this->GetHashTbl()));
  4943. }
  4944. // Fast forward to formal parameter list, check for future reserved words,
  4945. // then restore scanner as it was.
  4946. this->GetScanner()->SeekToForcingPid(beginFormals);
  4947. CheckStrictFormalParameters();
  4948. this->GetScanner()->SeekTo(afterFnc);
  4949. }
  4950. if (buildAST)
  4951. {
  4952. if (pnodeFnc->pnodeName != nullptr)
  4953. {
  4954. Assert(pnodeFnc->pnodeName->nop == knopVarDecl);
  4955. CheckStrictModeEvalArgumentsUsage(pnodeFnc->pnodeName->pid, pnodeFnc->pnodeName);
  4956. }
  4957. }
  4958. this->m_fUseStrictMode = oldStrictMode;
  4959. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, StrictModeFunction, m_scriptContext);
  4960. }
  4961. ProcessCapturedNames(pnodeFnc);
  4962. if (fDeferred)
  4963. {
  4964. AnalysisAssert(pnodeFnc);
  4965. pnodeFnc->pnodeVars = nullptr;
  4966. }
  4967. #if ENABLE_BACKGROUND_PARSING
  4968. if (parallelJobStarted)
  4969. {
  4970. pnodeFnc = pnodeRealFnc;
  4971. m_currentNodeFunc = pnodeRealFnc;
  4972. // Let the foreground thread take care of marking the limit on the function node,
  4973. // because in some cases this function's caller will want to change that limit,
  4974. // so we don't want the background thread to try and touch it.
  4975. pnodeFnc->ichLim = this->GetScanner()->IchLimTok();
  4976. pnodeFnc->cbLim = this->GetScanner()->IecpLimTok();
  4977. }
  4978. #endif
  4979. }
  4980. // after parsing asm.js module, we want to reset asm.js state before continuing
  4981. AnalysisAssert(pnodeFnc);
  4982. if (pnodeFnc->GetAsmjsMode())
  4983. {
  4984. m_InAsmMode = false;
  4985. }
  4986. // Restore the statement stack.
  4987. Assert(nullptr == m_pstmtCur);
  4988. SetCurrentStatement(pstmtSave);
  4989. if (pnodeFncExprScope)
  4990. {
  4991. FinishParseFncExprScope(pnodeFnc, pnodeFncExprScope);
  4992. }
  4993. m_grfscr |= uCanDeferSave;
  4994. if (!m_stoppedDeferredParse)
  4995. {
  4996. m_grfscr |= uDeferSave;
  4997. }
  4998. this->GetScanner()->SetYieldIsKeywordRegion(fPreviousYieldIsKeyword);
  4999. this->GetScanner()->SetAwaitIsKeywordRegion(fPreviousAwaitIsKeyword);
  5000. // Restore the current function.
  5001. if (buildAST)
  5002. {
  5003. Assert(pnodeFnc == m_currentNodeFunc);
  5004. m_currentNodeFunc = pnodeFncSave;
  5005. m_pCurrentAstSize = pAstSizeSave;
  5006. if (!fLambda)
  5007. {
  5008. Assert(pnodeFnc == m_currentNodeNonLambdaFunc);
  5009. m_currentNodeNonLambdaFunc = pnodeFncSaveNonLambda;
  5010. }
  5011. }
  5012. else
  5013. {
  5014. Assert(pnodeFnc == m_currentNodeDeferredFunc);
  5015. if (!fLambda)
  5016. {
  5017. Assert(pnodeFnc == m_currentNodeNonLambdaDeferredFunc);
  5018. m_currentNodeNonLambdaDeferredFunc = pnodeFncSaveNonLambda;
  5019. }
  5020. m_currentNodeDeferredFunc = pnodeFncSave;
  5021. }
  5022. if (m_currentNodeFunc && pnodeFnc->HasWithStmt())
  5023. {
  5024. GetCurrentFunctionNode()->SetHasWithStmt(true);
  5025. }
  5026. }
  5027. template<bool buildAST>
  5028. void Parser::UpdateCurrentNodeFunc(ParseNodeFnc * pnodeFnc, bool fLambda)
  5029. {
  5030. if (buildAST)
  5031. {
  5032. // Make this the current function and start its sub-function list.
  5033. m_currentNodeFunc = pnodeFnc;
  5034. Assert(m_currentNodeDeferredFunc == nullptr);
  5035. if (!fLambda)
  5036. {
  5037. m_currentNodeNonLambdaFunc = pnodeFnc;
  5038. }
  5039. }
  5040. else // if !buildAST
  5041. {
  5042. AnalysisAssert(pnodeFnc);
  5043. if (!fLambda)
  5044. {
  5045. m_currentNodeNonLambdaDeferredFunc = pnodeFnc;
  5046. }
  5047. m_currentNodeDeferredFunc = pnodeFnc;
  5048. }
  5049. }
  5050. void Parser::ParseTopLevelDeferredFunc(ParseNodeFnc * pnodeFnc, ParseNodeFnc * pnodeFncParent, LPCOLESTR pNameHint, bool fLambda, bool *pNeedScanRCurly, bool fAllowIn)
  5051. {
  5052. // Parse a function body that is a transition point from building AST to doing fast syntax check.
  5053. pnodeFnc->pnodeVars = nullptr;
  5054. pnodeFnc->pnodeBody = nullptr;
  5055. this->m_deferringAST = TRUE;
  5056. // Put the scanner into "no hashing" mode.
  5057. BYTE deferFlags = this->GetScanner()->SetDeferredParse(TRUE);
  5058. if (!fLambda)
  5059. {
  5060. ChkCurTok(tkLCurly, ERRnoLcurly);
  5061. }
  5062. else
  5063. {
  5064. // Lambda may consist of a single expression instead of a block
  5065. if (this->GetScanner()->m_ptoken->tk == tkLCurly)
  5066. {
  5067. this->GetScanner()->Scan();
  5068. }
  5069. else
  5070. {
  5071. *pNeedScanRCurly = false;
  5072. }
  5073. }
  5074. ParseNodePtr *ppnodeVarSave = m_ppnodeVar;
  5075. m_ppnodeVar = &pnodeFnc->pnodeVars;
  5076. // Don't try and skip scanning nested deferred lambdas which have only a single expression in the body.
  5077. // Their more-complicated text extents won't match the deferred-stub and the single expression should be fast to scan, anyway.
  5078. if (fLambda && !*pNeedScanRCurly)
  5079. {
  5080. ParseExpressionLambdaBody<false>(pnodeFnc, fAllowIn);
  5081. }
  5082. else if (pnodeFncParent != nullptr && m_currDeferredStub != nullptr)
  5083. {
  5084. // We've already parsed this function body for syntax errors on the initial parse of the script.
  5085. // We have information that allows us to skip it, so do so.
  5086. Assert(pnodeFncParent->nestedCount != 0);
  5087. DeferredFunctionStub *stub = m_currDeferredStub + (pnodeFncParent->nestedCount - 1);
  5088. Assert(pnodeFnc->ichMin == stub->ichMin
  5089. || (stub->fncFlags & kFunctionIsAsync) == kFunctionIsAsync
  5090. || ((stub->fncFlags & kFunctionIsMethod) == kFunctionIsMethod && (
  5091. (stub->fncFlags & kFunctionIsAccessor) == kFunctionIsAccessor
  5092. || (stub->fncFlags & kFunctionIsGenerator) == kFunctionIsGenerator
  5093. || (stub->fncFlags & kFunctionHasComputedName) == kFunctionHasComputedName
  5094. )));
  5095. if (stub->fncFlags & kFunctionCallsEval)
  5096. {
  5097. this->MarkEvalCaller();
  5098. }
  5099. PHASE_PRINT_TRACE1(
  5100. Js::SkipNestedDeferredPhase,
  5101. _u("Skipping nested deferred function %d. %s: %d...%d\n"),
  5102. pnodeFnc->functionId, GetFunctionName(pnodeFnc, pNameHint), pnodeFnc->ichMin, stub->restorePoint.m_ichMinTok);
  5103. this->GetScanner()->SeekTo(stub->restorePoint, m_nextFunctionId);
  5104. for (uint i = 0; i < stub->capturedNameCount; i++)
  5105. {
  5106. int stringId = stub->capturedNameSerializedIds[i];
  5107. uint32 stringLength = 0;
  5108. LPCWSTR stringVal = Js::ByteCodeSerializer::DeserializeString(stub, stringId, stringLength);
  5109. OUTPUT_TRACE_DEBUGONLY(Js::SkipNestedDeferredPhase, _u("\tPushing a reference to '%s'\n"), stringVal);
  5110. IdentPtr pid = this->GetHashTbl()->PidHashNameLen(stringVal, stringLength);
  5111. PushPidRef(pid);
  5112. }
  5113. pnodeFnc->nestedCount = stub->nestedCount;
  5114. pnodeFnc->deferredStub = stub->deferredStubs;
  5115. pnodeFnc->fncFlags = (FncFlags)(pnodeFnc->fncFlags | stub->fncFlags);
  5116. }
  5117. else
  5118. {
  5119. ParseStmtList<false>(nullptr, nullptr, SM_DeferredParse, true /* isSourceElementList */);
  5120. }
  5121. if (!fLambda || *pNeedScanRCurly)
  5122. {
  5123. pnodeFnc->ichLim = this->GetScanner()->IchLimTok();
  5124. pnodeFnc->cbLim = this->GetScanner()->IecpLimTok();
  5125. }
  5126. m_ppnodeVar = ppnodeVarSave;
  5127. // Restore the scanner's default hashing mode.
  5128. // Do this before we consume the next token.
  5129. this->GetScanner()->SetDeferredParseFlags(deferFlags);
  5130. if (*pNeedScanRCurly)
  5131. {
  5132. ChkCurTokNoScan(tkRCurly, ERRnoRcurly);
  5133. }
  5134. #if DBG
  5135. pnodeFnc->deferredParseNextFunctionId = *this->m_nextFunctionId;
  5136. #endif
  5137. this->m_deferringAST = FALSE;
  5138. }
  5139. bool Parser::DoParallelParse(ParseNodeFnc * pnodeFnc) const
  5140. {
  5141. #if ENABLE_BACKGROUND_PARSING
  5142. if (!PHASE_ENABLED_RAW(ParallelParsePhase, m_sourceContextInfo->sourceContextId, pnodeFnc->functionId))
  5143. {
  5144. return false;
  5145. }
  5146. BackgroundParser *bgp = m_scriptContext->GetBackgroundParser();
  5147. return bgp != nullptr;
  5148. #else
  5149. return false;
  5150. #endif
  5151. }
  5152. bool Parser::ScanAheadToFunctionEnd(uint count)
  5153. {
  5154. bool found = false;
  5155. uint curlyDepth = 0;
  5156. RestorePoint funcStart;
  5157. this->GetScanner()->Capture(&funcStart);
  5158. for (uint i = 0; i < count; i++)
  5159. {
  5160. switch (m_token.tk)
  5161. {
  5162. case tkStrTmplBegin:
  5163. case tkStrTmplMid:
  5164. case tkStrTmplEnd:
  5165. case tkDiv:
  5166. case tkAsgDiv:
  5167. case tkScanError:
  5168. case tkEOF:
  5169. goto LEnd;
  5170. case tkLCurly:
  5171. UInt32Math::Inc(curlyDepth, Parser::OutOfMemory);
  5172. break;
  5173. case tkRCurly:
  5174. if (curlyDepth == 1)
  5175. {
  5176. found = true;
  5177. goto LEnd;
  5178. }
  5179. if (curlyDepth == 0)
  5180. {
  5181. goto LEnd;
  5182. }
  5183. curlyDepth--;
  5184. break;
  5185. }
  5186. this->GetScanner()->ScanAhead();
  5187. }
  5188. LEnd:
  5189. this->GetScanner()->SeekTo(funcStart);
  5190. return found;
  5191. }
  5192. #if ENABLE_BACKGROUND_PARSING
  5193. bool Parser::FastScanFormalsAndBody()
  5194. {
  5195. // The scanner is currently pointing just past the name of a function.
  5196. // The idea here is to find the end of the function body as quickly as possible,
  5197. // by tokenizing and tracking {}'s if possible.
  5198. // String templates require some extra logic but can be handled.
  5199. // The real wrinkle is "/" and "/=", which may indicate either a RegExp literal or a division, depending
  5200. // on the context.
  5201. // To handle this with minimal work, keep track of the last ";" seen at each {} depth. If we see one of the
  5202. // difficult tokens, rewind to the last ";" at the current {} depth and parse statements until we pass the
  5203. // point where we had to rewind. This will process the "/" as required.
  5204. RestorePoint funcStart;
  5205. this->GetScanner()->Capture(&funcStart);
  5206. const int maxRestorePointDepth = 16;
  5207. struct FastScanRestorePoint
  5208. {
  5209. RestorePoint restorePoint;
  5210. uint parenDepth;
  5211. Js::LocalFunctionId functionId;
  5212. int blockId;
  5213. FastScanRestorePoint() : restorePoint(), parenDepth(0) {};
  5214. };
  5215. FastScanRestorePoint lastSColonAtCurlyDepth[maxRestorePointDepth];
  5216. charcount_t ichStart = this->GetScanner()->IchMinTok();
  5217. uint blockIdSave = m_nextBlockId;
  5218. uint functionIdSave = *m_nextFunctionId;
  5219. uint curlyDepth = 0;
  5220. uint strTmplDepth = 0;
  5221. for (;;)
  5222. {
  5223. switch (m_token.tk)
  5224. {
  5225. case tkStrTmplBegin:
  5226. UInt32Math::Inc(strTmplDepth, Parser::OutOfMemory);
  5227. // Fall through
  5228. case tkStrTmplMid:
  5229. case tkLCurly:
  5230. UInt32Math::Inc(curlyDepth, Parser::OutOfMemory);
  5231. Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
  5232. break;
  5233. case tkStrTmplEnd:
  5234. // We can assert here, because the scanner will only return this token if we've told it we're
  5235. // in a string template.
  5236. Assert(strTmplDepth > 0);
  5237. strTmplDepth--;
  5238. break;
  5239. case tkRCurly:
  5240. if (curlyDepth == 1)
  5241. {
  5242. Assert(strTmplDepth == 0);
  5243. if (PHASE_TRACE1(Js::ParallelParsePhase))
  5244. {
  5245. Output::Print(_u("Finished fast seek: %d. %s -- %d...%d\n"),
  5246. m_currentNodeFunc->functionId,
  5247. GetFunctionName(m_currentNodeFunc, m_currentNodeFunc->hint),
  5248. ichStart, this->GetScanner()->IchLimTok());
  5249. }
  5250. return true;
  5251. }
  5252. if (curlyDepth < maxRestorePointDepth)
  5253. {
  5254. lastSColonAtCurlyDepth[curlyDepth].restorePoint.m_ichMinTok = (uint)-1;
  5255. }
  5256. curlyDepth--;
  5257. if (strTmplDepth > 0)
  5258. {
  5259. this->GetScanner()->SetScanState(Scanner_t::ScanState::ScanStateStringTemplateMiddleOrEnd);
  5260. }
  5261. break;
  5262. case tkSColon:
  5263. // Track the location of the ";" (if it's outside parens, as we don't, for instance, want
  5264. // to track the ";"'s in a for-loop header. If we find it's important to rewind within a paren
  5265. // expression, we can do something more sophisticated.)
  5266. if (curlyDepth < maxRestorePointDepth && lastSColonAtCurlyDepth[curlyDepth].parenDepth == 0)
  5267. {
  5268. this->GetScanner()->Capture(&lastSColonAtCurlyDepth[curlyDepth].restorePoint);
  5269. lastSColonAtCurlyDepth[curlyDepth].functionId = *this->m_nextFunctionId;
  5270. lastSColonAtCurlyDepth[curlyDepth].blockId = m_nextBlockId;
  5271. }
  5272. break;
  5273. case tkLParen:
  5274. if (curlyDepth < maxRestorePointDepth)
  5275. {
  5276. UInt32Math::Inc(lastSColonAtCurlyDepth[curlyDepth].parenDepth);
  5277. }
  5278. break;
  5279. case tkRParen:
  5280. if (curlyDepth < maxRestorePointDepth)
  5281. {
  5282. Assert(lastSColonAtCurlyDepth[curlyDepth].parenDepth != 0);
  5283. lastSColonAtCurlyDepth[curlyDepth].parenDepth--;
  5284. }
  5285. break;
  5286. case tkID:
  5287. {
  5288. charcount_t tokLength = this->GetScanner()->IchLimTok() - this->GetScanner()->IchMinTok();
  5289. // Detect the function and class keywords so we can track function ID's.
  5290. // (In fast mode, the scanner doesn't distinguish keywords and doesn't point the token
  5291. // to a PID.)
  5292. // Detect try/catch/for to increment block count for them.
  5293. switch (tokLength)
  5294. {
  5295. case 3:
  5296. if (!memcmp(this->GetScanner()->PchMinTok(), "try", 3) || !memcmp(this->GetScanner()->PchMinTok(), "for", 3))
  5297. {
  5298. Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
  5299. }
  5300. break;
  5301. case 5:
  5302. if (!memcmp(this->GetScanner()->PchMinTok(), "catch", 5))
  5303. {
  5304. Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
  5305. }
  5306. else if (!memcmp(this->GetScanner()->PchMinTok(), "class", 5))
  5307. {
  5308. Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
  5309. Int32Math::Inc(*this->m_nextFunctionId, (int*)this->m_nextFunctionId);
  5310. }
  5311. break;
  5312. case 8:
  5313. if (!memcmp(this->GetScanner()->PchMinTok(), "function", 8))
  5314. {
  5315. // Account for the possible func expr scope or dummy block for missing {}'s around a declaration
  5316. Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
  5317. Int32Math::Inc(*this->m_nextFunctionId, (int*)this->m_nextFunctionId);
  5318. }
  5319. break;
  5320. }
  5321. break;
  5322. }
  5323. case tkDArrow:
  5324. Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
  5325. Int32Math::Inc(*this->m_nextFunctionId, (int*)this->m_nextFunctionId);
  5326. break;
  5327. case tkDiv:
  5328. case tkAsgDiv:
  5329. {
  5330. int opl;
  5331. OpCode nop;
  5332. tokens tkPrev = this->GetScanner()->m_tkPrevious;
  5333. if ((this->GetHashTbl()->TokIsBinop(tkPrev, &opl, &nop) && nop != knopNone) ||
  5334. (this->GetHashTbl()->TokIsUnop(tkPrev, &opl, &nop) &&
  5335. nop != knopNone &&
  5336. tkPrev != tkInc &&
  5337. tkPrev != tkDec) ||
  5338. tkPrev == tkColon ||
  5339. tkPrev == tkLParen ||
  5340. tkPrev == tkLBrack ||
  5341. tkPrev == tkRETURN)
  5342. {
  5343. // Previous token indicates that we're starting an expression here and can't have a
  5344. // binary operator now.
  5345. // Assume this is a RegExp.
  5346. ParseRegExp<false>();
  5347. break;
  5348. }
  5349. uint tempCurlyDepth = curlyDepth < maxRestorePointDepth ? curlyDepth : maxRestorePointDepth - 1;
  5350. for (; tempCurlyDepth != (uint)-1; tempCurlyDepth--)
  5351. {
  5352. // We don't know whether we've got a RegExp or a divide. Rewind to the last safe ";"
  5353. // if we can and parse statements until we pass this point.
  5354. if (lastSColonAtCurlyDepth[tempCurlyDepth].restorePoint.m_ichMinTok != -1)
  5355. {
  5356. break;
  5357. }
  5358. }
  5359. if (tempCurlyDepth != (uint)-1)
  5360. {
  5361. ParseNodeFnc * pnodeFncSave = m_currentNodeFunc;
  5362. int32 *pastSizeSave = m_pCurrentAstSize;
  5363. uint *pnestedCountSave = m_pnestedCount;
  5364. ParseNodePtr *ppnodeScopeSave = m_ppnodeScope;
  5365. ParseNodePtr *ppnodeExprScopeSave = m_ppnodeExprScope;
  5366. ParseNodeFnc * pnodeFnc = CreateDummyFuncNode(true);
  5367. charcount_t ichStop = this->GetScanner()->IchLimTok();
  5368. curlyDepth = tempCurlyDepth;
  5369. this->GetScanner()->SeekTo(lastSColonAtCurlyDepth[tempCurlyDepth].restorePoint);
  5370. m_nextBlockId = lastSColonAtCurlyDepth[tempCurlyDepth].blockId;
  5371. *this->m_nextFunctionId = lastSColonAtCurlyDepth[tempCurlyDepth].functionId;
  5372. ParseNodeBlock * pnodeBlock = StartParseBlock<true>(PnodeBlockType::Function, ScopeType_FunctionBody);
  5373. pnodeFnc->pnodeScopes = pnodeBlock;
  5374. m_ppnodeScope = &pnodeBlock->pnodeScopes;
  5375. m_ppnodeExprScope = nullptr;
  5376. this->GetScanner()->Scan();
  5377. do
  5378. {
  5379. ParseStatement<false>();
  5380. } while (this->GetScanner()->IchMinTok() < ichStop);
  5381. FinishParseBlock(pnodeBlock);
  5382. m_currentNodeFunc = pnodeFncSave;
  5383. m_pCurrentAstSize = pastSizeSave;
  5384. m_pnestedCount = pnestedCountSave;
  5385. m_ppnodeScope = ppnodeScopeSave;
  5386. m_ppnodeExprScope = ppnodeExprScopeSave;
  5387. // We've already consumed the first token of the next statement, so just continue
  5388. // without a further scan.
  5389. continue;
  5390. }
  5391. }
  5392. // fall through to rewind to function start
  5393. case tkScanError:
  5394. case tkEOF:
  5395. // Unexpected token.
  5396. if (PHASE_TRACE1(Js::ParallelParsePhase))
  5397. {
  5398. Output::Print(_u("Failed fast seek: %d. %s -- %d...%d\n"),
  5399. m_currentNodeFunc->functionId,
  5400. GetFunctionName(m_currentNodeFunc, m_currentNodeFunc->hint),
  5401. ichStart, this->GetScanner()->IchLimTok());
  5402. }
  5403. m_nextBlockId = blockIdSave;
  5404. *m_nextFunctionId = functionIdSave;
  5405. this->GetScanner()->SeekTo(funcStart);
  5406. return false;
  5407. }
  5408. this->GetScanner()->ScanNoKeywords();
  5409. }
  5410. }
  5411. #endif
  5412. ParseNodeFnc * Parser::CreateDummyFuncNode(bool fDeclaration)
  5413. {
  5414. // Create a dummy node and make it look like the current function declaration.
  5415. // Do this in situations where we want to parse statements without impacting
  5416. // the state of the "real" AST.
  5417. ParseNodeFnc * pnodeFnc = CreateAllowDeferNodeForOpT<knopFncDecl>();
  5418. pnodeFnc->SetDeclaration(fDeclaration);
  5419. pnodeFnc->SetNested(m_currentNodeFunc != nullptr); // If there is a current function, then we're a nested function.
  5420. pnodeFnc->SetStrictMode(IsStrictMode()); // Inherit current strict mode -- may be overridden by the function itself if it contains a strict mode directive.
  5421. m_pCurrentAstSize = &pnodeFnc->astSize;
  5422. m_currentNodeFunc = pnodeFnc;
  5423. m_pnestedCount = &pnodeFnc->nestedCount;
  5424. return pnodeFnc;
  5425. }
  5426. void Parser::ParseNestedDeferredFunc(ParseNodeFnc * pnodeFnc, bool fLambda, bool *pNeedScanRCurly, bool *pStrictModeTurnedOn, bool fAllowIn)
  5427. {
  5428. // Parse a function nested inside another deferred function.
  5429. size_t lengthBeforeBody = this->GetSourceLength();
  5430. if (m_token.tk != tkLCurly && fLambda)
  5431. {
  5432. ParseExpressionLambdaBody<false>(pnodeFnc, fAllowIn);
  5433. *pNeedScanRCurly = false;
  5434. }
  5435. else
  5436. {
  5437. ChkCurTok(tkLCurly, ERRnoLcurly);
  5438. bool* detectStrictModeOn = IsStrictMode() ? nullptr : pStrictModeTurnedOn;
  5439. m_ppnodeVar = &m_currentNodeDeferredFunc->pnodeVars;
  5440. ParseStmtList<false>(nullptr, nullptr, SM_DeferredParse, true /* isSourceElementList */, detectStrictModeOn);
  5441. ChkCurTokNoScan(tkRCurly, ERRnoRcurly);
  5442. pnodeFnc->ichLim = this->GetScanner()->IchLimTok();
  5443. pnodeFnc->cbLim = this->GetScanner()->IecpLimTok();
  5444. }
  5445. if (*pStrictModeTurnedOn)
  5446. {
  5447. pnodeFnc->SetStrictMode(true);
  5448. }
  5449. if (!PHASE_OFF1(Js::SkipNestedDeferredPhase))
  5450. {
  5451. // Record the end of the function and the function ID increment that happens inside the function.
  5452. // Byte code gen will use this to build stub information to allow us to skip this function when the
  5453. // enclosing function is fully parsed.
  5454. RestorePoint *restorePoint = Anew(&m_nodeAllocator, RestorePoint);
  5455. this->GetScanner()->Capture(restorePoint,
  5456. *m_nextFunctionId - pnodeFnc->functionId - 1,
  5457. lengthBeforeBody - this->GetSourceLength());
  5458. pnodeFnc->pRestorePoint = restorePoint;
  5459. }
  5460. }
  5461. template<bool buildAST>
  5462. void Parser::ParseFncName(ParseNodeFnc * pnodeFnc, ushort flags, IdentPtr* pFncNamePid)
  5463. {
  5464. Assert(pnodeFnc);
  5465. BOOL fDeclaration = flags & fFncDeclaration;
  5466. BOOL fIsAsync = flags & fFncAsync;
  5467. this->GetScanner()->Scan();
  5468. // If generators are enabled then we are in a recent enough version
  5469. // that deferred parsing will create a parse node for pnodeFnc and
  5470. // it is safe to assume it is not null.
  5471. if (flags & fFncGenerator)
  5472. {
  5473. Assert(m_scriptContext->GetConfig()->IsES6GeneratorsEnabled());
  5474. pnodeFnc->SetIsGenerator();
  5475. }
  5476. else if (m_scriptContext->GetConfig()->IsES6GeneratorsEnabled() &&
  5477. m_token.tk == tkStar &&
  5478. !(flags & fFncClassMember))
  5479. {
  5480. if (!fDeclaration)
  5481. {
  5482. bool fPreviousYieldIsKeyword = this->GetScanner()->SetYieldIsKeywordRegion(!fDeclaration);
  5483. this->GetScanner()->Scan();
  5484. this->GetScanner()->SetYieldIsKeywordRegion(fPreviousYieldIsKeyword);
  5485. }
  5486. else
  5487. {
  5488. this->GetScanner()->Scan();
  5489. }
  5490. pnodeFnc->SetIsGenerator();
  5491. }
  5492. if (fIsAsync)
  5493. {
  5494. if (pnodeFnc->IsGenerator())
  5495. {
  5496. Error(ERRsyntax);
  5497. }
  5498. pnodeFnc->SetIsAsync();
  5499. }
  5500. pnodeFnc->pnodeName = nullptr;
  5501. if ((m_token.tk != tkID || flags & fFncNoName)
  5502. && (IsStrictMode() || fDeclaration
  5503. || pnodeFnc->IsGenerator() || pnodeFnc->IsAsync()
  5504. || (m_token.tk != tkYIELD && m_token.tk != tkAWAIT))) // Function expressions can have the name yield/await even inside generator/async functions
  5505. {
  5506. if (fDeclaration ||
  5507. m_token.IsReservedWord()) // For example: var x = (function break(){});
  5508. {
  5509. IdentifierExpectedError(m_token);
  5510. }
  5511. return;
  5512. }
  5513. Assert(m_token.tk == tkID || (m_token.tk == tkYIELD && !fDeclaration) || (m_token.tk == tkAWAIT && !fDeclaration));
  5514. if (IsStrictMode())
  5515. {
  5516. CheckStrictModeEvalArgumentsUsage(m_token.GetIdentifier(this->GetHashTbl()));
  5517. }
  5518. IdentPtr pidBase = m_token.GetIdentifier(this->GetHashTbl());
  5519. pnodeFnc->pnodeName = CreateDeclNode(knopVarDecl, pidBase, STFunction);
  5520. pnodeFnc->pid = pnodeFnc->pnodeName->pid;
  5521. if (pFncNamePid != nullptr)
  5522. {
  5523. *pFncNamePid = pidBase;
  5524. }
  5525. this->GetScanner()->Scan();
  5526. }
  5527. void Parser::ValidateFormals()
  5528. {
  5529. ParseFncFormals<false>(this->GetCurrentFunctionNode(), nullptr, fFncNoFlgs);
  5530. // Eat the tkRParen. The ParseFncDeclHelper caller expects to see it.
  5531. this->GetScanner()->Scan();
  5532. }
  5533. void Parser::ValidateSourceElementList()
  5534. {
  5535. ParseStmtList<false>(nullptr, nullptr, SM_NotUsed, true);
  5536. }
  5537. void Parser::UpdateOrCheckForDuplicateInFormals(IdentPtr pid, SList<IdentPtr> *formals)
  5538. {
  5539. bool isStrictMode = IsStrictMode();
  5540. if (isStrictMode)
  5541. {
  5542. CheckStrictModeEvalArgumentsUsage(pid);
  5543. }
  5544. if (formals->Has(pid))
  5545. {
  5546. if (isStrictMode)
  5547. {
  5548. Error(ERRES5ArgSame);
  5549. }
  5550. else
  5551. {
  5552. Error(ERRFormalSame);
  5553. }
  5554. }
  5555. else
  5556. {
  5557. formals->Prepend(pid);
  5558. }
  5559. }
  5560. template<bool buildAST>
  5561. void Parser::ParseFncFormals(ParseNodeFnc * pnodeFnc, ParseNodeFnc * pnodeParentFnc, ushort flags, bool isTopLevelDeferredFunc)
  5562. {
  5563. bool fLambda = (flags & fFncLambda) != 0;
  5564. bool fMethod = (flags & fFncMethod) != 0;
  5565. bool fNoArg = (flags & fFncNoArg) != 0;
  5566. bool fOneArg = (flags & fFncOneArg) != 0;
  5567. bool fAsync = (flags & fFncAsync) != 0;
  5568. bool fPreviousYieldIsKeyword = false;
  5569. bool fPreviousAwaitIsKeyword = false;
  5570. if (fLambda)
  5571. {
  5572. fPreviousYieldIsKeyword = this->GetScanner()->SetYieldIsKeywordRegion(pnodeParentFnc != nullptr && pnodeParentFnc->IsGenerator());
  5573. fPreviousAwaitIsKeyword = this->GetScanner()->SetAwaitIsKeywordRegion(fAsync || (pnodeParentFnc != nullptr && pnodeParentFnc->IsAsync()));
  5574. }
  5575. Assert(!fNoArg || !fOneArg); // fNoArg and fOneArg can never be true at the same time.
  5576. // strictFormals corresponds to the StrictFormalParameters grammar production
  5577. // in the ES spec which just means duplicate names are not allowed
  5578. bool fStrictFormals = IsStrictMode() || fLambda || fMethod;
  5579. // When detecting duplicated formals pids are needed so force PID creation (unless the function should take 0 or 1 arg).
  5580. bool forcePid = fStrictFormals && !fNoArg && !fOneArg;
  5581. AutoTempForcePid autoForcePid(this->GetScanner(), forcePid);
  5582. // Lambda's allow single formal specified by a single binding identifier without parentheses, special case it.
  5583. if (fLambda && m_token.tk == tkID)
  5584. {
  5585. IdentPtr pid = m_token.GetIdentifier(this->GetHashTbl());
  5586. CreateVarDeclNode(pid, STFormal, false, nullptr, false);
  5587. CheckPidIsValid(pid);
  5588. this->GetScanner()->Scan();
  5589. if (m_token.tk != tkDArrow)
  5590. {
  5591. Error(ERRsyntax, this->GetScanner()->IchMinTok(), this->GetScanner()->IchLimTok());
  5592. }
  5593. if (fLambda)
  5594. {
  5595. this->GetScanner()->SetYieldIsKeywordRegion(fPreviousYieldIsKeyword);
  5596. this->GetScanner()->SetAwaitIsKeywordRegion(fPreviousAwaitIsKeyword);
  5597. }
  5598. return;
  5599. }
  5600. else if (fLambda && m_token.tk == tkAWAIT)
  5601. {
  5602. // async await => {}
  5603. IdentifierExpectedError(m_token);
  5604. }
  5605. // Otherwise, must have a parameter list within parens.
  5606. ChkCurTok(tkLParen, ERRnoLparen);
  5607. // Now parse the list of arguments, if present
  5608. if (m_token.tk == tkRParen)
  5609. {
  5610. if (fOneArg)
  5611. {
  5612. Error(ERRSetterMustHaveOneParameter);
  5613. }
  5614. }
  5615. else
  5616. {
  5617. if (fNoArg)
  5618. {
  5619. Error(ERRGetterMustHaveNoParameters);
  5620. }
  5621. SList<IdentPtr> formals(&m_nodeAllocator);
  5622. ParseNodeVar * pnodeT = nullptr;
  5623. bool seenRestParameter = false;
  5624. bool isNonSimpleParameterList = false;
  5625. for (Js::ArgSlot argPos = 0; ; ++argPos)
  5626. {
  5627. bool isBindingPattern = false;
  5628. if (m_scriptContext->GetConfig()->IsES6RestEnabled() && m_token.tk == tkEllipsis)
  5629. {
  5630. // Possible rest parameter
  5631. this->GetScanner()->Scan();
  5632. seenRestParameter = true;
  5633. }
  5634. if (m_token.tk != tkID)
  5635. {
  5636. if (IsES6DestructuringEnabled() && IsPossiblePatternStart())
  5637. {
  5638. // Mark that the function has a non simple parameter list before parsing the pattern since the pattern can have function definitions.
  5639. this->GetCurrentFunctionNode()->SetHasNonSimpleParameterList();
  5640. this->GetCurrentFunctionNode()->SetHasDestructuredParams();
  5641. ParseNodePtr *const ppnodeVarSave = m_ppnodeVar;
  5642. m_ppnodeVar = &pnodeFnc->pnodeVars;
  5643. ParseNodePtr * ppNodeLex = m_currentBlockInfo->m_ppnodeLex;
  5644. Assert(ppNodeLex != nullptr);
  5645. ParseNodeParamPattern * paramPattern = nullptr;
  5646. ParseNode * pnodePattern = nullptr;
  5647. if (isTopLevelDeferredFunc)
  5648. {
  5649. pnodePattern = ParseDestructuredLiteral<false>(tkLET, true /*isDecl*/, false /*topLevel*/);
  5650. }
  5651. else
  5652. {
  5653. pnodePattern = ParseDestructuredLiteral<buildAST>(tkLET, true /*isDecl*/, false /*topLevel*/);
  5654. }
  5655. // Instead of passing the STFormal all the way on many methods, it seems it is better to change the symbol type afterward.
  5656. for (ParseNodePtr lexNode = *ppNodeLex; lexNode != nullptr; lexNode = lexNode->AsParseNodeVar()->pnodeNext)
  5657. {
  5658. Assert(lexNode->IsVarLetOrConst());
  5659. UpdateOrCheckForDuplicateInFormals(lexNode->AsParseNodeVar()->pid, &formals);
  5660. lexNode->AsParseNodeVar()->sym->SetSymbolType(STFormal);
  5661. if (lexNode->AsParseNodeVar()->pid == wellKnownPropertyPids.arguments)
  5662. {
  5663. GetCurrentFunctionNode()->grfpn |= PNodeFlags::fpnArguments_overriddenInParam;
  5664. }
  5665. }
  5666. m_ppnodeVar = ppnodeVarSave;
  5667. if (buildAST)
  5668. {
  5669. if (isTopLevelDeferredFunc)
  5670. {
  5671. Assert(pnodePattern == nullptr);
  5672. // Create a dummy pattern node as we need the node to be considered for the param count
  5673. paramPattern = CreateDummyParamPatternNode(this->GetScanner()->IchMinTok());
  5674. }
  5675. else
  5676. {
  5677. Assert(pnodePattern);
  5678. paramPattern = CreateParamPatternNode(pnodePattern);
  5679. }
  5680. // Linking the current formal parameter (which is pattern parameter) with other formals.
  5681. *m_ppnodeVar = paramPattern;
  5682. paramPattern->pnodeNext = nullptr;
  5683. m_ppnodeVar = &paramPattern->pnodeNext;
  5684. }
  5685. isBindingPattern = true;
  5686. isNonSimpleParameterList = true;
  5687. }
  5688. else
  5689. {
  5690. IdentifierExpectedError(m_token);
  5691. }
  5692. }
  5693. if (!isBindingPattern)
  5694. {
  5695. IdentPtr pid = m_token.GetIdentifier(this->GetHashTbl());
  5696. LPCOLESTR pNameHint = pid->Psz();
  5697. uint32 nameHintLength = pid->Cch();
  5698. uint32 nameHintOffset = 0;
  5699. if (seenRestParameter)
  5700. {
  5701. this->GetCurrentFunctionNode()->SetHasNonSimpleParameterList();
  5702. if (flags & fFncOneArg)
  5703. {
  5704. // The parameter of a setter cannot be a rest parameter.
  5705. Error(ERRUnexpectedEllipsis);
  5706. }
  5707. pnodeT = CreateDeclNode(knopVarDecl, pid, STFormal, false);
  5708. pnodeT->sym->SetIsNonSimpleParameter(true);
  5709. if (buildAST)
  5710. {
  5711. // When only validating formals, we won't have a function node.
  5712. pnodeFnc->pnodeRest = pnodeT;
  5713. if (!isNonSimpleParameterList)
  5714. {
  5715. // This is the first non-simple parameter we've seen. We need to go back
  5716. // and set the Symbols of all previous parameters.
  5717. MapFormalsWithoutRest(m_currentNodeFunc, [&](ParseNodePtr pnodeArg) { pnodeArg->AsParseNodeVar()->sym->SetIsNonSimpleParameter(true); });
  5718. }
  5719. }
  5720. isNonSimpleParameterList = true;
  5721. }
  5722. else
  5723. {
  5724. pnodeT = CreateVarDeclNode(pid, STFormal, false, nullptr, false);
  5725. if (isNonSimpleParameterList)
  5726. {
  5727. pnodeT->sym->SetIsNonSimpleParameter(true);
  5728. }
  5729. }
  5730. if (buildAST && pid == wellKnownPropertyPids.arguments)
  5731. {
  5732. // This formal parameter overrides the built-in 'arguments' object
  5733. m_currentNodeFunc->grfpn |= PNodeFlags::fpnArguments_overriddenInParam;
  5734. }
  5735. if (fStrictFormals)
  5736. {
  5737. UpdateOrCheckForDuplicateInFormals(pid, &formals);
  5738. }
  5739. this->GetScanner()->Scan();
  5740. if (seenRestParameter && m_token.tk != tkRParen && m_token.tk != tkAsg)
  5741. {
  5742. Error(ERRRestLastArg);
  5743. }
  5744. if (m_token.tk == tkAsg && m_scriptContext->GetConfig()->IsES6DefaultArgsEnabled())
  5745. {
  5746. if (seenRestParameter && m_scriptContext->GetConfig()->IsES6RestEnabled())
  5747. {
  5748. Error(ERRRestWithDefault);
  5749. }
  5750. // In defer parse mode we have to flag the function node to indicate that it has default arguments
  5751. // so that it will be considered for any syntax error scenario.
  5752. // Also mark it before parsing the expression as it may contain functions.
  5753. ParseNodeFnc * currentFncNode = GetCurrentFunctionNode();
  5754. if (!currentFncNode->HasDefaultArguments())
  5755. {
  5756. currentFncNode->SetHasDefaultArguments();
  5757. currentFncNode->SetHasNonSimpleParameterList();
  5758. currentFncNode->firstDefaultArg = argPos;
  5759. }
  5760. this->GetScanner()->Scan();
  5761. ParseNodePtr pnodeInit;
  5762. if (isTopLevelDeferredFunc)
  5763. {
  5764. // Defer default expressions if the function will be deferred, since we know they can't be evaluated
  5765. // until the function is fully compiled, and generating code for a function nested inside a deferred function
  5766. // creates inconsistencies.
  5767. pnodeInit = ParseExpr<false>(koplCma, nullptr, TRUE, FALSE, pNameHint, &nameHintLength, &nameHintOffset);
  5768. }
  5769. else
  5770. {
  5771. pnodeInit = ParseExpr<buildAST>(koplCma, nullptr, TRUE, FALSE, pNameHint, &nameHintLength, &nameHintOffset);
  5772. }
  5773. if (buildAST && pnodeInit && pnodeInit->nop == knopFncDecl)
  5774. {
  5775. Assert(nameHintLength >= nameHintOffset);
  5776. ParseNodeFnc * pnodeFncInit = pnodeInit->AsParseNodeFnc();
  5777. pnodeFncInit->hint = pNameHint;
  5778. pnodeFncInit->hintLength = nameHintLength;
  5779. pnodeFncInit->hintOffset = nameHintOffset;
  5780. }
  5781. AnalysisAssert(pnodeT);
  5782. pnodeT->sym->SetIsNonSimpleParameter(true);
  5783. if (!isNonSimpleParameterList)
  5784. {
  5785. if (buildAST)
  5786. {
  5787. // This is the first non-simple parameter we've seen. We need to go back
  5788. // and set the Symbols of all previous parameters.
  5789. MapFormalsWithoutRest(m_currentNodeFunc, [&](ParseNodePtr pnodeArg) { pnodeArg->AsParseNodeVar()->sym->SetIsNonSimpleParameter(true); });
  5790. }
  5791. // There may be previous parameters that need to be checked for duplicates.
  5792. isNonSimpleParameterList = true;
  5793. }
  5794. if (buildAST)
  5795. {
  5796. if (!m_currentNodeFunc->HasDefaultArguments())
  5797. {
  5798. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, DefaultArgFunction, m_scriptContext);
  5799. }
  5800. pnodeT->pnodeInit = pnodeInit;
  5801. pnodeT->ichLim = this->GetScanner()->IchLimTok();
  5802. }
  5803. }
  5804. }
  5805. if (isNonSimpleParameterList && m_currentScope->GetHasDuplicateFormals())
  5806. {
  5807. Error(ERRFormalSame);
  5808. }
  5809. if (flags & fFncOneArg)
  5810. {
  5811. if (m_token.tk != tkRParen)
  5812. {
  5813. Error(ERRSetterMustHaveOneParameter);
  5814. }
  5815. break; //enforce only one arg
  5816. }
  5817. if (m_token.tk != tkComma)
  5818. {
  5819. break;
  5820. }
  5821. this->GetScanner()->Scan();
  5822. if (m_token.tk == tkRParen && m_scriptContext->GetConfig()->IsES7TrailingCommaEnabled())
  5823. {
  5824. break;
  5825. }
  5826. }
  5827. if (seenRestParameter)
  5828. {
  5829. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, Rest, m_scriptContext);
  5830. }
  5831. if (m_token.tk != tkRParen)
  5832. {
  5833. Error(ERRnoRparen);
  5834. }
  5835. if (this->GetCurrentFunctionNode()->CallsEval() || this->GetCurrentFunctionNode()->ChildCallsEval())
  5836. {
  5837. Assert(pnodeFnc->HasNonSimpleParameterList());
  5838. pnodeFnc->ResetBodyAndParamScopeMerged();
  5839. }
  5840. }
  5841. Assert(m_token.tk == tkRParen);
  5842. if (fLambda)
  5843. {
  5844. this->GetScanner()->SetYieldIsKeywordRegion(fPreviousYieldIsKeyword);
  5845. this->GetScanner()->SetAwaitIsKeywordRegion(fPreviousAwaitIsKeyword);
  5846. }
  5847. }
  5848. template<bool buildAST>
  5849. ParseNodePtr Parser::GenerateModuleFunctionWrapper()
  5850. {
  5851. ParseNodePtr pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(fFncModule, SuperRestrictionState::Disallowed, nullptr, /* needsPIDOnRCurlyScan */ false, /* fUnaryOrParen */ true);
  5852. ParseNodePtr callNode = CreateCallNode(knopCall, pnodeFnc, nullptr);
  5853. return callNode;
  5854. }
  5855. template<bool buildAST>
  5856. ParseNodeFnc * Parser::GenerateEmptyConstructor(bool extends)
  5857. {
  5858. ParseNodeFnc * pnodeFnc;
  5859. // Create the node.
  5860. pnodeFnc = CreateAllowDeferNodeForOpT<knopFncDecl>();
  5861. pnodeFnc->SetNested(NULL != m_currentNodeFunc);
  5862. pnodeFnc->SetStrictMode();
  5863. pnodeFnc->SetDeclaration(TRUE);
  5864. pnodeFnc->SetIsMethod(TRUE);
  5865. pnodeFnc->SetIsClassMember(TRUE);
  5866. pnodeFnc->SetIsClassConstructor(TRUE);
  5867. pnodeFnc->SetIsBaseClassConstructor(!extends);
  5868. pnodeFnc->SetHasNonThisStmt();
  5869. pnodeFnc->SetIsGeneratedDefault(TRUE);
  5870. pnodeFnc->SetHasComputedName();
  5871. pnodeFnc->SetHasHomeObj();
  5872. pnodeFnc->SetHomeObjLocation(Js::Constants::NoRegister);
  5873. pnodeFnc->ichLim = this->GetScanner()->IchLimTok();
  5874. pnodeFnc->ichMin = this->GetScanner()->IchMinTok();
  5875. pnodeFnc->cbLim = this->GetScanner()->IecpLimTok();
  5876. pnodeFnc->cbMin = this->GetScanner()->IecpMinTok();
  5877. pnodeFnc->cbStringMin = pnodeFnc->cbMin;
  5878. pnodeFnc->lineNumber = this->GetScanner()->LineCur();
  5879. pnodeFnc->functionId = (*m_nextFunctionId);
  5880. // In order to (re-)defer the default constructor, we need to, for instance, track
  5881. // deferred class expression the way we track function expression, since we lose the part of the source
  5882. // that tells us which we have.
  5883. Assert(!pnodeFnc->canBeDeferred);
  5884. #ifdef DBG
  5885. pnodeFnc->deferredParseNextFunctionId = *(this->m_nextFunctionId);
  5886. #endif
  5887. AppendFunctionToScopeList(true, pnodeFnc);
  5888. if (m_nextFunctionId)
  5889. {
  5890. (*m_nextFunctionId)++;
  5891. }
  5892. // Update the count of functions nested in the current parent.
  5893. if (m_pnestedCount)
  5894. {
  5895. (*m_pnestedCount)++;
  5896. }
  5897. if (this->GetScanner()->IchMinTok() >= this->GetScanner()->IchMinLine())
  5898. {
  5899. // In scenarios involving defer parse IchMinLine() can be incorrect for the first line after defer parse
  5900. pnodeFnc->columnNumber = this->GetScanner()->IchMinTok() - this->GetScanner()->IchMinLine();
  5901. }
  5902. else if (m_currentNodeFunc)
  5903. {
  5904. // For the first line after defer parse, compute the column relative to the column number
  5905. // of the lexically parent function.
  5906. ULONG offsetFromCurrentFunction = this->GetScanner()->IchMinTok() - m_currentNodeFunc->ichMin;
  5907. pnodeFnc->columnNumber = m_currentNodeFunc->columnNumber + offsetFromCurrentFunction;
  5908. }
  5909. else
  5910. {
  5911. // if there is no current function, lets give a default of 0.
  5912. pnodeFnc->columnNumber = 0;
  5913. }
  5914. int32 * pAstSizeSave = m_pCurrentAstSize;
  5915. m_pCurrentAstSize = &(pnodeFnc->astSize);
  5916. // Make this the current function.
  5917. ParseNodeFnc * pnodeFncSave = m_currentNodeFunc;
  5918. m_currentNodeFunc = pnodeFnc;
  5919. ParseNodeName * argsId = nullptr;
  5920. ParseNodePtr *lastNodeRef = nullptr;
  5921. ParseNodeBlock * pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Parameter, ScopeType_Parameter);
  5922. if (buildAST && extends)
  5923. {
  5924. // constructor(...args) { super(...args); }
  5925. // ^^^^^^^
  5926. ParseNodePtr *const ppnodeVarSave = m_ppnodeVar;
  5927. m_ppnodeVar = &pnodeFnc->pnodeVars;
  5928. IdentPtr pidargs = this->GetHashTbl()->PidHashNameLen(_u("args"), sizeof("args") - 1);
  5929. ParseNodeVar * pnodeT = CreateVarDeclNode(pidargs, STFormal);
  5930. pnodeT->sym->SetIsNonSimpleParameter(true);
  5931. pnodeFnc->pnodeRest = pnodeT;
  5932. PidRefStack *ref = this->PushPidRef(pidargs);
  5933. argsId = CreateNameNode(pidargs, ref, pnodeFnc->ichMin, pnodeFnc->ichLim);
  5934. m_ppnodeVar = ppnodeVarSave;
  5935. }
  5936. ParseNodeBlock * pnodeInnerBlock = StartParseBlock<buildAST>(PnodeBlockType::Function, ScopeType_FunctionBody);
  5937. pnodeBlock->pnodeScopes = pnodeInnerBlock;
  5938. pnodeFnc->pnodeBodyScope = pnodeInnerBlock;
  5939. pnodeFnc->pnodeScopes = pnodeBlock;
  5940. if (buildAST)
  5941. {
  5942. if (extends)
  5943. {
  5944. // constructor(...args) { super(...args); }
  5945. // ^^^^^^^^^^^^^^^
  5946. Assert(argsId);
  5947. ParseNodeUni * spreadArg = CreateUniNode(knopEllipsis, argsId, pnodeFnc->ichMin, pnodeFnc->ichLim);
  5948. ParseNodeSpecialName * superRef = ReferenceSpecialName(wellKnownPropertyPids._superConstructor, pnodeFnc->ichMin, pnodeFnc->ichLim, true);
  5949. pnodeFnc->SetHasSuperReference(TRUE);
  5950. ParseNodeSuperCall * callNode = CreateSuperCallNode(superRef, spreadArg);
  5951. callNode->pnodeThis = ReferenceSpecialName(wellKnownPropertyPids._this, pnodeFnc->ichMin, pnodeFnc->ichLim, true);
  5952. callNode->pnodeNewTarget = ReferenceSpecialName(wellKnownPropertyPids._newTarget, pnodeFnc->ichMin, pnodeFnc->ichLim, true);
  5953. callNode->spreadArgCount = 1;
  5954. AddToNodeList(&pnodeFnc->pnodeBody, &lastNodeRef, callNode);
  5955. }
  5956. AddToNodeList(&pnodeFnc->pnodeBody, &lastNodeRef, CreateNodeForOpT<knopEndCode>());
  5957. }
  5958. FinishParseBlock(pnodeInnerBlock);
  5959. CreateSpecialSymbolDeclarations(pnodeFnc);
  5960. FinishParseBlock(pnodeBlock);
  5961. m_currentNodeFunc = pnodeFncSave;
  5962. m_pCurrentAstSize = pAstSizeSave;
  5963. return pnodeFnc;
  5964. }
  5965. template<bool buildAST>
  5966. void Parser::ParseExpressionLambdaBody(ParseNodeFnc * pnodeLambda, bool fAllowIn)
  5967. {
  5968. ParseNodePtr *lastNodeRef = nullptr;
  5969. // The lambda body is a single expression, the result of which is the return value.
  5970. ParseNodeReturn * pnodeRet = nullptr;
  5971. if (buildAST)
  5972. {
  5973. pnodeRet = CreateNodeForOpT<knopReturn>();
  5974. pnodeRet->grfpn |= PNodeFlags::fpnSyntheticNode;
  5975. pnodeLambda->pnodeScopes->pnodeStmt = pnodeRet;
  5976. }
  5977. IdentToken token;
  5978. charcount_t lastRParen = 0;
  5979. // We need to disable deferred parse mode in the scanner because the lambda body doesn't end with a right paren.
  5980. // The scanner needs to create a pid in the case of a string constant token immediately following the lambda body expression.
  5981. // Otherwise, we'll save null for the string constant pid which will AV during ByteCode generation.
  5982. BYTE fScanDeferredFlagsSave = this->GetScanner()->SetDeferredParse(FALSE);
  5983. ParseNodePtr result = ParseExpr<buildAST>(koplAsg, nullptr, fAllowIn, FALSE, nullptr, nullptr, nullptr, &token, false, nullptr, &lastRParen);
  5984. this->GetScanner()->SetDeferredParseFlags(fScanDeferredFlagsSave);
  5985. this->MarkEscapingRef(result, &token);
  5986. if (buildAST)
  5987. {
  5988. pnodeRet->pnodeExpr = result;
  5989. pnodeRet->ichMin = pnodeRet->pnodeExpr->ichMin;
  5990. pnodeRet->ichLim = pnodeRet->pnodeExpr->ichLim;
  5991. // Pushing a statement node with PushStmt<>() normally does this initialization
  5992. // but do it here manually since we know there is no outer statement node.
  5993. pnodeRet->grfnop = 0;
  5994. pnodeRet->pnodeOuter = nullptr;
  5995. pnodeLambda->ichLim = max(pnodeRet->ichLim, lastRParen);
  5996. pnodeLambda->cbLim = this->GetScanner()->IecpLimTokPrevious();
  5997. pnodeLambda->pnodeScopes->ichLim = pnodeRet->ichLim;
  5998. pnodeLambda->pnodeBody = nullptr;
  5999. AddToNodeList(&pnodeLambda->pnodeBody, &lastNodeRef, pnodeRet);
  6000. // Append an EndCode node.
  6001. ParseNodePtr end = CreateNodeForOpT<knopEndCode>(pnodeRet->ichLim);
  6002. end->ichLim = end->ichMin; // make end code zero width at the immediate end of lambda body
  6003. AddToNodeList(&pnodeLambda->pnodeBody, &lastNodeRef, end);
  6004. // Lambda's do not have arguments binding
  6005. pnodeLambda->SetHasReferenceableBuiltInArguments(false);
  6006. }
  6007. else
  6008. {
  6009. pnodeLambda->ichLim = max(this->GetScanner()->IchLimTokPrevious(), lastRParen);
  6010. pnodeLambda->cbLim = this->GetScanner()->IecpLimTokPrevious();
  6011. }
  6012. }
  6013. void Parser::CheckStrictFormalParameters()
  6014. {
  6015. if (m_token.tk == tkID)
  6016. {
  6017. // single parameter arrow function case
  6018. IdentPtr pid = m_token.GetIdentifier(this->GetHashTbl());
  6019. CheckStrictModeEvalArgumentsUsage(pid);
  6020. return;
  6021. }
  6022. Assert(m_token.tk == tkLParen);
  6023. this->GetScanner()->ScanForcingPid();
  6024. if (m_token.tk != tkRParen)
  6025. {
  6026. SList<IdentPtr> formals(&m_nodeAllocator);
  6027. for (;;)
  6028. {
  6029. if (m_token.tk != tkID)
  6030. {
  6031. IdentifierExpectedError(m_token);
  6032. }
  6033. IdentPtr pid = m_token.GetIdentifier(this->GetHashTbl());
  6034. CheckStrictModeEvalArgumentsUsage(pid);
  6035. if (formals.Has(pid))
  6036. {
  6037. Error(ERRES5ArgSame, this->GetScanner()->IchMinTok(), this->GetScanner()->IchLimTok());
  6038. }
  6039. else
  6040. {
  6041. formals.Prepend(pid);
  6042. }
  6043. this->GetScanner()->Scan();
  6044. if (m_token.tk == tkAsg && m_scriptContext->GetConfig()->IsES6DefaultArgsEnabled())
  6045. {
  6046. this->GetScanner()->Scan();
  6047. // We can avoid building the AST since we are just checking the default expression.
  6048. ParseNodePtr pnodeInit = ParseExpr<false>(koplCma);
  6049. Assert(pnodeInit == nullptr);
  6050. }
  6051. if (m_token.tk != tkComma)
  6052. {
  6053. break;
  6054. }
  6055. this->GetScanner()->ScanForcingPid();
  6056. if (m_token.tk == tkRParen && m_scriptContext->GetConfig()->IsES7TrailingCommaEnabled())
  6057. {
  6058. break;
  6059. }
  6060. }
  6061. }
  6062. Assert(m_token.tk == tkRParen);
  6063. }
  6064. void Parser::FinishFncNode(ParseNodeFnc * pnodeFnc, bool fAllowIn)
  6065. {
  6066. AnalysisAssert(pnodeFnc);
  6067. // Finish the AST for a function that was deferred earlier, but which we decided
  6068. // to finish after the fact.
  6069. // We assume that the name(s) and arg(s) have already got parse nodes, so
  6070. // we just have to do the function body.
  6071. // Save the current next function Id, and resume from the old one.
  6072. Js::LocalFunctionId * nextFunctionIdSave = m_nextFunctionId;
  6073. Js::LocalFunctionId tempNextFunctionId = pnodeFnc->functionId + 1;
  6074. this->m_nextFunctionId = &tempNextFunctionId;
  6075. ParseNodeFnc * pnodeFncSave = m_currentNodeFunc;
  6076. uint *pnestedCountSave = m_pnestedCount;
  6077. int32* pAstSizeSave = m_pCurrentAstSize;
  6078. m_currentNodeFunc = pnodeFnc;
  6079. m_pCurrentAstSize = &(pnodeFnc->astSize);
  6080. pnodeFnc->nestedCount = 0;
  6081. m_pnestedCount = &pnodeFnc->nestedCount;
  6082. bool fLambda = pnodeFnc->IsLambda();
  6083. bool fMethod = pnodeFnc->IsMethod();
  6084. // Cue up the parser to the start of the function body.
  6085. if (pnodeFnc->pnodeName)
  6086. {
  6087. // Skip the name(s).
  6088. this->GetScanner()->SetCurrentCharacter(pnodeFnc->pnodeName->ichLim, pnodeFnc->lineNumber);
  6089. }
  6090. else
  6091. {
  6092. this->GetScanner()->SetCurrentCharacter(pnodeFnc->ichMin, pnodeFnc->lineNumber);
  6093. if (fMethod)
  6094. {
  6095. // Method. Skip identifier name, computed property name, "async", "get", "set", and '*' or '(' characters.
  6096. for (;;)
  6097. {
  6098. this->GetScanner()->Scan();
  6099. // '[' character indicates a computed property name for this method. We should consume it.
  6100. if (m_token.tk == tkLBrack)
  6101. {
  6102. // We don't care what the name expr is.
  6103. this->GetScanner()->Scan();
  6104. ParseExpr<false>();
  6105. Assert(m_token.tk == tkRBrack);
  6106. continue;
  6107. }
  6108. // Quit scanning ahead when we reach a '(' character which opens the arg list.
  6109. if (m_token.tk == tkLParen)
  6110. {
  6111. break;
  6112. }
  6113. }
  6114. }
  6115. else if (pnodeFnc->IsAccessor())
  6116. {
  6117. // Getter/setter. The node text starts with the name, so eat that.
  6118. this->GetScanner()->ScanNoKeywords();
  6119. }
  6120. else if (!fLambda)
  6121. {
  6122. // Anonymous function. Skip "async", "function", and '(' or '*' characters.
  6123. for (;;)
  6124. {
  6125. this->GetScanner()->Scan();
  6126. if (m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.async)
  6127. {
  6128. Assert(pnodeFnc->IsAsync());
  6129. continue;
  6130. }
  6131. // Quit scanning ahead when we reach a 'function' keyword which precedes the arg list.
  6132. if (m_token.tk == tkFUNCTION)
  6133. {
  6134. break;
  6135. }
  6136. Assert(m_token.tk == tkLParen || m_token.tk == tkStar);
  6137. }
  6138. }
  6139. }
  6140. // switch scanner to treat 'yield' as keyword in generator functions
  6141. // or as an identifier in non-generator functions
  6142. bool fPreviousYieldIsKeyword = this->GetScanner()->SetYieldIsKeywordRegion(pnodeFnc && pnodeFnc->IsGenerator());
  6143. bool fPreviousAwaitIsKeyword = this->GetScanner()->SetAwaitIsKeywordRegion(pnodeFnc && pnodeFnc->IsAsync());
  6144. // Skip the arg list.
  6145. if (!fMethod)
  6146. {
  6147. // If this is a method, we've already advanced to the '(' token.
  6148. this->GetScanner()->Scan();
  6149. }
  6150. if (m_token.tk == tkStar)
  6151. {
  6152. Assert(pnodeFnc->IsGenerator());
  6153. this->GetScanner()->ScanNoKeywords();
  6154. }
  6155. if (fLambda && m_token.tk == tkID && m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.async)
  6156. {
  6157. Assert(pnodeFnc->IsAsync());
  6158. this->GetScanner()->ScanNoKeywords();
  6159. }
  6160. Assert(m_token.tk == tkLParen || (fLambda && m_token.tk == tkID));
  6161. this->GetScanner()->ScanNoKeywords();
  6162. if (m_token.tk != tkRParen && m_token.tk != tkDArrow)
  6163. {
  6164. for (;;)
  6165. {
  6166. if (m_token.tk == tkEllipsis)
  6167. {
  6168. this->GetScanner()->ScanNoKeywords();
  6169. }
  6170. if (m_token.tk == tkID)
  6171. {
  6172. this->GetScanner()->ScanNoKeywords();
  6173. if (m_token.tk == tkAsg)
  6174. {
  6175. // Eat the default expression
  6176. this->GetScanner()->Scan();
  6177. ParseExpr<false>(koplCma);
  6178. }
  6179. }
  6180. else if (IsPossiblePatternStart())
  6181. {
  6182. ParseDestructuredLiteralWithScopeSave(tkLET, false/*isDecl*/, false /*topLevel*/);
  6183. }
  6184. else
  6185. {
  6186. AssertMsg(false, "Unexpected identifier prefix while fast-scanning formals");
  6187. }
  6188. if (m_token.tk != tkComma)
  6189. {
  6190. break;
  6191. }
  6192. this->GetScanner()->ScanNoKeywords();
  6193. if (m_token.tk == tkRParen && m_scriptContext->GetConfig()->IsES7TrailingCommaEnabled())
  6194. {
  6195. break;
  6196. }
  6197. }
  6198. }
  6199. if (m_token.tk == tkRParen)
  6200. {
  6201. this->GetScanner()->Scan();
  6202. }
  6203. if (fLambda && m_token.tk == tkDArrow)
  6204. {
  6205. this->GetScanner()->Scan();
  6206. }
  6207. // Finish the function body.
  6208. {
  6209. // Note that in IE8- modes, surrounding parentheses are considered part of function body. e.g. "( function x(){} )".
  6210. // We lose that context here since we start from middle of function body. So save and restore source range info.
  6211. const charcount_t ichLim = pnodeFnc->ichLim;
  6212. const size_t cbLim = pnodeFnc->cbLim;
  6213. this->FinishFncDecl(pnodeFnc, NULL, fLambda, /* skipCurlyBraces */ false, fAllowIn);
  6214. #if DBG
  6215. // The pnode extent may not match the original extent.
  6216. // We expect this to happen only when there are trailing ")"'s.
  6217. // Consume them and make sure that's all we've got.
  6218. if (pnodeFnc->ichLim != ichLim)
  6219. {
  6220. Assert(pnodeFnc->ichLim < ichLim);
  6221. this->GetScanner()->SetCurrentCharacter(pnodeFnc->ichLim);
  6222. while (this->GetScanner()->IchLimTok() != ichLim)
  6223. {
  6224. this->GetScanner()->ScanNoKeywords();
  6225. Assert(m_token.tk == tkRParen);
  6226. }
  6227. }
  6228. #endif
  6229. pnodeFnc->ichLim = ichLim;
  6230. pnodeFnc->cbLim = cbLim;
  6231. }
  6232. m_currentNodeFunc = pnodeFncSave;
  6233. m_pCurrentAstSize = pAstSizeSave;
  6234. m_pnestedCount = pnestedCountSave;
  6235. Assert(m_pnestedCount);
  6236. Assert(tempNextFunctionId == pnodeFnc->deferredParseNextFunctionId);
  6237. this->m_nextFunctionId = nextFunctionIdSave;
  6238. this->GetScanner()->SetYieldIsKeywordRegion(fPreviousYieldIsKeyword);
  6239. this->GetScanner()->SetAwaitIsKeywordRegion(fPreviousAwaitIsKeyword);
  6240. }
  6241. void Parser::FinishFncDecl(ParseNodeFnc * pnodeFnc, LPCOLESTR pNameHint, bool fLambda, bool skipCurlyBraces, bool fAllowIn)
  6242. {
  6243. LPCOLESTR name = NULL;
  6244. JS_ETW(int32 startAstSize = *m_pCurrentAstSize);
  6245. if (IS_JS_ETW(EventEnabledJSCRIPT_PARSE_METHOD_START()) || PHASE_TRACE1(Js::DeferParsePhase))
  6246. {
  6247. name = GetFunctionName(pnodeFnc, pNameHint);
  6248. m_functionBody = NULL; // for nested functions we do not want to get the name of the top deferred function return name;
  6249. JS_ETW(EventWriteJSCRIPT_PARSE_METHOD_START(m_sourceContextInfo->dwHostSourceContext, GetScriptContext(), pnodeFnc->functionId, 0, m_parseType, name));
  6250. OUTPUT_TRACE(Js::DeferParsePhase, _u("Parsing function (%s) : %s (%d)\n"), GetParseType(), name, pnodeFnc->functionId);
  6251. }
  6252. JS_ETW_INTERNAL(EventWriteJSCRIPT_PARSE_FUNC(GetScriptContext(), pnodeFnc->functionId, /*Undefer*/FALSE));
  6253. // Do the work of creating an AST for a function body.
  6254. // This is common to the un-deferred case and the case in which we un-defer late in the game.
  6255. Assert(pnodeFnc->nop == knopFncDecl);
  6256. if (fLambda && m_token.tk != tkLCurly)
  6257. {
  6258. ParseExpressionLambdaBody<true>(pnodeFnc, fAllowIn);
  6259. }
  6260. else
  6261. {
  6262. if (!skipCurlyBraces)
  6263. {
  6264. ChkCurTok(tkLCurly, ERRnoLcurly);
  6265. }
  6266. ParseNodePtr * lastNodeRef = nullptr;
  6267. ParseStmtList<true>(&pnodeFnc->pnodeBody, &lastNodeRef, SM_OnFunctionCode, true /* isSourceElementList */);
  6268. // Append an EndCode node.
  6269. AddToNodeList(&pnodeFnc->pnodeBody, &lastNodeRef, CreateNodeForOpT<knopEndCode>());
  6270. if (!skipCurlyBraces)
  6271. {
  6272. ChkCurTokNoScan(tkRCurly, ERRnoRcurly);
  6273. }
  6274. pnodeFnc->ichLim = this->GetScanner()->IchLimTok();
  6275. pnodeFnc->cbLim = this->GetScanner()->IecpLimTok();
  6276. }
  6277. #ifdef ENABLE_JS_ETW
  6278. int32 astSize = *m_pCurrentAstSize - startAstSize;
  6279. EventWriteJSCRIPT_PARSE_METHOD_STOP(m_sourceContextInfo->dwHostSourceContext, GetScriptContext(), pnodeFnc->functionId, astSize, m_parseType, name);
  6280. #endif
  6281. }
  6282. ParseNodeVar * Parser::CreateSpecialVarDeclNode(ParseNodeFnc * pnodeFnc, IdentPtr pid)
  6283. {
  6284. ParseNodeVar * pnode = InsertVarAtBeginning(pnodeFnc, pid);
  6285. pnode->grfpn |= fpnSpecialSymbol;
  6286. // special symbol must not be global
  6287. pnode->sym->SetIsGlobal(false);
  6288. return pnode;
  6289. }
  6290. ParseNodeVar * Parser::InsertVarAtBeginning(ParseNodeFnc * pnodeFnc, IdentPtr pid)
  6291. {
  6292. ParseNodeVar * pnode = nullptr;
  6293. if (m_ppnodeVar == &pnodeFnc->pnodeVars)
  6294. {
  6295. pnode = CreateVarDeclNode(pid, STVariable, true, pnodeFnc);
  6296. }
  6297. else
  6298. {
  6299. ParseNodePtr * const ppnodeVarSave = m_ppnodeVar;
  6300. m_ppnodeVar = &pnodeFnc->pnodeVars;
  6301. pnode = CreateVarDeclNode(pid, STVariable, true, pnodeFnc);
  6302. m_ppnodeVar = ppnodeVarSave;
  6303. }
  6304. Assert(pnode);
  6305. return pnode;
  6306. }
  6307. ParseNodeVar * Parser::AddArgumentsNodeToVars(ParseNodeFnc * pnodeFnc)
  6308. {
  6309. Assert(!GetCurrentFunctionNode()->IsLambda());
  6310. ParseNodeVar * argNode = InsertVarAtBeginning(pnodeFnc, wellKnownPropertyPids.arguments);
  6311. argNode->grfpn |= PNodeFlags::fpnArguments; // Flag this as the built-in arguments node
  6312. return argNode;
  6313. }
  6314. void Parser::UpdateArgumentsNode(ParseNodeFnc * pnodeFnc, ParseNodeVar * argNode)
  6315. {
  6316. if ((pnodeFnc->grfpn & PNodeFlags::fpnArguments_overriddenInParam) || pnodeFnc->IsLambda())
  6317. {
  6318. // There is a parameter named arguments. So we don't have to create the built-in arguments.
  6319. pnodeFnc->SetHasReferenceableBuiltInArguments(false);
  6320. }
  6321. else if ((pnodeFnc->grfpn & PNodeFlags::fpnArguments_overriddenByDecl) && pnodeFnc->IsBodyAndParamScopeMerged())
  6322. {
  6323. // In non-split scope case there is a var or function definition named arguments in the body
  6324. pnodeFnc->SetHasReferenceableBuiltInArguments(false);
  6325. }
  6326. else
  6327. {
  6328. pnodeFnc->SetHasReferenceableBuiltInArguments(true);
  6329. Assert(argNode);
  6330. }
  6331. if (argNode != nullptr && !argNode->sym->IsArguments())
  6332. {
  6333. // A duplicate definition has updated the declaration node. Need to reset it back.
  6334. argNode->grfpn |= PNodeFlags::fpnArguments;
  6335. argNode->sym->SetDecl(argNode);
  6336. }
  6337. }
  6338. LPCOLESTR Parser::GetFunctionName(ParseNodeFnc * pnodeFnc, LPCOLESTR pNameHint)
  6339. {
  6340. LPCOLESTR name = nullptr;
  6341. if (pnodeFnc->pnodeName != nullptr)
  6342. {
  6343. Assert(pnodeFnc->pnodeName->nop == knopVarDecl);
  6344. name = pnodeFnc->pnodeName->pid->Psz();
  6345. }
  6346. if (name == nullptr && pNameHint != nullptr)
  6347. {
  6348. name = pNameHint;
  6349. }
  6350. if (name == nullptr && (pnodeFnc->IsLambda() ||
  6351. (!pnodeFnc->IsDeclaration() && !pnodeFnc->IsMethod())))
  6352. {
  6353. name = Js::Constants::AnonymousFunction;
  6354. }
  6355. if (name == nullptr && m_functionBody != nullptr)
  6356. {
  6357. name = m_functionBody->GetExternalDisplayName();
  6358. }
  6359. else if (name == nullptr)
  6360. {
  6361. name = Js::Constants::AnonymousFunction;
  6362. }
  6363. return name;
  6364. }
  6365. IdentPtr Parser::ParseClassPropertyName(IdentPtr * pidHint)
  6366. {
  6367. if (m_token.tk == tkID || m_token.tk == tkStrCon || m_token.IsReservedWord())
  6368. {
  6369. IdentPtr pid;
  6370. if (m_token.tk == tkStrCon)
  6371. {
  6372. if (this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
  6373. {
  6374. Error(ERRES5NoOctal);
  6375. }
  6376. pid = m_token.GetStr();
  6377. }
  6378. else
  6379. {
  6380. pid = m_token.GetIdentifier(this->GetHashTbl());
  6381. }
  6382. *pidHint = pid;
  6383. return pid;
  6384. }
  6385. else if (m_token.tk == tkIntCon)
  6386. {
  6387. if (this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
  6388. {
  6389. Error(ERRES5NoOctal);
  6390. }
  6391. return this->GetScanner()->PidFromLong(m_token.GetLong());
  6392. }
  6393. else if (m_token.tk == tkFltCon)
  6394. {
  6395. if (this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
  6396. {
  6397. Error(ERRES5NoOctal);
  6398. }
  6399. return this->GetScanner()->PidFromDbl(m_token.GetDouble());
  6400. }
  6401. Error(ERRnoMemberIdent);
  6402. }
  6403. LPCOLESTR Parser::ConstructFinalHintNode(IdentPtr pClassName, IdentPtr pMemberName, IdentPtr pGetSet, bool isStatic, uint32* nameLength, uint32* pShortNameOffset, bool isComputedName, LPCOLESTR pMemberNameHint)
  6404. {
  6405. if ((pMemberName == nullptr && !isComputedName) ||
  6406. (pMemberNameHint == nullptr && isComputedName) ||
  6407. !CONFIG_FLAG(UseFullName))
  6408. {
  6409. return nullptr;
  6410. }
  6411. LPCOLESTR pFinalName = isComputedName ? pMemberNameHint : pMemberName->Psz();
  6412. uint32 fullNameHintLength = (uint32)wcslen(pFinalName);
  6413. uint32 shortNameOffset = 0;
  6414. if (!isStatic)
  6415. {
  6416. // Add prototype.
  6417. pFinalName = AppendNameHints(wellKnownPropertyPids.prototype, pFinalName, &fullNameHintLength, &shortNameOffset);
  6418. }
  6419. if (pClassName)
  6420. {
  6421. uint32 classNameOffset = 0;
  6422. pFinalName = AppendNameHints(pClassName, pFinalName, &fullNameHintLength, &classNameOffset);
  6423. shortNameOffset += classNameOffset;
  6424. }
  6425. if (pGetSet)
  6426. {
  6427. // displays as get/set prototype.funcname
  6428. uint32 getSetOffset = 0;
  6429. pFinalName = AppendNameHints(pGetSet, pFinalName, &fullNameHintLength, &getSetOffset, true);
  6430. shortNameOffset += getSetOffset;
  6431. }
  6432. *nameLength = fullNameHintLength;
  6433. *pShortNameOffset = shortNameOffset;
  6434. return pFinalName;
  6435. }
  6436. template<bool buildAST>
  6437. ParseNodeClass * Parser::ParseClassDecl(BOOL isDeclaration, LPCOLESTR pNameHint, uint32 *pHintLength, uint32 *pShortNameOffset)
  6438. {
  6439. bool hasConstructor = false;
  6440. bool hasExtends = false;
  6441. IdentPtr name = nullptr;
  6442. ParseNodeVar * pnodeName = nullptr;
  6443. ParseNodeFnc * pnodeConstructor = nullptr;
  6444. ParseNodePtr pnodeExtends = nullptr;
  6445. ParseNodePtr pnodeMembers = nullptr;
  6446. ParseNodePtr *lastMemberNodeRef = nullptr;
  6447. ParseNodePtr pnodeStaticMembers = nullptr;
  6448. ParseNodePtr *lastStaticMemberNodeRef = nullptr;
  6449. uint32 nameHintLength = pHintLength ? *pHintLength : 0;
  6450. uint32 nameHintOffset = pShortNameOffset ? *pShortNameOffset : 0;
  6451. ArenaAllocator tempAllocator(_u("ClassMemberNames"), m_nodeAllocator.GetPageAllocator(), Parser::OutOfMemory);
  6452. size_t cbMinConstructor = 0;
  6453. ParseNodeClass * pnodeClass = nullptr;
  6454. if (buildAST)
  6455. {
  6456. pnodeClass = CreateNodeForOpT<knopClassDecl>();
  6457. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, Class, m_scriptContext);
  6458. cbMinConstructor = this->GetScanner()->IecpMinTok();
  6459. }
  6460. this->GetScanner()->Scan();
  6461. if (m_token.tk == tkID)
  6462. {
  6463. name = m_token.GetIdentifier(this->GetHashTbl());
  6464. this->GetScanner()->Scan();
  6465. }
  6466. else if (isDeclaration)
  6467. {
  6468. IdentifierExpectedError(m_token);
  6469. }
  6470. if (isDeclaration && name == wellKnownPropertyPids.arguments && GetCurrentBlockInfo()->pnodeBlock->blockType == Function)
  6471. {
  6472. GetCurrentFunctionNode()->grfpn |= PNodeFlags::fpnArguments_overriddenByDecl;
  6473. }
  6474. BOOL strictSave = m_fUseStrictMode;
  6475. m_fUseStrictMode = TRUE;
  6476. ParseNodeVar * pnodeDeclName = nullptr;
  6477. if (isDeclaration)
  6478. {
  6479. pnodeDeclName = CreateBlockScopedDeclNode(name, knopLetDecl);
  6480. }
  6481. ParseNodePtr *ppnodeScopeSave = nullptr;
  6482. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  6483. ParseNodeBlock * pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Regular, ScopeType_Block);
  6484. if (buildAST)
  6485. {
  6486. PushFuncBlockScope(pnodeBlock, &ppnodeScopeSave, &ppnodeExprScopeSave);
  6487. pnodeClass->pnodeBlock = pnodeBlock;
  6488. }
  6489. if (name)
  6490. {
  6491. pnodeName = CreateBlockScopedDeclNode(name, knopConstDecl);
  6492. }
  6493. if (m_token.tk == tkEXTENDS)
  6494. {
  6495. this->GetScanner()->Scan();
  6496. pnodeExtends = ParseTerm<buildAST>();
  6497. hasExtends = true;
  6498. }
  6499. if (m_token.tk != tkLCurly)
  6500. {
  6501. Error(ERRnoLcurly);
  6502. }
  6503. OUTPUT_TRACE_DEBUGONLY(Js::ES6VerboseFlag, _u("Parsing class (%s) : %s\n"), GetParseType(), name ? name->Psz() : _u("anonymous class"));
  6504. RestorePoint beginClass;
  6505. this->GetScanner()->Capture(&beginClass);
  6506. this->GetScanner()->ScanForcingPid();
  6507. IdentPtr pClassNamePid = pnodeName ? pnodeName->pid : nullptr;
  6508. for (;;)
  6509. {
  6510. if (m_token.tk == tkSColon)
  6511. {
  6512. this->GetScanner()->ScanForcingPid();
  6513. continue;
  6514. }
  6515. if (m_token.tk == tkRCurly)
  6516. {
  6517. break;
  6518. }
  6519. bool isStatic = false;
  6520. if (m_token.tk == tkSTATIC)
  6521. {
  6522. // 'static' can be used as an IdentifierName here, even in strict mode code. We need to see the next token before we know
  6523. // if this is being used as a keyword. This is similar to the way we treat 'let' in some cases.
  6524. // See https://tc39.github.io/ecma262/#sec-keywords for more info.
  6525. RestorePoint beginStatic;
  6526. this->GetScanner()->Capture(&beginStatic);
  6527. this->GetScanner()->ScanForcingPid();
  6528. if (m_token.tk == tkLParen)
  6529. {
  6530. this->GetScanner()->SeekTo(beginStatic);
  6531. }
  6532. else
  6533. {
  6534. isStatic = true;
  6535. }
  6536. }
  6537. ushort fncDeclFlags = fFncNoName | fFncMethod | fFncClassMember;
  6538. charcount_t ichMin = this->GetScanner()->IchMinTok();
  6539. size_t iecpMin = this->GetScanner()->IecpMinTok();
  6540. ParseNodePtr pnodeMemberName = nullptr;
  6541. IdentPtr pidHint = nullptr;
  6542. IdentPtr memberPid = nullptr;
  6543. LPCOLESTR pMemberNameHint = nullptr;
  6544. uint32 memberNameHintLength = 0;
  6545. uint32 memberNameOffset = 0;
  6546. bool isComputedName = false;
  6547. bool isAsyncMethod = false;
  6548. if (m_token.tk == tkID && m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.async && m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
  6549. {
  6550. RestorePoint parsedAsync;
  6551. this->GetScanner()->Capture(&parsedAsync);
  6552. ichMin = this->GetScanner()->IchMinTok();
  6553. iecpMin = this->GetScanner()->IecpMinTok();
  6554. this->GetScanner()->Scan();
  6555. if (m_token.tk == tkLParen || this->GetScanner()->FHadNewLine())
  6556. {
  6557. this->GetScanner()->SeekTo(parsedAsync);
  6558. }
  6559. else
  6560. {
  6561. isAsyncMethod = true;
  6562. }
  6563. }
  6564. bool isGenerator = m_scriptContext->GetConfig()->IsES6GeneratorsEnabled() &&
  6565. m_token.tk == tkStar;
  6566. if (isGenerator)
  6567. {
  6568. fncDeclFlags |= fFncGenerator;
  6569. this->GetScanner()->ScanForcingPid();
  6570. }
  6571. if (m_token.tk == tkLBrack && m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
  6572. {
  6573. // Computed member name: [expr] () { }
  6574. LPCOLESTR emptyHint = nullptr;
  6575. ParseComputedName<buildAST>(&pnodeMemberName, &emptyHint, &pMemberNameHint, &memberNameHintLength, &memberNameOffset);
  6576. isComputedName = true;
  6577. }
  6578. else // not computed name
  6579. {
  6580. memberPid = this->ParseClassPropertyName(&pidHint);
  6581. if (pidHint)
  6582. {
  6583. pMemberNameHint = pidHint->Psz();
  6584. memberNameHintLength = pidHint->Cch();
  6585. }
  6586. }
  6587. if (buildAST && memberPid)
  6588. {
  6589. pnodeMemberName = CreateStrNode(memberPid);
  6590. }
  6591. if (!isStatic && memberPid == wellKnownPropertyPids.constructor)
  6592. {
  6593. if (hasConstructor || isAsyncMethod)
  6594. {
  6595. Error(ERRsyntax);
  6596. }
  6597. hasConstructor = true;
  6598. LPCOLESTR pConstructorName = nullptr;
  6599. uint32 constructorNameLength = 0;
  6600. uint32 constructorShortNameHintOffset = 0;
  6601. if (pnodeName && pnodeName->pid)
  6602. {
  6603. pConstructorName = pnodeName->pid->Psz();
  6604. constructorNameLength = pnodeName->pid->Cch();
  6605. }
  6606. else
  6607. {
  6608. pConstructorName = pNameHint;
  6609. constructorNameLength = nameHintLength;
  6610. constructorShortNameHintOffset = nameHintOffset;
  6611. }
  6612. {
  6613. SuperRestrictionState::State state = hasExtends ? SuperRestrictionState::CallAndPropertyAllowed : SuperRestrictionState::PropertyAllowed;
  6614. // Add the class constructor flag and base class constructor flag if pnodeExtends is nullptr
  6615. fncDeclFlags |= fFncClassConstructor | (hasExtends ? kFunctionNone : fFncBaseClassConstructor);
  6616. pnodeConstructor = ParseFncDeclNoCheckScope<buildAST>(fncDeclFlags, state, pConstructorName, /* needsPIDOnRCurlyScan */ true);
  6617. }
  6618. if (pnodeConstructor->IsGenerator())
  6619. {
  6620. Error(ERRConstructorCannotBeGenerator);
  6621. }
  6622. Assert(constructorNameLength >= constructorShortNameHintOffset);
  6623. // The constructor function will get the same name as class.
  6624. pnodeConstructor->hint = pConstructorName;
  6625. pnodeConstructor->hintLength = constructorNameLength;
  6626. pnodeConstructor->hintOffset = constructorShortNameHintOffset;
  6627. pnodeConstructor->pid = pnodeName && pnodeName->pid ? pnodeName->pid : wellKnownPropertyPids.constructor;
  6628. pnodeConstructor->SetHasNonThisStmt();
  6629. pnodeConstructor->SetHasComputedName();
  6630. pnodeConstructor->SetHasHomeObj();
  6631. }
  6632. else
  6633. {
  6634. ParseNodePtr pnodeMember = nullptr;
  6635. bool isMemberNamedGetOrSet = false;
  6636. RestorePoint beginMethodName;
  6637. this->GetScanner()->Capture(&beginMethodName);
  6638. if (memberPid == wellKnownPropertyPids.get || memberPid == wellKnownPropertyPids.set)
  6639. {
  6640. this->GetScanner()->ScanForcingPid();
  6641. }
  6642. if (m_token.tk == tkLParen)
  6643. {
  6644. this->GetScanner()->SeekTo(beginMethodName);
  6645. isMemberNamedGetOrSet = true;
  6646. }
  6647. if ((memberPid == wellKnownPropertyPids.get || memberPid == wellKnownPropertyPids.set) && !isMemberNamedGetOrSet)
  6648. {
  6649. bool isGetter = (memberPid == wellKnownPropertyPids.get);
  6650. if (m_token.tk == tkLBrack && m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
  6651. {
  6652. // Computed get/set member name: get|set [expr] () { }
  6653. LPCOLESTR emptyHint = nullptr;
  6654. ParseComputedName<buildAST>(&pnodeMemberName, &emptyHint, &pMemberNameHint, &memberNameHintLength, &memberNameOffset);
  6655. isComputedName = true;
  6656. }
  6657. else // not computed name
  6658. {
  6659. memberPid = this->ParseClassPropertyName(&pidHint);
  6660. }
  6661. if ((isStatic ? (memberPid == wellKnownPropertyPids.prototype) : (memberPid == wellKnownPropertyPids.constructor)) || isAsyncMethod)
  6662. {
  6663. Error(ERRsyntax);
  6664. }
  6665. if (buildAST && memberPid && !isComputedName)
  6666. {
  6667. pnodeMemberName = CreateStrNode(memberPid);
  6668. }
  6669. ParseNodeFnc * pnodeFnc = nullptr;
  6670. {
  6671. pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(fncDeclFlags | (isGetter ? fFncNoArg : fFncOneArg),
  6672. SuperRestrictionState::PropertyAllowed, pidHint ? pidHint->Psz() : nullptr, /* needsPIDOnRCurlyScan */ true);
  6673. }
  6674. pnodeFnc->SetIsStaticMember(isStatic);
  6675. if (isComputedName)
  6676. {
  6677. pnodeFnc->SetHasComputedName();
  6678. }
  6679. pnodeFnc->SetHasHomeObj();
  6680. if (buildAST)
  6681. {
  6682. pnodeFnc->SetIsAccessor();
  6683. pnodeMember = CreateBinNode(isGetter ? knopGetMember : knopSetMember, pnodeMemberName, pnodeFnc);
  6684. pMemberNameHint = ConstructFinalHintNode(pClassNamePid, pidHint,
  6685. isGetter ? wellKnownPropertyPids.get : wellKnownPropertyPids.set, isStatic,
  6686. &memberNameHintLength, &memberNameOffset, isComputedName, pMemberNameHint);
  6687. }
  6688. }
  6689. else
  6690. {
  6691. if (isStatic && (memberPid == wellKnownPropertyPids.prototype))
  6692. {
  6693. Error(ERRsyntax);
  6694. }
  6695. ParseNodeFnc * pnodeFnc = nullptr;
  6696. {
  6697. if (isAsyncMethod)
  6698. {
  6699. fncDeclFlags |= fFncAsync;
  6700. }
  6701. pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(fncDeclFlags, SuperRestrictionState::PropertyAllowed, pidHint ? pidHint->Psz() : nullptr, /* needsPIDOnRCurlyScan */ true);
  6702. if (isAsyncMethod)
  6703. {
  6704. pnodeFnc->cbMin = iecpMin;
  6705. pnodeFnc->ichMin = ichMin;
  6706. }
  6707. if (isAsyncMethod || isGenerator || isComputedName)
  6708. {
  6709. pnodeFnc->cbStringMin = iecpMin;
  6710. }
  6711. }
  6712. pnodeFnc->SetIsStaticMember(isStatic);
  6713. if (isComputedName)
  6714. {
  6715. pnodeFnc->SetHasComputedName();
  6716. }
  6717. pnodeFnc->SetHasHomeObj();
  6718. if (buildAST)
  6719. {
  6720. pnodeMember = CreateBinNode(knopMember, pnodeMemberName, pnodeFnc);
  6721. pMemberNameHint = ConstructFinalHintNode(pClassNamePid, pidHint, nullptr /*pgetset*/, isStatic, &memberNameHintLength, &memberNameOffset, isComputedName, pMemberNameHint);
  6722. }
  6723. }
  6724. if (buildAST)
  6725. {
  6726. Assert(memberNameHintLength >= memberNameOffset);
  6727. pnodeMember->AsParseNodeBin()->pnode2->AsParseNodeFnc()->hint = pMemberNameHint; // Fully qualified name
  6728. pnodeMember->AsParseNodeBin()->pnode2->AsParseNodeFnc()->hintLength = memberNameHintLength;
  6729. pnodeMember->AsParseNodeBin()->pnode2->AsParseNodeFnc()->hintOffset = memberNameOffset;
  6730. pnodeMember->AsParseNodeBin()->pnode2->AsParseNodeFnc()->pid = memberPid; // Short name
  6731. AddToNodeList(isStatic ? &pnodeStaticMembers : &pnodeMembers, isStatic ? &lastStaticMemberNodeRef : &lastMemberNodeRef, pnodeMember);
  6732. }
  6733. }
  6734. }
  6735. size_t cbLimConstructor = 0;
  6736. if (buildAST)
  6737. {
  6738. pnodeClass->ichLim = this->GetScanner()->IchLimTok();
  6739. cbLimConstructor = this->GetScanner()->IecpLimTok();
  6740. }
  6741. if (!hasConstructor)
  6742. {
  6743. OUTPUT_TRACE_DEBUGONLY(Js::ES6VerboseFlag, _u("Generating constructor (%s) : %s\n"), GetParseType(), name ? name->Psz() : _u("anonymous class"));
  6744. RestorePoint endClass;
  6745. this->GetScanner()->Capture(&endClass);
  6746. this->GetScanner()->SeekTo(beginClass);
  6747. pnodeConstructor = GenerateEmptyConstructor<buildAST>(pnodeExtends != nullptr);
  6748. if (buildAST)
  6749. {
  6750. if (pClassNamePid)
  6751. {
  6752. pnodeConstructor->hint = pClassNamePid->Psz();
  6753. pnodeConstructor->hintLength = pClassNamePid->Cch();
  6754. pnodeConstructor->hintOffset = 0;
  6755. }
  6756. else
  6757. {
  6758. Assert(nameHintLength >= nameHintOffset);
  6759. pnodeConstructor->hint = pNameHint;
  6760. pnodeConstructor->hintLength = nameHintLength;
  6761. pnodeConstructor->hintOffset = nameHintOffset;
  6762. }
  6763. pnodeConstructor->pid = pClassNamePid;
  6764. }
  6765. this->GetScanner()->SeekTo(endClass);
  6766. }
  6767. if (buildAST)
  6768. {
  6769. pnodeConstructor->cbMin = cbMinConstructor;
  6770. pnodeConstructor->cbStringMin = cbMinConstructor;
  6771. pnodeConstructor->cbLim = cbLimConstructor;
  6772. pnodeConstructor->ichMin = pnodeClass->ichMin;
  6773. pnodeConstructor->ichLim = pnodeClass->ichLim;
  6774. PopFuncBlockScope(ppnodeScopeSave, ppnodeExprScopeSave);
  6775. pnodeClass->pnodeDeclName = pnodeDeclName;
  6776. pnodeClass->pnodeName = pnodeName;
  6777. pnodeClass->pnodeConstructor = pnodeConstructor;
  6778. pnodeClass->pnodeExtends = pnodeExtends;
  6779. pnodeClass->pnodeMembers = pnodeMembers;
  6780. pnodeClass->pnodeStaticMembers = pnodeStaticMembers;
  6781. pnodeClass->isDefaultModuleExport = false;
  6782. }
  6783. FinishParseBlock(pnodeBlock);
  6784. m_fUseStrictMode = strictSave;
  6785. this->GetScanner()->Scan();
  6786. return pnodeClass;
  6787. }
  6788. template<bool buildAST>
  6789. ParseNodePtr Parser::ParseStringTemplateDecl(ParseNodePtr pnodeTagFnc)
  6790. {
  6791. ParseNodePtr pnodeStringLiterals = nullptr;
  6792. ParseNodePtr* lastStringLiteralNodeRef = nullptr;
  6793. ParseNodePtr pnodeRawStringLiterals = nullptr;
  6794. ParseNodePtr* lastRawStringLiteralNodeRef = nullptr;
  6795. ParseNodePtr pnodeSubstitutionExpressions = nullptr;
  6796. ParseNodePtr* lastSubstitutionExpressionNodeRef = nullptr;
  6797. ParseNodePtr pnodeTagFncArgs = nullptr;
  6798. ParseNodePtr* lastTagFncArgNodeRef = nullptr;
  6799. ParseNodeStr * stringLiteral = nullptr;
  6800. ParseNodeStr * stringLiteralRaw = nullptr;
  6801. ParseNodeStrTemplate * pnodeStringTemplate = nullptr;
  6802. ParseNode * pnodeReturn = nullptr;
  6803. bool templateClosed = false;
  6804. const bool isTagged = pnodeTagFnc != nullptr;
  6805. uint16 stringConstantCount = 0;
  6806. charcount_t ichMin = 0;
  6807. Assert(m_token.tk == tkStrTmplBasic || m_token.tk == tkStrTmplBegin);
  6808. if (buildAST)
  6809. {
  6810. pnodeReturn = pnodeStringTemplate = CreateNodeForOpT<knopStrTemplate>();
  6811. pnodeStringTemplate->countStringLiterals = 0;
  6812. pnodeStringTemplate->isTaggedTemplate = isTagged ? TRUE : FALSE;
  6813. // If this is a tagged string template, we need to start building the arg list for the call
  6814. if (isTagged)
  6815. {
  6816. ichMin = pnodeTagFnc->ichMin;
  6817. AddToNodeListEscapedUse(&pnodeTagFncArgs, &lastTagFncArgNodeRef, pnodeStringTemplate);
  6818. }
  6819. }
  6820. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, StringTemplates, m_scriptContext);
  6821. OUTPUT_TRACE_DEBUGONLY(
  6822. Js::StringTemplateParsePhase,
  6823. _u("Starting to parse a string template (%s)...\n\tis tagged = %s\n"),
  6824. GetParseType(),
  6825. isTagged ? _u("true") : _u("false (Raw and cooked strings will not differ!)"));
  6826. // String template grammar
  6827. // `...` Simple string template
  6828. // `...${ String template beginning
  6829. // }...${ String template middle
  6830. // }...` String template end
  6831. while (!templateClosed)
  6832. {
  6833. // First, extract the string constant part - we always have one
  6834. if (IsStrictMode() && this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
  6835. {
  6836. Error(ERRES5NoOctal);
  6837. }
  6838. // We are not able to pass more than a ushort worth of arguments to the tag
  6839. // so use that as a logical limit on the number of string constant pieces.
  6840. if (stringConstantCount >= Js::Constants::MaxAllowedArgs)
  6841. {
  6842. Error(ERRTooManyArgs);
  6843. }
  6844. // Keep track of the string literal count (must be the same for raw strings)
  6845. // We use this in code gen so we don't need to count the string literals list
  6846. stringConstantCount++;
  6847. // If we are not creating parse nodes, there is no need to create strings
  6848. if (buildAST)
  6849. {
  6850. stringLiteral = CreateStrNode(m_token.GetStr());
  6851. AddToNodeList(&pnodeStringLiterals, &lastStringLiteralNodeRef, stringLiteral);
  6852. // We only need to collect a raw string when we are going to pass the string template to a tag
  6853. if (isTagged)
  6854. {
  6855. // Make the scanner create a PID for the raw string constant for the preceding scan
  6856. IdentPtr pid = this->GetScanner()->GetSecondaryBufferAsPid();
  6857. stringLiteralRaw = CreateStrNode(pid);
  6858. // Should have gotten a raw string literal above
  6859. AddToNodeList(&pnodeRawStringLiterals, &lastRawStringLiteralNodeRef, stringLiteralRaw);
  6860. }
  6861. else
  6862. {
  6863. #if DBG
  6864. // Assign the raw string for debug tracing below
  6865. stringLiteralRaw = stringLiteral;
  6866. #endif
  6867. }
  6868. OUTPUT_TRACE_DEBUGONLY(
  6869. Js::StringTemplateParsePhase,
  6870. _u("Parsed string constant: \n\tcooked = \"%s\" \n\traw = \"%s\" \n\tdiffer = %d\n"),
  6871. stringLiteral->pid->Psz(),
  6872. stringLiteralRaw->pid->Psz(),
  6873. stringLiteral->pid->Psz() == stringLiteralRaw->pid->Psz() ? 0 : 1);
  6874. }
  6875. switch (m_token.tk)
  6876. {
  6877. case tkStrTmplEnd:
  6878. case tkStrTmplBasic:
  6879. // We do not need to parse an expression for either the end or basic string template tokens
  6880. templateClosed = true;
  6881. break;
  6882. case tkStrTmplBegin:
  6883. case tkStrTmplMid:
  6884. {
  6885. // In the middle or begin string template token case, we need to parse an expression next
  6886. this->GetScanner()->Scan();
  6887. // Parse the contents of the curly braces as an expression
  6888. ParseNodePtr expression = ParseExpr<buildAST>(0);
  6889. // After parsing expression, scan should leave us with an RCurly token.
  6890. // Use the NoScan version so we do not automatically perform a scan - we need to
  6891. // set the scan state before next scan but we don't want to set that state if
  6892. // the token is not as expected since we'll error in that case.
  6893. ChkCurTokNoScan(tkRCurly, ERRnoRcurly);
  6894. // Notify the scanner that it should scan for a middle or end string template token
  6895. this->GetScanner()->SetScanState(Scanner_t::ScanState::ScanStateStringTemplateMiddleOrEnd);
  6896. this->GetScanner()->Scan();
  6897. if (buildAST)
  6898. {
  6899. // If we are going to call the tag function, add this expression into the list of args
  6900. if (isTagged)
  6901. {
  6902. AddToNodeListEscapedUse(&pnodeTagFncArgs, &lastTagFncArgNodeRef, expression);
  6903. }
  6904. else
  6905. {
  6906. // Otherwise add it to the substitution expression list
  6907. // TODO: Store the arguments and substitution expressions in a single list?
  6908. AddToNodeList(&pnodeSubstitutionExpressions, &lastSubstitutionExpressionNodeRef, expression);
  6909. }
  6910. }
  6911. if (!(m_token.tk == tkStrTmplMid || m_token.tk == tkStrTmplEnd))
  6912. {
  6913. // Scan with ScanState ScanStateStringTemplateMiddleOrEnd should only return
  6914. // tkStrTmpMid/End unless it is EOF or tkScanError
  6915. Assert(m_token.tk == tkEOF || m_token.tk == tkScanError);
  6916. Error(ERRsyntax);
  6917. }
  6918. OUTPUT_TRACE_DEBUGONLY(Js::StringTemplateParsePhase, _u("Parsed expression\n"));
  6919. }
  6920. break;
  6921. default:
  6922. Assert(false);
  6923. break;
  6924. }
  6925. }
  6926. if (buildAST)
  6927. {
  6928. pnodeStringTemplate->pnodeStringLiterals = pnodeStringLiterals;
  6929. pnodeStringTemplate->pnodeStringRawLiterals = pnodeRawStringLiterals;
  6930. pnodeStringTemplate->pnodeSubstitutionExpressions = pnodeSubstitutionExpressions;
  6931. pnodeStringTemplate->countStringLiterals = stringConstantCount;
  6932. // We should still have the last string literal.
  6933. // Use the char offset of the end of that constant as the end of the string template.
  6934. pnodeStringTemplate->ichLim = stringLiteral->ichLim;
  6935. // If this is a tagged template, we now have the argument list and can construct a call node
  6936. if (isTagged)
  6937. {
  6938. // Return the call node here and let the byte code generator Emit the string template automagically
  6939. ParseNodeCall * pnodeCall;
  6940. pnodeReturn = pnodeCall = CreateCallNode(knopCall, pnodeTagFnc, pnodeTagFncArgs, ichMin, pnodeStringTemplate->ichLim);
  6941. // We need to set the arg count explicitly
  6942. pnodeCall->argCount = stringConstantCount;
  6943. pnodeCall->hasDestructuring = m_hasDestructuringPattern;
  6944. }
  6945. }
  6946. this->GetScanner()->Scan();
  6947. return pnodeReturn;
  6948. }
  6949. LPCOLESTR Parser::FormatPropertyString(LPCOLESTR propertyString, ParseNodePtr pNode, uint32 *fullNameHintLength, uint32 *pShortNameOffset)
  6950. {
  6951. // propertyString could be null, such as 'this.foo' =
  6952. // propertyString could be empty, found in pattern as in (-1)[""][(x = z)]
  6953. OpCode op = pNode->nop;
  6954. LPCOLESTR rightNode = nullptr;
  6955. if (propertyString == nullptr)
  6956. {
  6957. propertyString = _u("");
  6958. }
  6959. if (op != knopInt && op != knopFlt && op != knopName && op != knopStr)
  6960. {
  6961. rightNode = _u("");
  6962. }
  6963. else if (op == knopStr)
  6964. {
  6965. return AppendNameHints(propertyString, pNode->AsParseNodeStr()->pid, fullNameHintLength, pShortNameOffset, false, true/*add brackets*/);
  6966. }
  6967. else if (op == knopFlt)
  6968. {
  6969. rightNode = this->GetScanner()->StringFromDbl(pNode->AsParseNodeFloat()->dbl);
  6970. }
  6971. else
  6972. {
  6973. rightNode = op == knopInt ? this->GetScanner()->StringFromLong(pNode->AsParseNodeInt()->lw)
  6974. : pNode->AsParseNodeName()->pid->Psz();
  6975. }
  6976. return AppendNameHints(propertyString, rightNode, fullNameHintLength, pShortNameOffset, false, true/*add brackets*/);
  6977. }
  6978. LPCOLESTR Parser::ConstructNameHint(ParseNodeBin * pNode, uint32* fullNameHintLength, uint32 *pShortNameOffset)
  6979. {
  6980. Assert(pNode != nullptr);
  6981. Assert(pNode->nop == knopDot || pNode->nop == knopIndex);
  6982. // This method recursively visits nodes in the AST and could cause an SOE crash for long knopDot chains.
  6983. // Although this method could be made non-recursive, Emit (ByteCodeEmitter.cpp) hits a stack probe
  6984. // for shorter chains than which cause SOE here, so add a stack probe to throw SOE rather than crash on SOE.
  6985. // Because of that correspondence, use Js::Constants::MinStackByteCodeVisitor (which is used in Emit)
  6986. // for the stack probe here. See OS#14711878.
  6987. PROBE_STACK_NO_DISPOSE(this->m_scriptContext, Js::Constants::MinStackByteCodeVisitor);
  6988. LPCOLESTR leftNode = nullptr;
  6989. if (pNode->pnode1->nop == knopDot || pNode->pnode1->nop == knopIndex)
  6990. {
  6991. leftNode = ConstructNameHint(pNode->pnode1->AsParseNodeBin(), fullNameHintLength, pShortNameOffset);
  6992. }
  6993. else if (pNode->pnode1->nop == knopName && !pNode->pnode1->AsParseNodeName()->IsSpecialName())
  6994. {
  6995. // We need to skip special names like 'this' because those shouldn't be appended to the
  6996. // name hint in the debugger stack trace.
  6997. // function ctor() {
  6998. // this.func = function() {
  6999. // // If we break here, the stack should say we are in 'func' and not 'this.func'
  7000. // }
  7001. // }
  7002. IdentPtr pid = pNode->pnode1->AsParseNodeName()->pid;
  7003. leftNode = pid->Psz();
  7004. *fullNameHintLength = pid->Cch();
  7005. *pShortNameOffset = 0;
  7006. }
  7007. if (pNode->nop == knopIndex)
  7008. {
  7009. return FormatPropertyString(
  7010. leftNode ? leftNode : Js::Constants::AnonymousFunction, // e.g. f()[0] = function () {}
  7011. pNode->pnode2, fullNameHintLength, pShortNameOffset);
  7012. }
  7013. Assert(pNode->pnode2->nop == knopDot || pNode->pnode2->nop == knopName);
  7014. LPCOLESTR rightNode = nullptr;
  7015. bool wrapWithBrackets = false;
  7016. if (pNode->pnode2->nop == knopDot)
  7017. {
  7018. rightNode = ConstructNameHint(pNode->pnode2->AsParseNodeBin(), fullNameHintLength, pShortNameOffset);
  7019. }
  7020. else
  7021. {
  7022. rightNode = pNode->pnode2->AsParseNodeName()->pid->Psz();
  7023. wrapWithBrackets = PNodeFlags::fpnIndexOperator == (pNode->grfpn & PNodeFlags::fpnIndexOperator);
  7024. }
  7025. Assert(rightNode != nullptr);
  7026. return AppendNameHints(leftNode, rightNode, fullNameHintLength, pShortNameOffset, false, wrapWithBrackets);
  7027. }
  7028. LPCOLESTR Parser::AppendNameHints(LPCOLESTR leftStr, uint32 leftLen, LPCOLESTR rightStr, uint32 rightLen, uint32 *pNameLength, uint32 *pShortNameOffset, bool ignoreAddDotWithSpace, bool wrapInBrackets)
  7029. {
  7030. Assert(rightStr != nullptr);
  7031. Assert(leftLen != 0 || wrapInBrackets);
  7032. Assert(rightLen != 0 || wrapInBrackets);
  7033. bool ignoreDot = rightStr[0] == _u('[') && !wrapInBrackets;//if we wrap in brackets it can be a string literal which can have brackets at the first char
  7034. uint32 totalLength = leftLen + rightLen + ((ignoreDot) ? 1 : 2); // 1 (for dot or [) + 1 (for null termination)
  7035. if (wrapInBrackets)
  7036. {
  7037. totalLength++; //1 for ']';
  7038. }
  7039. WCHAR * finalName = AllocateStringOfLength(totalLength);
  7040. if (leftStr != nullptr && leftLen != 0)
  7041. {
  7042. wcscpy_s(finalName, leftLen + 1, leftStr);
  7043. }
  7044. if (ignoreAddDotWithSpace)
  7045. {
  7046. finalName[leftLen++] = (OLECHAR)_u(' ');
  7047. }
  7048. // mutually exclusive from ignoreAddDotWithSpace which is used for getters/setters
  7049. else if (wrapInBrackets)
  7050. {
  7051. finalName[leftLen++] = (OLECHAR)_u('[');
  7052. finalName[totalLength - 2] = (OLECHAR)_u(']');
  7053. }
  7054. else if (!ignoreDot)
  7055. {
  7056. finalName[leftLen++] = (OLECHAR)_u('.');
  7057. }
  7058. //ignore case falls through
  7059. js_wmemcpy_s(finalName + leftLen, rightLen, rightStr, rightLen);
  7060. finalName[totalLength - 1] = (OLECHAR)_u('\0');
  7061. if (pNameLength != nullptr)
  7062. {
  7063. *pNameLength = totalLength - 1;
  7064. }
  7065. if (pShortNameOffset != nullptr)
  7066. {
  7067. *pShortNameOffset = leftLen;
  7068. }
  7069. return finalName;
  7070. }
  7071. WCHAR * Parser::AllocateStringOfLength(ULONG length)
  7072. {
  7073. Assert(length > 0);
  7074. ULONG totalBytes;
  7075. if (ULongMult(length, sizeof(OLECHAR), &totalBytes) != S_OK)
  7076. {
  7077. Error(ERRnoMemory);
  7078. }
  7079. WCHAR* finalName = (WCHAR*)this->GetHashTbl()->GetAllocator()->Alloc(totalBytes);
  7080. if (finalName == nullptr)
  7081. {
  7082. Error(ERRnoMemory);
  7083. }
  7084. return finalName;
  7085. }
  7086. LPCOLESTR Parser::AppendNameHints(IdentPtr left, IdentPtr right, uint32 *pNameLength, uint32 *pShortNameOffset, bool ignoreAddDotWithSpace, bool wrapInBrackets)
  7087. {
  7088. if (pShortNameOffset != nullptr)
  7089. {
  7090. *pShortNameOffset = 0;
  7091. }
  7092. if (left == nullptr && !wrapInBrackets)
  7093. {
  7094. if (right)
  7095. {
  7096. *pNameLength = right->Cch();
  7097. return right->Psz();
  7098. }
  7099. return nullptr;
  7100. }
  7101. uint32 leftLen = 0;
  7102. LPCOLESTR leftStr = _u("");
  7103. if (left != nullptr) // if wrapInBrackets is true
  7104. {
  7105. leftStr = left->Psz();
  7106. leftLen = left->Cch();
  7107. }
  7108. if (right == nullptr)
  7109. {
  7110. *pNameLength = leftLen;
  7111. return left->Psz();
  7112. }
  7113. uint32 rightLen = right->Cch();
  7114. return AppendNameHints(leftStr, leftLen, right->Psz(), rightLen, pNameLength, pShortNameOffset, ignoreAddDotWithSpace, wrapInBrackets);
  7115. }
  7116. LPCOLESTR Parser::AppendNameHints(IdentPtr left, LPCOLESTR right, uint32 *pNameLength, uint32 *pShortNameOffset, bool ignoreAddDotWithSpace, bool wrapInBrackets)
  7117. {
  7118. uint32 rightLen = (right == nullptr) ? 0 : (uint32)wcslen(right);
  7119. if (pShortNameOffset != nullptr)
  7120. {
  7121. *pShortNameOffset = 0;
  7122. }
  7123. Assert(rightLen <= ULONG_MAX); // name hints should not exceed ULONG_MAX characters
  7124. if (left == nullptr && !wrapInBrackets)
  7125. {
  7126. *pNameLength = rightLen;
  7127. return right;
  7128. }
  7129. LPCOLESTR leftStr = _u("");
  7130. uint32 leftLen = 0;
  7131. if (left != nullptr) // if wrapInBrackets is true
  7132. {
  7133. leftStr = left->Psz();
  7134. leftLen = left->Cch();
  7135. }
  7136. if (rightLen == 0 && !wrapInBrackets)
  7137. {
  7138. *pNameLength = leftLen;
  7139. return left->Psz();
  7140. }
  7141. return AppendNameHints(leftStr, leftLen, right, rightLen, pNameLength, pShortNameOffset, ignoreAddDotWithSpace, wrapInBrackets);
  7142. }
  7143. LPCOLESTR Parser::AppendNameHints(LPCOLESTR left, IdentPtr right, uint32 *pNameLength, uint32 *pShortNameOffset, bool ignoreAddDotWithSpace, bool wrapInBrackets)
  7144. {
  7145. uint32 leftLen = (left == nullptr) ? 0 : (uint32)wcslen(left);
  7146. if (pShortNameOffset != nullptr)
  7147. {
  7148. *pShortNameOffset = 0;
  7149. }
  7150. Assert(leftLen <= ULONG_MAX); // name hints should not exceed ULONG_MAX characters
  7151. if (left == nullptr || (leftLen == 0 && !wrapInBrackets))
  7152. {
  7153. if (right != nullptr)
  7154. {
  7155. *pNameLength = right->Cch();
  7156. return right->Psz();
  7157. }
  7158. return nullptr;
  7159. }
  7160. if (right == nullptr)
  7161. {
  7162. *pNameLength = leftLen;
  7163. return left;
  7164. }
  7165. uint32 rightLen = right->Cch();
  7166. return AppendNameHints(left, leftLen, right->Psz(), rightLen, pNameLength, pShortNameOffset, ignoreAddDotWithSpace, wrapInBrackets);
  7167. }
  7168. LPCOLESTR Parser::AppendNameHints(LPCOLESTR left, LPCOLESTR right, uint32 *pNameLength, uint32 *pShortNameOffset, bool ignoreAddDotWithSpace, bool wrapInBrackets)
  7169. {
  7170. uint32 leftLen = (left == nullptr) ? 0 : (uint32)wcslen(left);
  7171. uint32 rightLen = (right == nullptr) ? 0 : (uint32)wcslen(right);
  7172. if (pShortNameOffset != nullptr)
  7173. {
  7174. *pShortNameOffset = 0;
  7175. }
  7176. Assert(rightLen <= ULONG_MAX && leftLen <= ULONG_MAX); // name hints should not exceed ULONG_MAX characters
  7177. if (leftLen == 0 && !wrapInBrackets)
  7178. {
  7179. *pNameLength = right ? rightLen : 0;
  7180. return right;
  7181. }
  7182. if (rightLen == 0 && !wrapInBrackets)
  7183. {
  7184. *pNameLength = leftLen;
  7185. return left;
  7186. }
  7187. return AppendNameHints(left, leftLen, right, rightLen, pNameLength, pShortNameOffset, ignoreAddDotWithSpace, wrapInBrackets);
  7188. }
  7189. /**
  7190. * Emits a spread error if there is no ambiguity, or marks defers the error for
  7191. * when we can determine if it is a rest error or a spread error.
  7192. *
  7193. * The ambiguity arises when we are parsing a lambda parameter list but we have
  7194. * not seen the => token. At this point, we are either in a parenthesized
  7195. * expression or a parameter list, and cannot issue an error until the matching
  7196. * RParen has been scanned.
  7197. *
  7198. * The actual emission of the error happens in ParseExpr, when we first know if
  7199. * the expression is a lambda parameter list or not.
  7200. *
  7201. */
  7202. void Parser::DeferOrEmitPotentialSpreadError(ParseNodePtr pnodeT)
  7203. {
  7204. if (m_funcParenExprDepth > 0)
  7205. {
  7206. if (m_token.tk == tkRParen)
  7207. {
  7208. if (!m_deferEllipsisError)
  7209. {
  7210. // Capture only the first error instance. Because a lambda will cause a reparse in a formals context, we can assume
  7211. // that this will be a spread error. Nested paren exprs will have their own error instance.
  7212. this->GetScanner()->Capture(&m_deferEllipsisErrorLoc);
  7213. m_deferEllipsisError = true;
  7214. }
  7215. }
  7216. else
  7217. {
  7218. Error(ERRUnexpectedEllipsis);
  7219. }
  7220. }
  7221. else
  7222. {
  7223. Error(ERRInvalidSpreadUse);
  7224. }
  7225. }
  7226. bool Parser::IsTerminateToken(bool fAllowIn)
  7227. {
  7228. return (m_token.tk == tkRCurly ||
  7229. m_token.tk == tkRBrack ||
  7230. m_token.tk == tkRParen ||
  7231. m_token.tk == tkSColon ||
  7232. m_token.tk == tkColon ||
  7233. m_token.tk == tkComma ||
  7234. m_token.tk == tkLimKwd ||
  7235. (m_token.tk == tkIN && fAllowIn) ||
  7236. this->GetScanner()->FHadNewLine());
  7237. }
  7238. /***************************************************************************
  7239. Parse an optional sub expression returning null if there was no expression.
  7240. Checks for no expression by looking for a token that can follow an
  7241. Expression grammar production.
  7242. ***************************************************************************/
  7243. template<bool buildAST>
  7244. bool Parser::ParseOptionalExpr(ParseNodePtr* pnode, bool fUnaryOrParen, int oplMin, BOOL *pfCanAssign, BOOL fAllowIn, BOOL fAllowEllipsis, _Inout_opt_ IdentToken* pToken)
  7245. {
  7246. *pnode = nullptr;
  7247. if (IsTerminateToken(!fAllowIn))
  7248. {
  7249. return false;
  7250. }
  7251. IdentToken token;
  7252. ParseNodePtr pnodeT = ParseExpr<buildAST>(oplMin, pfCanAssign, fAllowIn, fAllowEllipsis, nullptr /*pNameHint*/, nullptr /*pHintLength*/, nullptr /*pShortNameOffset*/, &token, fUnaryOrParen);
  7253. // Detect nested function escapes of the pattern "return function(){...}" or "yield function(){...}".
  7254. // Doing so in the parser allows us to disable stack-nested-functions in common cases where an escape
  7255. // is not detected at byte code gen time because of deferred parsing.
  7256. this->MarkEscapingRef(pnodeT, &token);
  7257. if (pToken)
  7258. {
  7259. *pToken = token;
  7260. }
  7261. *pnode = pnodeT;
  7262. return true;
  7263. }
  7264. /***************************************************************************
  7265. Parse a sub expression.
  7266. 'fAllowIn' indicates if the 'in' operator should be allowed in the initializing
  7267. expression ( it is not allowed in the context of the first expression in a 'for' loop).
  7268. ***************************************************************************/
  7269. template<bool buildAST>
  7270. ParseNodePtr Parser::ParseExpr(int oplMin,
  7271. BOOL *pfCanAssign,
  7272. BOOL fAllowIn,
  7273. BOOL fAllowEllipsis,
  7274. LPCOLESTR pNameHint,
  7275. uint32 *pHintLength,
  7276. uint32 *pShortNameOffset,
  7277. _Inout_opt_ IdentToken* pToken,
  7278. bool fUnaryOrParen,
  7279. _Inout_opt_ bool* pfLikelyPattern,
  7280. _Inout_opt_ charcount_t *plastRParen)
  7281. {
  7282. Assert(pToken == nullptr || pToken->tk == tkNone); // Must be empty initially
  7283. int opl;
  7284. OpCode nop;
  7285. charcount_t ichMin;
  7286. ParseNodePtr pnode = nullptr;
  7287. ParseNodePtr pnodeT = nullptr;
  7288. BOOL fCanAssign = TRUE;
  7289. bool assignmentStmt = false;
  7290. bool fIsDotOrIndex = false;
  7291. IdentToken term;
  7292. RestorePoint termStart;
  7293. uint32 hintLength = 0;
  7294. uint32 hintOffset = 0;
  7295. BOOL fLikelyPattern = FALSE;
  7296. ParserState parserState;
  7297. if (pHintLength != nullptr)
  7298. {
  7299. hintLength = *pHintLength;
  7300. }
  7301. if (pShortNameOffset != nullptr)
  7302. {
  7303. hintOffset = *pShortNameOffset;
  7304. }
  7305. EnsureStackAvailable();
  7306. // Storing the state here as we need to restore this state back when we need to reparse the grammar under lambda syntax.
  7307. CaptureState(&parserState);
  7308. this->GetScanner()->Capture(&termStart);
  7309. bool savedDeferredInitError = m_hasDeferredShorthandInitError;
  7310. m_hasDeferredShorthandInitError = false;
  7311. // Is the current token a unary operator?
  7312. if (this->GetHashTbl()->TokIsUnop(m_token.tk, &opl, &nop) && nop != knopNone)
  7313. {
  7314. IdentToken operandToken;
  7315. ichMin = this->GetScanner()->IchMinTok();
  7316. if (nop == knopYield)
  7317. {
  7318. if (!this->GetScanner()->YieldIsKeywordRegion() || oplMin > opl)
  7319. {
  7320. // The case where 'yield' is scanned as a keyword (tkYIELD) but the scanner
  7321. // is not treating yield as a keyword (!this->GetScanner()->YieldIsKeywordRegion()) occurs
  7322. // in strict mode non-generator function contexts.
  7323. //
  7324. // That is, 'yield' is a keyword because of strict mode, but YieldExpression
  7325. // is not a grammar production outside of generator functions.
  7326. //
  7327. // Otherwise it is an error for a yield to appear in the context of a higher level
  7328. // binding operator, be it unary or binary.
  7329. Error(ERRsyntax);
  7330. }
  7331. if (m_currentScope->GetScopeType() == ScopeType_Parameter
  7332. || (m_currentScope->GetScopeType() == ScopeType_Block && m_currentScope->GetEnclosingScope()->GetScopeType() == ScopeType_Parameter)) // Check whether this is a class definition inside param scope
  7333. {
  7334. Error(ERRsyntax);
  7335. }
  7336. }
  7337. else if (nop == knopAwait)
  7338. {
  7339. if (!this->GetScanner()->AwaitIsKeywordRegion() ||
  7340. m_currentScope->GetScopeType() == ScopeType_Parameter ||
  7341. (m_currentScope->GetScopeType() == ScopeType_Block && m_currentScope->GetEnclosingScope()->GetScopeType() == ScopeType_Parameter)) // Check whether this is a class definition inside param scope
  7342. {
  7343. // As with the 'yield' keyword, the case where 'await' is scanned as a keyword (tkAWAIT)
  7344. // but the scanner is not treating await as a keyword (!this->GetScanner()->AwaitIsKeyword())
  7345. // occurs in strict mode non-async function contexts.
  7346. //
  7347. // That is, 'await' is a keyword because of strict mode, but AwaitExpression
  7348. // is not a grammar production outside of async functions.
  7349. //
  7350. // Further, await expressions are disallowed within parameter scopes.
  7351. Error(ERRBadAwait);
  7352. }
  7353. }
  7354. this->GetScanner()->Scan();
  7355. if (m_token.tk == tkEllipsis) {
  7356. // ... cannot have a unary prefix.
  7357. Error(ERRUnexpectedEllipsis);
  7358. }
  7359. if (nop == knopYield && !this->GetScanner()->FHadNewLine() && m_token.tk == tkStar)
  7360. {
  7361. this->GetScanner()->Scan();
  7362. nop = knopYieldStar;
  7363. }
  7364. if (nop == knopYield)
  7365. {
  7366. if (!ParseOptionalExpr<buildAST>(&pnodeT, false, opl, NULL, fAllowIn, fAllowEllipsis))
  7367. {
  7368. nop = knopYieldLeaf;
  7369. if (buildAST)
  7370. {
  7371. pnode = CreateNodeForOpT<knopYieldLeaf>(ichMin, this->GetScanner()->IchLimTok());
  7372. }
  7373. }
  7374. }
  7375. else if (nop == knopAwait && m_token.tk == tkColon)
  7376. {
  7377. Error(ERRAwaitAsLabelInAsync);
  7378. }
  7379. else
  7380. {
  7381. // Disallow spread after a unary operator.
  7382. pnodeT = ParseExpr<buildAST>(opl, &fCanAssign, TRUE, FALSE, nullptr /*hint*/, nullptr /*hintLength*/, nullptr /*hintOffset*/, &operandToken, true, nullptr, plastRParen);
  7383. }
  7384. if (nop != knopYieldLeaf)
  7385. {
  7386. if ((nop == knopIncPre || nop == knopDecPre) && (m_token.tk != tkDArrow))
  7387. {
  7388. if (!fCanAssign &&
  7389. (m_sourceContextInfo
  7390. ? !PHASE_OFF_RAW(Js::EarlyReferenceErrorsPhase, m_sourceContextInfo->sourceContextId, GetCurrentFunctionNode()->functionId)
  7391. : !PHASE_OFF1(Js::EarlyReferenceErrorsPhase)))
  7392. {
  7393. Error(JSERR_CantAssignTo);
  7394. }
  7395. TrackAssignment<buildAST>(pnodeT, &operandToken);
  7396. if (buildAST)
  7397. {
  7398. if (IsStrictMode() && pnodeT->nop == knopName)
  7399. {
  7400. CheckStrictModeEvalArgumentsUsage(pnodeT->AsParseNodeName()->pid);
  7401. }
  7402. }
  7403. else
  7404. {
  7405. if (IsStrictMode() && operandToken.tk == tkID)
  7406. {
  7407. CheckStrictModeEvalArgumentsUsage(operandToken.pid);
  7408. }
  7409. }
  7410. }
  7411. else if (nop == knopEllipsis)
  7412. {
  7413. if (!fAllowEllipsis)
  7414. {
  7415. DeferOrEmitPotentialSpreadError(pnodeT);
  7416. }
  7417. }
  7418. else if (m_token.tk == tkExpo)
  7419. {
  7420. //Unary operator on the left hand-side of ** is unexpected, except ++, -- or ...
  7421. Error(ERRInvalidUseofExponentiationOperator);
  7422. }
  7423. if (buildAST)
  7424. {
  7425. //Do not do the folding for Asm in case of KnopPos as we need this to determine the type
  7426. if (nop == knopPos && (pnodeT->nop == knopInt || pnodeT->nop == knopFlt) && !this->m_InAsmMode)
  7427. {
  7428. // Fold away a unary '+' on a number.
  7429. pnode = pnodeT;
  7430. }
  7431. else if (nop == knopNeg &&
  7432. ((pnodeT->nop == knopInt && pnodeT->AsParseNodeInt()->lw != 0) ||
  7433. (pnodeT->nop == knopFlt && (pnodeT->AsParseNodeFloat()->dbl != 0 || this->m_InAsmMode))))
  7434. {
  7435. // Fold a unary '-' on a number into the value of the number itself.
  7436. pnode = pnodeT;
  7437. if (pnode->nop == knopInt)
  7438. {
  7439. pnode->AsParseNodeInt()->lw = -pnode->AsParseNodeInt()->lw;
  7440. }
  7441. else
  7442. {
  7443. pnode->AsParseNodeFloat()->dbl = -pnode->AsParseNodeFloat()->dbl;
  7444. }
  7445. }
  7446. else
  7447. {
  7448. pnode = CreateUniNode(nop, pnodeT);
  7449. this->CheckArguments(pnode->AsParseNodeUni()->pnode1);
  7450. }
  7451. pnode->ichMin = ichMin;
  7452. }
  7453. if (nop == knopDelete)
  7454. {
  7455. if (IsStrictMode())
  7456. {
  7457. if ((buildAST && pnode->AsParseNodeUni()->pnode1->IsUserIdentifier()) ||
  7458. (!buildAST && operandToken.tk == tkID && !this->IsSpecialName(operandToken.pid)))
  7459. {
  7460. Error(ERRInvalidDelete);
  7461. }
  7462. }
  7463. if (buildAST)
  7464. {
  7465. ParseNodePtr pnode1 = pnode->AsParseNodeUni()->pnode1;
  7466. if (m_currentNodeFunc)
  7467. {
  7468. if (pnode1->nop == knopDot || pnode1->nop == knopIndex)
  7469. {
  7470. // If we delete an arguments property, use the conservative,
  7471. // heap-allocated arguments object.
  7472. this->CheckArguments(pnode1->AsParseNodeBin()->pnode1);
  7473. }
  7474. }
  7475. }
  7476. }
  7477. }
  7478. fCanAssign = FALSE;
  7479. }
  7480. else
  7481. {
  7482. ichMin = this->GetScanner()->IchMinTok();
  7483. pnode = ParseTerm<buildAST>(TRUE, pNameHint, &hintLength, &hintOffset, &term, fUnaryOrParen, TRUE, &fCanAssign, IsES6DestructuringEnabled() ? &fLikelyPattern : nullptr, &fIsDotOrIndex, plastRParen);
  7484. if (pfLikelyPattern != nullptr)
  7485. {
  7486. *pfLikelyPattern = !!fLikelyPattern;
  7487. }
  7488. if (m_token.tk == tkDArrow
  7489. // If we have introduced shorthand error above in the ParseExpr, we need to reset if next token is the assignment.
  7490. || (m_token.tk == tkAsg && oplMin <= koplAsg))
  7491. {
  7492. m_hasDeferredShorthandInitError = false;
  7493. }
  7494. if (m_token.tk == tkAsg && oplMin <= koplAsg && fLikelyPattern)
  7495. {
  7496. this->GetScanner()->SeekTo(termStart);
  7497. // As we are reparsing from the beginning of the destructured literal we need to reset the Block IDs as well to make sure the Block IDs
  7498. // on the pidref stack match.
  7499. int saveNextBlockId = m_nextBlockId;
  7500. m_nextBlockId = parserState.m_nextBlockId;
  7501. ParseDestructuredLiteralWithScopeSave(tkLCurly, false/*isDecl*/, false /*topLevel*/, DIC_ShouldNotParseInitializer);
  7502. // Restore the Block ID at the end of the reparsing so it matches the one at the end of the first pass. We need to do this
  7503. // because we don't parse initializers during reparse and there may be additional blocks (e.g. a class declaration)
  7504. // in the initializers that will cause the next Block ID at the end of the reparsing to be different.
  7505. m_nextBlockId = saveNextBlockId;
  7506. if (buildAST)
  7507. {
  7508. this->SetHasDestructuringPattern(true);
  7509. pnode = ConvertToPattern(pnode);
  7510. }
  7511. }
  7512. if (buildAST)
  7513. {
  7514. pNameHint = NULL;
  7515. if (pnode->nop == knopName)
  7516. {
  7517. IdentPtr pid = pnode->AsParseNodeName()->pid;
  7518. pNameHint = pid->Psz();
  7519. hintLength = pid->Cch();
  7520. hintOffset = 0;
  7521. }
  7522. else if (pnode->nop == knopDot || pnode->nop == knopIndex)
  7523. {
  7524. if (CONFIG_FLAG(UseFullName))
  7525. {
  7526. pNameHint = ConstructNameHint(pnode->AsParseNodeBin(), &hintLength, &hintOffset);
  7527. }
  7528. else
  7529. {
  7530. ParseNodePtr pnodeName = pnode;
  7531. while (pnodeName->nop == knopDot)
  7532. {
  7533. pnodeName = pnodeName->AsParseNodeBin()->pnode2;
  7534. }
  7535. if (pnodeName->nop == knopName)
  7536. {
  7537. IdentPtr pid = pnode->AsParseNodeName()->pid;
  7538. pNameHint = pid->Psz();
  7539. hintLength = pid->Cch();
  7540. hintOffset = 0;
  7541. }
  7542. }
  7543. }
  7544. }
  7545. // Check for postfix unary operators.
  7546. if (!this->GetScanner()->FHadNewLine() &&
  7547. (tkInc == m_token.tk || tkDec == m_token.tk))
  7548. {
  7549. if (!fCanAssign &&
  7550. (m_sourceContextInfo
  7551. ? !PHASE_OFF_RAW(Js::EarlyReferenceErrorsPhase, m_sourceContextInfo->sourceContextId, GetCurrentFunctionNode()->functionId)
  7552. : !PHASE_OFF1(Js::EarlyReferenceErrorsPhase)))
  7553. {
  7554. Error(JSERR_CantAssignTo);
  7555. }
  7556. TrackAssignment<buildAST>(pnode, &term);
  7557. fCanAssign = FALSE;
  7558. if (buildAST)
  7559. {
  7560. if (IsStrictMode() && pnode->nop == knopName)
  7561. {
  7562. CheckStrictModeEvalArgumentsUsage(pnode->AsParseNodeName()->pid);
  7563. }
  7564. this->CheckArguments(pnode);
  7565. pnode = CreateUniNode(tkInc == m_token.tk ? knopIncPost : knopDecPost, pnode);
  7566. pnode->ichLim = this->GetScanner()->IchLimTok();
  7567. }
  7568. else
  7569. {
  7570. if (IsStrictMode() && term.tk == tkID)
  7571. {
  7572. CheckStrictModeEvalArgumentsUsage(term.pid);
  7573. }
  7574. // This expression is not an identifier
  7575. term.tk = tkNone;
  7576. }
  7577. this->GetScanner()->Scan();
  7578. }
  7579. }
  7580. // Process a sequence of operators and operands.
  7581. for (;;)
  7582. {
  7583. if (!this->GetHashTbl()->TokIsBinop(m_token.tk, &opl, &nop) || nop == knopNone)
  7584. {
  7585. break;
  7586. }
  7587. if (!fAllowIn && nop == knopIn)
  7588. {
  7589. break;
  7590. }
  7591. Assert(opl != koplNo);
  7592. if (opl == koplAsg)
  7593. {
  7594. if (m_token.tk != tkDArrow)
  7595. {
  7596. // Assignment operator. These are the only right associative
  7597. // binary operators. We also need to special case the left
  7598. // operand - it should only be a LeftHandSideExpression.
  7599. Assert(ParseNode::Grfnop(nop) & fnopAsg || nop == knopFncDecl);
  7600. TrackAssignment<buildAST>(pnode, &term);
  7601. if (buildAST)
  7602. {
  7603. if (IsStrictMode() && pnode->nop == knopName)
  7604. {
  7605. CheckStrictModeEvalArgumentsUsage(pnode->AsParseNodeName()->pid);
  7606. }
  7607. // Assignment stmt of the form "this.<id> = <expr>"
  7608. if (nop == knopAsg
  7609. && pnode->nop == knopDot
  7610. && pnode->AsParseNodeBin()->pnode1->nop == knopName
  7611. && pnode->AsParseNodeBin()->pnode1->AsParseNodeName()->pid == wellKnownPropertyPids._this
  7612. && pnode->AsParseNodeBin()->pnode2->nop == knopName)
  7613. {
  7614. if (pnode->AsParseNodeBin()->pnode2->AsParseNodeName()->pid != wellKnownPropertyPids.__proto__)
  7615. {
  7616. assignmentStmt = true;
  7617. }
  7618. }
  7619. }
  7620. else
  7621. {
  7622. if (IsStrictMode() && term.tk == tkID)
  7623. {
  7624. CheckStrictModeEvalArgumentsUsage(term.pid);
  7625. }
  7626. }
  7627. }
  7628. if (opl < oplMin)
  7629. {
  7630. break;
  7631. }
  7632. if (m_token.tk != tkDArrow && !fCanAssign &&
  7633. (m_sourceContextInfo
  7634. ? !PHASE_OFF_RAW(Js::EarlyReferenceErrorsPhase, m_sourceContextInfo->sourceContextId, GetCurrentFunctionNode()->functionId)
  7635. : !PHASE_OFF1(Js::EarlyReferenceErrorsPhase)))
  7636. {
  7637. Error(JSERR_CantAssignTo);
  7638. // No recovery necessary since this is a semantic, not structural, error.
  7639. }
  7640. }
  7641. else if (opl == koplExpo)
  7642. {
  7643. // ** operator is right associative
  7644. if (opl < oplMin)
  7645. {
  7646. break;
  7647. }
  7648. }
  7649. else if (opl <= oplMin)
  7650. {
  7651. break;
  7652. }
  7653. // This expression is not an identifier
  7654. term.tk = tkNone;
  7655. // Precedence is high enough. Consume the operator token.
  7656. this->GetScanner()->Scan();
  7657. fCanAssign = !!fLikelyPattern;
  7658. // Special case the "?:" operator
  7659. if (nop == knopQmark)
  7660. {
  7661. pnodeT = ParseExpr<buildAST>(koplAsg, NULL, fAllowIn);
  7662. ChkCurTok(tkColon, ERRnoColon);
  7663. ParseNodePtr pnodeT2 = ParseExpr<buildAST>(koplAsg, NULL, fAllowIn, 0, nullptr, nullptr, nullptr, nullptr, false, nullptr, plastRParen);
  7664. if (buildAST)
  7665. {
  7666. pnode = CreateTriNode(nop, pnode, pnodeT, pnodeT2);
  7667. this->CheckArguments(pnode->AsParseNodeTri()->pnode2);
  7668. this->CheckArguments(pnode->AsParseNodeTri()->pnode3);
  7669. }
  7670. }
  7671. else if (nop == knopFncDecl)
  7672. {
  7673. ushort flags = fFncLambda;
  7674. size_t iecpMin = 0;
  7675. bool isAsyncMethod = false;
  7676. RestoreStateFrom(&parserState);
  7677. this->GetScanner()->SeekTo(termStart);
  7678. if (m_token.tk == tkID && m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.async && m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
  7679. {
  7680. ichMin = this->GetScanner()->IchMinTok();
  7681. iecpMin = this->GetScanner()->IecpMinTok();
  7682. this->GetScanner()->Scan();
  7683. if ((m_token.tk == tkID || m_token.tk == tkLParen) && !this->GetScanner()->FHadNewLine())
  7684. {
  7685. flags |= fFncAsync;
  7686. isAsyncMethod = true;
  7687. }
  7688. else
  7689. {
  7690. this->GetScanner()->SeekTo(termStart);
  7691. }
  7692. }
  7693. pnode = ParseFncDeclNoCheckScope<buildAST>(flags, SuperRestrictionState::Disallowed, nullptr, /* needsPIDOnRCurlyScan = */false, /* fUnaryOrParen = */ false, fAllowIn);
  7694. if (isAsyncMethod)
  7695. {
  7696. pnode->AsParseNodeFnc()->cbStringMin = iecpMin;
  7697. }
  7698. // ArrowFunction/AsyncArrowFunction is part of AssignmentExpression, which should terminate the expression unless followed by a comma
  7699. if (m_token.tk != tkComma && m_token.tk != tkIN)
  7700. {
  7701. if (!(IsTerminateToken(false)))
  7702. {
  7703. Error(ERRnoSemic);
  7704. }
  7705. break;
  7706. }
  7707. }
  7708. else // a binary operator
  7709. {
  7710. if (nop == knopComma && m_token.tk == tkRParen)
  7711. {
  7712. // Trailing comma
  7713. this->GetScanner()->Capture(&m_deferCommaErrorLoc);
  7714. m_deferCommaError = true;
  7715. break;
  7716. }
  7717. ParseNode* pnode1 = pnode;
  7718. // Parse the operand, make a new node, and look for more
  7719. IdentToken token;
  7720. ParseNode* pnode2 = ParseExpr<buildAST>(
  7721. opl, nullptr, fAllowIn, FALSE, pNameHint, &hintLength, &hintOffset, &token, false, nullptr, plastRParen);
  7722. // Detect nested function escapes of the pattern "o.f = function(){...}" or "o[s] = function(){...}".
  7723. // Doing so in the parser allows us to disable stack-nested-functions in common cases where an escape
  7724. // is not detected at byte code gen time because of deferred parsing.
  7725. if (fIsDotOrIndex && nop == knopAsg)
  7726. {
  7727. this->MarkEscapingRef(pnodeT, &token);
  7728. }
  7729. if (buildAST)
  7730. {
  7731. Assert(pnode2 != nullptr);
  7732. if (pnode2->nop == knopFncDecl)
  7733. {
  7734. Assert(hintLength >= hintOffset);
  7735. pnode2->AsParseNodeFnc()->hint = pNameHint;
  7736. pnode2->AsParseNodeFnc()->hintLength = hintLength;
  7737. pnode2->AsParseNodeFnc()->hintOffset = hintOffset;
  7738. if (pnode1->nop == knopDot)
  7739. {
  7740. pnode2->AsParseNodeFnc()->isNameIdentifierRef = false;
  7741. }
  7742. else if (pnode1->nop == knopName)
  7743. {
  7744. PidRefStack *pidRef = pnode1->AsParseNodeName()->pid->GetTopRef();
  7745. pidRef->isFuncAssignment = true;
  7746. }
  7747. }
  7748. else if (pnode2->nop == knopClassDecl && pnode1->nop == knopDot)
  7749. {
  7750. Assert(pnode2->AsParseNodeClass()->pnodeConstructor);
  7751. if (!pnode2->AsParseNodeClass()->pnodeConstructor->pid)
  7752. {
  7753. pnode2->AsParseNodeClass()->pnodeConstructor->isNameIdentifierRef = false;
  7754. }
  7755. }
  7756. else if (pnode1->nop == knopName && nop == knopIn)
  7757. {
  7758. PidRefStack* pidRef = pnode1->AsParseNodeName()->pid->GetTopRef();
  7759. pidRef->SetIsUsedInLdElem(true);
  7760. }
  7761. pnode = CreateBinNode(nop, pnode1, pnode2);
  7762. }
  7763. pNameHint = nullptr;
  7764. }
  7765. }
  7766. if (buildAST)
  7767. {
  7768. if (!assignmentStmt)
  7769. {
  7770. // Don't set the flag for following nodes
  7771. switch (pnode->nop)
  7772. {
  7773. case knopName:
  7774. case knopInt:
  7775. case knopFlt:
  7776. case knopStr:
  7777. case knopRegExp:
  7778. case knopNull:
  7779. case knopFalse:
  7780. case knopTrue:
  7781. break;
  7782. default:
  7783. if (m_currentNodeFunc)
  7784. {
  7785. m_currentNodeFunc->SetHasNonThisStmt();
  7786. }
  7787. else if (m_currentNodeProg)
  7788. {
  7789. m_currentNodeProg->SetHasNonThisStmt();
  7790. }
  7791. }
  7792. }
  7793. }
  7794. m_hasDeferredShorthandInitError = m_hasDeferredShorthandInitError || savedDeferredInitError;
  7795. if (NULL != pfCanAssign)
  7796. {
  7797. *pfCanAssign = fCanAssign;
  7798. }
  7799. // Pass back identifier if requested
  7800. if (pToken && term.tk == tkID)
  7801. {
  7802. *pToken = term;
  7803. }
  7804. //Track "obj.a" assignment patterns here - Promote the Assignment state for the property's PID.
  7805. // This includes =, += etc.
  7806. if (pnode != NULL)
  7807. {
  7808. uint nodeType = ParseNode::Grfnop(pnode->nop);
  7809. if (nodeType & fnopAsg)
  7810. {
  7811. if (nodeType & fnopBin)
  7812. {
  7813. ParseNodePtr lhs = pnode->AsParseNodeBin()->pnode1;
  7814. Assert(lhs);
  7815. if (lhs->nop == knopDot)
  7816. {
  7817. ParseNodePtr propertyNode = lhs->AsParseNodeBin()->pnode2;
  7818. if (propertyNode->nop == knopName)
  7819. {
  7820. propertyNode->AsParseNodeName()->pid->PromoteAssignmentState();
  7821. }
  7822. }
  7823. }
  7824. else if (nodeType & fnopUni)
  7825. {
  7826. // cases like obj.a++, ++obj.a
  7827. ParseNodePtr lhs = pnode->AsParseNodeUni()->pnode1;
  7828. if (lhs->nop == knopDot)
  7829. {
  7830. ParseNodePtr propertyNode = lhs->AsParseNodeBin()->pnode2;
  7831. if (propertyNode->nop == knopName)
  7832. {
  7833. propertyNode->AsParseNodeName()->pid->PromoteAssignmentState();
  7834. }
  7835. }
  7836. }
  7837. }
  7838. }
  7839. return pnode;
  7840. }
  7841. template<bool buildAST>
  7842. void Parser::TrackAssignment(ParseNodePtr pnodeT, IdentToken* pToken)
  7843. {
  7844. if (buildAST)
  7845. {
  7846. Assert(pnodeT != nullptr);
  7847. if (pnodeT->nop == knopName)
  7848. {
  7849. PidRefStack *ref = pnodeT->AsParseNodeName()->pid->GetTopRef();
  7850. Assert(ref);
  7851. ref->isAsg = true;
  7852. }
  7853. }
  7854. else
  7855. {
  7856. Assert(pToken != nullptr);
  7857. if (pToken->tk == tkID)
  7858. {
  7859. PidRefStack *ref = pToken->pid->GetTopRef();
  7860. Assert(ref);
  7861. ref->isAsg = true;
  7862. }
  7863. }
  7864. }
  7865. PidRefStack* Parser::PushPidRef(IdentPtr pid)
  7866. {
  7867. ParseNodeFnc* currentFnc = GetCurrentFunctionNode();
  7868. if (this->IsCreatingStateCache())
  7869. {
  7870. IdentPtrSet* capturedNames = currentFnc->EnsureCapturedNames(&m_nodeAllocator);
  7871. capturedNames->AddNew(pid);
  7872. }
  7873. if (PHASE_ON1(Js::ParallelParsePhase))
  7874. {
  7875. // NOTE: the phase check is here to protect perf. See OSG 1020424.
  7876. // In some LS AST-rewrite cases we lose a lot of perf searching the PID ref stack rather
  7877. // than just pushing on the top. This hasn't shown up as a perf issue in non-LS benchmarks.
  7878. return pid->FindOrAddPidRef(&m_nodeAllocator, GetCurrentBlock()->blockId, currentFnc->functionId);
  7879. }
  7880. Assert(GetCurrentBlock() != nullptr);
  7881. AssertMsg(pid != nullptr, "PID should be created");
  7882. PidRefStack *ref = pid->GetTopRef(m_nextBlockId - 1);
  7883. int blockId = GetCurrentBlock()->blockId;
  7884. int funcId = currentFnc->functionId;
  7885. if (!ref || (ref->GetScopeId() < blockId))
  7886. {
  7887. ref = Anew(&m_nodeAllocator, PidRefStack);
  7888. if (ref == nullptr)
  7889. {
  7890. Error(ERRnoMemory);
  7891. }
  7892. pid->PushPidRef(blockId, funcId, ref);
  7893. }
  7894. else if (m_reparsingLambdaParams)
  7895. {
  7896. // If we're reparsing params, then we may have pid refs left behind from the first pass. Make sure we're
  7897. // working with the right ref at this point.
  7898. ref = this->FindOrAddPidRef(pid, blockId, funcId);
  7899. // Fix up the function ID if we're reparsing lambda parameters.
  7900. ref->funcId = funcId;
  7901. }
  7902. return ref;
  7903. }
  7904. PidRefStack* Parser::FindOrAddPidRef(IdentPtr pid, int scopeId, Js::LocalFunctionId funcId)
  7905. {
  7906. PidRefStack *ref = pid->FindOrAddPidRef(&m_nodeAllocator, scopeId, funcId);
  7907. if (ref == NULL)
  7908. {
  7909. Error(ERRnoMemory);
  7910. }
  7911. return ref;
  7912. }
  7913. void Parser::RemovePrevPidRef(IdentPtr pid, PidRefStack *ref)
  7914. {
  7915. PidRefStack *prevRef = pid->RemovePrevPidRef(ref);
  7916. Assert(prevRef);
  7917. if (prevRef->GetSym() == nullptr)
  7918. {
  7919. AllocatorDelete(ArenaAllocator, &m_nodeAllocator, prevRef);
  7920. }
  7921. }
  7922. void Parser::SetPidRefsInScopeDynamic(IdentPtr pid, int blockId)
  7923. {
  7924. PidRefStack *ref = pid->GetTopRef();
  7925. while (ref && ref->GetScopeId() >= blockId)
  7926. {
  7927. ref->SetDynamicBinding();
  7928. ref = ref->prev;
  7929. }
  7930. }
  7931. ParseNodeBlock* Parser::GetFunctionBlock()
  7932. {
  7933. Assert(m_currentBlockInfo != nullptr);
  7934. return m_currentBlockInfo->pBlockInfoFunction->pnodeBlock;
  7935. }
  7936. ParseNodeBlock* Parser::GetCurrentBlock()
  7937. {
  7938. return m_currentBlockInfo != nullptr ? m_currentBlockInfo->pnodeBlock : nullptr;
  7939. }
  7940. BlockInfoStack* Parser::GetCurrentBlockInfo()
  7941. {
  7942. return m_currentBlockInfo;
  7943. }
  7944. BlockInfoStack* Parser::GetCurrentFunctionBlockInfo()
  7945. {
  7946. return m_currentBlockInfo->pBlockInfoFunction;
  7947. }
  7948. /***************************************************************************
  7949. Parse a variable declaration.
  7950. 'fAllowIn' indicates if the 'in' operator should be allowed in the initializing
  7951. expression ( it is not allowed in the context of the first expression in a 'for' loop).
  7952. ***************************************************************************/
  7953. template<bool buildAST>
  7954. ParseNodePtr Parser::ParseVariableDeclaration(
  7955. tokens declarationType, charcount_t ichMin,
  7956. BOOL fAllowIn/* = TRUE*/,
  7957. BOOL* pfForInOk/* = nullptr*/,
  7958. BOOL singleDefOnly/* = FALSE*/,
  7959. BOOL allowInit/* = TRUE*/,
  7960. BOOL isTopVarParse/* = TRUE*/,
  7961. BOOL isFor/* = FALSE*/,
  7962. BOOL* nativeForOk /*= nullptr*/)
  7963. {
  7964. ParseNodePtr pnodeThis = nullptr;
  7965. ParseNodePtr pnodeInit;
  7966. ParseNodePtr pnodeList = nullptr;
  7967. ParseNodePtr *lastNodeRef = nullptr;
  7968. LPCOLESTR pNameHint = nullptr;
  7969. uint32 nameHintLength = 0;
  7970. uint32 nameHintOffset = 0;
  7971. Assert(declarationType == tkVAR || declarationType == tkCONST || declarationType == tkLET);
  7972. for (;;)
  7973. {
  7974. if (IsES6DestructuringEnabled() && IsPossiblePatternStart())
  7975. {
  7976. pnodeThis = ParseDestructuredLiteral<buildAST>(declarationType, true, !!isTopVarParse, DIC_None, !!fAllowIn, pfForInOk, nativeForOk);
  7977. if (pnodeThis != nullptr)
  7978. {
  7979. pnodeThis->ichMin = ichMin;
  7980. pnodeThis->SetIsPatternDeclaration();
  7981. }
  7982. }
  7983. else
  7984. {
  7985. if (m_token.tk != tkID)
  7986. {
  7987. IdentifierExpectedError(m_token);
  7988. }
  7989. IdentPtr pid = m_token.GetIdentifier(this->GetHashTbl());
  7990. Assert(pid);
  7991. pNameHint = pid->Psz();
  7992. nameHintLength = pid->Cch();
  7993. nameHintOffset = 0;
  7994. if (pid == wellKnownPropertyPids.let && (declarationType == tkCONST || declarationType == tkLET))
  7995. {
  7996. Error(ERRLetIDInLexicalDecl, pnodeThis);
  7997. }
  7998. if (declarationType == tkVAR)
  7999. {
  8000. pnodeThis = CreateVarDeclNode(pid, STVariable);
  8001. }
  8002. else if (declarationType == tkCONST)
  8003. {
  8004. pnodeThis = CreateBlockScopedDeclNode(pid, knopConstDecl);
  8005. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, Const, m_scriptContext);
  8006. }
  8007. else
  8008. {
  8009. pnodeThis = CreateBlockScopedDeclNode(pid, knopLetDecl);
  8010. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, Let, m_scriptContext);
  8011. }
  8012. if (pid == wellKnownPropertyPids.arguments)
  8013. {
  8014. // This var declaration may change the way an 'arguments' identifier in the function is resolved
  8015. if (declarationType == tkVAR)
  8016. {
  8017. GetCurrentFunctionNode()->grfpn |= PNodeFlags::fpnArguments_varDeclaration;
  8018. }
  8019. else
  8020. {
  8021. if (GetCurrentBlockInfo()->pnodeBlock->blockType == Function)
  8022. {
  8023. // Only override arguments if we are at the function block level.
  8024. GetCurrentFunctionNode()->grfpn |= PNodeFlags::fpnArguments_overriddenByDecl;
  8025. }
  8026. }
  8027. }
  8028. if (pnodeThis)
  8029. {
  8030. pnodeThis->ichMin = ichMin;
  8031. }
  8032. this->GetScanner()->Scan();
  8033. if (m_token.tk == tkAsg)
  8034. {
  8035. if (!allowInit)
  8036. {
  8037. Error(ERRUnexpectedDefault);
  8038. }
  8039. if (pfForInOk && (declarationType == tkLET || declarationType == tkCONST || IsStrictMode()))
  8040. {
  8041. *pfForInOk = FALSE;
  8042. }
  8043. this->GetScanner()->Scan();
  8044. pnodeInit = ParseExpr<buildAST>(koplCma, nullptr, fAllowIn, FALSE, pNameHint, &nameHintLength, &nameHintOffset);
  8045. if (buildAST)
  8046. {
  8047. AnalysisAssert(pnodeThis);
  8048. pnodeThis->AsParseNodeVar()->pnodeInit = pnodeInit;
  8049. pnodeThis->ichLim = pnodeInit->ichLim;
  8050. if (pnodeInit->nop == knopFncDecl)
  8051. {
  8052. Assert(nameHintLength >= nameHintOffset);
  8053. pnodeInit->AsParseNodeFnc()->hint = pNameHint;
  8054. pnodeInit->AsParseNodeFnc()->hintLength = nameHintLength;
  8055. pnodeInit->AsParseNodeFnc()->hintOffset = nameHintOffset;
  8056. pnodeThis->AsParseNodeVar()->pid->GetTopRef()->isFuncAssignment = true;
  8057. }
  8058. else
  8059. {
  8060. this->CheckArguments(pnodeInit);
  8061. }
  8062. pNameHint = nullptr;
  8063. }
  8064. //Track var a =, let a= , const a =
  8065. // This is for FixedFields Constant Heuristics
  8066. if (pnodeThis && pnodeThis->AsParseNodeVar()->pnodeInit != nullptr)
  8067. {
  8068. pnodeThis->AsParseNodeVar()->sym->PromoteAssignmentState();
  8069. }
  8070. }
  8071. else if (declarationType == tkCONST /*pnodeThis->nop == knopConstDecl*/
  8072. && !singleDefOnly
  8073. && !(isFor && TokIsForInOrForOf()))
  8074. {
  8075. Error(ERRUninitializedConst);
  8076. }
  8077. if (m_currentNodeFunc && pnodeThis && pnodeThis->AsParseNodeVar()->sym->GetIsFormal())
  8078. {
  8079. m_currentNodeFunc->SetHasAnyWriteToFormals(true);
  8080. }
  8081. }
  8082. if (singleDefOnly)
  8083. {
  8084. return pnodeThis;
  8085. }
  8086. if (buildAST)
  8087. {
  8088. AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeThis);
  8089. }
  8090. if (m_token.tk != tkComma)
  8091. {
  8092. return pnodeList;
  8093. }
  8094. if (pfForInOk)
  8095. {
  8096. // don't allow "for (var a, b in c)"
  8097. *pfForInOk = FALSE;
  8098. }
  8099. this->GetScanner()->Scan();
  8100. ichMin = this->GetScanner()->IchMinTok();
  8101. }
  8102. }
  8103. /***************************************************************************
  8104. Parse try-catch-finally statement
  8105. ***************************************************************************/
  8106. // The try-catch-finally tree nests the try-catch within a try-finally.
  8107. // This matches the new runtime implementation.
  8108. template<bool buildAST>
  8109. ParseNodeStmt * Parser::ParseTryCatchFinally()
  8110. {
  8111. this->m_tryCatchOrFinallyDepth++;
  8112. ParseNodeTry * pnodeT = ParseTry<buildAST>();
  8113. ParseNodeTryCatch * pnodeTC = nullptr;
  8114. StmtNest stmt;
  8115. bool hasCatch = false;
  8116. if (tkCATCH == m_token.tk)
  8117. {
  8118. hasCatch = true;
  8119. if (buildAST)
  8120. {
  8121. pnodeTC = CreateNodeForOpT<knopTryCatch>();
  8122. pnodeT->pnodeOuter = pnodeTC;
  8123. pnodeTC->pnodeTry = pnodeT;
  8124. }
  8125. PushStmt<buildAST>(&stmt, pnodeTC, knopTryCatch, nullptr);
  8126. ParseNodeCatch * pnodeCatch = ParseCatch<buildAST>();
  8127. if (buildAST)
  8128. {
  8129. pnodeTC->pnodeCatch = pnodeCatch;
  8130. }
  8131. PopStmt(&stmt);
  8132. }
  8133. if (tkFINALLY != m_token.tk)
  8134. {
  8135. if (!hasCatch)
  8136. {
  8137. Error(ERRnoCatch);
  8138. }
  8139. Assert(!buildAST || pnodeTC);
  8140. this->m_tryCatchOrFinallyDepth--;
  8141. return pnodeTC;
  8142. }
  8143. ParseNodeTryFinally * pnodeTF = nullptr;
  8144. if (buildAST)
  8145. {
  8146. pnodeTF = CreateNodeForOpT<knopTryFinally>();
  8147. }
  8148. PushStmt<buildAST>(&stmt, pnodeTF, knopTryFinally, nullptr);
  8149. ParseNodeFinally * pnodeFinally = ParseFinally<buildAST>();
  8150. if (buildAST)
  8151. {
  8152. if (!hasCatch)
  8153. {
  8154. pnodeTF->pnodeTry = pnodeT;
  8155. pnodeT->pnodeOuter = pnodeTF;
  8156. }
  8157. else
  8158. {
  8159. pnodeTF->pnodeTry = CreateNodeForOpT<knopTry>();
  8160. pnodeTF->pnodeTry->pnodeOuter = pnodeTF;
  8161. pnodeTF->pnodeTry->pnodeBody = pnodeTC;
  8162. pnodeTC->pnodeOuter = pnodeTF->pnodeTry;
  8163. }
  8164. pnodeTF->pnodeFinally = pnodeFinally;
  8165. }
  8166. PopStmt(&stmt);
  8167. this->m_tryCatchOrFinallyDepth--;
  8168. return pnodeTF;
  8169. }
  8170. template<bool buildAST>
  8171. ParseNodeTry * Parser::ParseTry()
  8172. {
  8173. ParseNodeTry * pnode = nullptr;
  8174. StmtNest stmt;
  8175. Assert(tkTRY == m_token.tk);
  8176. if (buildAST)
  8177. {
  8178. pnode = CreateNodeForOpT<knopTry>();
  8179. }
  8180. this->GetScanner()->Scan();
  8181. if (tkLCurly != m_token.tk)
  8182. {
  8183. Error(ERRnoLcurly);
  8184. }
  8185. PushStmt<buildAST>(&stmt, pnode, knopTry, nullptr);
  8186. ParseNodePtr pnodeBody = ParseStatement<buildAST>();
  8187. if (buildAST)
  8188. {
  8189. pnode->pnodeBody = pnodeBody;
  8190. if (pnode->pnodeBody)
  8191. pnode->ichLim = pnode->pnodeBody->ichLim;
  8192. }
  8193. PopStmt(&stmt);
  8194. return pnode;
  8195. }
  8196. template<bool buildAST>
  8197. ParseNodeFinally * Parser::ParseFinally()
  8198. {
  8199. ParseNodeFinally * pnode = nullptr;
  8200. StmtNest stmt;
  8201. Assert(tkFINALLY == m_token.tk);
  8202. if (buildAST)
  8203. {
  8204. pnode = CreateNodeForOpT<knopFinally>();
  8205. }
  8206. this->GetScanner()->Scan();
  8207. if (tkLCurly != m_token.tk)
  8208. {
  8209. Error(ERRnoLcurly);
  8210. }
  8211. PushStmt<buildAST>(&stmt, pnode, knopFinally, nullptr);
  8212. ParseNodePtr pnodeBody = ParseStatement<buildAST>();
  8213. if (buildAST)
  8214. {
  8215. pnode->pnodeBody = pnodeBody;
  8216. if (!pnode->pnodeBody)
  8217. // Will only occur due to error correction.
  8218. pnode->pnodeBody = CreateNodeForOpT<knopEmpty>();
  8219. else
  8220. pnode->ichLim = pnode->pnodeBody->ichLim;
  8221. }
  8222. PopStmt(&stmt);
  8223. return pnode;
  8224. }
  8225. template<bool buildAST>
  8226. ParseNodeCatch * Parser::ParseCatch()
  8227. {
  8228. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  8229. ParseNodeCatch * pnode = nullptr;
  8230. ParseNodeBlock * pnodeCatchScope = nullptr;
  8231. StmtNest stmt;
  8232. IdentPtr pidCatch = nullptr;
  8233. if (tkCATCH == m_token.tk)
  8234. {
  8235. charcount_t ichMin;
  8236. if (buildAST)
  8237. {
  8238. ichMin = this->GetScanner()->IchMinTok();
  8239. }
  8240. this->GetScanner()->Scan(); //catch
  8241. ChkCurTok(tkLParen, ERRnoLparen); //catch(
  8242. bool isPattern = false;
  8243. if (tkID != m_token.tk)
  8244. {
  8245. isPattern = IsES6DestructuringEnabled() && IsPossiblePatternStart();
  8246. if (!isPattern)
  8247. {
  8248. IdentifierExpectedError(m_token);
  8249. }
  8250. }
  8251. if (buildAST)
  8252. {
  8253. pnode = CreateNodeForOpT<knopCatch>(ichMin);
  8254. pnode->pnodeNext = nullptr;
  8255. PushStmt<buildAST>(&stmt, pnode, knopCatch, nullptr);
  8256. }
  8257. pnodeCatchScope = StartParseBlock<buildAST>(PnodeBlockType::Regular, isPattern ? ScopeType_CatchParamPattern : ScopeType_Catch);
  8258. if (buildAST)
  8259. {
  8260. // Add this catch to the current scope list.
  8261. if (m_ppnodeExprScope)
  8262. {
  8263. Assert(*m_ppnodeExprScope == nullptr);
  8264. *m_ppnodeExprScope = pnode;
  8265. m_ppnodeExprScope = &pnode->pnodeNext;
  8266. }
  8267. else
  8268. {
  8269. Assert(m_ppnodeScope);
  8270. Assert(*m_ppnodeScope == nullptr);
  8271. *m_ppnodeScope = pnode;
  8272. m_ppnodeScope = &pnode->pnodeNext;
  8273. }
  8274. // Keep a list of function expressions (not declarations) at this scope.
  8275. ppnodeExprScopeSave = m_ppnodeExprScope;
  8276. m_ppnodeExprScope = &pnode->pnodeScopes;
  8277. pnode->pnodeScopes = nullptr;
  8278. }
  8279. if (isPattern)
  8280. {
  8281. ParseNodePtr pnodePattern = ParseDestructuredLiteral<buildAST>(tkLET, true /*isDecl*/, true /*topLevel*/, DIC_ForceErrorOnInitializer);
  8282. if (buildAST)
  8283. {
  8284. pnode->SetParam(CreateParamPatternNode(pnodePattern));
  8285. Scope *scope = pnodeCatchScope->scope;
  8286. pnode->scope = scope;
  8287. }
  8288. }
  8289. else
  8290. {
  8291. if (IsStrictMode())
  8292. {
  8293. IdentPtr pid = m_token.GetIdentifier(this->GetHashTbl());
  8294. if (pid == wellKnownPropertyPids.eval)
  8295. {
  8296. Error(ERREvalUsage);
  8297. }
  8298. else if (pid == wellKnownPropertyPids.arguments)
  8299. {
  8300. Error(ERRArgsUsage);
  8301. }
  8302. }
  8303. pidCatch = m_token.GetIdentifier(this->GetHashTbl());
  8304. PidRefStack *ref = this->FindOrAddPidRef(pidCatch, GetCurrentBlock()->blockId, GetCurrentFunctionNode()->functionId);
  8305. ParseNodeName * pnodeParam = CreateNameNode(pidCatch);
  8306. pnodeParam->SetSymRef(ref);
  8307. const char16 *name = reinterpret_cast<const char16*>(pidCatch->Psz());
  8308. int nameLength = pidCatch->Cch();
  8309. SymbolName const symName(name, nameLength);
  8310. Symbol *sym = Anew(&m_nodeAllocator, Symbol, symName, pnodeParam, STVariable);
  8311. if (sym == nullptr)
  8312. {
  8313. Error(ERRnoMemory);
  8314. }
  8315. sym->SetPid(pidCatch);
  8316. Assert(ref->GetSym() == nullptr);
  8317. ref->SetSym(sym);
  8318. Scope *scope = pnodeCatchScope->scope;
  8319. scope->AddNewSymbol(sym);
  8320. if (buildAST)
  8321. {
  8322. pnode->SetParam(pnodeParam);
  8323. pnode->scope = scope;
  8324. }
  8325. this->GetScanner()->Scan();
  8326. }
  8327. charcount_t ichLim;
  8328. if (buildAST)
  8329. {
  8330. ichLim = this->GetScanner()->IchLimTok();
  8331. }
  8332. ChkCurTok(tkRParen, ERRnoRparen); //catch(id[:expr])
  8333. if (tkLCurly != m_token.tk)
  8334. {
  8335. Error(ERRnoLcurly);
  8336. }
  8337. ParseNodePtr pnodeBody = ParseStatement<buildAST>(); //catch(id[:expr]) {block}
  8338. if (buildAST)
  8339. {
  8340. pnode->pnodeBody = pnodeBody;
  8341. pnode->ichLim = ichLim;
  8342. }
  8343. if (pnodeCatchScope != nullptr)
  8344. {
  8345. FinishParseBlock(pnodeCatchScope);
  8346. }
  8347. if (pnodeCatchScope->GetCallsEval() || pnodeCatchScope->GetChildCallsEval())
  8348. {
  8349. GetCurrentBlock()->SetChildCallsEval(true);
  8350. }
  8351. if (buildAST)
  8352. {
  8353. PopStmt(&stmt);
  8354. // Restore the lists of function expression scopes.
  8355. Assert(m_ppnodeExprScope);
  8356. Assert(*m_ppnodeExprScope == nullptr);
  8357. m_ppnodeExprScope = ppnodeExprScopeSave;
  8358. }
  8359. }
  8360. return pnode;
  8361. }
  8362. template<bool buildAST>
  8363. ParseNodeCase * Parser::ParseCase(ParseNodePtr *ppnodeBody)
  8364. {
  8365. ParseNodeCase * pnodeT = nullptr;
  8366. charcount_t ichMinT = this->GetScanner()->IchMinTok();
  8367. this->GetScanner()->Scan();
  8368. ParseNodePtr pnodeExpr = ParseExpr<buildAST>();
  8369. charcount_t ichLim = this->GetScanner()->IchLimTok();
  8370. ChkCurTok(tkColon, ERRnoColon);
  8371. if (buildAST)
  8372. {
  8373. pnodeT = CreateNodeForOpT<knopCase>(ichMinT);
  8374. pnodeT->pnodeExpr = pnodeExpr;
  8375. pnodeT->ichLim = ichLim;
  8376. }
  8377. ParseStmtList<buildAST>(ppnodeBody);
  8378. return pnodeT;
  8379. }
  8380. /***************************************************************************
  8381. Parse a single statement. Digest a trailing semicolon.
  8382. ***************************************************************************/
  8383. template<bool buildAST>
  8384. ParseNodePtr Parser::ParseStatement()
  8385. {
  8386. ParseNodePtr pnode = nullptr;
  8387. LabelId* pLabelIdList = nullptr;
  8388. charcount_t ichMin = 0;
  8389. size_t iecpMin = 0;
  8390. StmtNest stmt;
  8391. StmtNest *pstmt;
  8392. BOOL fForInOrOfOkay;
  8393. BOOL fCanAssign;
  8394. IdentPtr pid;
  8395. uint fnop;
  8396. bool expressionStmt = false;
  8397. bool isAsyncMethod = false;
  8398. bool labelledStatement = false;
  8399. tokens tok;
  8400. #if EXCEPTION_RECOVERY
  8401. ParseNodeTryCatch * pParentTryCatch = nullptr;
  8402. ParseNodeBlock * pTryBlock = nullptr;
  8403. ParseNodeTry * pTry = nullptr;
  8404. ParseNodeBlock * pParentTryCatchBlock = nullptr;
  8405. StmtNest stmtTryCatchBlock;
  8406. StmtNest stmtTryCatch;
  8407. StmtNest stmtTry;
  8408. StmtNest stmtTryBlock;
  8409. #endif
  8410. if (buildAST)
  8411. {
  8412. #if EXCEPTION_RECOVERY
  8413. if (Js::Configuration::Global.flags.SwallowExceptions)
  8414. {
  8415. // If we're swallowing exceptions, surround this statement with a try/catch block:
  8416. //
  8417. // Before: x.y = 3;
  8418. // After: try { x.y = 3; } catch(__ehobj) { }
  8419. //
  8420. // This is done to force the runtime to recover from exceptions at the most granular
  8421. // possible point. Recovering from EH dramatically improves coverage of testing via
  8422. // fault injection.
  8423. // create and push the try-catch node
  8424. pParentTryCatchBlock = CreateBlockNode();
  8425. PushStmt<buildAST>(&stmtTryCatchBlock, pParentTryCatchBlock, knopBlock, nullptr);
  8426. pParentTryCatch = CreateNodeForOpT<knopTryCatch>();
  8427. PushStmt<buildAST>(&stmtTryCatch, pParentTryCatch, knopTryCatch, nullptr);
  8428. // create and push a try node
  8429. pTry = CreateNodeForOpT<knopTry>();
  8430. PushStmt<buildAST>(&stmtTry, pTry, knopTry, nullptr);
  8431. pTryBlock = CreateBlockNode();
  8432. PushStmt<buildAST>(&stmtTryBlock, pTryBlock, knopBlock, nullptr);
  8433. // these nodes will be closed after the statement is parsed.
  8434. }
  8435. #endif // EXCEPTION_RECOVERY
  8436. }
  8437. EnsureStackAvailable();
  8438. LRestart:
  8439. tok = m_token.tk;
  8440. switch (tok)
  8441. {
  8442. case tkEOF:
  8443. if (labelledStatement)
  8444. {
  8445. Error(ERRLabelFollowedByEOF);
  8446. }
  8447. if (buildAST)
  8448. {
  8449. pnode = nullptr;
  8450. }
  8451. break;
  8452. case tkFUNCTION:
  8453. {
  8454. LFunctionStatement:
  8455. if (m_grfscr & fscrDeferredFncExpression)
  8456. {
  8457. // The top-level deferred function body was defined by a function expression whose parsing was deferred. We are now
  8458. // parsing it, so unset the flag so that any nested functions are parsed normally. This flag is only applicable the
  8459. // first time we see it.
  8460. m_grfscr &= ~fscrDeferredFncExpression;
  8461. pnode = ParseFncDeclNoCheckScope<buildAST>(isAsyncMethod ? fFncAsync : fFncNoFlgs);
  8462. }
  8463. else
  8464. {
  8465. pnode = ParseFncDeclCheckScope<buildAST>(fFncDeclaration | (isAsyncMethod ? fFncAsync : fFncNoFlgs));
  8466. }
  8467. Assert(pnode != nullptr);
  8468. ParseNodeFnc* pNodeFnc = (ParseNodeFnc*)pnode;
  8469. if (labelledStatement)
  8470. {
  8471. if (IsStrictMode())
  8472. {
  8473. Error(ERRFunctionAfterLabelInStrict);
  8474. }
  8475. else if (pNodeFnc->IsAsync())
  8476. {
  8477. Error(ERRLabelBeforeAsyncFncDeclaration);
  8478. }
  8479. else if (pNodeFnc->IsGenerator())
  8480. {
  8481. Error(ERRLabelBeforeGeneratorDeclaration);
  8482. }
  8483. }
  8484. if (isAsyncMethod)
  8485. {
  8486. pnode->AsParseNodeFnc()->cbStringMin = iecpMin;
  8487. }
  8488. break;
  8489. }
  8490. case tkCLASS:
  8491. if (labelledStatement)
  8492. {
  8493. Error(ERRLabelBeforeClassDeclaration);
  8494. }
  8495. else if (m_scriptContext->GetConfig()->IsES6ClassAndExtendsEnabled())
  8496. {
  8497. pnode = ParseClassDecl<buildAST>(TRUE, nullptr, nullptr, nullptr);
  8498. }
  8499. else
  8500. {
  8501. goto LDefaultToken;
  8502. }
  8503. break;
  8504. case tkID:
  8505. case tkLET:
  8506. if (m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.let)
  8507. {
  8508. // We see "let" at the start of a statement. This could either be a declaration or an identifier
  8509. // reference. The next token determines which.
  8510. RestorePoint parsedLet;
  8511. this->GetScanner()->Capture(&parsedLet);
  8512. ichMin = this->GetScanner()->IchMinTok();
  8513. this->GetScanner()->Scan();
  8514. if (labelledStatement)
  8515. {
  8516. if (!this->GetScanner()->FHadNewLine() || m_token.tk == tkLBrack)
  8517. {
  8518. // In the case where a label is followed by a let, we want to fail when parsing if there is no new line after let,
  8519. // otherwise fail at runtime as let will be viewed as undefined. A left bracket after a let signifies a syntax error regardless.
  8520. Error(ERRLabelBeforeLexicalDeclaration);
  8521. }
  8522. }
  8523. else if (this->NextTokenConfirmsLetDecl())
  8524. {
  8525. pnode = ParseVariableDeclaration<buildAST>(tkLET, ichMin);
  8526. goto LNeedTerminator;
  8527. }
  8528. this->GetScanner()->SeekTo(parsedLet);
  8529. }
  8530. else if (m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.async && m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
  8531. {
  8532. RestorePoint parsedAsync;
  8533. this->GetScanner()->Capture(&parsedAsync);
  8534. ichMin = this->GetScanner()->IchMinTok();
  8535. iecpMin = this->GetScanner()->IecpMinTok();
  8536. this->GetScanner()->Scan();
  8537. if (m_token.tk == tkFUNCTION && !this->GetScanner()->FHadNewLine())
  8538. {
  8539. isAsyncMethod = true;
  8540. goto LFunctionStatement;
  8541. }
  8542. this->GetScanner()->SeekTo(parsedAsync);
  8543. }
  8544. goto LDefaultToken;
  8545. case tkCONST:
  8546. if (labelledStatement)
  8547. {
  8548. Error(ERRLabelBeforeLexicalDeclaration);
  8549. }
  8550. ichMin = this->GetScanner()->IchMinTok();
  8551. this->GetScanner()->Scan();
  8552. pnode = ParseVariableDeclaration<buildAST>(tok, ichMin);
  8553. goto LNeedTerminator;
  8554. case tkVAR:
  8555. ichMin = this->GetScanner()->IchMinTok();
  8556. this->GetScanner()->Scan();
  8557. pnode = ParseVariableDeclaration<buildAST>(tok, ichMin);
  8558. goto LNeedTerminator;
  8559. case tkFOR:
  8560. {
  8561. ParseNodeBlock * pnodeBlock = nullptr;
  8562. ParseNodePtr *ppnodeScopeSave = nullptr;
  8563. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  8564. ichMin = this->GetScanner()->IchMinTok();
  8565. ChkNxtTok(tkLParen, ERRnoLparen);
  8566. pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Regular, ScopeType_Block);
  8567. if (buildAST)
  8568. {
  8569. PushFuncBlockScope(pnodeBlock, &ppnodeScopeSave, &ppnodeExprScopeSave);
  8570. }
  8571. RestorePoint startExprOrIdentifier;
  8572. fForInOrOfOkay = TRUE;
  8573. fCanAssign = TRUE;
  8574. tok = m_token.tk;
  8575. BOOL nativeForOkay = TRUE;
  8576. ParseNodePtr pnodeT;
  8577. switch (tok)
  8578. {
  8579. case tkID:
  8580. if (m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.let)
  8581. {
  8582. // We see "let" in the init part of a for loop. This could either be a declaration or an identifier
  8583. // reference. The next token determines which.
  8584. RestorePoint parsedLet;
  8585. this->GetScanner()->Capture(&parsedLet);
  8586. auto ichMinInner = this->GetScanner()->IchMinTok();
  8587. this->GetScanner()->Scan();
  8588. if (IsPossiblePatternStart())
  8589. {
  8590. this->GetScanner()->Capture(&startExprOrIdentifier);
  8591. }
  8592. if (this->NextTokenConfirmsLetDecl() && m_token.tk != tkIN)
  8593. {
  8594. pnodeT = ParseVariableDeclaration<buildAST>(tkLET, ichMinInner
  8595. , /*fAllowIn = */FALSE
  8596. , /*pfForInOk = */&fForInOrOfOkay
  8597. , /*singleDefOnly*/FALSE
  8598. , /*allowInit*/TRUE
  8599. , /*isTopVarParse*/TRUE
  8600. , /*isFor*/TRUE
  8601. , &nativeForOkay);
  8602. break;
  8603. }
  8604. this->GetScanner()->SeekTo(parsedLet);
  8605. }
  8606. goto LDefaultTokenFor;
  8607. case tkLET:
  8608. case tkCONST:
  8609. case tkVAR:
  8610. {
  8611. auto ichMinInner = this->GetScanner()->IchMinTok();
  8612. this->GetScanner()->Scan();
  8613. if (IsPossiblePatternStart())
  8614. {
  8615. this->GetScanner()->Capture(&startExprOrIdentifier);
  8616. }
  8617. pnodeT = ParseVariableDeclaration<buildAST>(tok, ichMinInner
  8618. , /*fAllowIn = */FALSE
  8619. , /*pfForInOk = */&fForInOrOfOkay
  8620. , /*singleDefOnly*/FALSE
  8621. , /*allowInit*/TRUE
  8622. , /*isTopVarParse*/TRUE
  8623. , /*isFor*/TRUE
  8624. , &nativeForOkay);
  8625. }
  8626. break;
  8627. case tkSColon:
  8628. pnodeT = nullptr;
  8629. fForInOrOfOkay = FALSE;
  8630. break;
  8631. default:
  8632. {
  8633. LDefaultTokenFor:
  8634. RestorePoint exprStart;
  8635. tokens beforeToken = tok;
  8636. this->GetScanner()->Capture(&exprStart);
  8637. if (IsPossiblePatternStart())
  8638. {
  8639. this->GetScanner()->Capture(&startExprOrIdentifier);
  8640. }
  8641. bool fLikelyPattern = false;
  8642. if (IsES6DestructuringEnabled() && (beforeToken == tkLBrack || beforeToken == tkLCurly))
  8643. {
  8644. pnodeT = ParseExpr<buildAST>(koplNo,
  8645. &fCanAssign,
  8646. /*fAllowIn = */FALSE,
  8647. /*fAllowEllipsis*/FALSE,
  8648. /*pHint*/nullptr,
  8649. /*pHintLength*/nullptr,
  8650. /*pShortNameOffset*/nullptr,
  8651. /*pToken*/nullptr,
  8652. /**fUnaryOrParen*/false,
  8653. &fLikelyPattern);
  8654. }
  8655. else
  8656. {
  8657. pnodeT = ParseExpr<buildAST>(koplNo, &fCanAssign, /*fAllowIn = */FALSE);
  8658. }
  8659. // We would veryfiy the grammar as destructuring grammar only when for..in/of case. As in the native for loop case the above ParseExpr call
  8660. // has already converted them appropriately.
  8661. if (fLikelyPattern && TokIsForInOrForOf())
  8662. {
  8663. this->GetScanner()->SeekTo(exprStart);
  8664. ParseDestructuredLiteralWithScopeSave(tkNone, false/*isDecl*/, false /*topLevel*/, DIC_None, false /*allowIn*/);
  8665. if (buildAST)
  8666. {
  8667. pnodeT = ConvertToPattern(pnodeT);
  8668. }
  8669. }
  8670. if (buildAST)
  8671. {
  8672. Assert(pnodeT);
  8673. pnodeT->isUsed = false;
  8674. }
  8675. }
  8676. break;
  8677. }
  8678. if (TokIsForInOrForOf())
  8679. {
  8680. bool isForOf = (m_token.tk != tkIN);
  8681. Assert(!isForOf || (m_token.tk == tkID && m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.of));
  8682. if ((buildAST && nullptr == pnodeT) || !fForInOrOfOkay)
  8683. {
  8684. if (isForOf)
  8685. {
  8686. Error(ERRForOfNoInitAllowed);
  8687. }
  8688. else
  8689. {
  8690. Error(ERRForInNoInitAllowed);
  8691. }
  8692. }
  8693. if (!fCanAssign &&
  8694. (m_sourceContextInfo
  8695. ? !PHASE_OFF_RAW(Js::EarlyReferenceErrorsPhase, m_sourceContextInfo->sourceContextId, GetCurrentFunctionNode()->functionId)
  8696. : !PHASE_OFF1(Js::EarlyReferenceErrorsPhase)))
  8697. {
  8698. Error(ERRInvalidLHSInFor);
  8699. }
  8700. this->GetScanner()->Scan();
  8701. ParseNodePtr pnodeObj = ParseExpr<buildAST>(isForOf ? koplCma : koplNo);
  8702. charcount_t ichLim = this->GetScanner()->IchLimTok();
  8703. ChkCurTok(tkRParen, ERRnoRparen);
  8704. ParseNodeForInOrForOf * pnodeForInOrForOf = nullptr;
  8705. if (buildAST)
  8706. {
  8707. if (isForOf)
  8708. {
  8709. pnodeForInOrForOf = CreateNodeForOpT<knopForOf>(ichMin);
  8710. }
  8711. else
  8712. {
  8713. pnodeForInOrForOf = CreateNodeForOpT<knopForIn>(ichMin);
  8714. }
  8715. pnodeForInOrForOf->pnodeBlock = pnodeBlock;
  8716. pnodeForInOrForOf->pnodeLval = pnodeT;
  8717. pnodeForInOrForOf->pnodeObj = pnodeObj;
  8718. pnodeForInOrForOf->ichLim = ichLim;
  8719. TrackAssignment<true>(pnodeT, nullptr);
  8720. }
  8721. PushStmt<buildAST>(&stmt, pnodeForInOrForOf, isForOf ? knopForOf : knopForIn, pLabelIdList);
  8722. ParseNodePtr pnodeBody = ParseStatement<buildAST>();
  8723. if (buildAST)
  8724. {
  8725. pnodeForInOrForOf->pnodeBody = pnodeBody;
  8726. pnode = pnodeForInOrForOf;
  8727. }
  8728. PopStmt(&stmt);
  8729. }
  8730. else
  8731. {
  8732. if (!nativeForOkay)
  8733. {
  8734. Error(ERRDestructInit);
  8735. }
  8736. ChkCurTok(tkSColon, ERRnoSemic);
  8737. ParseNodePtr pnodeCond = nullptr;
  8738. if (m_token.tk != tkSColon)
  8739. {
  8740. pnodeCond = ParseExpr<buildAST>();
  8741. if (m_token.tk != tkSColon)
  8742. {
  8743. Error(ERRnoSemic);
  8744. }
  8745. }
  8746. tokens tk;
  8747. tk = this->GetScanner()->Scan();
  8748. ParseNodePtr pnodeIncr = nullptr;
  8749. if (tk != tkRParen)
  8750. {
  8751. pnodeIncr = ParseExpr<buildAST>();
  8752. if (pnodeIncr)
  8753. {
  8754. pnodeIncr->isUsed = false;
  8755. }
  8756. }
  8757. charcount_t ichLim = this->GetScanner()->IchLimTok();
  8758. ChkCurTok(tkRParen, ERRnoRparen);
  8759. ParseNodeFor * pnodeFor = nullptr;
  8760. if (buildAST)
  8761. {
  8762. pnodeFor = CreateNodeForOpT<knopFor>(ichMin);
  8763. pnodeFor->pnodeBlock = pnodeBlock;
  8764. pnodeFor->pnodeInverted = nullptr;
  8765. pnodeFor->pnodeInit = pnodeT;
  8766. pnodeFor->pnodeCond = pnodeCond;
  8767. pnodeFor->pnodeIncr = pnodeIncr;
  8768. pnodeFor->ichLim = ichLim;
  8769. }
  8770. PushStmt<buildAST>(&stmt, pnodeFor, knopFor, pLabelIdList);
  8771. ParseNodePtr pnodeBody = ParseStatement<buildAST>();
  8772. if (buildAST)
  8773. {
  8774. pnodeFor->pnodeBody = pnodeBody;
  8775. pnode = pnodeFor;
  8776. }
  8777. PopStmt(&stmt);
  8778. }
  8779. if (buildAST)
  8780. {
  8781. PopFuncBlockScope(ppnodeScopeSave, ppnodeExprScopeSave);
  8782. }
  8783. FinishParseBlock(pnodeBlock);
  8784. break;
  8785. }
  8786. case tkSWITCH:
  8787. {
  8788. BOOL fSeenDefault = FALSE;
  8789. ParseNodeBlock * pnodeBlock = nullptr;
  8790. ParseNodePtr *ppnodeScopeSave = nullptr;
  8791. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  8792. ichMin = this->GetScanner()->IchMinTok();
  8793. ChkNxtTok(tkLParen, ERRnoLparen);
  8794. ParseNodePtr pnodeVal = ParseExpr<buildAST>();
  8795. charcount_t ichLim = this->GetScanner()->IchLimTok();
  8796. ChkCurTok(tkRParen, ERRnoRparen);
  8797. ChkCurTok(tkLCurly, ERRnoLcurly);
  8798. ParseNodeSwitch * pnodeSwitch = nullptr;
  8799. if (buildAST)
  8800. {
  8801. pnodeSwitch = CreateNodeForOpT<knopSwitch>(ichMin);
  8802. }
  8803. PushStmt<buildAST>(&stmt, pnodeSwitch, knopSwitch, pLabelIdList);
  8804. pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Regular, ScopeType_Block);
  8805. ParseNodeCase ** ppnodeCase = nullptr;
  8806. if (buildAST)
  8807. {
  8808. pnodeSwitch->pnodeVal = pnodeVal;
  8809. pnodeSwitch->pnodeBlock = pnodeBlock;
  8810. pnodeSwitch->ichLim = ichLim;
  8811. PushFuncBlockScope(pnodeSwitch->pnodeBlock, &ppnodeScopeSave, &ppnodeExprScopeSave);
  8812. pnodeSwitch->pnodeDefault = nullptr;
  8813. ppnodeCase = &pnodeSwitch->pnodeCases;
  8814. pnode = pnodeSwitch;
  8815. }
  8816. for (;;)
  8817. {
  8818. ParseNodeCase * pnodeCase;
  8819. ParseNodePtr pnodeBody = nullptr;
  8820. switch (m_token.tk)
  8821. {
  8822. default:
  8823. goto LEndSwitch;
  8824. case tkCASE:
  8825. {
  8826. pnodeCase = this->ParseCase<buildAST>(&pnodeBody);
  8827. break;
  8828. }
  8829. case tkDEFAULT:
  8830. if (fSeenDefault)
  8831. {
  8832. Error(ERRdupDefault);
  8833. // No recovery necessary since this is a semantic, not structural, error
  8834. }
  8835. fSeenDefault = TRUE;
  8836. charcount_t ichMinT = this->GetScanner()->IchMinTok();
  8837. this->GetScanner()->Scan();
  8838. charcount_t ichMinInner = this->GetScanner()->IchLimTok();
  8839. ChkCurTok(tkColon, ERRnoColon);
  8840. if (buildAST)
  8841. {
  8842. pnodeCase = CreateNodeForOpT<knopCase>(ichMinT);
  8843. pnodeSwitch->pnodeDefault = pnodeCase;
  8844. pnodeCase->ichLim = ichMinInner;
  8845. pnodeCase->pnodeExpr = nullptr;
  8846. }
  8847. ParseStmtList<buildAST>(&pnodeBody);
  8848. break;
  8849. }
  8850. // Create a block node to contain the statement list for this case.
  8851. // This helps us insert byte code to return the right value from
  8852. // global/eval code.
  8853. ParseNodeBlock * pnodeFakeBlock = CreateBlockNode();
  8854. if (buildAST)
  8855. {
  8856. if (pnodeBody)
  8857. {
  8858. pnodeFakeBlock->ichMin = pnodeCase->ichMin;
  8859. pnodeFakeBlock->ichLim = pnodeCase->ichLim;
  8860. pnodeCase->pnodeBody = pnodeFakeBlock;
  8861. pnodeCase->pnodeBody->grfpn |= PNodeFlags::fpnSyntheticNode; // block is not a user specifier block
  8862. pnodeCase->pnodeBody->pnodeStmt = pnodeBody;
  8863. }
  8864. else
  8865. {
  8866. pnodeCase->pnodeBody = nullptr;
  8867. }
  8868. *ppnodeCase = pnodeCase;
  8869. ppnodeCase = &pnodeCase->pnodeNext;
  8870. }
  8871. }
  8872. LEndSwitch:
  8873. ChkCurTok(tkRCurly, ERRnoRcurly);
  8874. if (buildAST)
  8875. {
  8876. *ppnodeCase = nullptr;
  8877. PopFuncBlockScope(ppnodeScopeSave, ppnodeExprScopeSave);
  8878. FinishParseBlock(pnode->AsParseNodeSwitch()->pnodeBlock);
  8879. }
  8880. else
  8881. {
  8882. FinishParseBlock(pnodeBlock);
  8883. }
  8884. PopStmt(&stmt);
  8885. break;
  8886. }
  8887. case tkWHILE:
  8888. {
  8889. ichMin = this->GetScanner()->IchMinTok();
  8890. ChkNxtTok(tkLParen, ERRnoLparen);
  8891. ParseNodePtr pnodeCond = ParseExpr<buildAST>();
  8892. charcount_t ichLim = this->GetScanner()->IchLimTok();
  8893. ChkCurTok(tkRParen, ERRnoRparen);
  8894. ParseNodeWhile * pnodeWhile = nullptr;
  8895. if (buildAST)
  8896. {
  8897. pnodeWhile = CreateNodeForOpT<knopWhile>(ichMin);
  8898. pnodeWhile->pnodeCond = pnodeCond;
  8899. pnodeWhile->ichLim = ichLim;
  8900. }
  8901. bool stashedDisallowImportExportStmt = m_disallowImportExportStmt;
  8902. m_disallowImportExportStmt = true;
  8903. PushStmt<buildAST>(&stmt, pnodeWhile, knopWhile, pLabelIdList);
  8904. ParseNodePtr pnodeBody = ParseStatement<buildAST>();
  8905. PopStmt(&stmt);
  8906. if (buildAST)
  8907. {
  8908. pnodeWhile->pnodeBody = pnodeBody;
  8909. pnode = pnodeWhile;
  8910. }
  8911. m_disallowImportExportStmt = stashedDisallowImportExportStmt;
  8912. break;
  8913. }
  8914. case tkDO:
  8915. {
  8916. ParseNodeWhile * pnodeWhile = nullptr;
  8917. if (buildAST)
  8918. {
  8919. pnodeWhile = CreateNodeForOpT<knopDoWhile>();
  8920. }
  8921. PushStmt<buildAST>(&stmt, pnodeWhile, knopDoWhile, pLabelIdList);
  8922. this->GetScanner()->Scan();
  8923. bool stashedDisallowImportExportStmt = m_disallowImportExportStmt;
  8924. m_disallowImportExportStmt = true;
  8925. ParseNodePtr pnodeBody = ParseStatement<buildAST>();
  8926. m_disallowImportExportStmt = stashedDisallowImportExportStmt;
  8927. PopStmt(&stmt);
  8928. charcount_t ichMinT = this->GetScanner()->IchMinTok();
  8929. ChkCurTok(tkWHILE, ERRnoWhile);
  8930. ChkCurTok(tkLParen, ERRnoLparen);
  8931. ParseNodePtr pnodeCond = ParseExpr<buildAST>();
  8932. charcount_t ichLim = this->GetScanner()->IchLimTok();
  8933. ChkCurTok(tkRParen, ERRnoRparen);
  8934. if (buildAST)
  8935. {
  8936. pnodeWhile->pnodeBody = pnodeBody;
  8937. pnodeWhile->pnodeCond = pnodeCond;
  8938. pnodeWhile->ichLim = ichLim;
  8939. pnodeWhile->ichMin = ichMinT;
  8940. pnode = pnodeWhile;
  8941. }
  8942. // REVIEW: Allow do...while statements to be embedded in other compound statements like if..else, or do..while?
  8943. // goto LNeedTerminator;
  8944. // For now just eat the trailing semicolon if present.
  8945. if (m_token.tk == tkSColon)
  8946. {
  8947. if (pnode)
  8948. {
  8949. pnode->grfpn |= PNodeFlags::fpnExplicitSemicolon;
  8950. }
  8951. this->GetScanner()->Scan();
  8952. }
  8953. else if (pnode)
  8954. {
  8955. pnode->grfpn |= PNodeFlags::fpnAutomaticSemicolon;
  8956. }
  8957. break;
  8958. }
  8959. case tkIF:
  8960. {
  8961. ichMin = this->GetScanner()->IchMinTok();
  8962. ChkNxtTok(tkLParen, ERRnoLparen);
  8963. ParseNodePtr pnodeCond = ParseExpr<buildAST>();
  8964. ParseNodeIf * pnodeIf = nullptr;
  8965. if (buildAST)
  8966. {
  8967. pnodeIf = CreateNodeForOpT<knopIf>(ichMin);
  8968. pnodeIf->ichLim = this->GetScanner()->IchLimTok();
  8969. pnodeIf->pnodeCond = pnodeCond;
  8970. }
  8971. ChkCurTok(tkRParen, ERRnoRparen);
  8972. bool stashedDisallowImportExportStmt = m_disallowImportExportStmt;
  8973. m_disallowImportExportStmt = true;
  8974. PushStmt<buildAST>(&stmt, pnodeIf, knopIf, pLabelIdList);
  8975. ParseNodePtr pnodeTrue = ParseStatement<buildAST>();
  8976. ParseNodePtr pnodeFalse = nullptr;
  8977. if (m_token.tk == tkELSE)
  8978. {
  8979. this->GetScanner()->Scan();
  8980. pnodeFalse = ParseStatement<buildAST>();
  8981. }
  8982. if (buildAST)
  8983. {
  8984. pnodeIf->pnodeTrue = pnodeTrue;
  8985. pnodeIf->pnodeFalse = pnodeFalse;
  8986. pnode = pnodeIf;
  8987. }
  8988. PopStmt(&stmt);
  8989. m_disallowImportExportStmt = stashedDisallowImportExportStmt;
  8990. break;
  8991. }
  8992. case tkTRY:
  8993. {
  8994. ParseNodeBlock * pnodeBlock = CreateBlockNode();
  8995. pnodeBlock->grfpn |= PNodeFlags::fpnSyntheticNode; // block is not a user specifier block
  8996. PushStmt<buildAST>(&stmt, pnodeBlock, knopBlock, pLabelIdList);
  8997. ParseNodePtr pnodeStmt = ParseTryCatchFinally<buildAST>();
  8998. if (buildAST)
  8999. {
  9000. pnodeBlock->pnodeStmt = pnodeStmt;
  9001. }
  9002. PopStmt(&stmt);
  9003. pnode = pnodeBlock;
  9004. break;
  9005. }
  9006. case tkWITH:
  9007. {
  9008. if (IsStrictMode())
  9009. {
  9010. Error(ERRES5NoWith);
  9011. }
  9012. if (m_currentNodeFunc)
  9013. {
  9014. GetCurrentFunctionNode()->SetHasWithStmt(); // Used by DeferNested
  9015. }
  9016. ichMin = this->GetScanner()->IchMinTok();
  9017. ChkNxtTok(tkLParen, ERRnoLparen);
  9018. ParseNodePtr pnodeObj = ParseExpr<buildAST>();
  9019. if (!buildAST)
  9020. {
  9021. m_scopeCountNoAst++;
  9022. }
  9023. charcount_t ichLim = this->GetScanner()->IchLimTok();
  9024. ChkCurTok(tkRParen, ERRnoRparen);
  9025. ParseNodeWith * pnodeWith = nullptr;
  9026. if (buildAST)
  9027. {
  9028. pnodeWith = CreateNodeForOpT<knopWith>(ichMin);
  9029. }
  9030. PushStmt<buildAST>(&stmt, pnodeWith, knopWith, pLabelIdList);
  9031. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  9032. if (buildAST)
  9033. {
  9034. pnodeWith->pnodeObj = pnodeObj;
  9035. this->CheckArguments(pnodeWith->pnodeObj);
  9036. if (m_ppnodeExprScope)
  9037. {
  9038. Assert(*m_ppnodeExprScope == nullptr);
  9039. *m_ppnodeExprScope = pnodeWith;
  9040. m_ppnodeExprScope = &pnodeWith->pnodeNext;
  9041. }
  9042. else
  9043. {
  9044. Assert(m_ppnodeScope);
  9045. Assert(*m_ppnodeScope == nullptr);
  9046. *m_ppnodeScope = pnodeWith;
  9047. m_ppnodeScope = &pnodeWith->pnodeNext;
  9048. }
  9049. pnodeWith->pnodeNext = nullptr;
  9050. pnodeWith->scope = nullptr;
  9051. ppnodeExprScopeSave = m_ppnodeExprScope;
  9052. m_ppnodeExprScope = &pnodeWith->pnodeScopes;
  9053. pnodeWith->pnodeScopes = nullptr;
  9054. pnodeWith->ichLim = ichLim;
  9055. pnode = pnodeWith;
  9056. }
  9057. PushBlockInfo(CreateBlockNode());
  9058. PushDynamicBlock();
  9059. ParseNodePtr pnodeBody = ParseStatement<buildAST>();
  9060. if (buildAST)
  9061. {
  9062. pnode->AsParseNodeWith()->pnodeBody = pnodeBody;
  9063. m_ppnodeExprScope = ppnodeExprScopeSave;
  9064. }
  9065. else
  9066. {
  9067. m_scopeCountNoAst--;
  9068. }
  9069. // The dynamic block is not stored in the actual parse tree and so will not
  9070. // be visited by the byte code generator. Grab the callsEval flag off it and
  9071. // pass on to outer block in case of:
  9072. // with (...) eval(...); // i.e. blockless form of with
  9073. bool callsEval = GetCurrentBlock()->GetCallsEval();
  9074. PopBlockInfo();
  9075. if (callsEval)
  9076. {
  9077. // be careful not to overwrite an existing true with false
  9078. GetCurrentBlock()->SetCallsEval(true);
  9079. }
  9080. PopStmt(&stmt);
  9081. break;
  9082. }
  9083. case tkLCurly:
  9084. pnode = ParseBlock<buildAST>(pLabelIdList);
  9085. break;
  9086. case tkSColon:
  9087. pnode = nullptr;
  9088. this->GetScanner()->Scan();
  9089. break;
  9090. case tkBREAK:
  9091. if (buildAST)
  9092. {
  9093. pnode = CreateNodeForOpT<knopBreak>();
  9094. }
  9095. fnop = fnopBreak;
  9096. goto LGetJumpStatement;
  9097. case tkCONTINUE:
  9098. if (buildAST)
  9099. {
  9100. pnode = CreateNodeForOpT<knopContinue>();
  9101. }
  9102. fnop = fnopContinue;
  9103. LGetJumpStatement:
  9104. this->GetScanner()->ScanForcingPid();
  9105. if (tkID == m_token.tk && !this->GetScanner()->FHadNewLine())
  9106. {
  9107. // Labeled break or continue.
  9108. pid = m_token.GetIdentifier(this->GetHashTbl());
  9109. if (buildAST)
  9110. {
  9111. ParseNodeJump * pnodeJump = pnode->AsParseNodeJump();
  9112. pnodeJump->hasExplicitTarget = true;
  9113. pnodeJump->ichLim = this->GetScanner()->IchLimTok();
  9114. this->GetScanner()->Scan();
  9115. PushStmt<buildAST>(&stmt, pnodeJump, pnodeJump->nop, pLabelIdList);
  9116. Assert(pnodeJump->grfnop == 0);
  9117. for (pstmt = m_pstmtCur; nullptr != pstmt; pstmt = pstmt->pstmtOuter)
  9118. {
  9119. for (LabelId* label = pstmt->pLabelId; label != nullptr; label = label->next)
  9120. {
  9121. if (pid == label->pid)
  9122. {
  9123. // Found the label. Make sure we can use it. We can
  9124. // break out of any statement, but we can only
  9125. // continue loops.
  9126. if (fnop == fnopContinue &&
  9127. !(pstmt->pnodeStmt->Grfnop() & fnop))
  9128. {
  9129. Error(ERRbadContinue);
  9130. }
  9131. else
  9132. {
  9133. pstmt->pnodeStmt->grfnop |= fnop;
  9134. pnodeJump->pnodeTarget = pstmt->pnodeStmt;
  9135. }
  9136. PopStmt(&stmt);
  9137. goto LNeedTerminator;
  9138. }
  9139. }
  9140. pnodeJump->grfnop |=
  9141. (pstmt->pnodeStmt->Grfnop() & fnopCleanup);
  9142. }
  9143. }
  9144. else
  9145. {
  9146. this->GetScanner()->Scan();
  9147. // Check if label is found within the current label id list.
  9148. auto checkLabelList = [&](LabelId* list, StmtNest* checkStmtOp)
  9149. {
  9150. for (LabelId* pLabelId = list; pLabelId; pLabelId = pLabelId->next)
  9151. {
  9152. if (pid == pLabelId->pid)
  9153. {
  9154. // Found the label. Make sure we can use it. We can
  9155. // break out of any statement, but we can only
  9156. // continue loops.
  9157. if (fnop == fnopContinue &&
  9158. !(ParseNode::Grfnop(checkStmtOp->op) & fnop))
  9159. {
  9160. Error(ERRbadContinue);
  9161. }
  9162. return true;
  9163. }
  9164. }
  9165. return false;
  9166. };
  9167. if (checkLabelList(pLabelIdList, m_pstmtCur)) goto LNeedTerminator;
  9168. for (pstmt = m_pstmtCur; pstmt; pstmt = pstmt->pstmtOuter)
  9169. {
  9170. if (checkLabelList(pstmt->pLabelId, pstmt)) goto LNeedTerminator;
  9171. }
  9172. }
  9173. Error(ERRnoLabel);
  9174. }
  9175. else
  9176. {
  9177. // If we're doing a fast scan, we're not tracking labels, so we can't accurately do this analysis.
  9178. // Let the thread that's doing the full parse detect the error, if there is one.
  9179. if (!this->IsDoingFastScan())
  9180. {
  9181. // Unlabeled break or continue.
  9182. ParseNodeJump * pnodeJump = nullptr;
  9183. if (buildAST)
  9184. {
  9185. pnodeJump = pnode->AsParseNodeJump();
  9186. pnodeJump->hasExplicitTarget = false;
  9187. PushStmt<buildAST>(&stmt, pnodeJump, pnodeJump->nop, pLabelIdList);
  9188. Assert(pnodeJump->grfnop == 0);
  9189. }
  9190. for (pstmt = m_pstmtCur; nullptr != pstmt; pstmt = pstmt->pstmtOuter)
  9191. {
  9192. if (buildAST)
  9193. {
  9194. AnalysisAssert(pstmt->pnodeStmt);
  9195. if (pstmt->pnodeStmt->Grfnop() & fnop)
  9196. {
  9197. pstmt->pnodeStmt->grfnop |= fnop;
  9198. pnodeJump->pnodeTarget = pstmt->pnodeStmt;
  9199. PopStmt(&stmt);
  9200. goto LNeedTerminator;
  9201. }
  9202. pnodeJump->grfnop |=
  9203. (pstmt->pnodeStmt->Grfnop() & fnopCleanup);
  9204. }
  9205. else
  9206. {
  9207. if (ParseNode::Grfnop(pstmt->GetNop()) & fnop)
  9208. {
  9209. if (!pstmt->isDeferred)
  9210. {
  9211. AnalysisAssert(pstmt->pnodeStmt);
  9212. pstmt->pnodeStmt->grfnop |= fnop;
  9213. }
  9214. goto LNeedTerminator;
  9215. }
  9216. }
  9217. }
  9218. Error(fnop == fnopBreak ? ERRbadBreak : ERRbadContinue);
  9219. }
  9220. goto LNeedTerminator;
  9221. }
  9222. case tkRETURN:
  9223. {
  9224. ParseNodeReturn * pnodeReturn;
  9225. if (buildAST)
  9226. {
  9227. if (nullptr == m_currentNodeFunc || IsTopLevelModuleFunc())
  9228. {
  9229. Error(ERRbadReturn);
  9230. }
  9231. pnodeReturn = CreateNodeForOpT<knopReturn>();
  9232. }
  9233. this->GetScanner()->Scan();
  9234. ParseNodePtr pnodeExpr = nullptr;
  9235. ParseOptionalExpr<buildAST>(&pnodeExpr, true);
  9236. // Class constructors have special semantics regarding return statements.
  9237. // This might require a reference to 'this'
  9238. if (GetCurrentFunctionNode()->IsClassConstructor())
  9239. {
  9240. ReferenceSpecialName(wellKnownPropertyPids._this);
  9241. }
  9242. if (buildAST)
  9243. {
  9244. pnodeReturn->pnodeExpr = pnodeExpr;
  9245. if (pnodeExpr)
  9246. {
  9247. this->CheckArguments(pnodeReturn->pnodeExpr);
  9248. pnodeReturn->ichLim = pnodeReturn->pnodeExpr->ichLim;
  9249. }
  9250. // See if return should call finally
  9251. PushStmt<buildAST>(&stmt, pnodeReturn, knopReturn, pLabelIdList);
  9252. Assert(pnodeReturn->grfnop == 0);
  9253. for (pstmt = m_pstmtCur; nullptr != pstmt; pstmt = pstmt->pstmtOuter)
  9254. {
  9255. if (pstmt->pnodeStmt->Grfnop() & fnopCleanup)
  9256. {
  9257. pnodeReturn->grfnop |= fnopCleanup;
  9258. break;
  9259. }
  9260. }
  9261. PopStmt(&stmt);
  9262. pnode = pnodeReturn;
  9263. }
  9264. goto LNeedTerminator;
  9265. }
  9266. case tkTHROW:
  9267. {
  9268. if (buildAST)
  9269. {
  9270. pnode = CreateUniNode(knopThrow, nullptr);
  9271. }
  9272. this->GetScanner()->Scan();
  9273. ParseNodePtr pnode1 = nullptr;
  9274. if (m_token.tk != tkSColon &&
  9275. m_token.tk != tkRCurly &&
  9276. !this->GetScanner()->FHadNewLine())
  9277. {
  9278. pnode1 = ParseExpr<buildAST>();
  9279. }
  9280. else
  9281. {
  9282. Error(ERRdanglingThrow);
  9283. }
  9284. if (buildAST)
  9285. {
  9286. pnode->AsParseNodeUni()->pnode1 = pnode1;
  9287. if (pnode1)
  9288. {
  9289. this->CheckArguments(pnode->AsParseNodeUni()->pnode1);
  9290. pnode->ichLim = pnode->AsParseNodeUni()->pnode1->ichLim;
  9291. }
  9292. }
  9293. goto LNeedTerminator;
  9294. }
  9295. case tkDEBUGGER:
  9296. if (buildAST)
  9297. {
  9298. pnode = CreateNodeForOpT<knopDebugger>();
  9299. }
  9300. this->GetScanner()->Scan();
  9301. goto LNeedTerminator;
  9302. case tkIMPORT:
  9303. pnode = ParseImport<buildAST>();
  9304. goto LNeedTerminator;
  9305. case tkEXPORT:
  9306. {
  9307. if (!(m_grfscr & fscrIsModuleCode))
  9308. {
  9309. goto LDefaultToken;
  9310. }
  9311. bool needTerminator = false;
  9312. pnode = ParseExportDeclaration<buildAST>(&needTerminator);
  9313. if (needTerminator)
  9314. {
  9315. goto LNeedTerminator;
  9316. }
  9317. else
  9318. {
  9319. break;
  9320. }
  9321. }
  9322. LDefaultToken:
  9323. default:
  9324. {
  9325. // First check for a label via lookahead. If not found,
  9326. // rewind and reparse as expression statement.
  9327. if (m_token.tk == tkID)
  9328. {
  9329. RestorePoint idStart;
  9330. this->GetScanner()->Capture(&idStart);
  9331. IdentPtr pidInner = m_token.GetIdentifier(this->GetHashTbl());
  9332. this->GetScanner()->Scan();
  9333. if (m_token.tk == tkColon)
  9334. {
  9335. // We have a label.
  9336. if (LabelExists(pidInner, pLabelIdList))
  9337. {
  9338. Error(ERRbadLabel);
  9339. }
  9340. LabelId* pLabelId = CreateLabelId(pidInner);
  9341. pLabelId->next = pLabelIdList;
  9342. pLabelIdList = pLabelId;
  9343. this->GetScanner()->Scan();
  9344. labelledStatement = true;
  9345. goto LRestart;
  9346. }
  9347. // No label, rewind back to the tkID and parse an expression
  9348. this->GetScanner()->SeekTo(idStart);
  9349. }
  9350. // Must be an expression statement.
  9351. pnode = ParseExpr<buildAST>();
  9352. if (m_hasDeferredShorthandInitError)
  9353. {
  9354. Error(ERRnoColon);
  9355. }
  9356. if (buildAST)
  9357. {
  9358. expressionStmt = true;
  9359. AnalysisAssert(pnode);
  9360. pnode->isUsed = false;
  9361. }
  9362. }
  9363. LNeedTerminator:
  9364. // Need a semicolon, new-line, } or end-of-file.
  9365. // We digest a semicolon if it's there.
  9366. switch (m_token.tk)
  9367. {
  9368. case tkSColon:
  9369. this->GetScanner()->Scan();
  9370. if (pnode != nullptr) pnode->grfpn |= PNodeFlags::fpnExplicitSemicolon;
  9371. break;
  9372. case tkEOF:
  9373. case tkRCurly:
  9374. if (pnode != nullptr) pnode->grfpn |= PNodeFlags::fpnAutomaticSemicolon;
  9375. break;
  9376. default:
  9377. if (!this->GetScanner()->FHadNewLine())
  9378. {
  9379. Error(ERRnoSemic);
  9380. }
  9381. else
  9382. {
  9383. if (pnode != nullptr) pnode->grfpn |= PNodeFlags::fpnAutomaticSemicolon;
  9384. }
  9385. break;
  9386. }
  9387. break;
  9388. }
  9389. if (m_hasDeferredShorthandInitError)
  9390. {
  9391. Error(ERRnoColon);
  9392. }
  9393. if (buildAST)
  9394. {
  9395. // All non expression statements excluded from the "this.x" optimization
  9396. // Another check while parsing expressions
  9397. if (!expressionStmt)
  9398. {
  9399. if (m_currentNodeFunc)
  9400. {
  9401. m_currentNodeFunc->SetHasNonThisStmt();
  9402. }
  9403. else if (m_currentNodeProg)
  9404. {
  9405. m_currentNodeProg->SetHasNonThisStmt();
  9406. }
  9407. }
  9408. #if EXCEPTION_RECOVERY
  9409. // close the try/catch block
  9410. if (Js::Configuration::Global.flags.SwallowExceptions)
  9411. {
  9412. // pop the try block and fill in the body
  9413. PopStmt(&stmtTryBlock);
  9414. pTryBlock->pnodeStmt = pnode;
  9415. PopStmt(&stmtTry);
  9416. if (pnode != nullptr)
  9417. {
  9418. pTry->ichLim = pnode->ichLim;
  9419. }
  9420. pTry->pnodeBody = pTryBlock;
  9421. // create a catch block with an empty body
  9422. StmtNest stmtCatch;
  9423. ParseNodeCatch * pCatch;
  9424. pCatch = CreateNodeForOpT<knopCatch>();
  9425. PushStmt<buildAST>(&stmtCatch, pCatch, knopCatch, nullptr);
  9426. pCatch->pnodeBody = nullptr;
  9427. if (pnode != nullptr)
  9428. {
  9429. pCatch->ichLim = pnode->ichLim;
  9430. }
  9431. pCatch->grfnop = 0;
  9432. pCatch->pnodeNext = nullptr;
  9433. // create a fake name for the catch var.
  9434. const WCHAR *uniqueNameStr = _u("__ehobj");
  9435. IdentPtr uniqueName = this->GetHashTbl()->PidHashNameLen(uniqueNameStr, static_cast<int32>(wcslen(uniqueNameStr)));
  9436. pCatch->SetParam(CreateNameNode(uniqueName));
  9437. // Add this catch to the current list. We don't bother adjusting the catch and function expression
  9438. // lists here because the catch is just an empty statement.
  9439. if (m_ppnodeExprScope)
  9440. {
  9441. Assert(*m_ppnodeExprScope == nullptr);
  9442. *m_ppnodeExprScope = pCatch;
  9443. m_ppnodeExprScope = &pCatch->pnodeNext;
  9444. }
  9445. else
  9446. {
  9447. Assert(m_ppnodeScope);
  9448. Assert(*m_ppnodeScope == nullptr);
  9449. *m_ppnodeScope = pCatch;
  9450. m_ppnodeScope = &pCatch->pnodeNext;
  9451. }
  9452. pCatch->pnodeScopes = nullptr;
  9453. PopStmt(&stmtCatch);
  9454. // fill in and pop the try-catch
  9455. pParentTryCatch->pnodeTry = pTry;
  9456. pParentTryCatch->pnodeCatch = pCatch;
  9457. PopStmt(&stmtTryCatch);
  9458. PopStmt(&stmtTryCatchBlock);
  9459. // replace the node that's being returned
  9460. pParentTryCatchBlock->pnodeStmt = pParentTryCatch;
  9461. pnode = pParentTryCatchBlock;
  9462. }
  9463. #endif // EXCEPTION_RECOVERY
  9464. }
  9465. return pnode;
  9466. }
  9467. BOOL
  9468. Parser::TokIsForInOrForOf()
  9469. {
  9470. return m_token.tk == tkIN ||
  9471. (m_token.tk == tkID &&
  9472. m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.of);
  9473. }
  9474. /***************************************************************************
  9475. Parse a sequence of statements.
  9476. ***************************************************************************/
  9477. template<bool buildAST>
  9478. void Parser::ParseStmtList(ParseNodePtr *ppnodeList, ParseNodePtr **pppnodeLast, StrictModeEnvironment smEnvironment, const bool isSourceElementList, bool* strictModeOn)
  9479. {
  9480. BOOL doneDirectives = !isSourceElementList; // directives may only exist in a SourceElementList, not a StatementList
  9481. BOOL seenDirectiveContainingOctal = false; // Have we seen an octal directive before a use strict directive?
  9482. BOOL old_UseStrictMode = m_fUseStrictMode;
  9483. ParseNodePtr pnodeStmt;
  9484. ParseNodePtr *lastNodeRef = nullptr;
  9485. if (buildAST)
  9486. {
  9487. Assert(ppnodeList);
  9488. *ppnodeList = nullptr;
  9489. }
  9490. if (CONFIG_FLAG(ForceStrictMode))
  9491. {
  9492. m_fUseStrictMode = TRUE;
  9493. }
  9494. for (;;)
  9495. {
  9496. switch (m_token.tk)
  9497. {
  9498. case tkCASE:
  9499. case tkDEFAULT:
  9500. case tkRCurly:
  9501. case tkEOF:
  9502. if (buildAST && nullptr != pppnodeLast)
  9503. {
  9504. *pppnodeLast = lastNodeRef;
  9505. }
  9506. if (!buildAST)
  9507. {
  9508. m_fUseStrictMode = old_UseStrictMode;
  9509. }
  9510. return;
  9511. }
  9512. if (doneDirectives == FALSE)
  9513. {
  9514. bool isOctalInString = false;
  9515. bool isUseStrictDirective = false;
  9516. bool isUseAsmDirective = false;
  9517. if (smEnvironment != SM_NotUsed && CheckForDirective(&isUseStrictDirective, &isUseAsmDirective, &isOctalInString))
  9518. {
  9519. // Ignore "use asm" statement when not building the AST
  9520. isUseAsmDirective &= buildAST;
  9521. if (isUseStrictDirective)
  9522. {
  9523. // Functions with non-simple parameter list cannot be made strict mode
  9524. if (GetCurrentFunctionNode()->HasNonSimpleParameterList())
  9525. {
  9526. Error(ERRNonSimpleParamListInStrictMode);
  9527. }
  9528. if (seenDirectiveContainingOctal)
  9529. {
  9530. // Directives seen before a "use strict" cannot contain an octal.
  9531. Error(ERRES5NoOctal);
  9532. }
  9533. if (!buildAST)
  9534. {
  9535. // Turning on strict mode in deferred code.
  9536. m_fUseStrictMode = TRUE;
  9537. if (!m_inDeferredNestedFunc)
  9538. {
  9539. // Top-level deferred function, so there's a parse node
  9540. Assert(m_currentNodeFunc != nullptr);
  9541. m_currentNodeFunc->SetStrictMode();
  9542. }
  9543. else if (strictModeOn)
  9544. {
  9545. // This turns on strict mode in a deferred function, we need to go back
  9546. // and re-check duplicated formals.
  9547. *strictModeOn = true;
  9548. }
  9549. }
  9550. else
  9551. {
  9552. if (smEnvironment == SM_OnGlobalCode)
  9553. {
  9554. // Turning on strict mode at the top level
  9555. m_fUseStrictMode = TRUE;
  9556. }
  9557. else
  9558. {
  9559. // i.e. smEnvironment == SM_OnFunctionCode
  9560. Assert(m_currentNodeFunc != nullptr);
  9561. m_currentNodeFunc->SetStrictMode();
  9562. }
  9563. }
  9564. }
  9565. else if (isUseAsmDirective)
  9566. {
  9567. if (smEnvironment != SM_OnGlobalCode) //Top level use asm doesn't mean anything.
  9568. {
  9569. // i.e. smEnvironment == SM_OnFunctionCode
  9570. Assert(m_currentNodeFunc != nullptr);
  9571. m_currentNodeFunc->SetAsmjsMode();
  9572. m_currentNodeFunc->SetCanBeDeferred(false);
  9573. m_InAsmMode = true;
  9574. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, AsmJSFunction, m_scriptContext);
  9575. }
  9576. }
  9577. else if (isOctalInString)
  9578. {
  9579. seenDirectiveContainingOctal = TRUE;
  9580. }
  9581. }
  9582. else
  9583. {
  9584. // The first time we see anything other than a directive we can have no more directives.
  9585. doneDirectives = TRUE;
  9586. }
  9587. }
  9588. if (nullptr != (pnodeStmt = ParseStatement<buildAST>()))
  9589. {
  9590. if (buildAST)
  9591. {
  9592. AddToNodeList(ppnodeList, &lastNodeRef, pnodeStmt);
  9593. }
  9594. }
  9595. }
  9596. }
  9597. template <class Fn>
  9598. void Parser::FinishFunctionsInScope(ParseNodePtr pnodeScopeList, Fn fn)
  9599. {
  9600. Scope * scope;
  9601. Scope * origCurrentScope = this->m_currentScope;
  9602. ParseNodePtr pnodeScope;
  9603. ParseNodeBlock * pnodeBlock;
  9604. for (pnodeScope = pnodeScopeList; pnodeScope;)
  9605. {
  9606. switch (pnodeScope->nop)
  9607. {
  9608. case knopBlock:
  9609. {
  9610. ParseNodeBlock * pnodeBlockScope = pnodeScope->AsParseNodeBlock();
  9611. m_nextBlockId = pnodeBlockScope->blockId + 1;
  9612. PushBlockInfo(pnodeBlockScope);
  9613. scope = pnodeBlockScope->scope;
  9614. if (scope && scope != origCurrentScope)
  9615. {
  9616. PushScope(scope);
  9617. }
  9618. FinishFunctionsInScope(pnodeBlockScope->pnodeScopes, fn);
  9619. if (scope && scope != origCurrentScope)
  9620. {
  9621. BindPidRefs<false>(GetCurrentBlockInfo(), m_nextBlockId - 1);
  9622. PopScope(scope);
  9623. }
  9624. PopBlockInfo();
  9625. pnodeScope = pnodeBlockScope->pnodeNext;
  9626. break;
  9627. }
  9628. case knopFncDecl:
  9629. fn(pnodeScope->AsParseNodeFnc());
  9630. pnodeScope = pnodeScope->AsParseNodeFnc()->pnodeNext;
  9631. break;
  9632. case knopCatch:
  9633. scope = pnodeScope->AsParseNodeCatch()->scope;
  9634. if (scope)
  9635. {
  9636. PushScope(scope);
  9637. }
  9638. pnodeBlock = CreateBlockNode(PnodeBlockType::Regular);
  9639. pnodeBlock->scope = scope;
  9640. PushBlockInfo(pnodeBlock);
  9641. FinishFunctionsInScope(pnodeScope->AsParseNodeCatch()->pnodeScopes, fn);
  9642. if (scope)
  9643. {
  9644. BindPidRefs<false>(GetCurrentBlockInfo(), m_nextBlockId - 1);
  9645. PopScope(scope);
  9646. }
  9647. PopBlockInfo();
  9648. pnodeScope = pnodeScope->AsParseNodeCatch()->pnodeNext;
  9649. break;
  9650. case knopWith:
  9651. PushBlockInfo(CreateBlockNode());
  9652. PushDynamicBlock();
  9653. FinishFunctionsInScope(pnodeScope->AsParseNodeWith()->pnodeScopes, fn);
  9654. PopBlockInfo();
  9655. pnodeScope = pnodeScope->AsParseNodeWith()->pnodeNext;
  9656. break;
  9657. default:
  9658. AssertMsg(false, "Unexpected node with scope list");
  9659. return;
  9660. }
  9661. }
  9662. }
  9663. // Scripts above this size (minus string literals and comments) will have parsing of
  9664. // function bodies deferred.
  9665. ULONG Parser::GetDeferralThreshold(bool isProfileLoaded)
  9666. {
  9667. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  9668. if (CONFIG_FLAG(ForceDeferParse) ||
  9669. PHASE_FORCE1(Js::DeferParsePhase) ||
  9670. Js::Configuration::Global.flags.IsEnabled(Js::ForceUndoDeferFlag))
  9671. {
  9672. return 0;
  9673. }
  9674. else if (Js::Configuration::Global.flags.IsEnabled(Js::DeferParseFlag))
  9675. {
  9676. return Js::Configuration::Global.flags.DeferParse;
  9677. }
  9678. else
  9679. #endif
  9680. {
  9681. if (isProfileLoaded)
  9682. {
  9683. return DEFAULT_CONFIG_ProfileBasedDeferParseThreshold;
  9684. }
  9685. return DEFAULT_CONFIG_DeferParseThreshold;
  9686. }
  9687. }
  9688. void Parser::FinishDeferredFunction(ParseNodeBlock * pnodeScopeList)
  9689. {
  9690. uint saveNextBlockId = m_nextBlockId;
  9691. m_nextBlockId = pnodeScopeList->blockId + 1;
  9692. FinishFunctionsInScope(pnodeScopeList,
  9693. [this](ParseNodeFnc * pnodeFnc)
  9694. {
  9695. Assert(pnodeFnc->nop == knopFncDecl);
  9696. // Non-simple params (such as default) require a good amount of logic to put vars on appropriate scopes. ParseFncDecl handles it
  9697. // properly (both on defer and non-defer case). This is to avoid write duplicated logic here as well. Function with non-simple-param
  9698. // will remain deferred until they are called.
  9699. if (pnodeFnc->pnodeBody == nullptr && !pnodeFnc->HasNonSimpleParameterList())
  9700. {
  9701. // Go back and generate an AST for this function.
  9702. JS_ETW_INTERNAL(EventWriteJSCRIPT_PARSE_FUNC(this->GetScriptContext(), pnodeFnc->functionId, /*Undefer*/TRUE));
  9703. ParseNodeFnc * pnodeFncSave = this->m_currentNodeFunc;
  9704. this->m_currentNodeFunc = pnodeFnc;
  9705. ParseNodeBlock * pnodeFncExprBlock = nullptr;
  9706. ParseNodePtr pnodeName = pnodeFnc->pnodeName;
  9707. if (pnodeName)
  9708. {
  9709. Assert(pnodeName->nop == knopVarDecl);
  9710. ParseNodeVar * pnodeVarName = pnodeName->AsParseNodeVar();
  9711. Assert(pnodeVarName->pnodeNext == nullptr);
  9712. if (!pnodeFnc->IsDeclaration())
  9713. {
  9714. // Set up the named function expression symbol so references inside the function can be bound.
  9715. pnodeFncExprBlock = this->StartParseBlock<true>(PnodeBlockType::Function, ScopeType_FuncExpr);
  9716. PidRefStack *ref = this->PushPidRef(pnodeVarName->pid);
  9717. pnodeVarName->symRef = ref->GetSymRef();
  9718. ref->SetSym(pnodeVarName->sym);
  9719. Scope *fncExprScope = pnodeFncExprBlock->scope;
  9720. fncExprScope->AddNewSymbol(pnodeVarName->sym);
  9721. pnodeFnc->scope = fncExprScope;
  9722. }
  9723. }
  9724. ParseNodeBlock * pnodeBlock = this->StartParseBlock<true>(PnodeBlockType::Parameter, ScopeType_Parameter);
  9725. pnodeFnc->pnodeScopes = pnodeBlock;
  9726. m_ppnodeScope = &pnodeBlock->pnodeScopes;
  9727. pnodeBlock->pnodeStmt = pnodeFnc;
  9728. ParseNodePtr * varNodesList = &pnodeFnc->pnodeVars;
  9729. ParseNodeVar * argNode = nullptr;
  9730. if (!pnodeFnc->IsModule() && !pnodeFnc->IsLambda() && !(pnodeFnc->grfpn & PNodeFlags::fpnArguments_overriddenInParam))
  9731. {
  9732. ParseNodePtr *const ppnodeVarSave = m_ppnodeVar;
  9733. m_ppnodeVar = &pnodeFnc->pnodeVars;
  9734. argNode = this->AddArgumentsNodeToVars(pnodeFnc);
  9735. varNodesList = m_ppnodeVar;
  9736. m_ppnodeVar = ppnodeVarSave;
  9737. }
  9738. // Add the args to the scope, since we won't re-parse those.
  9739. Scope *scope = pnodeBlock->scope;
  9740. uint blockId = GetCurrentBlock()->blockId;
  9741. uint funcId = GetCurrentFunctionNode()->functionId;
  9742. auto addArgsToScope = [&](ParseNodePtr pnodeArg) {
  9743. if (pnodeArg->IsVarLetOrConst())
  9744. {
  9745. ParseNodeVar * pnodeVarArg = pnodeArg->AsParseNodeVar();
  9746. PidRefStack *ref = this->FindOrAddPidRef(pnodeVarArg->pid, blockId, funcId);
  9747. pnodeVarArg->symRef = ref->GetSymRef();
  9748. if (ref->GetSym() != nullptr)
  9749. {
  9750. // Duplicate parameter in a configuration that allows them.
  9751. // The symbol is already in the scope, just point it to the right declaration.
  9752. Assert(ref->GetSym() == pnodeVarArg->sym);
  9753. ref->GetSym()->SetDecl(pnodeVarArg);
  9754. }
  9755. else
  9756. {
  9757. ref->SetSym(pnodeArg->AsParseNodeVar()->sym);
  9758. scope->AddNewSymbol(pnodeVarArg->sym);
  9759. }
  9760. }
  9761. };
  9762. MapFormals(pnodeFnc, addArgsToScope);
  9763. MapFormalsFromPattern(pnodeFnc, addArgsToScope);
  9764. ParseNodeBlock * pnodeInnerBlock = this->StartParseBlock<true>(PnodeBlockType::Function, ScopeType_FunctionBody);
  9765. pnodeFnc->pnodeBodyScope = pnodeInnerBlock;
  9766. // Set the parameter block's child to the function body block.
  9767. *m_ppnodeScope = pnodeInnerBlock;
  9768. ParseNodePtr *ppnodeScopeSave = nullptr;
  9769. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  9770. ppnodeScopeSave = m_ppnodeScope;
  9771. // This synthetic block scope will contain all the nested scopes.
  9772. m_ppnodeScope = &pnodeInnerBlock->pnodeScopes;
  9773. pnodeInnerBlock->pnodeStmt = pnodeFnc;
  9774. // Keep nested function declarations and expressions in the same list at function scope.
  9775. // (Indicate this by nulling out the current function expressions list.)
  9776. ppnodeExprScopeSave = m_ppnodeExprScope;
  9777. m_ppnodeExprScope = nullptr;
  9778. // Shouldn't be any temps in the arg list.
  9779. Assert(*m_ppnodeVar == nullptr);
  9780. // Start the var list.
  9781. m_ppnodeVar = varNodesList;
  9782. if (scope != nullptr)
  9783. {
  9784. Assert(pnodeFnc->IsBodyAndParamScopeMerged());
  9785. blockId = GetCurrentBlock()->blockId;
  9786. funcId = GetCurrentFunctionNode()->functionId;
  9787. scope->ForEachSymbol([this, blockId, funcId](Symbol* paramSym)
  9788. {
  9789. PidRefStack* ref = this->FindOrAddPidRef(paramSym->GetPid(), blockId, funcId);
  9790. ref->SetSym(paramSym);
  9791. });
  9792. }
  9793. Assert(m_currentNodeNonLambdaFunc == nullptr);
  9794. m_currentNodeNonLambdaFunc = pnodeFnc;
  9795. this->FinishFncNode(pnodeFnc);
  9796. Assert(pnodeFnc == m_currentNodeNonLambdaFunc);
  9797. m_currentNodeNonLambdaFunc = nullptr;
  9798. m_ppnodeExprScope = ppnodeExprScopeSave;
  9799. Assert(m_ppnodeScope);
  9800. Assert(nullptr == *m_ppnodeScope);
  9801. m_ppnodeScope = ppnodeScopeSave;
  9802. this->FinishParseBlock(pnodeInnerBlock);
  9803. if (!pnodeFnc->IsModule() && (m_token.tk == tkLCurly || !pnodeFnc->IsLambda()))
  9804. {
  9805. UpdateArgumentsNode(pnodeFnc, argNode);
  9806. }
  9807. CreateSpecialSymbolDeclarations(pnodeFnc);
  9808. this->FinishParseBlock(pnodeBlock);
  9809. if (pnodeFncExprBlock)
  9810. {
  9811. this->FinishParseBlock(pnodeFncExprBlock);
  9812. }
  9813. this->m_currentNodeFunc = pnodeFncSave;
  9814. }
  9815. });
  9816. m_nextBlockId = saveNextBlockId;
  9817. }
  9818. void Parser::InitPids()
  9819. {
  9820. wellKnownPropertyPids.arguments = this->GetHashTbl()->PidHashNameLen(g_ssym_arguments.sz, g_ssym_arguments.cch);
  9821. wellKnownPropertyPids.async = this->GetHashTbl()->PidHashNameLen(g_ssym_async.sz, g_ssym_async.cch);
  9822. wellKnownPropertyPids.eval = this->GetHashTbl()->PidHashNameLen(g_ssym_eval.sz, g_ssym_eval.cch);
  9823. wellKnownPropertyPids.get = this->GetHashTbl()->PidHashNameLen(g_ssym_get.sz, g_ssym_get.cch);
  9824. wellKnownPropertyPids.set = this->GetHashTbl()->PidHashNameLen(g_ssym_set.sz, g_ssym_set.cch);
  9825. wellKnownPropertyPids.let = this->GetHashTbl()->PidHashNameLen(g_ssym_let.sz, g_ssym_let.cch);
  9826. wellKnownPropertyPids.constructor = this->GetHashTbl()->PidHashNameLen(g_ssym_constructor.sz, g_ssym_constructor.cch);
  9827. wellKnownPropertyPids.prototype = this->GetHashTbl()->PidHashNameLen(g_ssym_prototype.sz, g_ssym_prototype.cch);
  9828. wellKnownPropertyPids.__proto__ = this->GetHashTbl()->PidHashNameLen(_u("__proto__"), sizeof("__proto__") - 1);
  9829. wellKnownPropertyPids.of = this->GetHashTbl()->PidHashNameLen(_u("of"), sizeof("of") - 1);
  9830. wellKnownPropertyPids.target = this->GetHashTbl()->PidHashNameLen(_u("target"), sizeof("target") - 1);
  9831. wellKnownPropertyPids.as = this->GetHashTbl()->PidHashNameLen(_u("as"), sizeof("as") - 1);
  9832. wellKnownPropertyPids.from = this->GetHashTbl()->PidHashNameLen(_u("from"), sizeof("from") - 1);
  9833. wellKnownPropertyPids._default = this->GetHashTbl()->PidHashNameLen(_u("default"), sizeof("default") - 1);
  9834. wellKnownPropertyPids._starDefaultStar = this->GetHashTbl()->PidHashNameLen(_u("*default*"), sizeof("*default*") - 1);
  9835. wellKnownPropertyPids._star = this->GetHashTbl()->PidHashNameLen(_u("*"), sizeof("*") - 1);
  9836. wellKnownPropertyPids._this = this->GetHashTbl()->PidHashNameLen(_u("*this*"), sizeof("*this*") - 1);
  9837. wellKnownPropertyPids._newTarget = this->GetHashTbl()->PidHashNameLen(_u("*new.target*"), sizeof("*new.target*") - 1);
  9838. wellKnownPropertyPids._super = this->GetHashTbl()->PidHashNameLen(_u("*super*"), sizeof("*super*") - 1);
  9839. wellKnownPropertyPids._superConstructor = this->GetHashTbl()->PidHashNameLen(_u("*superconstructor*"), sizeof("*superconstructor*") - 1);
  9840. }
  9841. void Parser::RestoreScopeInfo(Js::ScopeInfo * scopeInfo)
  9842. {
  9843. if (!scopeInfo)
  9844. {
  9845. return;
  9846. }
  9847. PROBE_STACK_NO_DISPOSE(m_scriptContext, Js::Constants::MinStackByteCodeVisitor);
  9848. RestoreScopeInfo(scopeInfo->GetParentScopeInfo()); // Recursively restore outer func scope info
  9849. scopeInfo->SetScopeId(m_nextBlockId);
  9850. ParseNodeBlock * pnodeScope = nullptr;
  9851. ScopeType scopeType = scopeInfo->GetScopeType();
  9852. PnodeBlockType blockType;
  9853. switch (scopeType)
  9854. {
  9855. case ScopeType_With:
  9856. PushDynamicBlock();
  9857. // fall through
  9858. case ScopeType_Block:
  9859. case ScopeType_Catch:
  9860. case ScopeType_CatchParamPattern:
  9861. case ScopeType_GlobalEvalBlock:
  9862. blockType = PnodeBlockType::Regular;
  9863. break;
  9864. case ScopeType_FunctionBody:
  9865. case ScopeType_FuncExpr:
  9866. blockType = PnodeBlockType::Function;
  9867. break;
  9868. case ScopeType_Parameter:
  9869. blockType = PnodeBlockType::Parameter;
  9870. break;
  9871. default:
  9872. Assert(0);
  9873. return;
  9874. }
  9875. pnodeScope = StartParseBlockWithCapacity<true>(blockType, scopeType, scopeInfo->GetSymbolCount());
  9876. Scope *scope = pnodeScope->scope;
  9877. scope->SetScopeInfo(scopeInfo);
  9878. scopeInfo->ExtractScopeInfo(this, /*nullptr, nullptr,*/ scope);
  9879. }
  9880. void Parser::FinishScopeInfo(Js::ScopeInfo * scopeInfo)
  9881. {
  9882. PROBE_STACK_NO_DISPOSE(m_scriptContext, Js::Constants::MinStackByteCodeVisitor);
  9883. for (; scopeInfo != nullptr; scopeInfo = scopeInfo->GetParentScopeInfo())
  9884. {
  9885. int scopeId = scopeInfo->GetScopeId();
  9886. scopeInfo->GetScope()->ForEachSymbol([this, scopeId](Symbol *sym)
  9887. {
  9888. this->BindPidRefsInScope(sym->GetPid(), sym, scopeId);
  9889. });
  9890. PopScope(scopeInfo->GetScope());
  9891. PopStmt(&m_currentBlockInfo->pstmt);
  9892. PopBlockInfo();
  9893. }
  9894. }
  9895. /***************************************************************************
  9896. Parse the code.
  9897. ***************************************************************************/
  9898. ParseNodeProg * Parser::Parse(LPCUTF8 pszSrc, size_t offset, size_t length, charcount_t charOffset, bool isUtf8, ULONG grfscr, ULONG lineNumber, Js::LocalFunctionId * nextFunctionId, CompileScriptException *pse)
  9899. {
  9900. ParseNodeProg * pnodeProg;
  9901. ParseNodePtr *lastNodeRef = nullptr;
  9902. m_nextBlockId = 0;
  9903. bool isDeferred = (grfscr & fscrDeferredFnc) != 0;
  9904. bool isModuleSource = (grfscr & fscrIsModuleCode) != 0;
  9905. bool isGlobalCode = (grfscr & fscrGlobalCode) != 0;
  9906. if (this->m_scriptContext->IsScriptContextInDebugMode()
  9907. #ifdef ENABLE_PREJIT
  9908. || Js::Configuration::Global.flags.Prejit
  9909. #endif
  9910. || ((grfscr & fscrNoDeferParse) != 0)
  9911. )
  9912. {
  9913. // Don't do deferred parsing if debugger is attached or feature is disabled
  9914. // by command-line switch.
  9915. grfscr &= ~fscrWillDeferFncParse;
  9916. }
  9917. else if (!isGlobalCode &&
  9918. (
  9919. PHASE_OFF1(Js::Phase::DeferEventHandlersPhase) ||
  9920. this->m_scriptContext->IsScriptContextInSourceRundownOrDebugMode()
  9921. )
  9922. )
  9923. {
  9924. // Don't defer event handlers in debug/rundown mode, because we need to register the document,
  9925. // so we need to create a full FunctionBody for the script body.
  9926. grfscr &= ~fscrWillDeferFncParse;
  9927. }
  9928. m_grfscr = grfscr;
  9929. m_length = length;
  9930. m_originalLength = length;
  9931. m_nextFunctionId = nextFunctionId;
  9932. if (m_parseType != ParseType_Deferred)
  9933. {
  9934. JS_ETW(EventWriteJSCRIPT_PARSE_METHOD_START(m_sourceContextInfo->dwHostSourceContext, GetScriptContext(), *m_nextFunctionId, 0, m_parseType, Js::Constants::GlobalFunction));
  9935. OUTPUT_TRACE(Js::DeferParsePhase, _u("Parsing function (%s) : %s (%d)\n"), GetParseType(), Js::Constants::GlobalFunction, *m_nextFunctionId);
  9936. }
  9937. // Give the scanner the source and get the first token
  9938. this->GetScanner()->SetText(pszSrc, offset, length, charOffset, isUtf8, grfscr, lineNumber);
  9939. this->GetScanner()->Scan();
  9940. // Make the main 'knopProg' node
  9941. int32 initSize = 0;
  9942. m_pCurrentAstSize = &initSize;
  9943. pnodeProg = CreateProgNode(isModuleSource, lineNumber);
  9944. if (!isDeferred || (isDeferred && isGlobalCode))
  9945. {
  9946. // In the deferred case, if the global function is deferred parse (which is in no-refresh case),
  9947. // we will re-use the same function body, so start with the correct functionId.
  9948. pnodeProg->functionId = (*m_nextFunctionId)++;
  9949. }
  9950. if (isModuleSource)
  9951. {
  9952. Assert(m_scriptContext->GetConfig()->IsES6ModuleEnabled());
  9953. pnodeProg->AsParseNodeModule()->localExportEntries = nullptr;
  9954. pnodeProg->AsParseNodeModule()->indirectExportEntries = nullptr;
  9955. pnodeProg->AsParseNodeModule()->starExportEntries = nullptr;
  9956. pnodeProg->AsParseNodeModule()->importEntries = nullptr;
  9957. pnodeProg->AsParseNodeModule()->requestedModules = nullptr;
  9958. }
  9959. m_pCurrentAstSize = &(pnodeProg->astSize);
  9960. // initialize parsing variables
  9961. m_currentNodeFunc = nullptr;
  9962. m_currentNodeDeferredFunc = nullptr;
  9963. m_currentNodeProg = pnodeProg;
  9964. m_cactIdentToNodeLookup = 1;
  9965. m_pnestedCount = &pnodeProg->nestedCount;
  9966. m_inDeferredNestedFunc = false;
  9967. m_ppnodeVar = &pnodeProg->pnodeVars;
  9968. SetCurrentStatement(nullptr);
  9969. AssertMsg(m_pstmtCur == nullptr, "Statement stack should be empty when we start parse global code");
  9970. // Create block for const's and let's
  9971. ParseNodeBlock * pnodeGlobalBlock = StartParseBlock<true>(PnodeBlockType::Global, ScopeType_Global);
  9972. pnodeProg->scope = pnodeGlobalBlock->scope;
  9973. ParseNodeBlock * pnodeGlobalEvalBlock = nullptr;
  9974. // Don't track function expressions separately from declarations at global scope.
  9975. m_ppnodeExprScope = nullptr;
  9976. // This synthetic block scope will contain all the nested scopes.
  9977. pnodeProg->pnodeScopes = pnodeGlobalBlock;
  9978. m_ppnodeScope = &pnodeGlobalBlock->pnodeScopes;
  9979. if ((this->m_grfscr & fscrEvalCode) &&
  9980. !(this->m_functionBody && this->m_functionBody->GetScopeInfo()))
  9981. {
  9982. pnodeGlobalEvalBlock = StartParseBlock<true>(PnodeBlockType::Regular, ScopeType_GlobalEvalBlock);
  9983. pnodeProg->pnodeScopes = pnodeGlobalEvalBlock;
  9984. m_ppnodeScope = &pnodeGlobalEvalBlock->pnodeScopes;
  9985. }
  9986. Js::ScopeInfo *scopeInfo = nullptr;
  9987. if (m_parseType == ParseType_Deferred && m_functionBody)
  9988. {
  9989. // this->m_functionBody can be cleared during parsing, but we need access to the scope info later.
  9990. scopeInfo = m_functionBody->GetScopeInfo();
  9991. if (scopeInfo)
  9992. {
  9993. // Create an enclosing function context.
  9994. m_currentNodeFunc = CreateNodeForOpT<knopFncDecl>();
  9995. m_currentNodeFunc->functionId = m_functionBody->GetLocalFunctionId();
  9996. m_currentNodeFunc->nestedCount = m_functionBody->GetNestedCount();
  9997. m_currentNodeFunc->SetStrictMode(!!this->m_fUseStrictMode);
  9998. this->RestoreScopeInfo(scopeInfo);
  9999. m_currentNodeFunc->SetIsGenerator(scopeInfo->IsGeneratorFunctionBody());
  10000. m_currentNodeFunc->SetIsAsync(scopeInfo->IsAsyncFunctionBody());
  10001. }
  10002. }
  10003. // It's possible for the module global to be defer-parsed in debug scenarios.
  10004. if (isModuleSource && (!isDeferred || (isDeferred && isGlobalCode)))
  10005. {
  10006. ParseNodePtr moduleFunction = GenerateModuleFunctionWrapper<true>();
  10007. pnodeProg->pnodeBody = nullptr;
  10008. AddToNodeList(&pnodeProg->pnodeBody, &lastNodeRef, moduleFunction);
  10009. }
  10010. else
  10011. {
  10012. if (isDeferred && !isGlobalCode)
  10013. {
  10014. // Defer parse for a single function should just parse that one function - there are no other statements.
  10015. ushort flags = fFncNoFlgs;
  10016. bool isAsync = false;
  10017. bool isGenerator = false;
  10018. bool isMethod = false;
  10019. // The top-level deferred function body was defined by a function expression whose parsing was deferred. We are now
  10020. // parsing it, so unset the flag so that any nested functions are parsed normally. This flag is only applicable the
  10021. // first time we see it.
  10022. //
  10023. // Normally, deferred functions will be parsed in ParseStatement upon encountering the 'function' token. The first
  10024. // token of the source code of the function may not be a 'function' token though, so we still need to reset this flag
  10025. // for the first function we parse. This can happen in compat modes, for instance, for a function expression enclosed
  10026. // in parentheses, where the legacy behavior was to include the parentheses in the function's source code.
  10027. if (m_grfscr & fscrDeferredFncExpression)
  10028. {
  10029. m_grfscr &= ~fscrDeferredFncExpression;
  10030. }
  10031. else
  10032. {
  10033. flags |= fFncDeclaration;
  10034. }
  10035. if (m_grfscr & fscrDeferredFncIsMethod)
  10036. {
  10037. m_grfscr &= ~fscrDeferredFncIsMethod;
  10038. isMethod = true;
  10039. flags |= fFncNoName | fFncMethod;
  10040. if (m_grfscr & fscrDeferredFncIsGenerator)
  10041. {
  10042. m_grfscr &= ~fscrDeferredFncIsGenerator;
  10043. isGenerator = true;
  10044. flags |= fFncGenerator;
  10045. }
  10046. if (m_token.tk == tkStar && m_scriptContext->GetConfig()->IsES6GeneratorsEnabled())
  10047. {
  10048. Assert(isGenerator && !isMethod);
  10049. this->GetScanner()->Scan();
  10050. }
  10051. }
  10052. if (m_grfscr & fscrDeferredFncIsAsync)
  10053. {
  10054. m_grfscr &= ~fscrDeferredFncIsAsync;
  10055. isAsync = true;
  10056. flags |= fFncAsync;
  10057. }
  10058. #if DBG
  10059. if (isMethod && m_token.tk == tkID)
  10060. {
  10061. RestorePoint atPid;
  10062. IdentPtr pidHint = m_token.GetIdentifier(this->GetHashTbl());
  10063. this->GetScanner()->Capture(&atPid);
  10064. this->GetScanner()->Scan();
  10065. if ((pidHint == wellKnownPropertyPids.get || pidHint == wellKnownPropertyPids.set) && NextTokenIsPropertyNameStart())
  10066. {
  10067. // Getter/setter
  10068. // Skip the get/set keyword and continue normally
  10069. AssertMsg(false, "We should not be re-parsing the get/set part of member accessor functions");
  10070. }
  10071. else
  10072. {
  10073. // Not a getter/setter; rewind and treat the token as a name.
  10074. this->GetScanner()->SeekTo(atPid);
  10075. }
  10076. }
  10077. #endif
  10078. // Ensure this isn't a computed name
  10079. AssertMsg(!(m_token.tk == tkLBrack && isMethod), "Can't defer parse a computed name expression, we should have started after this");
  10080. if (!isMethod && (m_token.tk == tkID || m_token.tk == tkLParen))
  10081. {
  10082. // If first token of the function is tkID or tkLParen, this is a lambda.
  10083. flags |= fFncLambda;
  10084. }
  10085. ParseNode * pnodeFnc = ParseFncDeclCheckScope<true>(flags);
  10086. pnodeProg->pnodeBody = nullptr;
  10087. AddToNodeList(&pnodeProg->pnodeBody, &lastNodeRef, pnodeFnc);
  10088. // No need to update the cbStringMin property since no ParseableFunctionInfo will be created from this defer-parsed pnodeFnc
  10089. }
  10090. else
  10091. {
  10092. // Process a sequence of statements/declarations
  10093. ParseStmtList<true>(
  10094. &pnodeProg->pnodeBody,
  10095. &lastNodeRef,
  10096. SM_OnGlobalCode,
  10097. !(m_grfscr & fscrDeferredFncExpression) /* isSourceElementList */);
  10098. }
  10099. }
  10100. if (m_parseType == ParseType_Deferred)
  10101. {
  10102. if (scopeInfo)
  10103. {
  10104. this->FinishScopeInfo(scopeInfo);
  10105. }
  10106. }
  10107. pnodeProg->m_UsesArgumentsAtGlobal = m_UsesArgumentsAtGlobal;
  10108. if (IsStrictMode())
  10109. {
  10110. pnodeProg->SetStrictMode();
  10111. }
  10112. #if DEBUG
  10113. if (m_grfscr & fscrEnforceJSON && !IsJSONValid(pnodeProg->pnodeBody))
  10114. {
  10115. Error(ERRsyntax);
  10116. }
  10117. #endif
  10118. if (tkEOF != m_token.tk)
  10119. Error(ERRsyntax);
  10120. // Append an EndCode node.
  10121. AddToNodeList(&pnodeProg->pnodeBody, &lastNodeRef,
  10122. CreateNodeForOpT<knopEndCode>());
  10123. Assert(lastNodeRef);
  10124. Assert(*lastNodeRef);
  10125. Assert((*lastNodeRef)->nop == knopEndCode);
  10126. (*lastNodeRef)->ichMin = 0;
  10127. (*lastNodeRef)->ichLim = 0;
  10128. // Get the extent of the code.
  10129. pnodeProg->ichLim = this->GetScanner()->IchLimTok();
  10130. pnodeProg->cbLim = this->GetScanner()->IecpLimTok();
  10131. // Terminate the local list
  10132. *m_ppnodeVar = nullptr;
  10133. Assert(nullptr == *m_ppnodeScope);
  10134. Assert(nullptr == pnodeProg->pnodeNext);
  10135. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  10136. if (Js::Configuration::Global.flags.IsEnabled(Js::ForceUndoDeferFlag))
  10137. {
  10138. m_stoppedDeferredParse = true;
  10139. }
  10140. #endif
  10141. if (m_stoppedDeferredParse)
  10142. {
  10143. #if ENABLE_BACKGROUND_PARSING
  10144. if (this->m_hasParallelJob)
  10145. {
  10146. BackgroundParser *bgp = static_cast<BackgroundParser*>(m_scriptContext->GetBackgroundParser());
  10147. Assert(bgp);
  10148. this->WaitForBackgroundJobs(bgp, pse);
  10149. }
  10150. #endif
  10151. // Do any remaining bindings of globals referenced in non-deferred functions.
  10152. if (pnodeGlobalEvalBlock)
  10153. {
  10154. FinishParseBlock(pnodeGlobalEvalBlock);
  10155. }
  10156. FinishParseBlock(pnodeGlobalBlock);
  10157. // Clear out references to undeclared identifiers.
  10158. this->GetHashTbl()->VisitPids([&](IdentPtr pid) { pid->SetTopRef(nullptr); });
  10159. // Restore global scope and blockinfo stacks preparatory to reparsing deferred functions.
  10160. PushScope(pnodeGlobalBlock->scope);
  10161. BlockInfoStack *newBlockInfo = PushBlockInfo(pnodeGlobalBlock);
  10162. PushStmt<true>(&newBlockInfo->pstmt, pnodeGlobalBlock, knopBlock, nullptr);
  10163. if (pnodeGlobalEvalBlock)
  10164. {
  10165. PushScope(pnodeGlobalEvalBlock->scope);
  10166. newBlockInfo = PushBlockInfo(pnodeGlobalEvalBlock);
  10167. PushStmt<true>(&newBlockInfo->pstmt, pnodeGlobalEvalBlock, knopBlock, nullptr);
  10168. }
  10169. // Finally, see if there are any function bodies we now want to generate because we
  10170. // decided to stop deferring.
  10171. FinishDeferredFunction(pnodeProg->pnodeScopes);
  10172. }
  10173. if (pnodeGlobalEvalBlock)
  10174. {
  10175. FinishParseBlock(pnodeGlobalEvalBlock);
  10176. }
  10177. // Append block as body of pnodeProg
  10178. FinishParseBlock(pnodeGlobalBlock);
  10179. m_scriptContext->AddSourceSize(m_length);
  10180. if (m_parseType != ParseType_Deferred)
  10181. {
  10182. JS_ETW(EventWriteJSCRIPT_PARSE_METHOD_STOP(m_sourceContextInfo->dwHostSourceContext, GetScriptContext(), pnodeProg->functionId, *m_pCurrentAstSize, false, Js::Constants::GlobalFunction));
  10183. }
  10184. return pnodeProg;
  10185. }
  10186. bool Parser::CheckForDirective(bool* pIsUseStrict, bool *pIsUseAsm, bool* pIsOctalInString)
  10187. {
  10188. // A directive is a string constant followed by a statement terminating token
  10189. if (m_token.tk != tkStrCon)
  10190. return false;
  10191. // Careful, need to check for octal before calling this->GetScanner()->Scan()
  10192. // because Scan() clears the "had octal" flag on the scanner and
  10193. // this->GetScanner()->Restore() does not restore this flag.
  10194. if (pIsOctalInString != nullptr)
  10195. {
  10196. *pIsOctalInString = this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber();
  10197. }
  10198. Ident* pidDirective = m_token.GetStr();
  10199. RestorePoint start;
  10200. this->GetScanner()->Capture(&start);
  10201. this->GetScanner()->Scan();
  10202. bool isDirective = true;
  10203. switch (m_token.tk)
  10204. {
  10205. case tkSColon:
  10206. case tkEOF:
  10207. case tkLCurly:
  10208. case tkRCurly:
  10209. break;
  10210. default:
  10211. if (!this->GetScanner()->FHadNewLine())
  10212. {
  10213. isDirective = false;
  10214. }
  10215. break;
  10216. }
  10217. if (isDirective)
  10218. {
  10219. if (pIsUseStrict != nullptr)
  10220. {
  10221. *pIsUseStrict = CheckStrictModeStrPid(pidDirective);
  10222. }
  10223. if (pIsUseAsm != nullptr)
  10224. {
  10225. *pIsUseAsm = CheckAsmjsModeStrPid(pidDirective);
  10226. }
  10227. }
  10228. this->GetScanner()->SeekTo(start);
  10229. return isDirective;
  10230. }
  10231. bool Parser::CheckStrictModeStrPid(IdentPtr pid)
  10232. {
  10233. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  10234. if (Js::Configuration::Global.flags.NoStrictMode)
  10235. return false;
  10236. #endif
  10237. return pid != nullptr &&
  10238. pid->Cch() == 10 &&
  10239. !this->GetScanner()->IsEscapeOnLastTkStrCon() &&
  10240. wcsncmp(pid->Psz(), _u("use strict"), 10) == 0;
  10241. }
  10242. bool Parser::CheckAsmjsModeStrPid(IdentPtr pid)
  10243. {
  10244. #ifdef ASMJS_PLAT
  10245. if (!CONFIG_FLAG(AsmJs))
  10246. {
  10247. return false;
  10248. }
  10249. bool isAsmCandidate = (pid != nullptr &&
  10250. AutoSystemInfo::Data.SSE2Available() &&
  10251. pid->Cch() == 7 &&
  10252. !this->GetScanner()->IsEscapeOnLastTkStrCon() &&
  10253. wcsncmp(pid->Psz(), _u("use asm"), 10) == 0);
  10254. #ifdef ENABLE_SCRIPT_DEBUGGING
  10255. if (isAsmCandidate && m_scriptContext->IsScriptContextInDebugMode())
  10256. {
  10257. // We would like to report this to debugger - they may choose to disable debugging.
  10258. // TODO : localization of the string?
  10259. m_scriptContext->RaiseMessageToDebugger(DEIT_ASMJS_IN_DEBUGGING, _u("AsmJs initialization error - AsmJs disabled due to script debugger"), m_sourceContextInfo && !m_sourceContextInfo->IsDynamic() ? m_sourceContextInfo->url : nullptr);
  10260. return false;
  10261. }
  10262. #endif
  10263. return isAsmCandidate && !(m_grfscr & fscrNoAsmJs);
  10264. #else
  10265. return false;
  10266. #endif
  10267. }
  10268. HRESULT Parser::ParseUtf8Source(__out ParseNodeProg ** parseTree, LPCUTF8 pSrc, size_t length, ULONG grfsrc, CompileScriptException *pse,
  10269. Js::LocalFunctionId * nextFunctionId, SourceContextInfo * sourceContextInfo)
  10270. {
  10271. m_functionBody = nullptr;
  10272. m_parseType = ParseType_Upfront;
  10273. return ParseSourceInternal(parseTree, pSrc, 0, length, 0, true, grfsrc, pse, nextFunctionId, 0, sourceContextInfo);
  10274. }
  10275. HRESULT Parser::ParseCesu8Source(__out ParseNodeProg ** parseTree, LPCUTF8 pSrc, size_t length, ULONG grfsrc, CompileScriptException *pse,
  10276. Js::LocalFunctionId * nextFunctionId, SourceContextInfo * sourceContextInfo)
  10277. {
  10278. m_functionBody = nullptr;
  10279. m_parseType = ParseType_Upfront;
  10280. return ParseSourceInternal(parseTree, pSrc, 0, length, 0, false, grfsrc, pse, nextFunctionId, 0, sourceContextInfo);
  10281. }
  10282. #if ENABLE_BACKGROUND_PARSING
  10283. void Parser::PrepareForBackgroundParse()
  10284. {
  10285. this->GetScanner()->PrepareForBackgroundParse(m_scriptContext);
  10286. }
  10287. void Parser::AddBackgroundParseItem(BackgroundParseItem *const item)
  10288. {
  10289. if (currBackgroundParseItem == nullptr)
  10290. {
  10291. backgroundParseItems = item;
  10292. }
  10293. else
  10294. {
  10295. currBackgroundParseItem->SetNext(item);
  10296. }
  10297. currBackgroundParseItem = item;
  10298. }
  10299. void Parser::AddFastScannedRegExpNode(ParseNodePtr const pnode)
  10300. {
  10301. Assert(!IsBackgroundParser());
  10302. Assert(m_doingFastScan);
  10303. if (fastScannedRegExpNodes == nullptr)
  10304. {
  10305. fastScannedRegExpNodes = Anew(&m_nodeAllocator, NodeDList, &m_nodeAllocator);
  10306. }
  10307. fastScannedRegExpNodes->Append(pnode);
  10308. }
  10309. void Parser::AddBackgroundRegExpNode(ParseNodePtr const pnode)
  10310. {
  10311. Assert(IsBackgroundParser());
  10312. Assert(currBackgroundParseItem != nullptr);
  10313. currBackgroundParseItem->AddRegExpNode(pnode, &m_nodeAllocator);
  10314. }
  10315. HRESULT Parser::ParseFunctionInBackground(ParseNodeFnc * pnodeFnc, ParseContext *parseContext, bool topLevelDeferred, CompileScriptException *pse)
  10316. {
  10317. m_functionBody = nullptr;
  10318. m_parseType = ParseType_Upfront;
  10319. HRESULT hr = S_OK;
  10320. SmartFPUControl smartFpuControl;
  10321. uint nextFunctionId = pnodeFnc->functionId + 1;
  10322. this->RestoreContext(parseContext);
  10323. m_nextFunctionId = &nextFunctionId;
  10324. m_deferringAST = topLevelDeferred;
  10325. m_inDeferredNestedFunc = false;
  10326. m_scopeCountNoAst = 0;
  10327. SetCurrentStatement(nullptr);
  10328. pnodeFnc->pnodeVars = nullptr;
  10329. pnodeFnc->pnodeParams = nullptr;
  10330. pnodeFnc->pnodeBody = nullptr;
  10331. pnodeFnc->nestedCount = 0;
  10332. ParseNodeFnc * pnodeParentFnc = GetCurrentFunctionNode();
  10333. m_currentNodeFunc = pnodeFnc;
  10334. m_currentNodeDeferredFunc = nullptr;
  10335. m_ppnodeScope = nullptr;
  10336. m_ppnodeExprScope = nullptr;
  10337. m_pnestedCount = &pnodeFnc->nestedCount;
  10338. m_pCurrentAstSize = &pnodeFnc->astSize;
  10339. ParseNodeBlock * pnodeBlock = StartParseBlock<true>(PnodeBlockType::Function, ScopeType_FunctionBody);
  10340. pnodeFnc->pnodeScopes = pnodeBlock;
  10341. m_ppnodeScope = &pnodeBlock->pnodeScopes;
  10342. uint uDeferSave = m_grfscr & (fscrCanDeferFncParse | fscrWillDeferFncParse);
  10343. try
  10344. {
  10345. this->GetScanner()->Scan();
  10346. m_ppnodeVar = &pnodeFnc->pnodeParams;
  10347. this->ParseFncFormals<true>(pnodeFnc, pnodeParentFnc, fFncNoFlgs);
  10348. if (m_token.tk == tkRParen)
  10349. {
  10350. this->GetScanner()->Scan();
  10351. }
  10352. ChkCurTok(tkLCurly, ERRnoLcurly);
  10353. m_ppnodeVar = &pnodeFnc->pnodeVars;
  10354. // Put the scanner into "no hashing" mode.
  10355. BYTE deferFlags = this->GetScanner()->SetDeferredParse(topLevelDeferred);
  10356. // Process a sequence of statements/declarations
  10357. if (topLevelDeferred)
  10358. {
  10359. ParseStmtList<false>(nullptr, nullptr, SM_DeferredParse, true);
  10360. }
  10361. else
  10362. {
  10363. ParseNodePtr *lastNodeRef = nullptr;
  10364. ParseStmtList<true>(&pnodeFnc->pnodeBody, &lastNodeRef, SM_OnFunctionCode, true);
  10365. AddArgumentsNodeToVars(pnodeFnc);
  10366. // Append an EndCode node.
  10367. AddToNodeList(&pnodeFnc->pnodeBody, &lastNodeRef, CreateNodeForOpT<knopEndCode>());
  10368. }
  10369. // Restore the scanner's default hashing mode.
  10370. this->GetScanner()->SetDeferredParseFlags(deferFlags);
  10371. #if DBG
  10372. pnodeFnc->deferredParseNextFunctionId = *this->m_nextFunctionId;
  10373. #endif
  10374. this->m_deferringAST = FALSE;
  10375. // Append block as body of pnodeProg
  10376. FinishParseBlock(pnodeBlock);
  10377. }
  10378. catch (ParseExceptionObject& e)
  10379. {
  10380. hr = e.GetError();
  10381. }
  10382. if (FAILED(hr))
  10383. {
  10384. hr = pse->ProcessError(this->GetScanner(), hr, nullptr);
  10385. }
  10386. if (IsStrictMode())
  10387. {
  10388. pnodeFnc->SetStrictMode();
  10389. }
  10390. if (topLevelDeferred)
  10391. {
  10392. pnodeFnc->pnodeVars = nullptr;
  10393. }
  10394. m_grfscr |= uDeferSave;
  10395. Assert(nullptr == *m_ppnodeScope);
  10396. return hr;
  10397. }
  10398. #endif
  10399. HRESULT Parser::ParseSourceWithOffset(__out ParseNodeProg ** parseTree, LPCUTF8 pSrc, size_t offset, size_t cbLength, charcount_t cchOffset,
  10400. bool isCesu8, ULONG grfscr, CompileScriptException *pse, Js::LocalFunctionId * nextFunctionId, ULONG lineNumber, SourceContextInfo * sourceContextInfo,
  10401. Js::ParseableFunctionInfo* functionInfo)
  10402. {
  10403. m_functionBody = functionInfo;
  10404. if (m_functionBody)
  10405. {
  10406. m_currDeferredStub = m_functionBody->GetDeferredStubs();
  10407. m_currDeferredStubCount = m_currDeferredStub != nullptr ? m_functionBody->GetNestedCount() : 0;
  10408. m_InAsmMode = grfscr & fscrNoAsmJs ? false : m_functionBody->GetIsAsmjsMode();
  10409. }
  10410. m_deferAsmJs = !m_InAsmMode;
  10411. m_parseType = ParseType_Deferred;
  10412. return ParseSourceInternal(parseTree, pSrc, offset, cbLength, cchOffset, !isCesu8, grfscr, pse, nextFunctionId, lineNumber, sourceContextInfo);
  10413. }
  10414. bool Parser::IsStrictMode() const
  10415. {
  10416. return (m_fUseStrictMode ||
  10417. (m_currentNodeFunc != nullptr && m_currentNodeFunc->GetStrictMode()));
  10418. }
  10419. BOOL Parser::ExpectingExternalSource()
  10420. {
  10421. return m_fExpectExternalSource;
  10422. }
  10423. Symbol *ParseNodeFnc::GetFuncSymbol()
  10424. {
  10425. if (pnodeName)
  10426. {
  10427. Assert(pnodeName->nop == knopVarDecl);
  10428. return pnodeName->sym;
  10429. }
  10430. return nullptr;
  10431. }
  10432. void ParseNodeFnc::SetFuncSymbol(Symbol *sym)
  10433. {
  10434. Assert(pnodeName);
  10435. Assert(pnodeName->nop == knopVarDecl);
  10436. pnodeName->sym = sym;
  10437. }
  10438. ParseNodePtr ParseNodeFnc::GetParamScope() const
  10439. {
  10440. if (this->pnodeScopes == nullptr)
  10441. {
  10442. return nullptr;
  10443. }
  10444. Assert(this->pnodeScopes->nop == knopBlock &&
  10445. this->pnodeScopes->pnodeNext == nullptr);
  10446. return this->pnodeScopes->pnodeScopes;
  10447. }
  10448. ParseNodePtr ParseNodeFnc::GetBodyScope() const
  10449. {
  10450. if (this->pnodeBodyScope == nullptr)
  10451. {
  10452. return nullptr;
  10453. }
  10454. Assert(this->pnodeBodyScope->nop == knopBlock &&
  10455. this->pnodeBodyScope->pnodeNext == nullptr);
  10456. return this->pnodeBodyScope->pnodeScopes;
  10457. }
  10458. bool ParseNodeBlock::HasBlockScopedContent() const
  10459. {
  10460. // A block has its own content if a let, const, or function is declared there.
  10461. if (this->pnodeLexVars != nullptr || this->blockType == Parameter)
  10462. {
  10463. return true;
  10464. }
  10465. // The enclosing scopes can contain functions and other things, so walk the list
  10466. // looking specifically for functions.
  10467. for (ParseNodePtr pnode = this->pnodeScopes; pnode;)
  10468. {
  10469. switch (pnode->nop) {
  10470. case knopFncDecl:
  10471. return true;
  10472. case knopBlock:
  10473. pnode = pnode->AsParseNodeBlock()->pnodeNext;
  10474. break;
  10475. case knopCatch:
  10476. pnode = pnode->AsParseNodeCatch()->pnodeNext;
  10477. break;
  10478. case knopWith:
  10479. pnode = pnode->AsParseNodeWith()->pnodeNext;
  10480. break;
  10481. default:
  10482. Assert(UNREACHED);
  10483. return true;
  10484. }
  10485. }
  10486. return false;
  10487. }
  10488. class ByteCodeGenerator;
  10489. // Copy AST; this works mostly on expressions for now
  10490. ParseNode* Parser::CopyPnode(ParseNode *pnode) {
  10491. if (pnode == NULL)
  10492. return NULL;
  10493. switch (pnode->nop) {
  10494. //PTNODE(knopName , "name" ,None ,Pid ,fnopLeaf)
  10495. case knopName: {
  10496. ParseNodeName * nameNode = CreateNameNode(pnode->AsParseNodeName()->pid);
  10497. nameNode->ichMin = pnode->ichMin;
  10498. nameNode->ichLim = pnode->ichLim;
  10499. nameNode->sym = pnode->AsParseNodeName()->sym;
  10500. return nameNode;
  10501. }
  10502. //PTNODE(knopInt , "int const" ,None ,Int ,fnopLeaf|fnopConst)
  10503. case knopInt:
  10504. return pnode;
  10505. //PTNODE(knopFlt , "flt const" ,None ,Flt ,fnopLeaf|fnopConst)
  10506. case knopFlt:
  10507. return pnode;
  10508. //PTNODE(knopStr , "str const" ,None ,Pid ,fnopLeaf|fnopConst)
  10509. case knopStr:
  10510. return pnode;
  10511. //PTNODE(knopRegExp , "reg expr" ,None ,Pid ,fnopLeaf|fnopConst)
  10512. case knopRegExp:
  10513. return pnode;
  10514. break;
  10515. //PTNODE(knopNull , "null" ,Null ,None ,fnopLeaf)
  10516. case knopNull:
  10517. return pnode;
  10518. //PTNODE(knopFalse , "false" ,False ,None ,fnopLeaf)
  10519. case knopFalse:
  10520. {
  10521. ParseNode* ret = CreateNodeForOpT<knopFalse>(pnode->ichMin, pnode->ichLim);
  10522. ret->location = pnode->location;
  10523. return ret;
  10524. }
  10525. //PTNODE(knopTrue , "true" ,True ,None ,fnopLeaf)
  10526. case knopTrue:
  10527. {
  10528. ParseNode* ret = CreateNodeForOpT<knopTrue>(pnode->ichMin, pnode->ichLim);
  10529. ret->location = pnode->location;
  10530. return ret;
  10531. }
  10532. //PTNODE(knopEmpty , "empty" ,Empty ,None ,fnopLeaf)
  10533. case knopEmpty:
  10534. return CreateNodeForOpT<knopEmpty>(pnode->ichMin, pnode->ichLim);
  10535. // Unary operators.
  10536. //PTNODE(knopNot , "~" ,BitNot ,Uni ,fnopUni)
  10537. //PTNODE(knopNeg , "unary -" ,Neg ,Uni ,fnopUni)
  10538. //PTNODE(knopPos , "unary +" ,Pos ,Uni ,fnopUni)
  10539. //PTNODE(knopLogNot , "!" ,LogNot ,Uni ,fnopUni)
  10540. //PTNODE(knopEllipsis , "..." ,Spread ,Uni , fnopUni)
  10541. //PTNODE(knopDecPost , "-- post" ,Dec ,Uni ,fnopUni|fnopAsg)
  10542. //PTNODE(knopIncPre , "++ pre" ,Inc ,Uni ,fnopUni|fnopAsg)
  10543. //PTNODE(knopDecPre , "-- pre" ,Dec ,Uni ,fnopUni|fnopAsg)
  10544. //PTNODE(knopTypeof , "typeof" ,None ,Uni ,fnopUni)
  10545. //PTNODE(knopVoid , "void" ,Void ,Uni ,fnopUni)
  10546. //PTNODE(knopDelete , "delete" ,None ,Uni ,fnopUni)
  10547. case knopNot:
  10548. case knopNeg:
  10549. case knopPos:
  10550. case knopLogNot:
  10551. case knopEllipsis:
  10552. case knopIncPost:
  10553. case knopDecPost:
  10554. case knopIncPre:
  10555. case knopDecPre:
  10556. case knopTypeof:
  10557. case knopVoid:
  10558. case knopDelete:
  10559. return CreateUniNode(pnode->nop, CopyPnode(pnode->AsParseNodeUni()->pnode1), pnode->ichMin, pnode->ichLim);
  10560. //PTNODE(knopArray , "arr cnst" ,None ,Uni ,fnopUni)
  10561. //PTNODE(knopObject , "obj cnst" ,None ,Uni ,fnopUni)
  10562. case knopArray:
  10563. case knopObject:
  10564. // TODO: need to copy arr
  10565. Assert(false);
  10566. break;
  10567. // Binary operators
  10568. //PTNODE(knopAdd , "+" ,Add ,Bin ,fnopBin)
  10569. //PTNODE(knopSub , "-" ,Sub ,Bin ,fnopBin)
  10570. //PTNODE(knopMul , "*" ,Mul ,Bin ,fnopBin)
  10571. //PTNODE(knopExpo , "**" ,Expo ,Bin ,fnopBin)
  10572. //PTNODE(knopDiv , "/" ,Div ,Bin ,fnopBin)
  10573. //PTNODE(knopMod , "%" ,Mod ,Bin ,fnopBin)
  10574. //PTNODE(knopOr , "|" ,BitOr ,Bin ,fnopBin)
  10575. //PTNODE(knopXor , "^" ,BitXor ,Bin ,fnopBin)
  10576. //PTNODE(knopAnd , "&" ,BitAnd ,Bin ,fnopBin)
  10577. //PTNODE(knopEq , "==" ,EQ ,Bin ,fnopBin|fnopRel)
  10578. //PTNODE(knopNe , "!=" ,NE ,Bin ,fnopBin|fnopRel)
  10579. //PTNODE(knopLt , "<" ,LT ,Bin ,fnopBin|fnopRel)
  10580. //PTNODE(knopLe , "<=" ,LE ,Bin ,fnopBin|fnopRel)
  10581. //PTNODE(knopGe , ">=" ,GE ,Bin ,fnopBin|fnopRel)
  10582. //PTNODE(knopGt , ">" ,GT ,Bin ,fnopBin|fnopRel)
  10583. //PTNODE(knopEqv , "===" ,Eqv ,Bin ,fnopBin|fnopRel)
  10584. //PTNODE(knopIn , "in" ,In ,Bin ,fnopBin|fnopRel)
  10585. //PTNODE(knopInstOf , "instanceof",InstOf ,Bin ,fnopBin|fnopRel)
  10586. //PTNODE(knopNEqv , "!==" ,NEqv ,Bin ,fnopBin|fnopRel)
  10587. //PTNODE(knopComma , "," ,None ,Bin ,fnopBin)
  10588. //PTNODE(knopLogOr , "||" ,None ,Bin ,fnopBin)
  10589. //PTNODE(knopLogAnd , "&&" ,None ,Bin ,fnopBin)
  10590. //PTNODE(knopLsh , "<<" ,Lsh ,Bin ,fnopBin)
  10591. //PTNODE(knopRsh , ">>" ,Rsh ,Bin ,fnopBin)
  10592. //PTNODE(knopRs2 , ">>>" ,Rs2 ,Bin ,fnopBin)
  10593. case knopAdd:
  10594. case knopSub:
  10595. case knopMul:
  10596. case knopExpo:
  10597. case knopDiv:
  10598. case knopMod:
  10599. case knopOr:
  10600. case knopXor:
  10601. case knopAnd:
  10602. case knopEq:
  10603. case knopNe:
  10604. case knopLt:
  10605. case knopLe:
  10606. case knopGe:
  10607. case knopGt:
  10608. case knopEqv:
  10609. case knopIn:
  10610. case knopInstOf:
  10611. case knopNEqv:
  10612. case knopComma:
  10613. case knopLogOr:
  10614. case knopLogAnd:
  10615. case knopLsh:
  10616. case knopRsh:
  10617. case knopRs2:
  10618. //PTNODE(knopAsg , "=" ,None ,Bin ,fnopBin|fnopAsg)
  10619. case knopAsg:
  10620. //PTNODE(knopDot , "." ,None ,Bin ,fnopBin)
  10621. case knopDot:
  10622. //PTNODE(knopAsgAdd , "+=" ,Add ,Bin ,fnopBin|fnopAsg)
  10623. case knopAsgAdd:
  10624. //PTNODE(knopAsgSub , "-=" ,Sub ,Bin ,fnopBin|fnopAsg)
  10625. case knopAsgSub:
  10626. //PTNODE(knopAsgMul , "*=" ,Mul ,Bin ,fnopBin|fnopAsg)
  10627. case knopAsgMul:
  10628. //PTNODE(knopAsgDiv , "/=" ,Div ,Bin ,fnopBin|fnopAsg)
  10629. case knopAsgExpo:
  10630. //PTNODE(knopAsgExpo , "**=" ,Expo ,Bin ,fnopBin|fnopAsg)
  10631. case knopAsgDiv:
  10632. //PTNODE(knopAsgMod , "%=" ,Mod ,Bin ,fnopBin|fnopAsg)
  10633. case knopAsgMod:
  10634. //PTNODE(knopAsgAnd , "&=" ,BitAnd ,Bin ,fnopBin|fnopAsg)
  10635. case knopAsgAnd:
  10636. //PTNODE(knopAsgXor , "^=" ,BitXor ,Bin ,fnopBin|fnopAsg)
  10637. case knopAsgXor:
  10638. //PTNODE(knopAsgOr , "|=" ,BitOr ,Bin ,fnopBin|fnopAsg)
  10639. case knopAsgOr:
  10640. //PTNODE(knopAsgLsh , "<<=" ,Lsh ,Bin ,fnopBin|fnopAsg)
  10641. case knopAsgLsh:
  10642. //PTNODE(knopAsgRsh , ">>=" ,Rsh ,Bin ,fnopBin|fnopAsg)
  10643. case knopAsgRsh:
  10644. //PTNODE(knopAsgRs2 , ">>>=" ,Rs2 ,Bin ,fnopBin|fnopAsg)
  10645. case knopAsgRs2:
  10646. //PTNODE(knopMember , ":" ,None ,Bin ,fnopBin)
  10647. case knopMember:
  10648. case knopMemberShort:
  10649. //PTNODE(knopIndex , "[]" ,None ,Bin ,fnopBin)
  10650. //PTNODE(knopList , "<list>" ,None ,Bin ,fnopNone)
  10651. case knopIndex:
  10652. case knopList:
  10653. return CreateBinNode(pnode->nop, CopyPnode(pnode->AsParseNodeBin()->pnode1),
  10654. CopyPnode(pnode->AsParseNodeBin()->pnode2), pnode->ichMin, pnode->ichLim);
  10655. //PTNODE(knopCall , "()" ,None ,Bin ,fnopBin)
  10656. //PTNODE(knopNew , "new" ,None ,Bin ,fnopBin)
  10657. case knopNew:
  10658. case knopCall:
  10659. return CreateCallNode(pnode->nop, CopyPnode(pnode->AsParseNodeCall()->pnodeTarget),
  10660. CopyPnode(pnode->AsParseNodeCall()->pnodeArgs), pnode->ichMin, pnode->ichLim);
  10661. //PTNODE(knopQmark , "?" ,None ,Tri ,fnopBin)
  10662. case knopQmark:
  10663. return CreateTriNode(pnode->nop, CopyPnode(pnode->AsParseNodeTri()->pnode1),
  10664. CopyPnode(pnode->AsParseNodeTri()->pnode2), CopyPnode(pnode->AsParseNodeTri()->pnode3),
  10665. pnode->ichMin, pnode->ichLim);
  10666. // General nodes.
  10667. //PTNODE(knopVarDecl , "varDcl" ,None ,Var ,fnopNone)
  10668. case knopVarDecl: {
  10669. ParseNodeVar* copyNode = Anew(&m_nodeAllocator, ParseNodeVar, knopVarDecl, pnode->ichMin, pnode->ichLim, nullptr);
  10670. copyNode->pnodeInit = CopyPnode(pnode->AsParseNodeVar()->pnodeInit);
  10671. copyNode->sym = pnode->AsParseNodeVar()->sym;
  10672. // TODO: mult-decl
  10673. Assert(pnode->AsParseNodeVar()->pnodeNext == NULL);
  10674. copyNode->pnodeNext = NULL;
  10675. return copyNode;
  10676. }
  10677. //PTNODE(knopFncDecl , "fncDcl" ,None ,Fnc ,fnopLeaf)
  10678. //PTNODE(knopProg , "program" ,None ,Fnc ,fnopNone)
  10679. case knopFncDecl:
  10680. case knopProg:
  10681. Assert(false);
  10682. break;
  10683. //PTNODE(knopEndCode , "<endcode>" ,None ,None ,fnopNone)
  10684. case knopEndCode:
  10685. break;
  10686. //PTNODE(knopDebugger , "debugger" ,None ,None ,fnopNone)
  10687. case knopDebugger:
  10688. break;
  10689. //PTNODE(knopFor , "for" ,None ,For ,fnopBreak|fnopContinue)
  10690. case knopFor: {
  10691. ParseNode* copyNode = CreateNodeForOpT<knopFor>(pnode->ichMin, pnode->ichLim);
  10692. copyNode->AsParseNodeFor()->pnodeInverted = NULL;
  10693. copyNode->AsParseNodeFor()->pnodeInit = CopyPnode(pnode->AsParseNodeFor()->pnodeInit);
  10694. copyNode->AsParseNodeFor()->pnodeCond = CopyPnode(pnode->AsParseNodeFor()->pnodeCond);
  10695. copyNode->AsParseNodeFor()->pnodeIncr = CopyPnode(pnode->AsParseNodeFor()->pnodeIncr);
  10696. copyNode->AsParseNodeFor()->pnodeBody = CopyPnode(pnode->AsParseNodeFor()->pnodeBody);
  10697. return copyNode;
  10698. }
  10699. //PTNODE(knopIf , "if" ,None ,If ,fnopNone)
  10700. case knopIf:
  10701. Assert(false);
  10702. break;
  10703. //PTNODE(knopWhile , "while" ,None ,While,fnopBreak|fnopContinue)
  10704. case knopWhile:
  10705. Assert(false);
  10706. break;
  10707. //PTNODE(knopDoWhile , "do-while" ,None ,While,fnopBreak|fnopContinue)
  10708. case knopDoWhile:
  10709. Assert(false);
  10710. break;
  10711. //PTNODE(knopForIn , "for in" ,None ,ForIn,fnopBreak|fnopContinue|fnopCleanup)
  10712. case knopForIn:
  10713. Assert(false);
  10714. break;
  10715. case knopForOf:
  10716. Assert(false);
  10717. break;
  10718. //PTNODE(knopReturn , "return" ,None ,Uni ,fnopNone)
  10719. case knopReturn: {
  10720. ParseNode* copyNode = CreateNodeForOpT<knopReturn>(pnode->ichMin, pnode->ichLim);
  10721. copyNode->AsParseNodeReturn()->pnodeExpr = CopyPnode(pnode->AsParseNodeReturn()->pnodeExpr);
  10722. return copyNode;
  10723. }
  10724. //PTNODE(knopBlock , "{}" ,None ,Block,fnopNone)
  10725. case knopBlock: {
  10726. ParseNodeBlock* copyNode = CreateBlockNode(pnode->ichMin, pnode->ichLim, pnode->AsParseNodeBlock()->blockType);
  10727. if (pnode->grfpn & PNodeFlags::fpnSyntheticNode) {
  10728. // fpnSyntheticNode is sometimes set on PnodeBlockType::Regular blocks which
  10729. // CreateBlockNode() will not automatically set for us, so set it here if it's
  10730. // specified on the source node.
  10731. copyNode->grfpn |= PNodeFlags::fpnSyntheticNode;
  10732. }
  10733. copyNode->pnodeStmt = CopyPnode(pnode->AsParseNodeBlock()->pnodeStmt);
  10734. return copyNode;
  10735. }
  10736. //PTNODE(knopWith , "with" ,None ,With ,fnopCleanup)
  10737. case knopWith:
  10738. Assert(false);
  10739. break;
  10740. //PTNODE(knopBreak , "break" ,None ,Jump ,fnopNone)
  10741. case knopBreak:
  10742. Assert(false);
  10743. break;
  10744. //PTNODE(knopContinue , "continue" ,None ,Jump ,fnopNone)
  10745. case knopContinue:
  10746. Assert(false);
  10747. break;
  10748. //PTNODE(knopSwitch , "switch" ,None ,Switch,fnopBreak)
  10749. case knopSwitch:
  10750. Assert(false);
  10751. break;
  10752. //PTNODE(knopCase , "case" ,None ,Case ,fnopNone)
  10753. case knopCase:
  10754. Assert(false);
  10755. break;
  10756. //PTNODE(knopTryFinally,"try-finally",None,TryFinally,fnopCleanup)
  10757. case knopTryFinally:
  10758. Assert(false);
  10759. break;
  10760. case knopFinally:
  10761. Assert(false);
  10762. break;
  10763. //PTNODE(knopCatch , "catch" ,None ,Catch,fnopNone)
  10764. case knopCatch:
  10765. Assert(false);
  10766. break;
  10767. //PTNODE(knopTryCatch , "try-catch" ,None ,TryCatch ,fnopCleanup)
  10768. case knopTryCatch:
  10769. Assert(false);
  10770. break;
  10771. //PTNODE(knopTry , "try" ,None ,Try ,fnopCleanup)
  10772. case knopTry:
  10773. Assert(false);
  10774. break;
  10775. //PTNODE(knopThrow , "throw" ,None ,Uni ,fnopNone)
  10776. case knopThrow:
  10777. Assert(false);
  10778. break;
  10779. default:
  10780. Assert(false);
  10781. break;
  10782. }
  10783. return NULL;
  10784. }
  10785. // Returns true when str is string for Nan, Infinity or -Infinity.
  10786. // Does not check for double number value being in NaN/Infinity range.
  10787. // static
  10788. template<bool CheckForNegativeInfinity>
  10789. inline bool Parser::IsNaNOrInfinityLiteral(LPCOLESTR str)
  10790. {
  10791. // Note: wcscmp crashes when one of the parameters is NULL.
  10792. return str &&
  10793. (wcscmp(_u("NaN"), str) == 0 ||
  10794. wcscmp(_u("Infinity"), str) == 0 ||
  10795. (CheckForNegativeInfinity && wcscmp(_u("-Infinity"), str) == 0));
  10796. }
  10797. template <bool buildAST>
  10798. IdentPtr Parser::ParseSuper(bool fAllowCall)
  10799. {
  10800. ParseNodeFnc * currentNodeFunc = GetCurrentFunctionNode();
  10801. ParseNodeFnc * currentNonLambdaFunc = GetCurrentNonLambdaFunctionNode();
  10802. IdentPtr superPid = nullptr;
  10803. switch (m_token.tk)
  10804. {
  10805. case tkDot: // super.prop
  10806. case tkLBrack: // super[foo]
  10807. superPid = wellKnownPropertyPids._super;
  10808. break;
  10809. case tkLParen: // super(args)
  10810. superPid = wellKnownPropertyPids._superConstructor;
  10811. break;
  10812. default:
  10813. Error(ERRInvalidSuper);
  10814. break;
  10815. }
  10816. currentNodeFunc->SetHasSuperReference(TRUE);
  10817. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, Super, m_scriptContext);
  10818. // If we are defer parsing, we can skip verifying that the super reference is valid.
  10819. // If it wasn't the parser would have thrown during upfront parsing and we wouldn't be defer parsing the function.
  10820. if (m_parseType == ParseType_Deferred)
  10821. {
  10822. return superPid;
  10823. }
  10824. if (!fAllowCall && (m_token.tk == tkLParen))
  10825. {
  10826. Error(ERRInvalidSuper); // new super() is not allowed
  10827. }
  10828. else if ((currentNodeFunc->IsConstructor() && currentNodeFunc->superRestrictionState == SuperRestrictionState::CallAndPropertyAllowed)
  10829. || (currentNonLambdaFunc != nullptr && currentNonLambdaFunc->superRestrictionState == SuperRestrictionState::CallAndPropertyAllowed))
  10830. {
  10831. // Any super access is good within a class constructor
  10832. }
  10833. else if ((this->m_grfscr & fscrEval) == fscrEval || (currentNonLambdaFunc != nullptr && currentNonLambdaFunc->superRestrictionState == SuperRestrictionState::PropertyAllowed))
  10834. {
  10835. // Currently for eval cases during compile time we use propertyallowed and throw during runtime for error cases
  10836. if (m_token.tk == tkLParen)
  10837. {
  10838. if ((this->m_grfscr & fscrEval) == fscrNil)
  10839. {
  10840. // Cannot call super within a class member
  10841. Error(ERRInvalidSuper);
  10842. }
  10843. else
  10844. {
  10845. Js::JavascriptFunction * caller = nullptr;
  10846. if (Js::JavascriptStackWalker::GetCaller(&caller, m_scriptContext))
  10847. {
  10848. Js::FunctionBody * callerBody = caller->GetFunctionBody();
  10849. Assert(callerBody);
  10850. if (!callerBody->GetFunctionInfo()->GetAllowDirectSuper())
  10851. {
  10852. Error(ERRInvalidSuper);
  10853. }
  10854. }
  10855. }
  10856. }
  10857. }
  10858. else
  10859. {
  10860. // Anything else is an error
  10861. Error(ERRInvalidSuper);
  10862. }
  10863. return superPid;
  10864. }
  10865. void Parser::AppendToList(ParseNodePtr *node, ParseNodePtr nodeToAppend)
  10866. {
  10867. Assert(nodeToAppend);
  10868. ParseNodePtr* lastPtr = node;
  10869. while ((*lastPtr) && (*lastPtr)->nop == knopList)
  10870. {
  10871. lastPtr = &(*lastPtr)->AsParseNodeBin()->pnode2;
  10872. }
  10873. auto last = (*lastPtr);
  10874. if (last)
  10875. {
  10876. *lastPtr = CreateBinNode(knopList, last, nodeToAppend, last->ichMin, nodeToAppend->ichLim);
  10877. }
  10878. else
  10879. {
  10880. *lastPtr = nodeToAppend;
  10881. }
  10882. }
  10883. ParseNodePtr Parser::ConvertArrayToArrayPattern(ParseNodePtr pnode)
  10884. {
  10885. Assert(pnode->nop == knopArray);
  10886. pnode->nop = knopArrayPattern;
  10887. ForEachItemRefInList(&pnode->AsParseNodeArrLit()->pnode1, [&](ParseNodePtr *itemRef) {
  10888. ParseNodePtr item = *itemRef;
  10889. if (item->nop == knopEllipsis)
  10890. {
  10891. itemRef = &item->AsParseNodeUni()->pnode1;
  10892. item = *itemRef;
  10893. if (!(item->nop == knopName
  10894. || item->nop == knopDot
  10895. || item->nop == knopIndex
  10896. || item->nop == knopArray
  10897. || item->nop == knopObject))
  10898. {
  10899. Error(ERRInvalidAssignmentTarget);
  10900. }
  10901. }
  10902. else if (item->nop == knopAsg)
  10903. {
  10904. itemRef = &item->AsParseNodeBin()->pnode1;
  10905. item = *itemRef;
  10906. }
  10907. if (item->nop == knopArray)
  10908. {
  10909. ConvertArrayToArrayPattern(item);
  10910. }
  10911. else if (item->nop == knopObject)
  10912. {
  10913. *itemRef = ConvertObjectToObjectPattern(item);
  10914. }
  10915. else if (item->nop == knopName)
  10916. {
  10917. TrackAssignment<true>(item, nullptr);
  10918. }
  10919. });
  10920. return pnode;
  10921. }
  10922. ParseNodeUni * Parser::ConvertObjectToObjectPattern(ParseNodePtr pnodeMemberList)
  10923. {
  10924. charcount_t ichMin = this->GetScanner()->IchMinTok();
  10925. charcount_t ichLim = this->GetScanner()->IchLimTok();
  10926. if (pnodeMemberList != nullptr && pnodeMemberList->nop == knopObject)
  10927. {
  10928. ichMin = pnodeMemberList->ichMin;
  10929. ichLim = pnodeMemberList->ichLim;
  10930. pnodeMemberList = pnodeMemberList->AsParseNodeUni()->pnode1;
  10931. }
  10932. ParseNodeObjLit * objectPatternNode = CreateObjectPatternNode(pnodeMemberList, ichMin, ichLim, true/*convertToPattern*/);
  10933. return objectPatternNode;
  10934. }
  10935. ParseNodePtr Parser::GetRightSideNodeFromPattern(ParseNodePtr pnode)
  10936. {
  10937. Assert(pnode != nullptr);
  10938. ParseNodePtr rightNode = nullptr;
  10939. OpCode op = pnode->nop;
  10940. if (op == knopObject)
  10941. {
  10942. rightNode = ConvertObjectToObjectPattern(pnode);
  10943. }
  10944. else if (op == knopArray)
  10945. {
  10946. rightNode = ConvertArrayToArrayPattern(pnode);
  10947. }
  10948. else
  10949. {
  10950. rightNode = pnode;
  10951. if (op == knopName)
  10952. {
  10953. TrackAssignment<true>(pnode, nullptr);
  10954. }
  10955. else if (op == knopAsg)
  10956. {
  10957. TrackAssignment<true>(pnode->AsParseNodeBin()->pnode1, nullptr);
  10958. }
  10959. }
  10960. return rightNode;
  10961. }
  10962. ParseNodePtr Parser::ConvertMemberToMemberPattern(ParseNodePtr pnodeMember)
  10963. {
  10964. if (pnodeMember->nop == knopObjectPatternMember || pnodeMember->nop == knopEllipsis)
  10965. {
  10966. return pnodeMember;
  10967. }
  10968. Assert(pnodeMember->nop == knopMember || pnodeMember->nop == knopMemberShort);
  10969. ParseNodePtr rightNode = GetRightSideNodeFromPattern(pnodeMember->AsParseNodeBin()->pnode2);
  10970. ParseNodePtr resultNode = CreateBinNode(knopObjectPatternMember, pnodeMember->AsParseNodeBin()->pnode1, rightNode);
  10971. resultNode->ichMin = pnodeMember->ichMin;
  10972. resultNode->ichLim = pnodeMember->ichLim;
  10973. return resultNode;
  10974. }
  10975. ParseNodePtr Parser::ConvertToPattern(ParseNodePtr pnode)
  10976. {
  10977. if (pnode != nullptr)
  10978. {
  10979. if (pnode->nop == knopArray)
  10980. {
  10981. ConvertArrayToArrayPattern(pnode);
  10982. }
  10983. else if (pnode->nop == knopObject)
  10984. {
  10985. pnode = ConvertObjectToObjectPattern(pnode);
  10986. }
  10987. }
  10988. return pnode;
  10989. }
  10990. // This essentially be called for verifying the structure of the current tree with satisfying the destructuring grammar.
  10991. void Parser::ParseDestructuredLiteralWithScopeSave(tokens declarationType,
  10992. bool isDecl,
  10993. bool topLevel,
  10994. DestructuringInitializerContext initializerContext/* = DIC_None*/,
  10995. bool allowIn /*= true*/)
  10996. {
  10997. // We are going to parse the text again to validate the current grammar as Destructuring. Saving some scopes and
  10998. // AST related information before the validation parsing and later they will be restored.
  10999. ParseNodeFnc * pnodeFncSave = m_currentNodeFunc;
  11000. ParseNodeFnc * pnodeDeferredFncSave = m_currentNodeDeferredFunc;
  11001. if (m_currentNodeDeferredFunc == nullptr)
  11002. {
  11003. m_currentNodeDeferredFunc = m_currentNodeFunc;
  11004. }
  11005. int32 *pAstSizeSave = m_pCurrentAstSize;
  11006. uint *pNestedCountSave = m_pnestedCount;
  11007. ParseNodePtr *ppnodeScopeSave = m_ppnodeScope;
  11008. ParseNodePtr *ppnodeExprScopeSave = m_ppnodeExprScope;
  11009. ParseNodePtr newTempScope = nullptr;
  11010. m_ppnodeScope = &newTempScope;
  11011. int32 newTempAstSize = 0;
  11012. m_pCurrentAstSize = &newTempAstSize;
  11013. uint newTempNestedCount = 0;
  11014. m_pnestedCount = &newTempNestedCount;
  11015. m_ppnodeExprScope = nullptr;
  11016. charcount_t funcInArraySave = m_funcInArray;
  11017. uint funcInArrayDepthSave = m_funcInArrayDepth;
  11018. // we need to reset this as we are going to parse the grammar again.
  11019. m_hasDeferredShorthandInitError = false;
  11020. ParseDestructuredLiteral<false>(declarationType, isDecl, topLevel, initializerContext, allowIn);
  11021. m_currentNodeFunc = pnodeFncSave;
  11022. m_currentNodeDeferredFunc = pnodeDeferredFncSave;
  11023. m_pCurrentAstSize = pAstSizeSave;
  11024. m_pnestedCount = pNestedCountSave;
  11025. m_ppnodeScope = ppnodeScopeSave;
  11026. m_ppnodeExprScope = ppnodeExprScopeSave;
  11027. m_funcInArray = funcInArraySave;
  11028. m_funcInArrayDepth = funcInArrayDepthSave;
  11029. }
  11030. template <bool buildAST>
  11031. ParseNodePtr Parser::ParseDestructuredLiteral(tokens declarationType,
  11032. bool isDecl,
  11033. bool topLevel/* = true*/,
  11034. DestructuringInitializerContext initializerContext/* = DIC_None*/,
  11035. bool allowIn/* = true*/,
  11036. BOOL *forInOfOkay/* = nullptr*/,
  11037. BOOL *nativeForOkay/* = nullptr*/)
  11038. {
  11039. ParseNodeUni * pnode = nullptr;
  11040. Assert(IsPossiblePatternStart());
  11041. if (m_token.tk == tkLCurly)
  11042. {
  11043. pnode = ParseDestructuredObjectLiteral<buildAST>(declarationType, isDecl, topLevel);
  11044. }
  11045. else
  11046. {
  11047. pnode = ParseDestructuredArrayLiteral<buildAST>(declarationType, isDecl, topLevel);
  11048. }
  11049. return ParseDestructuredInitializer<buildAST>(pnode, isDecl, topLevel, initializerContext, allowIn, forInOfOkay, nativeForOkay);
  11050. }
  11051. template <bool buildAST>
  11052. ParseNodePtr Parser::ParseDestructuredInitializer(ParseNodeUni * lhsNode,
  11053. bool isDecl,
  11054. bool topLevel,
  11055. DestructuringInitializerContext initializerContext,
  11056. bool allowIn,
  11057. BOOL *forInOfOkay,
  11058. BOOL *nativeForOkay)
  11059. {
  11060. this->GetScanner()->Scan();
  11061. if (topLevel && nativeForOkay == nullptr)
  11062. {
  11063. if (initializerContext != DIC_ForceErrorOnInitializer && m_token.tk != tkAsg)
  11064. {
  11065. // e.g. var {x};
  11066. Error(ERRDestructInit);
  11067. }
  11068. else if (initializerContext == DIC_ForceErrorOnInitializer && m_token.tk == tkAsg)
  11069. {
  11070. // e.g. catch([x] = [0])
  11071. Error(ERRDestructNotInit);
  11072. }
  11073. }
  11074. if (m_token.tk != tkAsg || initializerContext == DIC_ShouldNotParseInitializer)
  11075. {
  11076. if (topLevel && nativeForOkay != nullptr)
  11077. {
  11078. // Native loop should have destructuring initializer
  11079. *nativeForOkay = FALSE;
  11080. }
  11081. return lhsNode;
  11082. }
  11083. if (forInOfOkay)
  11084. {
  11085. *forInOfOkay = FALSE;
  11086. }
  11087. this->GetScanner()->Scan();
  11088. bool alreadyHasInitError = m_hasDeferredShorthandInitError;
  11089. ParseNodePtr pnodeDefault = ParseExpr<buildAST>(koplCma, nullptr, allowIn);
  11090. if (m_hasDeferredShorthandInitError && !alreadyHasInitError)
  11091. {
  11092. Error(ERRnoColon);
  11093. }
  11094. ParseNodeBin * pnodeDestructAsg = nullptr;
  11095. if (buildAST)
  11096. {
  11097. Assert(lhsNode != nullptr);
  11098. pnodeDestructAsg = CreateBinNode(knopAsg, lhsNode, pnodeDefault, lhsNode->ichMin, pnodeDefault->ichLim);
  11099. }
  11100. return pnodeDestructAsg;
  11101. }
  11102. template <bool buildAST>
  11103. ParseNodeUni * Parser::ParseDestructuredObjectLiteral(tokens declarationType, bool isDecl, bool topLevel/* = true*/)
  11104. {
  11105. Assert(m_token.tk == tkLCurly);
  11106. charcount_t ichMin = this->GetScanner()->IchMinTok();
  11107. this->GetScanner()->Scan();
  11108. if (!isDecl)
  11109. {
  11110. declarationType = tkLCurly;
  11111. }
  11112. ParseNodePtr pnodeMemberList = ParseMemberList<buildAST>(nullptr/*pNameHint*/, nullptr/*pHintLength*/, declarationType);
  11113. charcount_t ichLim = this->GetScanner()->IchLimTok();
  11114. ParseNodeObjLit * objectPatternNode = buildAST ? CreateObjectPatternNode(pnodeMemberList, ichMin, ichLim) : nullptr;
  11115. Assert(m_token.tk == tkRCurly);
  11116. return objectPatternNode;
  11117. }
  11118. template <bool buildAST>
  11119. ParseNodePtr Parser::ParseDestructuredVarDecl(tokens declarationType, bool isDecl, bool *hasSeenRest, bool topLevel/* = true*/, bool allowEmptyExpression/* = true*/, bool isObjectPattern/* =false*/)
  11120. {
  11121. ParseNodePtr pnodeElem = nullptr;
  11122. int parenCount = 0;
  11123. bool seenRest = false;
  11124. // Save the Block ID prior to the increments, so we can restore it back.
  11125. int originalCurrentBlockId = GetCurrentBlock()->blockId;
  11126. // Eat the left parentheses only when its not a declaration. This will make sure we throw syntax errors early.
  11127. if (!isDecl)
  11128. {
  11129. while (m_token.tk == tkLParen)
  11130. {
  11131. this->GetScanner()->Scan();
  11132. ++parenCount;
  11133. // Match the block increment we do upon entering parenthetical expressions
  11134. // so that the block ID's will match on reparsing of parameters.
  11135. GetCurrentBlock()->blockId = m_nextBlockId++;
  11136. }
  11137. }
  11138. if (m_token.tk == tkEllipsis)
  11139. {
  11140. // As per ES 2015 : Rest can have left-hand-side-expression when on assignment expression, but under declaration only binding identifier is allowed
  11141. // But spec is going to change for this one to allow LHS-expression both on expression and declaration - so making that happen early.
  11142. seenRest = true;
  11143. this->GetScanner()->Scan();
  11144. // Eat the left parentheses only when its not a declaration. This will make sure we throw syntax errors early.
  11145. if (!isDecl)
  11146. {
  11147. while (m_token.tk == tkLParen)
  11148. {
  11149. this->GetScanner()->Scan();
  11150. ++parenCount;
  11151. // Match the block increment we do upon entering parenthetical expressions
  11152. // so that the block ID's will match on reparsing of parameters.
  11153. GetCurrentBlock()->blockId = m_nextBlockId++;
  11154. }
  11155. }
  11156. if (m_token.tk != tkID && m_token.tk != tkTHIS && m_token.tk != tkSUPER)
  11157. {
  11158. bool nestedDestructuring = m_token.tk == tkLCurly || m_token.tk == tkLBrack;
  11159. if ((isObjectPattern && nestedDestructuring) || (!isObjectPattern && !nestedDestructuring))
  11160. {
  11161. if (isDecl)
  11162. {
  11163. Error(ERRnoIdent);
  11164. }
  11165. else
  11166. {
  11167. Error(ERRInvalidAssignmentTarget);
  11168. }
  11169. }
  11170. }
  11171. }
  11172. if (IsPossiblePatternStart())
  11173. {
  11174. // For the possible pattern start we do not allow the parens before
  11175. if (parenCount != 0)
  11176. {
  11177. Error(ERRDestructIDRef);
  11178. }
  11179. // Go recursively
  11180. pnodeElem = ParseDestructuredLiteral<buildAST>(declarationType, isDecl, false /*topLevel*/, seenRest ? DIC_ShouldNotParseInitializer : DIC_None);
  11181. if (!isDecl)
  11182. {
  11183. BOOL fCanAssign;
  11184. IdentToken token;
  11185. // Look for postfix operator
  11186. pnodeElem = ParsePostfixOperators<buildAST>(pnodeElem, TRUE, FALSE, FALSE, TRUE, &fCanAssign, &token);
  11187. }
  11188. }
  11189. else if (m_token.tk == tkSUPER || m_token.tk == tkID || m_token.tk == tkTHIS)
  11190. {
  11191. if (isDecl)
  11192. {
  11193. charcount_t ichMin = this->GetScanner()->IchMinTok();
  11194. pnodeElem = ParseVariableDeclaration<buildAST>(declarationType, ichMin
  11195. ,/* fAllowIn */false, /* pfForInOk */nullptr, /* singleDefOnly */true, /* allowInit */!seenRest, false /*topLevelParse*/);
  11196. }
  11197. else
  11198. {
  11199. BOOL fCanAssign;
  11200. IdentToken token;
  11201. // We aren't declaring anything, so scan the ID reference manually.
  11202. pnodeElem = ParseTerm<buildAST>(/* fAllowCall */ m_token.tk != tkSUPER, nullptr /*pNameHint*/, nullptr /*pHintLength*/, nullptr /*pShortNameOffset*/, &token, false,
  11203. FALSE, &fCanAssign);
  11204. // In this destructuring case we can force error here as we cannot assign.
  11205. if (!fCanAssign)
  11206. {
  11207. Error(ERRInvalidAssignmentTarget);
  11208. }
  11209. if (buildAST)
  11210. {
  11211. if (IsStrictMode() && pnodeElem != nullptr && pnodeElem->nop == knopName)
  11212. {
  11213. CheckStrictModeEvalArgumentsUsage(pnodeElem->AsParseNodeName()->pid);
  11214. }
  11215. }
  11216. else
  11217. {
  11218. if (IsStrictMode() && token.tk == tkID)
  11219. {
  11220. CheckStrictModeEvalArgumentsUsage(token.pid);
  11221. }
  11222. token.tk = tkNone;
  11223. }
  11224. }
  11225. }
  11226. else if (!((m_token.tk == tkComma || m_token.tk == tkRBrack || m_token.tk == tkRCurly) && allowEmptyExpression))
  11227. {
  11228. if (m_token.IsOperator())
  11229. {
  11230. Error(ERRDestructNoOper);
  11231. }
  11232. Error(ERRDestructIDRef);
  11233. }
  11234. // Swallow RParens before a default expression, if any.
  11235. // We eat the left parentheses only when its not a declaration. This will make sure we throw syntax errors early. We need to do the same for right parentheses.
  11236. if (!isDecl)
  11237. {
  11238. while (m_token.tk == tkRParen)
  11239. {
  11240. this->GetScanner()->Scan();
  11241. --parenCount;
  11242. }
  11243. // Restore the Block ID of the current block after the parsing of destructured variable declarations and initializers.
  11244. GetCurrentBlock()->blockId = originalCurrentBlockId;
  11245. }
  11246. if (parenCount != 0)
  11247. {
  11248. Error(ERRnoRparen);
  11249. }
  11250. if (hasSeenRest != nullptr)
  11251. {
  11252. *hasSeenRest = seenRest;
  11253. }
  11254. if (m_token.tk == tkAsg)
  11255. {
  11256. // Parse the initializer.
  11257. if (seenRest)
  11258. {
  11259. Error(ERRRestWithDefault);
  11260. }
  11261. this->GetScanner()->Scan();
  11262. bool alreadyHasInitError = m_hasDeferredShorthandInitError;
  11263. ParseNodePtr pnodeInit = ParseExpr<buildAST>(koplCma);
  11264. if (m_hasDeferredShorthandInitError && !alreadyHasInitError)
  11265. {
  11266. Error(ERRnoColon);
  11267. }
  11268. if (buildAST)
  11269. {
  11270. pnodeElem = CreateBinNode(knopAsg, pnodeElem, pnodeInit);
  11271. }
  11272. }
  11273. if (buildAST && seenRest)
  11274. {
  11275. ParseNodePtr pnodeRest = CreateUniNode(knopEllipsis, pnodeElem);
  11276. pnodeElem = pnodeRest;
  11277. }
  11278. if (!(m_token.tk == tkComma || m_token.tk == tkRBrack || m_token.tk == tkRCurly))
  11279. {
  11280. if (m_token.IsOperator())
  11281. {
  11282. Error(ERRDestructNoOper);
  11283. }
  11284. Error(ERRsyntax);
  11285. }
  11286. return pnodeElem;
  11287. }
  11288. template <bool buildAST>
  11289. ParseNodeUni * Parser::ParseDestructuredArrayLiteral(tokens declarationType, bool isDecl, bool topLevel)
  11290. {
  11291. Assert(m_token.tk == tkLBrack);
  11292. charcount_t ichMin = this->GetScanner()->IchMinTok();
  11293. this->GetScanner()->Scan();
  11294. ParseNodeArrLit * pnodeDestructArr = nullptr;
  11295. ParseNodePtr pnodeList = nullptr;
  11296. ParseNodePtr *lastNodeRef = nullptr;
  11297. uint count = 0;
  11298. bool hasMissingValues = false;
  11299. bool seenRest = false;
  11300. if (m_token.tk != tkRBrack)
  11301. {
  11302. while (true)
  11303. {
  11304. ParseNodePtr pnodeElem = ParseDestructuredVarDecl<buildAST>(declarationType, isDecl, &seenRest, topLevel);
  11305. if (buildAST)
  11306. {
  11307. if (pnodeElem == nullptr && buildAST)
  11308. {
  11309. pnodeElem = CreateNodeForOpT<knopEmpty>();
  11310. hasMissingValues = true;
  11311. }
  11312. AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeElem);
  11313. }
  11314. count++;
  11315. if (m_token.tk == tkRBrack)
  11316. {
  11317. break;
  11318. }
  11319. if (m_token.tk != tkComma)
  11320. {
  11321. Error(ERRDestructNoOper);
  11322. }
  11323. if (seenRest) // Rest must be in the last position.
  11324. {
  11325. Error(ERRDestructRestLast);
  11326. }
  11327. this->GetScanner()->Scan();
  11328. // break if we have the trailing comma as well, eg. [a,]
  11329. if (m_token.tk == tkRBrack)
  11330. {
  11331. break;
  11332. }
  11333. }
  11334. }
  11335. if (buildAST)
  11336. {
  11337. pnodeDestructArr = CreateNodeForOpT<knopArrayPattern>(ichMin);
  11338. pnodeDestructArr->pnode1 = pnodeList;
  11339. pnodeDestructArr->arrayOfTaggedInts = false;
  11340. pnodeDestructArr->arrayOfInts = false;
  11341. pnodeDestructArr->arrayOfNumbers = false;
  11342. pnodeDestructArr->hasMissingValues = hasMissingValues;
  11343. pnodeDestructArr->count = count;
  11344. pnodeDestructArr->spreadCount = seenRest ? 1 : 0;
  11345. if (pnodeDestructArr->pnode1)
  11346. {
  11347. this->CheckArguments(pnodeDestructArr->pnode1);
  11348. }
  11349. }
  11350. return pnodeDestructArr;
  11351. }
  11352. void Parser::CaptureContext(ParseContext *parseContext) const
  11353. {
  11354. parseContext->pszSrc = this->GetScanner()->PchBase();
  11355. parseContext->length = this->m_originalLength;
  11356. parseContext->characterOffset = this->GetScanner()->IchMinTok();
  11357. parseContext->offset = parseContext->characterOffset + this->GetScanner()->m_cMultiUnits;
  11358. parseContext->grfscr = this->m_grfscr;
  11359. parseContext->lineNumber = this->GetScanner()->LineCur();
  11360. parseContext->pnodeProg = this->m_currentNodeProg;
  11361. parseContext->isUtf8 = this->GetScanner()->IsUtf8();
  11362. parseContext->strictMode = this->IsStrictMode();
  11363. parseContext->sourceContextInfo = this->m_sourceContextInfo;
  11364. parseContext->currentBlockInfo = this->m_currentBlockInfo;
  11365. parseContext->nextBlockId = this->m_nextBlockId;
  11366. }
  11367. void Parser::RestoreContext(ParseContext *const parseContext)
  11368. {
  11369. m_sourceContextInfo = parseContext->sourceContextInfo;
  11370. m_currentBlockInfo = parseContext->currentBlockInfo;
  11371. m_nextBlockId = parseContext->nextBlockId;
  11372. m_grfscr = parseContext->grfscr;
  11373. m_length = parseContext->length;
  11374. this->GetScanner()->SetText(parseContext->pszSrc, parseContext->offset, parseContext->length, parseContext->characterOffset, parseContext->isUtf8, parseContext->grfscr, parseContext->lineNumber);
  11375. m_currentNodeProg = parseContext->pnodeProg;
  11376. m_fUseStrictMode = parseContext->strictMode;
  11377. }
  11378. class ByteCodeGenerator;
  11379. #if DBG_DUMP
  11380. #define INDENT_SIZE 2
  11381. void PrintPnodeListWIndent(ParseNode *pnode, int indentAmt);
  11382. void PrintFormalsWIndent(ParseNode *pnode, int indentAmt);
  11383. void Indent(int indentAmt) {
  11384. for (int i = 0; i < indentAmt; i++) {
  11385. Output::Print(_u(" "));
  11386. }
  11387. }
  11388. void PrintBlockType(PnodeBlockType type)
  11389. {
  11390. switch (type)
  11391. {
  11392. case Global:
  11393. Output::Print(_u("(Global)"));
  11394. break;
  11395. case Function:
  11396. Output::Print(_u("(Function)"));
  11397. break;
  11398. case Regular:
  11399. Output::Print(_u("(Regular)"));
  11400. break;
  11401. case Parameter:
  11402. Output::Print(_u("(Parameter)"));
  11403. break;
  11404. default:
  11405. Output::Print(_u("(unknown blocktype)"));
  11406. break;
  11407. }
  11408. }
  11409. void PrintScopesWIndent(ParseNode *pnode, int indentAmt) {
  11410. ParseNode *scope = nullptr;
  11411. bool firstOnly = false;
  11412. switch (pnode->nop)
  11413. {
  11414. case knopProg:
  11415. case knopFncDecl: scope = pnode->AsParseNodeFnc()->pnodeScopes; break;
  11416. case knopBlock: scope = pnode->AsParseNodeBlock()->pnodeScopes; break;
  11417. case knopCatch: scope = pnode->AsParseNodeCatch()->pnodeScopes; break;
  11418. case knopWith: scope = pnode->AsParseNodeWith()->pnodeScopes; break;
  11419. case knopSwitch: scope = pnode->AsParseNodeSwitch()->pnodeBlock; firstOnly = true; break;
  11420. case knopFor: scope = pnode->AsParseNodeFor()->pnodeBlock; firstOnly = true; break;
  11421. case knopForIn: scope = pnode->AsParseNodeForInOrForOf()->pnodeBlock; firstOnly = true; break;
  11422. case knopForOf: scope = pnode->AsParseNodeForInOrForOf()->pnodeBlock; firstOnly = true; break;
  11423. }
  11424. if (scope) {
  11425. Output::Print(_u("[%4d, %4d): "), scope->ichMin, scope->ichLim);
  11426. Indent(indentAmt);
  11427. Output::Print(_u("Scopes: "));
  11428. ParseNode *next = nullptr;
  11429. ParseNode *syntheticBlock = nullptr;
  11430. while (scope) {
  11431. switch (scope->nop) {
  11432. case knopFncDecl: Output::Print(_u("knopFncDecl")); next = scope->AsParseNodeFnc()->pnodeNext; break;
  11433. case knopBlock: Output::Print(_u("knopBlock")); PrintBlockType(scope->AsParseNodeBlock()->blockType); next = scope->AsParseNodeBlock()->pnodeNext; break;
  11434. case knopCatch: Output::Print(_u("knopCatch")); next = scope->AsParseNodeCatch()->pnodeNext; break;
  11435. case knopWith: Output::Print(_u("knopWith")); next = scope->AsParseNodeWith()->pnodeNext; break;
  11436. default: Output::Print(_u("unknown")); break;
  11437. }
  11438. if (firstOnly) {
  11439. next = nullptr;
  11440. syntheticBlock = scope;
  11441. }
  11442. if (scope->grfpn & fpnSyntheticNode) {
  11443. Output::Print(_u(" synthetic"));
  11444. if (scope->nop == knopBlock)
  11445. syntheticBlock = scope;
  11446. }
  11447. Output::Print(_u(" (%d-%d)"), scope->ichMin, scope->ichLim);
  11448. if (next) Output::Print(_u(", "));
  11449. scope = next;
  11450. }
  11451. Output::Print(_u("\n"));
  11452. if (syntheticBlock || firstOnly) {
  11453. PrintScopesWIndent(syntheticBlock, indentAmt + INDENT_SIZE);
  11454. }
  11455. }
  11456. }
  11457. void PrintPnodeWIndent(ParseNode *pnode, int indentAmt) {
  11458. if (pnode == NULL)
  11459. return;
  11460. Output::Print(_u("[%4d, %4d): "), pnode->ichMin, pnode->ichLim);
  11461. switch (pnode->nop) {
  11462. //PTNODE(knopName , "name" ,None ,Pid ,fnopLeaf)
  11463. case knopName:
  11464. Indent(indentAmt);
  11465. if (pnode->AsParseNodeName()->pid != NULL) {
  11466. Output::Print(_u("id: %s\n"), pnode->AsParseNodeName()->pid->Psz());
  11467. }
  11468. else {
  11469. Output::Print(_u("name node\n"));
  11470. }
  11471. break;
  11472. //PTNODE(knopInt , "int const" ,None ,Int ,fnopLeaf|fnopConst)
  11473. case knopInt:
  11474. Indent(indentAmt);
  11475. Output::Print(_u("%d\n"), pnode->AsParseNodeInt()->lw);
  11476. break;
  11477. //PTNODE(knopFlt , "flt const" ,None ,Flt ,fnopLeaf|fnopConst)
  11478. case knopFlt:
  11479. Indent(indentAmt);
  11480. Output::Print(_u("%lf\n"), pnode->AsParseNodeFloat()->dbl);
  11481. break;
  11482. //PTNODE(knopStr , "str const" ,None ,Pid ,fnopLeaf|fnopConst)
  11483. case knopStr:
  11484. Indent(indentAmt);
  11485. Output::Print(_u("\"%s\"\n"), pnode->AsParseNodeStr()->pid->Psz());
  11486. break;
  11487. //PTNODE(knopRegExp , "reg expr" ,None ,Pid ,fnopLeaf|fnopConst)
  11488. case knopRegExp:
  11489. Indent(indentAmt);
  11490. Output::Print(_u("/%x/\n"), pnode->AsParseNodeRegExp()->regexPattern);
  11491. break;
  11492. //PTNODE(knopNull , "null" ,Null ,None ,fnopLeaf)
  11493. case knopNull:
  11494. Indent(indentAmt);
  11495. Output::Print(_u("null\n"));
  11496. break;
  11497. //PTNODE(knopFalse , "false" ,False ,None ,fnopLeaf)
  11498. case knopFalse:
  11499. Indent(indentAmt);
  11500. Output::Print(_u("false\n"));
  11501. break;
  11502. //PTNODE(knopTrue , "true" ,True ,None ,fnopLeaf)
  11503. case knopTrue:
  11504. Indent(indentAmt);
  11505. Output::Print(_u("true\n"));
  11506. break;
  11507. //PTNODE(knopEmpty , "empty" ,Empty ,None ,fnopLeaf)
  11508. case knopEmpty:
  11509. Indent(indentAmt);
  11510. Output::Print(_u("empty\n"));
  11511. break;
  11512. // Unary operators.
  11513. //PTNODE(knopNot , "~" ,BitNot ,Uni ,fnopUni)
  11514. case knopNot:
  11515. Indent(indentAmt);
  11516. Output::Print(_u("~\n"));
  11517. PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
  11518. break;
  11519. //PTNODE(knopNeg , "unary -" ,Neg ,Uni ,fnopUni)
  11520. case knopNeg:
  11521. Indent(indentAmt);
  11522. Output::Print(_u("U-\n"));
  11523. PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
  11524. break;
  11525. //PTNODE(knopPos , "unary +" ,Pos ,Uni ,fnopUni)
  11526. case knopPos:
  11527. Indent(indentAmt);
  11528. Output::Print(_u("U+\n"));
  11529. PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
  11530. break;
  11531. //PTNODE(knopLogNot , "!" ,LogNot ,Uni ,fnopUni)
  11532. case knopLogNot:
  11533. Indent(indentAmt);
  11534. Output::Print(_u("!\n"));
  11535. PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
  11536. break;
  11537. //PTNODE(knopEllipsis , "..." ,Spread ,Uni , fnopUni)
  11538. case knopEllipsis:
  11539. Indent(indentAmt);
  11540. Output::Print(_u("...<expr>\n"));
  11541. PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
  11542. break;
  11543. //PTNODE(knopIncPost , "++ post" ,Inc ,Uni ,fnopUni|fnopAsg)
  11544. case knopIncPost:
  11545. Indent(indentAmt);
  11546. Output::Print(_u("<expr>++\n"));
  11547. PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
  11548. break;
  11549. //PTNODE(knopDecPost , "-- post" ,Dec ,Uni ,fnopUni|fnopAsg)
  11550. case knopDecPost:
  11551. Indent(indentAmt);
  11552. Output::Print(_u("<expr>--\n"));
  11553. PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
  11554. break;
  11555. //PTNODE(knopIncPre , "++ pre" ,Inc ,Uni ,fnopUni|fnopAsg)
  11556. case knopIncPre:
  11557. Indent(indentAmt);
  11558. Output::Print(_u("++<expr>\n"));
  11559. PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
  11560. break;
  11561. //PTNODE(knopDecPre , "-- pre" ,Dec ,Uni ,fnopUni|fnopAsg)
  11562. case knopDecPre:
  11563. Indent(indentAmt);
  11564. Output::Print(_u("--<expr>\n"));
  11565. PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
  11566. break;
  11567. //PTNODE(knopTypeof , "typeof" ,None ,Uni ,fnopUni)
  11568. case knopTypeof:
  11569. Indent(indentAmt);
  11570. Output::Print(_u("typeof\n"));
  11571. PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
  11572. break;
  11573. //PTNODE(knopVoid , "void" ,Void ,Uni ,fnopUni)
  11574. case knopVoid:
  11575. Indent(indentAmt);
  11576. Output::Print(_u("void\n"));
  11577. PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
  11578. break;
  11579. //PTNODE(knopDelete , "delete" ,None ,Uni ,fnopUni)
  11580. case knopDelete:
  11581. Indent(indentAmt);
  11582. Output::Print(_u("delete\n"));
  11583. PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
  11584. break;
  11585. //PTNODE(knopArray , "arr cnst" ,None ,Uni ,fnopUni)
  11586. case knopArrayPattern:
  11587. Indent(indentAmt);
  11588. Output::Print(_u("Array Pattern\n"));
  11589. PrintPnodeListWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
  11590. break;
  11591. case knopObjectPattern:
  11592. Indent(indentAmt);
  11593. Output::Print(_u("Object Pattern\n"));
  11594. PrintPnodeListWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
  11595. break;
  11596. case knopArray:
  11597. Indent(indentAmt);
  11598. Output::Print(_u("Array Literal\n"));
  11599. PrintPnodeListWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
  11600. break;
  11601. //PTNODE(knopObject , "obj cnst" ,None ,Uni ,fnopUni)
  11602. case knopObject:
  11603. Indent(indentAmt);
  11604. Output::Print(_u("Object Literal\n"));
  11605. PrintPnodeListWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
  11606. break;
  11607. // Binary and Ternary Operators
  11608. //PTNODE(knopAdd , "+" ,Add ,Bin ,fnopBin)
  11609. case knopAdd:
  11610. Indent(indentAmt);
  11611. Output::Print(_u("+\n"));
  11612. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11613. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11614. break;
  11615. //PTNODE(knopSub , "-" ,Sub ,Bin ,fnopBin)
  11616. case knopSub:
  11617. Indent(indentAmt);
  11618. Output::Print(_u("-\n"));
  11619. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11620. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11621. break;
  11622. //PTNODE(knopMul , "*" ,Mul ,Bin ,fnopBin)
  11623. case knopMul:
  11624. Indent(indentAmt);
  11625. Output::Print(_u("*\n"));
  11626. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11627. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11628. break;
  11629. //PTNODE(knopDiv , "/" ,Div ,Bin ,fnopBin)
  11630. case knopExpo:
  11631. Indent(indentAmt);
  11632. Output::Print(_u("**\n"));
  11633. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11634. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11635. break;
  11636. //PTNODE(knopExpo , "**" ,Expo ,Bin ,fnopBin)
  11637. case knopDiv:
  11638. Indent(indentAmt);
  11639. Output::Print(_u("/\n"));
  11640. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11641. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11642. break;
  11643. //PTNODE(knopMod , "%" ,Mod ,Bin ,fnopBin)
  11644. case knopMod:
  11645. Indent(indentAmt);
  11646. Output::Print(_u("%%\n"));
  11647. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11648. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11649. break;
  11650. //PTNODE(knopOr , "|" ,BitOr ,Bin ,fnopBin)
  11651. case knopOr:
  11652. Indent(indentAmt);
  11653. Output::Print(_u("|\n"));
  11654. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11655. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11656. break;
  11657. //PTNODE(knopXor , "^" ,BitXor ,Bin ,fnopBin)
  11658. case knopXor:
  11659. Indent(indentAmt);
  11660. Output::Print(_u("^\n"));
  11661. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11662. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11663. break;
  11664. //PTNODE(knopAnd , "&" ,BitAnd ,Bin ,fnopBin)
  11665. case knopAnd:
  11666. Indent(indentAmt);
  11667. Output::Print(_u("&\n"));
  11668. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11669. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11670. break;
  11671. //PTNODE(knopEq , "==" ,EQ ,Bin ,fnopBin|fnopRel)
  11672. case knopEq:
  11673. Indent(indentAmt);
  11674. Output::Print(_u("==\n"));
  11675. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11676. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11677. break;
  11678. //PTNODE(knopNe , "!=" ,NE ,Bin ,fnopBin|fnopRel)
  11679. case knopNe:
  11680. Indent(indentAmt);
  11681. Output::Print(_u("!=\n"));
  11682. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11683. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11684. break;
  11685. //PTNODE(knopLt , "<" ,LT ,Bin ,fnopBin|fnopRel)
  11686. case knopLt:
  11687. Indent(indentAmt);
  11688. Output::Print(_u("<\n"));
  11689. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11690. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11691. break;
  11692. //PTNODE(knopLe , "<=" ,LE ,Bin ,fnopBin|fnopRel)
  11693. case knopLe:
  11694. Indent(indentAmt);
  11695. Output::Print(_u("<=\n"));
  11696. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11697. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11698. break;
  11699. //PTNODE(knopGe , ">=" ,GE ,Bin ,fnopBin|fnopRel)
  11700. case knopGe:
  11701. Indent(indentAmt);
  11702. Output::Print(_u(">=\n"));
  11703. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11704. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11705. break;
  11706. //PTNODE(knopGt , ">" ,GT ,Bin ,fnopBin|fnopRel)
  11707. case knopGt:
  11708. Indent(indentAmt);
  11709. Output::Print(_u(">\n"));
  11710. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11711. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11712. break;
  11713. //PTNODE(knopCall , "()" ,None ,Bin ,fnopBin)
  11714. case knopCall:
  11715. Indent(indentAmt);
  11716. Output::Print(_u("Call\n"));
  11717. PrintPnodeWIndent(pnode->AsParseNodeCall()->pnodeTarget, indentAmt + INDENT_SIZE);
  11718. PrintPnodeListWIndent(pnode->AsParseNodeCall()->pnodeArgs, indentAmt + INDENT_SIZE);
  11719. break;
  11720. //PTNODE(knopDot , "." ,None ,Bin ,fnopBin)
  11721. case knopDot:
  11722. Indent(indentAmt);
  11723. Output::Print(_u(".\n"));
  11724. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11725. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11726. break;
  11727. //PTNODE(knopAsg , "=" ,None ,Bin ,fnopBin|fnopAsg)
  11728. case knopAsg:
  11729. Indent(indentAmt);
  11730. Output::Print(_u("=\n"));
  11731. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11732. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11733. break;
  11734. //PTNODE(knopInstOf , "instanceof",InstOf ,Bin ,fnopBin|fnopRel)
  11735. case knopInstOf:
  11736. Indent(indentAmt);
  11737. Output::Print(_u("instanceof\n"));
  11738. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11739. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11740. break;
  11741. //PTNODE(knopIn , "in" ,In ,Bin ,fnopBin|fnopRel)
  11742. case knopIn:
  11743. Indent(indentAmt);
  11744. Output::Print(_u("in\n"));
  11745. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11746. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11747. break;
  11748. //PTNODE(knopEqv , "===" ,Eqv ,Bin ,fnopBin|fnopRel)
  11749. case knopEqv:
  11750. Indent(indentAmt);
  11751. Output::Print(_u("===\n"));
  11752. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11753. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11754. break;
  11755. //PTNODE(knopNEqv , "!==" ,NEqv ,Bin ,fnopBin|fnopRel)
  11756. case knopNEqv:
  11757. Indent(indentAmt);
  11758. Output::Print(_u("!==\n"));
  11759. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11760. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11761. break;
  11762. //PTNODE(knopComma , "," ,None ,Bin ,fnopBin)
  11763. case knopComma:
  11764. Indent(indentAmt);
  11765. Output::Print(_u(",\n"));
  11766. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11767. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11768. break;
  11769. //PTNODE(knopLogOr , "||" ,None ,Bin ,fnopBin)
  11770. case knopLogOr:
  11771. Indent(indentAmt);
  11772. Output::Print(_u("||\n"));
  11773. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11774. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11775. break;
  11776. //PTNODE(knopLogAnd , "&&" ,None ,Bin ,fnopBin)
  11777. case knopLogAnd:
  11778. Indent(indentAmt);
  11779. Output::Print(_u("&&\n"));
  11780. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11781. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11782. break;
  11783. //PTNODE(knopLsh , "<<" ,Lsh ,Bin ,fnopBin)
  11784. case knopLsh:
  11785. Indent(indentAmt);
  11786. Output::Print(_u("<<\n"));
  11787. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11788. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11789. break;
  11790. //PTNODE(knopRsh , ">>" ,Rsh ,Bin ,fnopBin)
  11791. case knopRsh:
  11792. Indent(indentAmt);
  11793. Output::Print(_u(">>\n"));
  11794. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11795. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11796. break;
  11797. //PTNODE(knopRs2 , ">>>" ,Rs2 ,Bin ,fnopBin)
  11798. case knopRs2:
  11799. Indent(indentAmt);
  11800. Output::Print(_u(">>>\n"));
  11801. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11802. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11803. break;
  11804. //PTNODE(knopNew , "new" ,None ,Bin ,fnopBin)
  11805. case knopNew:
  11806. Indent(indentAmt);
  11807. Output::Print(_u("new\n"));
  11808. PrintPnodeWIndent(pnode->AsParseNodeCall()->pnodeTarget, indentAmt + INDENT_SIZE);
  11809. PrintPnodeListWIndent(pnode->AsParseNodeCall()->pnodeArgs, indentAmt + INDENT_SIZE);
  11810. break;
  11811. //PTNODE(knopIndex , "[]" ,None ,Bin ,fnopBin)
  11812. case knopIndex:
  11813. Indent(indentAmt);
  11814. Output::Print(_u("[]\n"));
  11815. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11816. PrintPnodeListWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11817. break;
  11818. //PTNODE(knopQmark , "?" ,None ,Tri ,fnopBin)
  11819. case knopQmark:
  11820. Indent(indentAmt);
  11821. Output::Print(_u("?:\n"));
  11822. PrintPnodeWIndent(pnode->AsParseNodeTri()->pnode1, indentAmt + INDENT_SIZE);
  11823. PrintPnodeWIndent(pnode->AsParseNodeTri()->pnode2, indentAmt + INDENT_SIZE);
  11824. PrintPnodeWIndent(pnode->AsParseNodeTri()->pnode3, indentAmt + INDENT_SIZE);
  11825. break;
  11826. //PTNODE(knopAsgAdd , "+=" ,Add ,Bin ,fnopBin|fnopAsg)
  11827. case knopAsgAdd:
  11828. Indent(indentAmt);
  11829. Output::Print(_u("+=\n"));
  11830. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11831. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11832. break;
  11833. //PTNODE(knopAsgSub , "-=" ,Sub ,Bin ,fnopBin|fnopAsg)
  11834. case knopAsgSub:
  11835. Indent(indentAmt);
  11836. Output::Print(_u("-=\n"));
  11837. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11838. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11839. break;
  11840. //PTNODE(knopAsgMul , "*=" ,Mul ,Bin ,fnopBin|fnopAsg)
  11841. case knopAsgMul:
  11842. Indent(indentAmt);
  11843. Output::Print(_u("*=\n"));
  11844. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11845. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11846. break;
  11847. //PTNODE(knopAsgDiv , "/=" ,Div ,Bin ,fnopBin|fnopAsg)
  11848. case knopAsgExpo:
  11849. Indent(indentAmt);
  11850. Output::Print(_u("**=\n"));
  11851. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11852. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11853. break;
  11854. //PTNODE(knopAsgExpo , "**=" ,Expo ,Bin ,fnopBin|fnopAsg)
  11855. case knopAsgDiv:
  11856. Indent(indentAmt);
  11857. Output::Print(_u("/=\n"));
  11858. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11859. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11860. break;
  11861. //PTNODE(knopAsgMod , "%=" ,Mod ,Bin ,fnopBin|fnopAsg)
  11862. case knopAsgMod:
  11863. Indent(indentAmt);
  11864. Output::Print(_u("%=\n"));
  11865. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11866. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11867. break;
  11868. //PTNODE(knopAsgAnd , "&=" ,BitAnd ,Bin ,fnopBin|fnopAsg)
  11869. case knopAsgAnd:
  11870. Indent(indentAmt);
  11871. Output::Print(_u("&=\n"));
  11872. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11873. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11874. break;
  11875. //PTNODE(knopAsgXor , "^=" ,BitXor ,Bin ,fnopBin|fnopAsg)
  11876. case knopAsgXor:
  11877. Indent(indentAmt);
  11878. Output::Print(_u("^=\n"));
  11879. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11880. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11881. break;
  11882. //PTNODE(knopAsgOr , "|=" ,BitOr ,Bin ,fnopBin|fnopAsg)
  11883. case knopAsgOr:
  11884. Indent(indentAmt);
  11885. Output::Print(_u("|=\n"));
  11886. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11887. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11888. break;
  11889. //PTNODE(knopAsgLsh , "<<=" ,Lsh ,Bin ,fnopBin|fnopAsg)
  11890. case knopAsgLsh:
  11891. Indent(indentAmt);
  11892. Output::Print(_u("<<=\n"));
  11893. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11894. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11895. break;
  11896. //PTNODE(knopAsgRsh , ">>=" ,Rsh ,Bin ,fnopBin|fnopAsg)
  11897. case knopAsgRsh:
  11898. Indent(indentAmt);
  11899. Output::Print(_u(">>=\n"));
  11900. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11901. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11902. break;
  11903. //PTNODE(knopAsgRs2 , ">>>=" ,Rs2 ,Bin ,fnopBin|fnopAsg)
  11904. case knopAsgRs2:
  11905. Indent(indentAmt);
  11906. Output::Print(_u(">>>=\n"));
  11907. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11908. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11909. break;
  11910. case knopComputedName:
  11911. Indent(indentAmt);
  11912. Output::Print(_u("ComputedProperty\n"));
  11913. PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
  11914. break;
  11915. //PTNODE(knopMember , ":" ,None ,Bin ,fnopBin)
  11916. case knopMember:
  11917. case knopMemberShort:
  11918. case knopObjectPatternMember:
  11919. Indent(indentAmt);
  11920. Output::Print(_u(":\n"));
  11921. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
  11922. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
  11923. break;
  11924. // General nodes.
  11925. //PTNODE(knopList , "<list>" ,None ,Bin ,fnopNone)
  11926. case knopList:
  11927. Indent(indentAmt);
  11928. Output::Print(_u("List\n"));
  11929. PrintPnodeListWIndent(pnode, indentAmt + INDENT_SIZE);
  11930. break;
  11931. //PTNODE(knopVarDecl , "varDcl" ,None ,Var ,fnopNone)
  11932. case knopVarDecl:
  11933. Indent(indentAmt);
  11934. Output::Print(_u("var %s\n"), pnode->AsParseNodeVar()->pid->Psz());
  11935. if (pnode->AsParseNodeVar()->pnodeInit != NULL)
  11936. PrintPnodeWIndent(pnode->AsParseNodeVar()->pnodeInit, indentAmt + INDENT_SIZE);
  11937. break;
  11938. case knopConstDecl:
  11939. Indent(indentAmt);
  11940. Output::Print(_u("const %s\n"), pnode->AsParseNodeVar()->pid->Psz());
  11941. if (pnode->AsParseNodeVar()->pnodeInit != NULL)
  11942. PrintPnodeWIndent(pnode->AsParseNodeVar()->pnodeInit, indentAmt + INDENT_SIZE);
  11943. break;
  11944. case knopLetDecl:
  11945. Indent(indentAmt);
  11946. Output::Print(_u("let %s\n"), pnode->AsParseNodeVar()->pid->Psz());
  11947. if (pnode->AsParseNodeVar()->pnodeInit != NULL)
  11948. PrintPnodeWIndent(pnode->AsParseNodeVar()->pnodeInit, indentAmt + INDENT_SIZE);
  11949. break;
  11950. //PTNODE(knopFncDecl , "fncDcl" ,None ,Fnc ,fnopLeaf)
  11951. case knopFncDecl:
  11952. Indent(indentAmt);
  11953. if (pnode->AsParseNodeFnc()->pid != NULL)
  11954. {
  11955. Output::Print(_u("fn decl %d nested %d name %s (%d-%d)\n"), pnode->AsParseNodeFnc()->IsDeclaration(), pnode->AsParseNodeFnc()->IsNested(),
  11956. pnode->AsParseNodeFnc()->pid->Psz(), pnode->ichMin, pnode->ichLim);
  11957. }
  11958. else
  11959. {
  11960. Output::Print(_u("fn decl %d nested %d anonymous (%d-%d)\n"), pnode->AsParseNodeFnc()->IsDeclaration(), pnode->AsParseNodeFnc()->IsNested(), pnode->ichMin, pnode->ichLim);
  11961. }
  11962. PrintScopesWIndent(pnode, indentAmt + INDENT_SIZE);
  11963. PrintFormalsWIndent(pnode->AsParseNodeFnc()->pnodeParams, indentAmt + INDENT_SIZE);
  11964. PrintPnodeWIndent(pnode->AsParseNodeFnc()->pnodeRest, indentAmt + INDENT_SIZE);
  11965. PrintPnodeWIndent(pnode->AsParseNodeFnc()->pnodeBody, indentAmt + INDENT_SIZE);
  11966. if (pnode->AsParseNodeFnc()->pnodeBody == nullptr)
  11967. {
  11968. Output::Print(_u("[%4d, %4d): "), pnode->ichMin, pnode->ichLim);
  11969. Indent(indentAmt + INDENT_SIZE);
  11970. Output::Print(_u("<parse deferred body>\n"));
  11971. }
  11972. break;
  11973. //PTNODE(knopProg , "program" ,None ,Fnc ,fnopNone)
  11974. case knopProg:
  11975. Indent(indentAmt);
  11976. Output::Print(_u("program\n"));
  11977. PrintScopesWIndent(pnode, indentAmt + INDENT_SIZE);
  11978. PrintPnodeListWIndent(pnode->AsParseNodeFnc()->pnodeBody, indentAmt + INDENT_SIZE);
  11979. break;
  11980. //PTNODE(knopEndCode , "<endcode>" ,None ,None ,fnopNone)
  11981. case knopEndCode:
  11982. Indent(indentAmt);
  11983. Output::Print(_u("<endcode>\n"));
  11984. break;
  11985. //PTNODE(knopDebugger , "debugger" ,None ,None ,fnopNone)
  11986. case knopDebugger:
  11987. Indent(indentAmt);
  11988. Output::Print(_u("<debugger>\n"));
  11989. break;
  11990. //PTNODE(knopFor , "for" ,None ,For ,fnopBreak|fnopContinue)
  11991. case knopFor:
  11992. Indent(indentAmt);
  11993. Output::Print(_u("for\n"));
  11994. PrintScopesWIndent(pnode, indentAmt + INDENT_SIZE);
  11995. PrintPnodeWIndent(pnode->AsParseNodeFor()->pnodeInit, indentAmt + INDENT_SIZE);
  11996. PrintPnodeWIndent(pnode->AsParseNodeFor()->pnodeCond, indentAmt + INDENT_SIZE);
  11997. PrintPnodeWIndent(pnode->AsParseNodeFor()->pnodeIncr, indentAmt + INDENT_SIZE);
  11998. PrintPnodeWIndent(pnode->AsParseNodeFor()->pnodeBody, indentAmt + INDENT_SIZE);
  11999. break;
  12000. //PTNODE(knopIf , "if" ,None ,If ,fnopNone)
  12001. case knopIf:
  12002. Indent(indentAmt);
  12003. Output::Print(_u("if\n"));
  12004. PrintPnodeWIndent(pnode->AsParseNodeIf()->pnodeCond, indentAmt + INDENT_SIZE);
  12005. PrintPnodeWIndent(pnode->AsParseNodeIf()->pnodeTrue, indentAmt + INDENT_SIZE);
  12006. if (pnode->AsParseNodeIf()->pnodeFalse != NULL)
  12007. PrintPnodeWIndent(pnode->AsParseNodeIf()->pnodeFalse, indentAmt + INDENT_SIZE);
  12008. break;
  12009. //PTNODE(knopWhile , "while" ,None ,While,fnopBreak|fnopContinue)
  12010. case knopWhile:
  12011. Indent(indentAmt);
  12012. Output::Print(_u("while\n"));
  12013. PrintPnodeWIndent(pnode->AsParseNodeWhile()->pnodeCond, indentAmt + INDENT_SIZE);
  12014. PrintPnodeWIndent(pnode->AsParseNodeWhile()->pnodeBody, indentAmt + INDENT_SIZE);
  12015. break;
  12016. //PTNODE(knopDoWhile , "do-while" ,None ,While,fnopBreak|fnopContinue)
  12017. case knopDoWhile:
  12018. Indent(indentAmt);
  12019. Output::Print(_u("do\n"));
  12020. PrintPnodeWIndent(pnode->AsParseNodeWhile()->pnodeCond, indentAmt + INDENT_SIZE);
  12021. PrintPnodeWIndent(pnode->AsParseNodeWhile()->pnodeBody, indentAmt + INDENT_SIZE);
  12022. break;
  12023. //PTNODE(knopForIn , "for in" ,None ,ForIn,fnopBreak|fnopContinue|fnopCleanup)
  12024. case knopForIn:
  12025. Indent(indentAmt);
  12026. Output::Print(_u("forIn\n"));
  12027. PrintScopesWIndent(pnode, indentAmt + INDENT_SIZE);
  12028. PrintPnodeWIndent(pnode->AsParseNodeForInOrForOf()->pnodeLval, indentAmt + INDENT_SIZE);
  12029. PrintPnodeWIndent(pnode->AsParseNodeForInOrForOf()->pnodeObj, indentAmt + INDENT_SIZE);
  12030. PrintPnodeWIndent(pnode->AsParseNodeForInOrForOf()->pnodeBody, indentAmt + INDENT_SIZE);
  12031. break;
  12032. case knopForOf:
  12033. Indent(indentAmt);
  12034. Output::Print(_u("forOf\n"));
  12035. PrintScopesWIndent(pnode, indentAmt + INDENT_SIZE);
  12036. PrintPnodeWIndent(pnode->AsParseNodeForInOrForOf()->pnodeLval, indentAmt + INDENT_SIZE);
  12037. PrintPnodeWIndent(pnode->AsParseNodeForInOrForOf()->pnodeObj, indentAmt + INDENT_SIZE);
  12038. PrintPnodeWIndent(pnode->AsParseNodeForInOrForOf()->pnodeBody, indentAmt + INDENT_SIZE);
  12039. break;
  12040. //PTNODE(knopReturn , "return" ,None ,Uni ,fnopNone)
  12041. case knopReturn:
  12042. Indent(indentAmt);
  12043. Output::Print(_u("return\n"));
  12044. if (pnode->AsParseNodeReturn()->pnodeExpr != NULL)
  12045. PrintPnodeWIndent(pnode->AsParseNodeReturn()->pnodeExpr, indentAmt + INDENT_SIZE);
  12046. break;
  12047. //PTNODE(knopBlock , "{}" ,None ,Block,fnopNone)
  12048. case knopBlock:
  12049. Indent(indentAmt);
  12050. Output::Print(_u("block "));
  12051. if (pnode->grfpn & fpnSyntheticNode)
  12052. Output::Print(_u("synthetic "));
  12053. PrintBlockType(pnode->AsParseNodeBlock()->blockType);
  12054. Output::Print(_u("(%d-%d)\n"), pnode->ichMin, pnode->ichLim);
  12055. PrintScopesWIndent(pnode, indentAmt + INDENT_SIZE);
  12056. if (pnode->AsParseNodeBlock()->pnodeStmt != NULL)
  12057. PrintPnodeWIndent(pnode->AsParseNodeBlock()->pnodeStmt, indentAmt + INDENT_SIZE);
  12058. break;
  12059. //PTNODE(knopWith , "with" ,None ,With ,fnopCleanup)
  12060. case knopWith:
  12061. Indent(indentAmt);
  12062. Output::Print(_u("with (%d-%d)\n"), pnode->ichMin, pnode->ichLim);
  12063. PrintScopesWIndent(pnode, indentAmt + INDENT_SIZE);
  12064. PrintPnodeWIndent(pnode->AsParseNodeWith()->pnodeObj, indentAmt + INDENT_SIZE);
  12065. PrintPnodeWIndent(pnode->AsParseNodeWith()->pnodeBody, indentAmt + INDENT_SIZE);
  12066. break;
  12067. //PTNODE(knopBreak , "break" ,None ,Jump ,fnopNone)
  12068. case knopBreak:
  12069. Indent(indentAmt);
  12070. Output::Print(_u("break\n"));
  12071. // TODO: some representation of target
  12072. break;
  12073. //PTNODE(knopContinue , "continue" ,None ,Jump ,fnopNone)
  12074. case knopContinue:
  12075. Indent(indentAmt);
  12076. Output::Print(_u("continue\n"));
  12077. // TODO: some representation of target
  12078. break;
  12079. //PTNODE(knopSwitch , "switch" ,None ,Switch,fnopBreak)
  12080. case knopSwitch:
  12081. Indent(indentAmt);
  12082. Output::Print(_u("switch\n"));
  12083. PrintScopesWIndent(pnode, indentAmt + INDENT_SIZE);
  12084. for (ParseNodeCase *pnodeT = pnode->AsParseNodeSwitch()->pnodeCases; NULL != pnodeT; pnodeT = pnodeT->pnodeNext) {
  12085. PrintPnodeWIndent(pnodeT, indentAmt + 2);
  12086. }
  12087. break;
  12088. //PTNODE(knopCase , "case" ,None ,Case ,fnopNone)
  12089. case knopCase:
  12090. Indent(indentAmt);
  12091. Output::Print(_u("case\n"));
  12092. PrintPnodeWIndent(pnode->AsParseNodeCase()->pnodeExpr, indentAmt + INDENT_SIZE);
  12093. PrintPnodeWIndent(pnode->AsParseNodeCase()->pnodeBody, indentAmt + INDENT_SIZE);
  12094. break;
  12095. //PTNODE(knopTryFinally,"try-finally",None,TryFinally,fnopCleanup)
  12096. case knopTryFinally:
  12097. PrintPnodeWIndent(pnode->AsParseNodeTryFinally()->pnodeTry, indentAmt);
  12098. PrintPnodeWIndent(pnode->AsParseNodeTryFinally()->pnodeFinally, indentAmt);
  12099. break;
  12100. case knopFinally:
  12101. Indent(indentAmt);
  12102. Output::Print(_u("finally\n"));
  12103. PrintPnodeWIndent(pnode->AsParseNodeFinally()->pnodeBody, indentAmt + INDENT_SIZE);
  12104. break;
  12105. //PTNODE(knopCatch , "catch" ,None ,Catch,fnopNone)
  12106. case knopCatch:
  12107. Indent(indentAmt);
  12108. Output::Print(_u("catch (%d-%d)\n"), pnode->ichMin, pnode->ichLim);
  12109. PrintScopesWIndent(pnode, indentAmt + INDENT_SIZE);
  12110. PrintPnodeWIndent(pnode->AsParseNodeCatch()->GetParam(), indentAmt + INDENT_SIZE);
  12111. // if (pnode->AsParseNodeCatch()->pnodeGuard!=NULL)
  12112. // PrintPnodeWIndent(pnode->AsParseNodeCatch()->pnodeGuard,indentAmt+INDENT_SIZE);
  12113. PrintPnodeWIndent(pnode->AsParseNodeCatch()->pnodeBody, indentAmt + INDENT_SIZE);
  12114. break;
  12115. //PTNODE(knopTryCatch , "try-catch" ,None ,TryCatch ,fnopCleanup)
  12116. case knopTryCatch:
  12117. PrintPnodeWIndent(pnode->AsParseNodeTryCatch()->pnodeTry, indentAmt);
  12118. PrintPnodeWIndent(pnode->AsParseNodeTryCatch()->pnodeCatch, indentAmt);
  12119. break;
  12120. //PTNODE(knopTry , "try" ,None ,Try ,fnopCleanup)
  12121. case knopTry:
  12122. Indent(indentAmt);
  12123. Output::Print(_u("try\n"));
  12124. PrintPnodeWIndent(pnode->AsParseNodeTry()->pnodeBody, indentAmt + INDENT_SIZE);
  12125. break;
  12126. //PTNODE(knopThrow , "throw" ,None ,Uni ,fnopNone)
  12127. case knopThrow:
  12128. Indent(indentAmt);
  12129. Output::Print(_u("throw\n"));
  12130. PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
  12131. break;
  12132. //PTNODE(knopClassDecl, "classDecl", None , Class, fnopLeaf)
  12133. case knopClassDecl:
  12134. Indent(indentAmt);
  12135. Output::Print(_u("class %s"), pnode->AsParseNodeClass()->pnodeName->pid->Psz());
  12136. if (pnode->AsParseNodeClass()->pnodeExtends != nullptr)
  12137. {
  12138. Output::Print(_u(" extends "));
  12139. PrintPnodeWIndent(pnode->AsParseNodeClass()->pnodeExtends, 0);
  12140. }
  12141. else {
  12142. Output::Print(_u("\n"));
  12143. }
  12144. PrintPnodeWIndent(pnode->AsParseNodeClass()->pnodeConstructor, indentAmt + INDENT_SIZE);
  12145. PrintPnodeWIndent(pnode->AsParseNodeClass()->pnodeMembers, indentAmt + INDENT_SIZE);
  12146. PrintPnodeWIndent(pnode->AsParseNodeClass()->pnodeStaticMembers, indentAmt + INDENT_SIZE);
  12147. break;
  12148. case knopStrTemplate:
  12149. Indent(indentAmt);
  12150. Output::Print(_u("string template\n"));
  12151. PrintPnodeListWIndent(pnode->AsParseNodeStrTemplate()->pnodeSubstitutionExpressions, indentAmt + INDENT_SIZE);
  12152. break;
  12153. case knopYieldStar:
  12154. Indent(indentAmt);
  12155. Output::Print(_u("yield*\n"));
  12156. PrintPnodeListWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
  12157. break;
  12158. case knopYield:
  12159. case knopYieldLeaf:
  12160. Indent(indentAmt);
  12161. Output::Print(_u("yield\n"));
  12162. PrintPnodeListWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
  12163. break;
  12164. case knopAwait:
  12165. Indent(indentAmt);
  12166. Output::Print(_u("await\n"));
  12167. PrintPnodeListWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
  12168. break;
  12169. case knopExportDefault:
  12170. Indent(indentAmt);
  12171. Output::Print(_u("export default\n"));
  12172. PrintPnodeListWIndent(pnode->AsParseNodeExportDefault()->pnodeExpr, indentAmt + INDENT_SIZE);
  12173. break;
  12174. default:
  12175. Output::Print(_u("unhandled pnode op %d\n"), pnode->nop);
  12176. break;
  12177. }
  12178. }
  12179. void PrintPnodeListWIndent(ParseNode *pnode, int indentAmt) {
  12180. if (pnode != NULL) {
  12181. while (pnode->nop == knopList) {
  12182. PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt);
  12183. pnode = pnode->AsParseNodeBin()->pnode2;
  12184. }
  12185. PrintPnodeWIndent(pnode, indentAmt);
  12186. }
  12187. }
  12188. void PrintFormalsWIndent(ParseNode *pnodeArgs, int indentAmt)
  12189. {
  12190. for (ParseNode *pnode = pnodeArgs; pnode != nullptr; pnode = pnode->GetFormalNext())
  12191. {
  12192. PrintPnodeWIndent(pnode->nop == knopParamPattern ? pnode->AsParseNodeParamPattern()->pnode1 : pnode, indentAmt);
  12193. }
  12194. }
  12195. void PrintPnode(ParseNode *pnode) {
  12196. PrintPnodeWIndent(pnode, 0);
  12197. }
  12198. void ParseNode::Dump()
  12199. {
  12200. switch (nop)
  12201. {
  12202. case knopFncDecl:
  12203. case knopProg:
  12204. LPCOLESTR name = Js::Constants::AnonymousFunction;
  12205. if (this->AsParseNodeFnc()->pnodeName)
  12206. {
  12207. Assert(this->AsParseNodeFnc()->pnodeName->nop == knopVarDecl);
  12208. name = this->AsParseNodeFnc()->pnodeName->pid->Psz();
  12209. }
  12210. Output::Print(_u("%s (%d) [%d, %d]:\n"), name, this->AsParseNodeFnc()->functionId, this->AsParseNodeFnc()->lineNumber, this->AsParseNodeFnc()->columnNumber);
  12211. Output::Print(_u("hasArguments: %s callsEval:%s childCallsEval:%s HasReferenceableBuiltInArguments:%s ArgumentsObjectEscapes:%s HasWith:%s HasOnlyThis:%s \n"),
  12212. IsTrueOrFalse(this->AsParseNodeFnc()->HasHeapArguments()),
  12213. IsTrueOrFalse(this->AsParseNodeFnc()->CallsEval()),
  12214. IsTrueOrFalse(this->AsParseNodeFnc()->ChildCallsEval()),
  12215. IsTrueOrFalse(this->AsParseNodeFnc()->HasReferenceableBuiltInArguments()),
  12216. IsTrueOrFalse(this->AsParseNodeFnc()->GetArgumentsObjectEscapes()),
  12217. IsTrueOrFalse(this->AsParseNodeFnc()->HasWithStmt()),
  12218. IsTrueOrFalse(this->AsParseNodeFnc()->HasOnlyThisStmts()));
  12219. if (this->AsParseNodeFnc()->funcInfo)
  12220. {
  12221. this->AsParseNodeFnc()->funcInfo->Dump();
  12222. }
  12223. break;
  12224. }
  12225. }
  12226. void DumpCapturedNames(ParseNodeFnc* pnodeFnc, IdentPtrSet* capturedNames, ArenaAllocator* alloc)
  12227. {
  12228. auto sortedNames = JsUtil::List<IdentPtr, ArenaAllocator>::New(alloc);
  12229. capturedNames->Map([=](const IdentPtr& pid) -> void {
  12230. sortedNames->Add(pid);
  12231. });
  12232. sortedNames->Sort([](void* context, const void* left, const void* right) -> int {
  12233. const IdentPtr leftIdentPtr = *(const IdentPtr*)(left);
  12234. const IdentPtr rightIdentPtr = *(const IdentPtr*)(right);
  12235. return ::wcscmp(leftIdentPtr->Psz(), rightIdentPtr->Psz());
  12236. }, nullptr);
  12237. sortedNames->Map([=](int index, const IdentPtr pid) -> void {
  12238. OUTPUT_TRACE_DEBUGONLY(Js::CreateParserStatePhase, _u(" Function %u captured name \"%s\"\n"), pnodeFnc->functionId, pid->Psz());
  12239. });
  12240. }
  12241. #endif
  12242. void Parser::AddNestedCapturedNames(ParseNodeFnc* pnodeChildFnc)
  12243. {
  12244. if (m_currentNodeFunc && this->IsCreatingStateCache() && pnodeChildFnc->HasAnyCapturedNames())
  12245. {
  12246. IdentPtrSet* parentCapturedNames = GetCurrentFunctionNode()->EnsureCapturedNames(&m_nodeAllocator);
  12247. IdentPtrSet* childCaptureNames = pnodeChildFnc->GetCapturedNames();
  12248. auto iter = childCaptureNames->GetIterator();
  12249. while (iter.IsValid())
  12250. {
  12251. parentCapturedNames->AddNew(iter.CurrentValue());
  12252. iter.MoveNext();
  12253. }
  12254. }
  12255. }
  12256. void Parser::ProcessCapturedNames(ParseNodeFnc* pnodeFnc)
  12257. {
  12258. if (this->IsCreatingStateCache() && pnodeFnc->HasAnyCapturedNames())
  12259. {
  12260. IdentPtrSet* capturedNames = pnodeFnc->GetCapturedNames();
  12261. auto iter = capturedNames->GetIteratorWithRemovalSupport();
  12262. while (iter.IsValid())
  12263. {
  12264. const IdentPtr& pid = iter.CurrentValueReference();
  12265. PidRefStack* ref = pid->GetTopRef();
  12266. // If the pid has no refs left in our function's scope after binding, we didn't capture it.
  12267. if (!ref || ref->GetFuncScopeId() < pnodeFnc->functionId)
  12268. {
  12269. iter.RemoveCurrent();
  12270. }
  12271. iter.MoveNext();
  12272. }
  12273. #if DBG_DUMP
  12274. if (Js::Configuration::Global.flags.Trace.IsEnabled(Js::CreateParserStatePhase))
  12275. {
  12276. DumpCapturedNames(pnodeFnc, capturedNames, &this->m_nodeAllocator);
  12277. fflush(stdout);
  12278. }
  12279. #endif
  12280. }
  12281. }
  12282. void Parser::ReleaseTemporaryGuestArena()
  12283. {
  12284. // In case of modules the Parser lives longer than the temporary Guest Arena. We may have already released the arena explicitly.
  12285. if (!m_tempGuestArenaReleased)
  12286. {
  12287. // The regex patterns list has references to the temporary Guest Arena. Reset it first.
  12288. m_registeredRegexPatterns.Reset();
  12289. if (this->m_scriptContext != nullptr)
  12290. {
  12291. this->m_scriptContext->ReleaseTemporaryGuestAllocator(m_tempGuestArena);
  12292. m_tempGuestArena.Unroot();
  12293. }
  12294. m_tempGuestArenaReleased = true;
  12295. }
  12296. }
  12297. bool Parser::IsCreatingStateCache()
  12298. {
  12299. return (((this->m_grfscr & fscrCreateParserState) == fscrCreateParserState)
  12300. && this->m_functionBody == nullptr
  12301. && CONFIG_FLAG(ParserStateCache));
  12302. }
  12303. void Parser::ShiftCurrDeferredStubToChildFunction(ParseNodeFnc* pnodeFnc, ParseNodeFnc* pnodeFncParent)
  12304. {
  12305. // Goal here is to shift the current deferred stub to point to the stubs for pnodeFnc
  12306. // so we may continue parsing pnodeFnc using the correct set of stubs instead of the
  12307. // stubs for pnodeFncParent.
  12308. // This function assumes we are in the middle of parsing pnodeFnc which is a child
  12309. // nested in pnodeFncParent.
  12310. if (pnodeFnc->IsNested() && pnodeFncParent != nullptr && m_currDeferredStub != nullptr && pnodeFncParent->ichMin != pnodeFnc->ichMin)
  12311. {
  12312. AssertOrFailFast(pnodeFncParent->nestedCount > 0);
  12313. DeferredFunctionStub* childStub = m_currDeferredStub + (pnodeFncParent->nestedCount - 1);
  12314. m_currDeferredStubCount = childStub->nestedCount;
  12315. m_currDeferredStub = childStub->deferredStubs;
  12316. }
  12317. }
  12318. uint Parser::BuildDeferredStubTreeHelper(ParseNodeBlock* pnodeBlock, DeferredFunctionStub* deferredStubs, uint currentStubIndex, uint deferredStubCount, Recycler *recycler)
  12319. {
  12320. Assert(pnodeBlock != nullptr
  12321. && (pnodeBlock->blockType == PnodeBlockType::Function
  12322. || pnodeBlock->blockType == PnodeBlockType::Parameter));
  12323. ParseNodePtr pnodeChild = pnodeBlock->pnodeScopes;
  12324. while (pnodeChild != nullptr)
  12325. {
  12326. if (pnodeChild->nop != knopFncDecl)
  12327. {
  12328. // We only expect to find a function body block in a parameter scope block.
  12329. Assert(pnodeChild->nop == knopBlock
  12330. && (pnodeBlock->blockType == PnodeBlockType::Parameter
  12331. || pnodeChild->AsParseNodeBlock()->blockType == PnodeBlockType::Function));
  12332. pnodeChild = pnodeChild->AsParseNodeBlock()->pnodeNext;
  12333. continue;
  12334. }
  12335. ParseNodeFnc* pnodeFncChild = pnodeChild->AsParseNodeFnc();
  12336. AnalysisAssertOrFailFast(currentStubIndex < deferredStubCount);
  12337. Assert(pnodeFncChild->pnodeBody == nullptr);
  12338. if (pnodeFncChild->IsGeneratedDefault())
  12339. {
  12340. ++currentStubIndex;
  12341. pnodeChild = pnodeFncChild->pnodeNext;
  12342. continue;
  12343. }
  12344. deferredStubs[currentStubIndex].fncFlags = pnodeFncChild->fncFlags;
  12345. deferredStubs[currentStubIndex].nestedCount = pnodeFncChild->nestedCount;
  12346. deferredStubs[currentStubIndex].restorePoint = *pnodeFncChild->pRestorePoint;
  12347. deferredStubs[currentStubIndex].deferredStubs = BuildDeferredStubTree(pnodeFncChild, recycler);
  12348. deferredStubs[currentStubIndex].ichMin = pnodeChild->ichMin;
  12349. // Save the set of captured names onto the deferred stub.
  12350. // Since this set is allocated in the Parser arena, we'll have to convert these
  12351. // into indices in a string table which will survive when the parser goes away.
  12352. deferredStubs[currentStubIndex].capturedNamePointers = pnodeFncChild->GetCapturedNames();
  12353. ++currentStubIndex;
  12354. pnodeChild = pnodeFncChild->pnodeNext;
  12355. }
  12356. return currentStubIndex;
  12357. }
  12358. DeferredFunctionStub * Parser::BuildDeferredStubTree(ParseNodeFnc *pnodeFnc, Recycler *recycler)
  12359. {
  12360. Assert(CONFIG_FLAG(ParserStateCache));
  12361. uint nestedCount = pnodeFnc->nestedCount;
  12362. if (nestedCount == 0)
  12363. {
  12364. return nullptr;
  12365. }
  12366. if (pnodeFnc->deferredStub)
  12367. {
  12368. return pnodeFnc->deferredStub;
  12369. }
  12370. DeferredFunctionStub* deferredStubs = RecyclerNewArray(recycler, DeferredFunctionStub, nestedCount);
  12371. uint currentStubIndex = BuildDeferredStubTreeHelper(pnodeFnc->pnodeScopes, deferredStubs, 0, nestedCount, recycler);
  12372. currentStubIndex = BuildDeferredStubTreeHelper(pnodeFnc->pnodeBodyScope, deferredStubs, currentStubIndex, nestedCount, recycler);
  12373. Assert(currentStubIndex == nestedCount);
  12374. pnodeFnc->deferredStub = deferredStubs;
  12375. return deferredStubs;
  12376. }