parse.cpp 418 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457
  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. #if DBG_DUMP
  9. void PrintPnodeWIndent(ParseNode *pnode,int indentAmt);
  10. #endif
  11. const char* const nopNames[knopLim]= {
  12. #define PTNODE(nop,sn,pc,nk,grfnop,json) sn,
  13. #include "ptlist.h"
  14. };
  15. void printNop(int nop) {
  16. printf("%s\n",nopNames[nop]);
  17. }
  18. const uint ParseNode::mpnopgrfnop[knopLim] =
  19. {
  20. #define PTNODE(nop,sn,pc,nk,grfnop,json) grfnop,
  21. #include "ptlist.h"
  22. };
  23. bool Parser::BindDeferredPidRefs() const
  24. {
  25. return m_scriptContext->GetConfig()->BindDeferredPidRefs();
  26. }
  27. bool Parser::IsES6DestructuringEnabled() const
  28. {
  29. return m_scriptContext->GetConfig()->IsES6DestructuringEnabled();
  30. }
  31. struct DeferredFunctionStub
  32. {
  33. RestorePoint restorePoint;
  34. uint fncFlags;
  35. uint nestedCount;
  36. DeferredFunctionStub *deferredStubs;
  37. #if DEBUG
  38. charcount_t ichMin;
  39. #endif
  40. };
  41. struct StmtNest
  42. {
  43. union
  44. {
  45. struct
  46. {
  47. ParseNodePtr pnodeStmt; // This statement node.
  48. ParseNodePtr pnodeLab; // Labels for this statement.
  49. };
  50. struct
  51. {
  52. bool isDeferred : 1;
  53. OpCode op; // This statement operation.
  54. LabelId* pLabelId; // Labels for this statement.
  55. };
  56. };
  57. StmtNest *pstmtOuter; // Enclosing statement.
  58. };
  59. struct BlockInfoStack
  60. {
  61. StmtNest pstmt;
  62. ParseNode *pnodeBlock;
  63. ParseNodePtr *m_ppnodeLex; // lexical variable list tail
  64. BlockInfoStack *pBlockInfoOuter; // containing block's BlockInfoStack
  65. BlockInfoStack *pBlockInfoFunction; // nearest function's BlockInfoStack (if pnodeBlock is a function, this points to itself)
  66. };
  67. #if DEBUG
  68. Parser::Parser(Js::ScriptContext* scriptContext, BOOL strictMode, PageAllocator *alloc, bool isBackground, size_t size)
  69. #else
  70. Parser::Parser(Js::ScriptContext* scriptContext, BOOL strictMode, PageAllocator *alloc, bool isBackground)
  71. #endif
  72. : m_nodeAllocator(L"Parser", alloc ? alloc : scriptContext->GetThreadContext()->GetPageAllocator(), Parser::OutOfMemory),
  73. // use the GuestArena directly for keeping the RegexPattern* alive during byte code generation
  74. m_registeredRegexPatterns(scriptContext->GetGuestArena())
  75. {
  76. AssertMsg(size == sizeof(Parser), "verify conditionals affecting the size of Parser agree");
  77. Assert(scriptContext != nullptr);
  78. m_isInBackground = isBackground;
  79. m_phtbl = nullptr;
  80. m_pscan = nullptr;
  81. m_deferringAST = FALSE;
  82. m_stoppedDeferredParse = FALSE;
  83. m_hasParallelJob = false;
  84. m_doingFastScan = false;
  85. m_scriptContext = scriptContext;
  86. m_pCurrentAstSize = nullptr;
  87. m_parsingDuplicate = 0;
  88. m_arrayDepth = 0;
  89. m_funcInArrayDepth = 0;
  90. m_parenDepth = 0;
  91. m_funcInArray = 0;
  92. m_tryCatchOrFinallyDepth = 0;
  93. m_UsesArgumentsAtGlobal = false;
  94. m_currentNodeFunc = nullptr;
  95. m_currentNodeDeferredFunc = nullptr;
  96. m_currentNodeNonLambdaFunc = nullptr;
  97. m_currentNodeNonLambdaDeferredFunc = nullptr;
  98. m_currentNodeProg = nullptr;
  99. m_currDeferredStub = nullptr;
  100. m_pstmtCur = nullptr;
  101. m_currentBlockInfo = nullptr;
  102. m_currentScope = nullptr;
  103. m_currentDynamicBlock = nullptr;
  104. m_catchPidRefList = nullptr;
  105. m_grfscr = fscrNil;
  106. m_length = 0;
  107. m_originalLength = 0;
  108. m_nextFunctionId = nullptr;
  109. m_errorCallback = nullptr;
  110. m_uncertainStructure = FALSE;
  111. currBackgroundParseItem = nullptr;
  112. backgroundParseItems = nullptr;
  113. fastScannedRegExpNodes = nullptr;
  114. m_fUseStrictMode = strictMode;
  115. m_InAsmMode = false;
  116. m_deferAsmJs = true;
  117. m_scopeCountNoAst = 0;
  118. m_fExpectExternalSource = 0;
  119. m_parseType = ParseType_Upfront;
  120. m_deferEllipsisError = false;
  121. m_parsingSuperRestrictionState = ParsingSuperRestrictionState_SuperDisallowed;
  122. }
  123. Parser::~Parser(void)
  124. {
  125. if (m_scriptContext == nullptr || m_scriptContext->GetGuestArena() == nullptr)
  126. {
  127. // If the scriptContext or guestArena have gone away, there is no point clearing each item of this list.
  128. // Just reset it so that destructor of the SList will be no-op
  129. m_registeredRegexPatterns.Reset();
  130. }
  131. if (this->m_hasParallelJob)
  132. {
  133. #if ENABLE_BACKGROUND_PARSING
  134. // Let the background threads know that they can decommit their arena pages.
  135. BackgroundParser *bgp = m_scriptContext->GetBackgroundParser();
  136. Assert(bgp);
  137. if (bgp->Processor()->ProcessesInBackground())
  138. {
  139. JsUtil::BackgroundJobProcessor *processor = static_cast<JsUtil::BackgroundJobProcessor*>(bgp->Processor());
  140. bool result = processor->IterateBackgroundThreads([&](JsUtil::ParallelThreadData *threadData)->bool {
  141. threadData->canDecommit = true;
  142. return false;
  143. });
  144. Assert(result);
  145. }
  146. #endif
  147. }
  148. Release();
  149. }
  150. void Parser::OutOfMemory()
  151. {
  152. throw ParseExceptionObject(ERRnoMemory);
  153. }
  154. void Parser::Error(HRESULT hr)
  155. {
  156. Assert(FAILED(hr));
  157. m_err.Throw(hr);
  158. }
  159. void Parser::Error(HRESULT hr, ParseNodePtr pnode)
  160. {
  161. if (pnode && pnode->ichLim)
  162. {
  163. Error(hr, pnode->ichMin, pnode->ichLim);
  164. }
  165. else
  166. {
  167. Error(hr);
  168. }
  169. }
  170. void Parser::Error(HRESULT hr, charcount_t ichMin, charcount_t ichLim)
  171. {
  172. m_pscan->SetErrorPosition(ichMin, ichLim);
  173. Error(hr);
  174. }
  175. void Parser::IdentifierExpectedError(const Token& token)
  176. {
  177. Assert(token.tk != tkID);
  178. HRESULT hr;
  179. if (token.IsReservedWord())
  180. {
  181. if (token.IsKeyword())
  182. {
  183. hr = ERRKeywordNotId;
  184. }
  185. else
  186. {
  187. Assert(token.IsFutureReservedWord(true));
  188. if (token.IsFutureReservedWord(false))
  189. {
  190. // Future reserved word in strict and non-strict modes
  191. hr = ERRFutureReservedWordNotId;
  192. }
  193. else
  194. {
  195. // Future reserved word only in strict mode. The token would have been converted to tkID by the scanner if not
  196. // in strict mode.
  197. Assert(IsStrictMode());
  198. hr = ERRFutureReservedWordInStrictModeNotId;
  199. }
  200. }
  201. }
  202. else
  203. {
  204. hr = ERRnoIdent;
  205. }
  206. Error(hr);
  207. }
  208. CatchPidRefList *Parser::EnsureCatchPidRefList()
  209. {
  210. if (this->m_catchPidRefList == nullptr)
  211. {
  212. this->m_catchPidRefList = Anew(&m_nodeAllocator, CatchPidRefList);
  213. }
  214. return this->m_catchPidRefList;
  215. }
  216. HRESULT Parser::ValidateSyntax(LPCUTF8 pszSrc, size_t encodedCharCount, bool isGenerator, bool isAsync, CompileScriptException *pse, void (Parser::*validateFunction)())
  217. {
  218. AssertPsz(pszSrc);
  219. AssertMemN(pse);
  220. if (this->IsBackgroundParser())
  221. {
  222. PROBE_STACK_NO_DISPOSE(m_scriptContext, Js::Constants::MinStackDefault);
  223. }
  224. else
  225. {
  226. PROBE_STACK(m_scriptContext, Js::Constants::MinStackDefault);
  227. }
  228. HRESULT hr;
  229. SmartFPUControl smartFpuControl;
  230. DebugOnly( m_err.fInited = TRUE; )
  231. BOOL fDeferSave = m_deferringAST;
  232. try
  233. {
  234. hr = NOERROR;
  235. this->PrepareScanner(false);
  236. m_length = encodedCharCount;
  237. m_originalLength = encodedCharCount;
  238. // make sure deferred parsing is turned off
  239. ULONG grfscr = fscrNil;
  240. // Give the scanner the source and get the first token
  241. m_pscan->SetText(pszSrc, 0, encodedCharCount, 0, grfscr);
  242. m_pscan->SetYieldIsKeyword(isGenerator);
  243. m_pscan->SetAwaitIsKeyword(isAsync);
  244. m_pscan->Scan();
  245. uint nestedCount = 0;
  246. m_pnestedCount = &nestedCount;
  247. ParseNodePtr pnodeScope = nullptr;
  248. m_ppnodeScope = &pnodeScope;
  249. m_ppnodeExprScope = nullptr;
  250. uint nextFunctionId = 0;
  251. m_nextFunctionId = &nextFunctionId;
  252. m_inDeferredNestedFunc = false;
  253. m_deferringAST = true;
  254. m_nextBlockId = 0;
  255. if (this->BindDeferredPidRefs())
  256. {
  257. ParseNode *pnodeFnc = CreateNode(knopFncDecl);
  258. pnodeFnc->sxFnc.ClearFlags();
  259. pnodeFnc->sxFnc.SetDeclaration(false);
  260. pnodeFnc->sxFnc.astSize = 0;
  261. pnodeFnc->sxFnc.pnodeVars = nullptr;
  262. pnodeFnc->sxFnc.pnodeArgs = nullptr;
  263. pnodeFnc->sxFnc.pnodeBody = nullptr;
  264. pnodeFnc->sxFnc.pnodeName = nullptr;
  265. pnodeFnc->sxFnc.pnodeRest = nullptr;
  266. pnodeFnc->sxFnc.deferredStub = nullptr;
  267. pnodeFnc->sxFnc.SetIsGenerator(isGenerator);
  268. pnodeFnc->sxFnc.SetIsAsync(isAsync);
  269. m_ppnodeVar = &pnodeFnc->sxFnc.pnodeVars;
  270. m_currentNodeFunc = pnodeFnc;
  271. m_currentNodeDeferredFunc = NULL;
  272. AssertMsg(m_pstmtCur == NULL, "Statement stack should be empty when we start parse function body");
  273. ParseNodePtr block = StartParseBlock<false>(PnodeBlockType::Function, ScopeType_FunctionBody);
  274. (this->*validateFunction)();
  275. FinishParseBlock(block);
  276. pnodeFnc->ichLim = m_pscan->IchLimTok();
  277. pnodeFnc->sxFnc.cbLim = m_pscan->IecpLimTok();
  278. pnodeFnc->sxFnc.pnodeVars = nullptr;
  279. if (m_asgToConst)
  280. {
  281. Error(ERRAssignmentToConst, m_asgToConst.GetIchMin(), m_asgToConst.GetIchLim());
  282. }
  283. }
  284. else
  285. {
  286. (this->*validateFunction)();
  287. }
  288. // there should be nothing after successful parsing for a given construct
  289. if (m_token.tk != tkEOF)
  290. Error(ERRsyntax);
  291. RELEASEPTR(m_pscan);
  292. m_deferringAST = fDeferSave;
  293. }
  294. catch(ParseExceptionObject& e)
  295. {
  296. m_deferringAST = fDeferSave;
  297. m_err.m_hr = e.GetError();
  298. hr = pse->ProcessError( m_pscan, m_err.m_hr, /* pnodeBase */ NULL);
  299. }
  300. return hr;
  301. }
  302. HRESULT Parser::ParseSourceInternal(
  303. __out ParseNodePtr* parseTree, LPCUTF8 pszSrc, size_t offsetInBytes, size_t encodedCharCount, charcount_t offsetInChars,
  304. bool fromExternal, ULONG grfscr, CompileScriptException *pse, Js::LocalFunctionId * nextFunctionId, ULONG lineNumber, SourceContextInfo * sourceContextInfo)
  305. {
  306. AssertMem(parseTree);
  307. AssertPsz(pszSrc);
  308. AssertMemN(pse);
  309. double startTime = m_scriptContext->GetThreadContext()->ParserTelemetry.Now();
  310. if (this->IsBackgroundParser())
  311. {
  312. PROBE_STACK_NO_DISPOSE(m_scriptContext, Js::Constants::MinStackDefault);
  313. }
  314. else
  315. {
  316. PROBE_STACK(m_scriptContext, Js::Constants::MinStackDefault);
  317. }
  318. #ifdef PROFILE_EXEC
  319. m_scriptContext->ProfileBegin(Js::ParsePhase);
  320. #endif
  321. JS_ETW(EventWriteJSCRIPT_PARSE_START(m_scriptContext,0));
  322. *parseTree = NULL;
  323. m_sourceLim = 0;
  324. m_grfscr = grfscr;
  325. m_sourceContextInfo = sourceContextInfo;
  326. ParseNodePtr pnodeBase = NULL;
  327. HRESULT hr;
  328. SmartFPUControl smartFpuControl;
  329. DebugOnly( m_err.fInited = TRUE; )
  330. try
  331. {
  332. this->PrepareScanner(fromExternal);
  333. if ((grfscr & fscrEvalCode) != 0)
  334. {
  335. // This makes the parser to believe when eval() is called, it accept any super access in global scope.
  336. this->m_parsingSuperRestrictionState = Parser::ParsingSuperRestrictionState_SuperCallAndPropertyAllowed;
  337. }
  338. // parse the source
  339. pnodeBase = Parse(pszSrc, offsetInBytes, encodedCharCount, offsetInChars, grfscr, lineNumber, nextFunctionId, pse);
  340. AssertNodeMem(pnodeBase);
  341. // Record the actual number of words parsed.
  342. m_sourceLim = pnodeBase->ichLim - offsetInChars;
  343. // TODO: The assert can be false positive in some scenarios and chuckj to fix it later
  344. // Assert(utf8::ByteIndexIntoCharacterIndex(pszSrc + offsetInBytes, encodedCharCount, fromExternal ? utf8::doDefault : utf8::doAllowThreeByteSurrogates) == m_sourceLim);
  345. #if DBG_DUMP
  346. if (Js::Configuration::Global.flags.Trace.IsEnabled(Js::ParsePhase))
  347. {
  348. PrintPnodeWIndent(pnodeBase,4);
  349. fflush(stdout);
  350. }
  351. #endif
  352. *parseTree = pnodeBase;
  353. hr = NOERROR;
  354. }
  355. catch(ParseExceptionObject& e)
  356. {
  357. m_err.m_hr = e.GetError();
  358. hr = pse->ProcessError( m_pscan, m_err.m_hr, pnodeBase);
  359. }
  360. if (this->m_hasParallelJob)
  361. {
  362. #if ENABLE_BACKGROUND_PARSING
  363. ///// Wait here for remaining jobs to finish. Then look for errors, do final const bindings.
  364. // pleath TODO: If there are remaining jobs, let the main thread help finish them.
  365. BackgroundParser *bgp = m_scriptContext->GetBackgroundParser();
  366. Assert(bgp);
  367. CompileScriptException se;
  368. this->WaitForBackgroundJobs(bgp, &se);
  369. BackgroundParseItem *failedItem = bgp->GetFailedBackgroundParseItem();
  370. if (failedItem)
  371. {
  372. CompileScriptException *bgPse = failedItem->GetPSE();
  373. Assert(bgPse);
  374. *pse = *bgPse;
  375. hr = failedItem->GetHR();
  376. bgp->SetFailedBackgroundParseItem(nullptr);
  377. }
  378. if (this->fastScannedRegExpNodes != nullptr)
  379. {
  380. this->FinishBackgroundRegExpNodes();
  381. }
  382. for (BackgroundParseItem *item = this->backgroundParseItems; item; item = item->GetNext())
  383. {
  384. Parser *parser = item->GetParser();
  385. parser->FinishBackgroundPidRefs(item, this != parser);
  386. }
  387. #endif
  388. }
  389. // done with the scanner
  390. RELEASEPTR(m_pscan);
  391. #ifdef PROFILE_EXEC
  392. m_scriptContext->ProfileEnd(Js::ParsePhase);
  393. #endif
  394. JS_ETW(EventWriteJSCRIPT_PARSE_STOP(m_scriptContext, 0));
  395. ThreadContext *threadContext = m_scriptContext->GetThreadContext();
  396. threadContext->ParserTelemetry.LogTime(threadContext->ParserTelemetry.Now() - startTime);
  397. return hr;
  398. }
  399. #if ENABLE_BACKGROUND_PARSING
  400. void Parser::WaitForBackgroundJobs(BackgroundParser *bgp, CompileScriptException *pse)
  401. {
  402. // The scan of the script is done, but there may be unfinished background jobs in the queue.
  403. // Enlist the main thread to help with those.
  404. BackgroundParseItem *item;
  405. if (!*bgp->GetPendingBackgroundItemsPtr())
  406. {
  407. // We're done.
  408. return;
  409. }
  410. // Save parser state, since we'll need to restore it in order to bind references correctly later.
  411. this->m_isInBackground = true;
  412. this->SetCurrBackgroundParseItem(nullptr);
  413. uint blockIdSave = this->m_nextBlockId;
  414. uint functionIdSave = *this->m_nextFunctionId;
  415. StmtNest *pstmtSave = this->m_pstmtCur;
  416. if (!bgp->Processor()->ProcessesInBackground())
  417. {
  418. // No background thread. Just walk the jobs with no locking and process them.
  419. for (item = bgp->GetNextUnprocessedItem(); item; item = bgp->GetNextUnprocessedItem())
  420. {
  421. bgp->Processor()->RemoveJob(item);
  422. bool succeeded = bgp->Process(item, this, pse);
  423. bgp->JobProcessed(item, succeeded);
  424. }
  425. Assert(!*bgp->GetPendingBackgroundItemsPtr());
  426. }
  427. else
  428. {
  429. // Background threads. We need to have the critical section in order to:
  430. // - Check for unprocessed jobs;
  431. // - Remove jobs from the processor queue;
  432. // - Do JobsProcessed work (such as removing jobs from the BackgroundParser's unprocessed list).
  433. CriticalSection *pcs = static_cast<JsUtil::BackgroundJobProcessor*>(bgp->Processor())->GetCriticalSection();
  434. pcs->Enter();
  435. for (;;)
  436. {
  437. // Grab a job (in lock)
  438. item = bgp->GetNextUnprocessedItem();
  439. if (item == nullptr)
  440. {
  441. break;
  442. }
  443. bgp->Processor()->RemoveJob(item);
  444. pcs->Leave();
  445. // Process job (if there is one) (outside lock)
  446. bool succeeded = bgp->Process(item, this, pse);
  447. pcs->Enter();
  448. bgp->JobProcessed(item, succeeded);
  449. }
  450. pcs->Leave();
  451. // Wait for the background threads to finish jobs they're already processing (if any).
  452. // TODO: Replace with a proper semaphore.
  453. while(*bgp->GetPendingBackgroundItemsPtr());
  454. }
  455. Assert(!*bgp->GetPendingBackgroundItemsPtr());
  456. // Restore parser state.
  457. this->m_pstmtCur = pstmtSave;
  458. this->m_isInBackground = false;
  459. this->m_nextBlockId = blockIdSave;
  460. *this->m_nextFunctionId = functionIdSave;
  461. }
  462. void Parser::FinishBackgroundPidRefs(BackgroundParseItem *item, bool isOtherParser)
  463. {
  464. for (BlockInfoStack *blockInfo = item->GetParseContext()->currentBlockInfo; blockInfo; blockInfo = blockInfo->pBlockInfoOuter)
  465. {
  466. if (isOtherParser)
  467. {
  468. this->BindPidRefs<true>(blockInfo, item->GetMaxBlockId());
  469. }
  470. else
  471. {
  472. this->BindPidRefs<false>(blockInfo, item->GetMaxBlockId());
  473. }
  474. }
  475. }
  476. void Parser::FinishBackgroundRegExpNodes()
  477. {
  478. // We have a list of RegExp nodes that we saw on the UI thread in functions we're parallel parsing,
  479. // and for each background job we have a list of RegExp nodes for which we couldn't allocate patterns.
  480. // We need to copy the pattern pointers from the UI thread nodes to the corresponding nodes on the
  481. // background nodes.
  482. // There may be UI thread nodes for which there are no background thread equivalents, because the UI thread
  483. // has to assume that the background thread won't defer anything.
  484. // Note that because these lists (and the list of background jobs) are SList's built by prepending, they are
  485. // all in reverse lexical order.
  486. Assert(!this->IsBackgroundParser());
  487. Assert(this->fastScannedRegExpNodes);
  488. Assert(this->backgroundParseItems != nullptr);
  489. BackgroundParseItem *currBackgroundItem;
  490. #if DBG
  491. for (currBackgroundItem = this->backgroundParseItems;
  492. currBackgroundItem;
  493. currBackgroundItem = currBackgroundItem->GetNext())
  494. {
  495. if (currBackgroundItem->RegExpNodeList())
  496. {
  497. FOREACH_DLIST_ENTRY(ParseNodePtr, ArenaAllocator, pnode, currBackgroundItem->RegExpNodeList())
  498. {
  499. Assert(pnode->sxPid.regexPattern == nullptr);
  500. }
  501. NEXT_DLIST_ENTRY;
  502. }
  503. }
  504. #endif
  505. // Hook up the patterns allocated on the main thread to the nodes created on the background thread.
  506. // Walk the list of foreground nodes, advancing through the work items and looking up each item.
  507. // Note that the background thread may have chosen to defer a given RegEx literal, so not every foreground
  508. // node will have a matching background node. Doesn't matter for correctness.
  509. // (It's inefficient, of course, to have to restart the inner loop from the beginning of the work item's
  510. // list, but it should be unusual to have many RegExes in a single work item's chunk of code. Figure out how
  511. // to start the inner loop from a known internal node within the list if that turns out to be important.)
  512. currBackgroundItem = this->backgroundParseItems;
  513. FOREACH_DLIST_ENTRY(ParseNodePtr, ArenaAllocator, pnodeFgnd, this->fastScannedRegExpNodes)
  514. {
  515. Assert(pnodeFgnd->nop == knopRegExp);
  516. Assert(pnodeFgnd->sxPid.regexPattern != nullptr);
  517. bool quit = false;
  518. while (!quit)
  519. {
  520. // Find the next work item with a RegEx in it.
  521. while (currBackgroundItem && currBackgroundItem->RegExpNodeList() == nullptr)
  522. {
  523. currBackgroundItem = currBackgroundItem->GetNext();
  524. }
  525. if (!currBackgroundItem)
  526. {
  527. break;
  528. }
  529. // Walk the RegExps in the work item.
  530. FOREACH_DLIST_ENTRY(ParseNodePtr, ArenaAllocator, pnodeBgnd, currBackgroundItem->RegExpNodeList())
  531. {
  532. Assert(pnodeBgnd->nop == knopRegExp);
  533. if (pnodeFgnd->ichMin <= pnodeBgnd->ichMin)
  534. {
  535. // Either we found a match, or the next background node is past the foreground node.
  536. // In any case, we can stop searching.
  537. if (pnodeFgnd->ichMin == pnodeBgnd->ichMin)
  538. {
  539. Assert(pnodeFgnd->ichLim == pnodeBgnd->ichLim);
  540. pnodeBgnd->sxPid.regexPattern = pnodeFgnd->sxPid.regexPattern;
  541. }
  542. quit = true;
  543. break;
  544. }
  545. }
  546. NEXT_DLIST_ENTRY;
  547. if (!quit)
  548. {
  549. // Need to advance to the next work item.
  550. currBackgroundItem = currBackgroundItem->GetNext();
  551. }
  552. }
  553. }
  554. NEXT_DLIST_ENTRY;
  555. #if DBG
  556. for (currBackgroundItem = this->backgroundParseItems;
  557. currBackgroundItem;
  558. currBackgroundItem = currBackgroundItem->GetNext())
  559. {
  560. if (currBackgroundItem->RegExpNodeList())
  561. {
  562. FOREACH_DLIST_ENTRY(ParseNodePtr, ArenaAllocator, pnode, currBackgroundItem->RegExpNodeList())
  563. {
  564. Assert(pnode->sxPid.regexPattern != nullptr);
  565. }
  566. NEXT_DLIST_ENTRY;
  567. }
  568. }
  569. #endif
  570. }
  571. #endif
  572. LabelId* Parser::CreateLabelId(IdentToken* pToken)
  573. {
  574. LabelId* pLabelId;
  575. pLabelId = (LabelId*)m_nodeAllocator.Alloc(sizeof(LabelId));
  576. if (NULL == pLabelId)
  577. Error(ERRnoMemory);
  578. pLabelId->pid = pToken->pid;
  579. pLabelId->next = NULL;
  580. return pLabelId;
  581. }
  582. /*****************************************************************************
  583. The following set of routines allocate parse tree nodes of various kinds.
  584. They catch an exception on out of memory.
  585. *****************************************************************************/
  586. static const int g_mpnopcbNode[] =
  587. {
  588. #define PTNODE(nop,sn,pc,nk,ok,json) kcbPn##nk,
  589. #include "ptlist.h"
  590. };
  591. const Js::RegSlot NoRegister = (Js::RegSlot)-1;
  592. const Js::RegSlot OneByteRegister = (Js::RegSlot_OneByte)-1;
  593. void Parser::InitNode(OpCode nop,ParseNodePtr pnode) {
  594. pnode->nop = nop;
  595. pnode->grfpn = PNodeFlags::fpnNone;
  596. pnode->location = NoRegister;
  597. pnode->emitLabels = false;
  598. pnode->isUsed = true;
  599. pnode->notEscapedUse = false;
  600. pnode->isInList = false;
  601. pnode->isCallApplyTargetLoad = false;
  602. }
  603. // Create nodes using Arena
  604. template <OpCode nop>
  605. ParseNodePtr Parser::StaticCreateNodeT(ArenaAllocator* alloc, charcount_t ichMin, charcount_t ichLim)
  606. {
  607. ParseNodePtr pnode = StaticAllocNode<nop>(alloc);
  608. InitNode(nop,pnode);
  609. // default - may be changed
  610. pnode->ichMin = ichMin;
  611. pnode->ichLim = ichLim;
  612. return pnode;
  613. }
  614. ParseNodePtr
  615. Parser::StaticCreateBlockNode(ArenaAllocator* alloc, charcount_t ichMin , charcount_t ichLim, int blockId, PnodeBlockType blockType)
  616. {
  617. ParseNodePtr pnode = StaticCreateNodeT<knopBlock>(alloc, ichMin, ichLim);
  618. InitBlockNode(pnode, blockId, blockType);
  619. return pnode;
  620. }
  621. void Parser::InitBlockNode(ParseNodePtr pnode, int blockId, PnodeBlockType blockType)
  622. {
  623. Assert(pnode->nop == knopBlock);
  624. pnode->sxBlock.pnodeScopes = nullptr;
  625. pnode->sxBlock.pnodeNext = nullptr;
  626. pnode->sxBlock.scope = nullptr;
  627. pnode->sxBlock.enclosingBlock = nullptr;
  628. pnode->sxBlock.pnodeLexVars = nullptr;
  629. pnode->sxBlock.pnodeStmt = nullptr;
  630. pnode->sxBlock.pnodeLastValStmt = nullptr;
  631. pnode->sxBlock.callsEval = false;
  632. pnode->sxBlock.childCallsEval = false;
  633. pnode->sxBlock.blockType = blockType;
  634. pnode->sxBlock.blockId = blockId;
  635. if (blockType != PnodeBlockType::Regular)
  636. {
  637. pnode->grfpn |= PNodeFlags::fpnSyntheticNode;
  638. }
  639. }
  640. // Create Node with limit
  641. template <OpCode nop>
  642. ParseNodePtr Parser::CreateNodeT(charcount_t ichMin,charcount_t ichLim)
  643. {
  644. Assert(!this->m_deferringAST);
  645. ParseNodePtr pnode = StaticCreateNodeT<nop>(&m_nodeAllocator, ichMin, ichLim);
  646. Assert(m_pCurrentAstSize != NULL);
  647. *m_pCurrentAstSize += GetNodeSize<nop>();
  648. return pnode;
  649. }
  650. ParseNodePtr Parser::CreateDeclNode(OpCode nop, IdentPtr pid, SymbolType symbolType, bool errorOnRedecl)
  651. {
  652. ParseNodePtr pnode = CreateNode(nop);
  653. pnode->sxVar.InitDeclNode(pid, NULL);
  654. if (symbolType != STUnknown)
  655. {
  656. pnode->sxVar.sym = AddDeclForPid(pnode, pid, symbolType, errorOnRedecl);
  657. }
  658. return pnode;
  659. }
  660. Symbol* Parser::AddDeclForPid(ParseNodePtr pnode, IdentPtr pid, SymbolType symbolType, bool errorOnRedecl)
  661. {
  662. Assert(pnode->IsVarLetOrConst());
  663. PidRefStack *refForUse = nullptr, *refForDecl = nullptr;
  664. BlockInfoStack *blockInfo;
  665. bool fBlockScope = false;
  666. if (m_scriptContext->GetConfig()->IsBlockScopeEnabled() &&
  667. (pnode->nop != knopVarDecl || symbolType == STFunction))
  668. {
  669. Assert(m_pstmtCur);
  670. if (m_pstmtCur->isDeferred)
  671. {
  672. // Deferred parsing: there's no pnodeStmt node, only an opcode on the Stmt struct.
  673. if (m_pstmtCur->op != knopBlock)
  674. {
  675. // Let/const declared in a bare statement context.
  676. Error(ERRDeclOutOfStmt);
  677. }
  678. if (m_pstmtCur->pstmtOuter && m_pstmtCur->pstmtOuter->op == knopSwitch)
  679. {
  680. // Let/const declared inside a switch block (requiring conservative use-before-decl check).
  681. pnode->sxVar.isSwitchStmtDecl = true;
  682. }
  683. }
  684. else
  685. {
  686. if (m_pstmtCur->pnodeStmt->nop != knopBlock)
  687. {
  688. // Let/const declared in a bare statement context.
  689. Error(ERRDeclOutOfStmt);
  690. }
  691. if (m_pstmtCur->pstmtOuter && m_pstmtCur->pstmtOuter->pnodeStmt->nop == knopSwitch)
  692. {
  693. // Let/const declared inside a switch block (requiring conservative use-before-decl check).
  694. pnode->sxVar.isSwitchStmtDecl = true;
  695. }
  696. }
  697. fBlockScope = pnode->nop != knopVarDecl ||
  698. (
  699. !GetCurrentBlockInfo()->pnodeBlock->sxBlock.scope ||
  700. GetCurrentBlockInfo()->pnodeBlock->sxBlock.scope->GetScopeType() != ScopeType_GlobalEvalBlock
  701. );
  702. }
  703. if (fBlockScope)
  704. {
  705. blockInfo = GetCurrentBlockInfo();
  706. }
  707. else
  708. {
  709. blockInfo = GetCurrentFunctionBlockInfo();
  710. }
  711. // If we are creating an 'arguments' Sym at function block scope, create it in
  712. // the parameter scope instead. That way, if we need to reuse the Sym for the
  713. // actual arguments object at the end of the function, we don't need to move it
  714. // into the parameter scope.
  715. if (pid == wellKnownPropertyPids.arguments
  716. && pnode->nop == knopVarDecl
  717. && blockInfo->pnodeBlock->sxBlock.blockType == PnodeBlockType::Function
  718. && blockInfo->pBlockInfoOuter != nullptr
  719. && blockInfo->pBlockInfoOuter->pnodeBlock->sxBlock.blockType == PnodeBlockType::Parameter)
  720. {
  721. blockInfo = blockInfo->pBlockInfoOuter;
  722. }
  723. int maxScopeId = blockInfo->pnodeBlock->sxBlock.blockId;
  724. // The body of catch may have let declared variable. In the case of pattern, found at catch parameter level,
  725. // we need to search the duplication at that scope level as well - thus extending the scope lookup range.
  726. if (IsES6DestructuringEnabled()
  727. && fBlockScope
  728. && blockInfo->pBlockInfoOuter != nullptr
  729. && blockInfo->pBlockInfoOuter->pnodeBlock->sxBlock.scope != nullptr
  730. && blockInfo->pBlockInfoOuter->pnodeBlock->sxBlock.scope->GetScopeType() == ScopeType_CatchParamPattern)
  731. {
  732. maxScopeId = blockInfo->pBlockInfoOuter->pnodeBlock->sxBlock.blockId;
  733. }
  734. if (blockInfo->pnodeBlock->sxBlock.scope != nullptr && blockInfo->pnodeBlock->sxBlock.scope->GetScopeType() == ScopeType_FunctionBody)
  735. {
  736. // Check if there is a parameter scope and try to get it first.
  737. BlockInfoStack *outerBlockInfo = blockInfo->pBlockInfoOuter;
  738. if (outerBlockInfo != nullptr && outerBlockInfo->pnodeBlock->sxBlock.blockType == PnodeBlockType::Parameter)
  739. {
  740. maxScopeId = outerBlockInfo->pnodeBlock->sxBlock.blockId;
  741. }
  742. }
  743. refForDecl = this->FindOrAddPidRef(pid, blockInfo->pnodeBlock->sxBlock.blockId, maxScopeId);
  744. if (refForDecl == nullptr)
  745. {
  746. Error(ERRnoMemory);
  747. }
  748. if (blockInfo == GetCurrentBlockInfo())
  749. {
  750. refForUse = refForDecl;
  751. }
  752. else
  753. {
  754. refForUse = this->PushPidRef(pid);
  755. }
  756. pnode->sxVar.symRef = refForUse->GetSymRef();
  757. Symbol *sym = refForDecl->GetSym();
  758. if (sym != nullptr)
  759. {
  760. // Multiple declarations in the same scope. 3 possibilities: error, existing one wins, new one wins.
  761. switch (pnode->nop)
  762. {
  763. case knopLetDecl:
  764. case knopConstDecl:
  765. if (!sym->GetDecl()->sxVar.isBlockScopeFncDeclVar)
  766. {
  767. Assert(errorOnRedecl);
  768. // Redeclaration error.
  769. Error(ERRRedeclaration);
  770. }
  771. else
  772. {
  773. // (New) let/const hides the (old) var
  774. sym->SetSymbolType(symbolType);
  775. sym->SetDecl(pnode);
  776. }
  777. break;
  778. case knopVarDecl:
  779. if (m_currentScope->GetScopeType() == ScopeType_Parameter)
  780. {
  781. // If this is a parameter list, mark the scope to indicate that it has duplicate definition.
  782. // 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.
  783. m_currentScope->SetHasDuplicateFormals();
  784. }
  785. if (sym->GetDecl() == nullptr)
  786. {
  787. Assert(symbolType == STFunction);
  788. sym->SetDecl(pnode);
  789. break;
  790. }
  791. switch (sym->GetDecl()->nop)
  792. {
  793. case knopLetDecl:
  794. case knopConstDecl:
  795. // Destructuring made possible to have the formals to be the let bind. But that shouldn't throw the error.
  796. if (errorOnRedecl && (!IsES6DestructuringEnabled() || sym->GetSymbolType() != STFormal))
  797. {
  798. Error(ERRRedeclaration);
  799. }
  800. // If !errorOnRedecl, (old) let/const hides the (new) var, so do nothing.
  801. break;
  802. case knopVarDecl:
  803. // Legal redeclaration. Who wins?
  804. if (errorOnRedecl || sym->GetDecl()->sxVar.isBlockScopeFncDeclVar)
  805. {
  806. if (symbolType == STFormal ||
  807. (symbolType == STFunction && sym->GetSymbolType() != STFormal) ||
  808. sym->GetSymbolType() == STVariable)
  809. {
  810. // New decl wins.
  811. sym->SetSymbolType(symbolType);
  812. sym->SetDecl(pnode);
  813. }
  814. }
  815. break;
  816. }
  817. break;
  818. }
  819. }
  820. else
  821. {
  822. Scope *scope = blockInfo->pnodeBlock->sxBlock.scope;
  823. if (scope == nullptr)
  824. {
  825. Assert(blockInfo->pnodeBlock->sxBlock.blockType == PnodeBlockType::Regular &&
  826. m_scriptContext->GetConfig()->IsBlockScopeEnabled());
  827. scope = Anew(&m_nodeAllocator, Scope, &m_nodeAllocator, ScopeType_Block);
  828. blockInfo->pnodeBlock->sxBlock.scope = scope;
  829. PushScope(scope);
  830. }
  831. if (scope->GetScopeType() == ScopeType_GlobalEvalBlock)
  832. {
  833. Assert(fBlockScope);
  834. Assert(scope->GetEnclosingScope() == m_currentNodeProg->sxProg.scope);
  835. // Check for same-named decl in Global scope.
  836. PidRefStack *pidRefOld = pid->GetPidRefForScopeId(0);
  837. if (pidRefOld && pidRefOld->GetSym())
  838. {
  839. Error(ERRRedeclaration);
  840. }
  841. }
  842. else if (scope->GetScopeType() == ScopeType_Global && (this->m_grfscr & fscrEvalCode) &&
  843. !(m_functionBody && m_functionBody->GetScopeInfo()))
  844. {
  845. // Check for same-named decl in GlobalEvalBlock scope. Note that this is not necessary
  846. // if we're compiling a deferred nested function and the global scope was restored from cached info,
  847. // because in that case we don't need a GlobalEvalScope.
  848. Assert(!fBlockScope || (this->m_grfscr & fscrConsoleScopeEval) == fscrConsoleScopeEval);
  849. PidRefStack *pidRefOld = pid->GetPidRefForScopeId(1);
  850. if (pidRefOld && pidRefOld->GetSym())
  851. {
  852. Error(ERRRedeclaration);
  853. }
  854. }
  855. if ((scope->GetScopeType() == ScopeType_FunctionBody || scope->GetScopeType() == ScopeType_Parameter) && symbolType != STFunction)
  856. {
  857. ParseNodePtr pnodeFnc = GetCurrentFunctionNode();
  858. AnalysisAssert(pnodeFnc);
  859. if (pnodeFnc->sxFnc.pnodeName &&
  860. pnodeFnc->sxFnc.pnodeName->nop == knopVarDecl &&
  861. pnodeFnc->sxFnc.pnodeName->sxVar.pid == pid)
  862. {
  863. // Named function expression has its name hidden by a local declaration.
  864. // This is important to know if we don't know whether nested deferred functions refer to it,
  865. // because if the name has a non-local reference then we have to create a scope object.
  866. m_currentNodeFunc->sxFnc.SetNameIsHidden();
  867. }
  868. }
  869. if (!sym)
  870. {
  871. const wchar_t *name = reinterpret_cast<const wchar_t*>(pid->Psz());
  872. int nameLength = pid->Cch();
  873. SymbolName const symName(name, nameLength);
  874. Assert(!scope->FindLocalSymbol(symName));
  875. sym = Anew(&m_nodeAllocator, Symbol, symName, pnode, symbolType);
  876. scope->AddNewSymbol(sym);
  877. sym->SetPid(pid);
  878. }
  879. refForDecl->SetSym(sym);
  880. }
  881. return sym;
  882. }
  883. void Parser::RestorePidRefForSym(Symbol *sym)
  884. {
  885. IdentPtr pid = m_pscan->m_phtbl->PidHashNameLen(sym->GetName().GetBuffer(), sym->GetName().GetLength());
  886. Assert(pid);
  887. sym->SetPid(pid);
  888. PidRefStack *ref = this->PushPidRef(pid);
  889. ref->SetSym(sym);
  890. }
  891. IdentPtr Parser::GenerateIdentPtr(__ecount(len) wchar_t* name, long len)
  892. {
  893. return m_phtbl->PidHashNameLen(name,len);
  894. }
  895. IdentPtr Parser::PidFromNode(ParseNodePtr pnode)
  896. {
  897. for (;;)
  898. {
  899. switch (pnode->nop)
  900. {
  901. case knopName:
  902. return pnode->sxPid.pid;
  903. case knopVarDecl:
  904. return pnode->sxVar.pid;
  905. case knopDot:
  906. Assert(pnode->sxBin.pnode2->nop == knopName);
  907. return pnode->sxBin.pnode2->sxPid.pid;
  908. case knopComma:
  909. // Advance to the RHS and iterate.
  910. pnode = pnode->sxBin.pnode2;
  911. break;
  912. default:
  913. return nullptr;
  914. }
  915. }
  916. }
  917. #if DBG
  918. void VerifyNodeSize(OpCode nop, int size)
  919. {
  920. Assert(nop >= 0 && nop < knopLim);
  921. __analysis_assume(nop < knopLim);
  922. Assert(g_mpnopcbNode[nop] == size);
  923. }
  924. #endif
  925. ParseNodePtr Parser::StaticCreateBinNode(OpCode nop, ParseNodePtr pnode1,
  926. ParseNodePtr pnode2,ArenaAllocator* alloc)
  927. {
  928. DebugOnly(VerifyNodeSize(nop, kcbPnBin));
  929. ParseNodePtr pnode = (ParseNodePtr)alloc->Alloc(kcbPnBin);
  930. InitNode(nop, pnode);
  931. pnode->sxBin.pnodeNext = nullptr;
  932. pnode->sxBin.pnode1 = pnode1;
  933. pnode->sxBin.pnode2 = pnode2;
  934. // Statically detect if the add is a concat
  935. if (!PHASE_OFF1(Js::ByteCodeConcatExprOptPhase))
  936. {
  937. // We can't flatten the concat expression if the LHS is not a flatten concat already
  938. // e.g. a + (<str> + b)
  939. // Side effect of ToStr(b) need to happen first before ToStr(a)
  940. // If we flatten the concat expression, we will do ToStr(a) before ToStr(b)
  941. if ((nop == knopAdd) && (pnode1->CanFlattenConcatExpr() || pnode2->nop == knopStr))
  942. {
  943. pnode->grfpn |= fpnCanFlattenConcatExpr;
  944. }
  945. }
  946. return pnode;
  947. }
  948. // Create nodes using parser allocator
  949. ParseNodePtr Parser::CreateNode(OpCode nop, charcount_t ichMin)
  950. {
  951. bool nodeAllowed = IsNodeAllowedForDeferParse(nop);
  952. Assert(nodeAllowed);
  953. Assert(nop >= 0 && nop < knopLim);
  954. ParseNodePtr pnode;
  955. int cb = (nop >= knopNone && nop < knopLim) ? g_mpnopcbNode[nop] : g_mpnopcbNode[knopEmpty];
  956. pnode = (ParseNodePtr)m_nodeAllocator.Alloc(cb);
  957. Assert(pnode != nullptr);
  958. if (!m_deferringAST)
  959. {
  960. Assert(m_pCurrentAstSize != nullptr);
  961. *m_pCurrentAstSize += cb;
  962. }
  963. InitNode(nop,pnode);
  964. // default - may be changed
  965. pnode->ichMin = ichMin;
  966. if (m_pscan!= nullptr) {
  967. pnode->ichLim = m_pscan->IchLimTok();
  968. }
  969. else pnode->ichLim=0;
  970. return pnode;
  971. }
  972. ParseNodePtr Parser::CreateUniNode(OpCode nop, ParseNodePtr pnode1)
  973. {
  974. Assert(!this->m_deferringAST);
  975. DebugOnly(VerifyNodeSize(nop, kcbPnUni));
  976. ParseNodePtr pnode = (ParseNodePtr)m_nodeAllocator.Alloc(kcbPnUni);
  977. Assert(m_pCurrentAstSize != nullptr);
  978. *m_pCurrentAstSize += kcbPnUni;
  979. InitNode(nop, pnode);
  980. pnode->sxUni.pnode1 = pnode1;
  981. if (nullptr == pnode1)
  982. {
  983. // no ops
  984. pnode->ichMin = m_pscan->IchMinTok();
  985. pnode->ichLim = m_pscan->IchLimTok();
  986. }
  987. else
  988. {
  989. // 1 op
  990. pnode->ichMin = pnode1->ichMin;
  991. pnode->ichLim = pnode1->ichLim;
  992. this->CheckArguments(pnode);
  993. }
  994. return pnode;
  995. }
  996. ParseNodePtr Parser::CreateBinNode(OpCode nop, ParseNodePtr pnode1, ParseNodePtr pnode2)
  997. {
  998. Assert(!this->m_deferringAST);
  999. charcount_t ichMin;
  1000. charcount_t ichLim;
  1001. if (nullptr == pnode1)
  1002. {
  1003. // no ops
  1004. Assert(nullptr == pnode2);
  1005. ichMin = m_pscan->IchMinTok();
  1006. ichLim = m_pscan->IchLimTok();
  1007. }
  1008. else
  1009. {
  1010. if (nullptr == pnode2)
  1011. {
  1012. // 1 op
  1013. ichMin = pnode1->ichMin;
  1014. ichLim = pnode1->ichLim;
  1015. }
  1016. else
  1017. {
  1018. // 2 ops
  1019. ichMin = pnode1->ichMin;
  1020. ichLim = pnode2->ichLim;
  1021. if (nop != knopDot && nop != knopIndex)
  1022. {
  1023. this->CheckArguments(pnode2);
  1024. }
  1025. }
  1026. if (nop != knopDot && nop != knopIndex)
  1027. {
  1028. this->CheckArguments(pnode1);
  1029. }
  1030. }
  1031. return CreateBinNode(nop, pnode1, pnode2, ichMin, ichLim);
  1032. }
  1033. ParseNodePtr Parser::CreateTriNode(OpCode nop, ParseNodePtr pnode1,
  1034. ParseNodePtr pnode2, ParseNodePtr pnode3)
  1035. {
  1036. charcount_t ichMin;
  1037. charcount_t ichLim;
  1038. if (nullptr == pnode1)
  1039. {
  1040. // no ops
  1041. Assert(nullptr == pnode2);
  1042. Assert(nullptr == pnode3);
  1043. ichMin = m_pscan->IchMinTok();
  1044. ichLim = m_pscan->IchLimTok();
  1045. }
  1046. else if (nullptr == pnode2)
  1047. {
  1048. // 1 op
  1049. Assert(nullptr == pnode3);
  1050. ichMin = pnode1->ichMin;
  1051. ichLim = pnode1->ichLim;
  1052. }
  1053. else if (nullptr == pnode3)
  1054. {
  1055. // 2 op
  1056. ichMin = pnode1->ichMin;
  1057. ichLim = pnode2->ichLim;
  1058. }
  1059. else
  1060. {
  1061. // 3 ops
  1062. ichMin = pnode1->ichMin;
  1063. ichLim = pnode3->ichLim;
  1064. }
  1065. return CreateTriNode(nop, pnode1, pnode2, pnode3, ichMin, ichLim);
  1066. }
  1067. ParseNodePtr Parser::CreateBlockNode(charcount_t ichMin,charcount_t ichLim, PnodeBlockType blockType)
  1068. {
  1069. return StaticCreateBlockNode(&m_nodeAllocator, ichMin, ichLim, this->m_nextBlockId++, blockType);
  1070. }
  1071. ParseNodePtr
  1072. Parser::CreateCallNode(OpCode nop, ParseNodePtr pnode1, ParseNodePtr pnode2,charcount_t ichMin,charcount_t ichLim)
  1073. {
  1074. Assert(!this->m_deferringAST);
  1075. DebugOnly(VerifyNodeSize(nop, kcbPnCall));
  1076. ParseNodePtr pnode = (ParseNodePtr)m_nodeAllocator.Alloc(kcbPnCall);
  1077. Assert(m_pCurrentAstSize != nullptr);
  1078. *m_pCurrentAstSize += kcbPnCall;
  1079. InitNode(nop, pnode);
  1080. pnode->sxCall.pnodeTarget = pnode1;
  1081. pnode->sxCall.pnodeArgs = pnode2;
  1082. pnode->sxCall.argCount = 0;
  1083. pnode->sxCall.spreadArgCount = 0;
  1084. pnode->sxCall.callOfConstants = false;
  1085. pnode->sxCall.isApplyCall = false;
  1086. pnode->sxCall.isEvalCall = false;
  1087. pnode->ichMin = ichMin;
  1088. pnode->ichLim = ichLim;
  1089. return pnode;
  1090. }
  1091. ParseNodePtr Parser::CreateStrNode(IdentPtr pid)
  1092. {
  1093. Assert(!this->m_deferringAST);
  1094. ParseNodePtr pnode = CreateNode(knopStr);
  1095. pnode->sxPid.pid=pid;
  1096. pnode->grfpn |= PNodeFlags::fpnCanFlattenConcatExpr;
  1097. return pnode;
  1098. }
  1099. ParseNodePtr Parser::CreateIntNode(long lw)
  1100. {
  1101. ParseNodePtr pnode = CreateNode(knopInt);
  1102. pnode->sxInt.lw = lw;
  1103. return pnode;
  1104. }
  1105. // Create Node with scanner limit
  1106. template <OpCode nop>
  1107. ParseNodePtr Parser::CreateNodeWithScanner()
  1108. {
  1109. Assert(m_pscan != nullptr);
  1110. return CreateNodeWithScanner<nop>(m_pscan->IchMinTok());
  1111. }
  1112. template <OpCode nop>
  1113. ParseNodePtr Parser::CreateNodeWithScanner(charcount_t ichMin)
  1114. {
  1115. Assert(m_pscan != nullptr);
  1116. return CreateNodeT<nop>(ichMin, m_pscan->IchLimTok());
  1117. }
  1118. ParseNodePtr Parser::CreateCallNode(OpCode nop, ParseNodePtr pnode1, ParseNodePtr pnode2)
  1119. {
  1120. charcount_t ichMin;
  1121. charcount_t ichLim;
  1122. if (nullptr == pnode1)
  1123. {
  1124. Assert(nullptr == pnode2);
  1125. ichMin = m_pscan->IchMinTok();
  1126. ichLim = m_pscan->IchLimTok();
  1127. }
  1128. else
  1129. {
  1130. if (nullptr == pnode2)
  1131. {
  1132. ichMin = pnode1->ichMin;
  1133. ichLim = pnode1->ichLim;
  1134. }
  1135. else
  1136. {
  1137. ichMin = pnode1->ichMin;
  1138. ichLim = pnode2->ichLim;
  1139. }
  1140. if (pnode1->nop == knopDot || pnode1->nop == knopIndex)
  1141. {
  1142. this->CheckArguments(pnode1->sxBin.pnode1);
  1143. }
  1144. }
  1145. return CreateCallNode(nop, pnode1, pnode2, ichMin, ichLim);
  1146. }
  1147. ParseNodePtr Parser::CreateStrNodeWithScanner(IdentPtr pid)
  1148. {
  1149. Assert(!this->m_deferringAST);
  1150. ParseNodePtr pnode = CreateNodeWithScanner<knopStr>();
  1151. pnode->sxPid.pid=pid;
  1152. pnode->grfpn |= PNodeFlags::fpnCanFlattenConcatExpr;
  1153. return pnode;
  1154. }
  1155. ParseNodePtr Parser::CreateIntNodeWithScanner(long lw)
  1156. {
  1157. Assert(!this->m_deferringAST);
  1158. ParseNodePtr pnode = CreateNodeWithScanner<knopInt>();
  1159. pnode->sxInt.lw = lw;
  1160. return pnode;
  1161. }
  1162. ParseNodePtr Parser::CreateTempNode(ParseNode* initExpr)
  1163. {
  1164. ParseNodePtr pnode = CreateNode(knopTemp, (charcount_t)0);
  1165. pnode->sxVar.pnodeInit =initExpr;
  1166. pnode->sxVar.pnodeNext = nullptr;
  1167. return pnode;
  1168. }
  1169. ParseNodePtr Parser::CreateTempRef(ParseNode* tempNode)
  1170. {
  1171. ParseNodePtr pnode = CreateUniNode(knopTempRef, tempNode);
  1172. return pnode;
  1173. }
  1174. void Parser::CheckPidIsValid(IdentPtr pid, bool autoArgumentsObject)
  1175. {
  1176. if (IsStrictMode())
  1177. {
  1178. // in strict mode, variable named 'eval' cannot be created
  1179. if (pid == wellKnownPropertyPids.eval)
  1180. {
  1181. Error(ERREvalUsage);
  1182. }
  1183. else if (pid == wellKnownPropertyPids.arguments && !autoArgumentsObject)
  1184. {
  1185. Error(ERRArgsUsage);
  1186. }
  1187. }
  1188. }
  1189. // CreateVarDecl needs m_ppnodeVar to be pointing to the right function.
  1190. // Post-parsing rewriting during bytecode gen may have m_ppnodeVar pointing to the last parsed function.
  1191. // This function sets up m_ppnodeVar to point to the given pnodeFnc and creates the new var declaration.
  1192. // This prevents accidentally adding var declarations to the last parsed function.
  1193. ParseNodePtr Parser::AddVarDeclNode(IdentPtr pid, ParseNodePtr pnodeFnc)
  1194. {
  1195. AnalysisAssert(pnodeFnc);
  1196. ParseNodePtr *const ppnodeVarSave = m_ppnodeVar;
  1197. m_ppnodeVar = &pnodeFnc->sxFnc.pnodeVars;
  1198. while (*m_ppnodeVar != nullptr)
  1199. {
  1200. m_ppnodeVar = &(*m_ppnodeVar)->sxVar.pnodeNext;
  1201. }
  1202. ParseNodePtr pnode = CreateVarDeclNode(pid, STUnknown, false, 0, /* checkReDecl = */ false);
  1203. m_ppnodeVar = ppnodeVarSave;
  1204. return pnode;
  1205. }
  1206. ParseNodePtr Parser::CreateVarDeclNode(IdentPtr pid, SymbolType symbolType, bool autoArgumentsObject, ParseNodePtr pnodeFnc, bool errorOnRedecl)
  1207. {
  1208. ParseNodePtr pnode = CreateDeclNode(knopVarDecl, pid, symbolType, errorOnRedecl);
  1209. // Append the variable to the end of the current variable list.
  1210. AssertMem(m_ppnodeVar);
  1211. pnode->sxVar.pnodeNext = *m_ppnodeVar;
  1212. *m_ppnodeVar = pnode;
  1213. if (nullptr != pid)
  1214. {
  1215. // this is not a temp - make sure temps go after this node
  1216. AssertMem(pid);
  1217. m_ppnodeVar = &pnode->sxVar.pnodeNext;
  1218. CheckPidIsValid(pid, autoArgumentsObject);
  1219. }
  1220. return pnode;
  1221. }
  1222. ParseNodePtr Parser::CreateBlockScopedDeclNode(IdentPtr pid, OpCode nodeType)
  1223. {
  1224. Assert(nodeType == knopConstDecl || nodeType == knopLetDecl);
  1225. ParseNodePtr pnode = CreateDeclNode(nodeType, pid, STVariable, true);
  1226. if (nullptr != pid)
  1227. {
  1228. AssertMem(pid);
  1229. pid->SetIsLetOrConst();
  1230. AddVarDeclToBlock(pnode);
  1231. CheckPidIsValid(pid);
  1232. }
  1233. return pnode;
  1234. }
  1235. void Parser::AddVarDeclToBlock(ParseNode *pnode)
  1236. {
  1237. Assert(pnode->nop == knopConstDecl || pnode->nop == knopLetDecl);
  1238. // Maintain a combined list of let and const declarations to keep
  1239. // track of declaration order.
  1240. AssertMem(m_currentBlockInfo->m_ppnodeLex);
  1241. *m_currentBlockInfo->m_ppnodeLex = pnode;
  1242. m_currentBlockInfo->m_ppnodeLex = &pnode->sxVar.pnodeNext;
  1243. pnode->sxVar.pnodeNext = nullptr;
  1244. }
  1245. void Parser::SetCurrentStatement(StmtNest *stmt)
  1246. {
  1247. m_pstmtCur = stmt;
  1248. }
  1249. template<bool buildAST>
  1250. ParseNodePtr Parser::StartParseBlockWithCapacity(PnodeBlockType blockType, ScopeType scopeType, int capacity)
  1251. {
  1252. Scope *scope = nullptr;
  1253. // Block scopes are created lazily when we discover block-scoped content.
  1254. if (scopeType != ScopeType_Unknown && scopeType != ScopeType_Block)
  1255. {
  1256. scope = Anew(&m_nodeAllocator, Scope, &m_nodeAllocator, scopeType, PHASE_OFF1(Js::ParserBindPhase), capacity);
  1257. PushScope(scope);
  1258. }
  1259. return StartParseBlockHelper<buildAST>(blockType, scope, nullptr, nullptr);
  1260. }
  1261. template<bool buildAST>
  1262. ParseNodePtr Parser::StartParseBlock(PnodeBlockType blockType, ScopeType scopeType, ParseNodePtr pnodeLabel, LabelId* pLabelId)
  1263. {
  1264. Scope *scope = nullptr;
  1265. // Block scopes are created lazily when we discover block-scoped content.
  1266. if (scopeType != ScopeType_Unknown && scopeType != ScopeType_Block)
  1267. {
  1268. scope = Anew(&m_nodeAllocator, Scope, &m_nodeAllocator, scopeType);
  1269. PushScope(scope);
  1270. }
  1271. return StartParseBlockHelper<buildAST>(blockType, scope, pnodeLabel, pLabelId);
  1272. }
  1273. template<bool buildAST>
  1274. ParseNodePtr Parser::StartParseBlockHelper(PnodeBlockType blockType, Scope *scope, ParseNodePtr pnodeLabel, LabelId* pLabelId)
  1275. {
  1276. ParseNodePtr pnodeBlock = CreateBlockNode(blockType);
  1277. pnodeBlock->sxBlock.scope = scope;
  1278. BlockInfoStack *newBlockInfo = PushBlockInfo(pnodeBlock);
  1279. PushStmt<buildAST>(&newBlockInfo->pstmt, pnodeBlock, knopBlock, pnodeLabel, pLabelId);
  1280. return pnodeBlock;
  1281. }
  1282. void Parser::PushScope(Scope *scope)
  1283. {
  1284. Assert(scope);
  1285. scope->SetEnclosingScope(m_currentScope);
  1286. m_currentScope = scope;
  1287. }
  1288. void Parser::PopScope(Scope *scope)
  1289. {
  1290. Assert(scope == m_currentScope);
  1291. m_currentScope = scope->GetEnclosingScope();
  1292. scope->SetEnclosingScope(nullptr);
  1293. }
  1294. void Parser::PushFuncBlockScope(ParseNodePtr pnodeBlock, ParseNodePtr **ppnodeScopeSave, ParseNodePtr **ppnodeExprScopeSave)
  1295. {
  1296. bool blockHasScope = m_scriptContext->GetConfig()->IsBlockScopeEnabled();
  1297. if (blockHasScope)
  1298. {
  1299. // Maintain the scope tree.
  1300. pnodeBlock->sxBlock.pnodeScopes = nullptr;
  1301. pnodeBlock->sxBlock.pnodeNext = nullptr;
  1302. // Insert this block into the active list of scopes (m_ppnodeExprScope or m_ppnodeScope).
  1303. // Save the current block's "next" pointer as the new endpoint of that list.
  1304. if (m_ppnodeExprScope)
  1305. {
  1306. *ppnodeScopeSave = m_ppnodeScope;
  1307. Assert(*m_ppnodeExprScope == nullptr);
  1308. *m_ppnodeExprScope = pnodeBlock;
  1309. *ppnodeExprScopeSave = &pnodeBlock->sxBlock.pnodeNext;
  1310. }
  1311. else
  1312. {
  1313. Assert(m_ppnodeScope);
  1314. Assert(*m_ppnodeScope == nullptr);
  1315. *m_ppnodeScope = pnodeBlock;
  1316. *ppnodeScopeSave = &pnodeBlock->sxBlock.pnodeNext;
  1317. *ppnodeExprScopeSave = m_ppnodeExprScope;
  1318. }
  1319. // Advance the global scope list pointer to the new block's child list.
  1320. m_ppnodeScope = &pnodeBlock->sxBlock.pnodeScopes;
  1321. // Set m_ppnodeExprScope to NULL to make that list inactive.
  1322. m_ppnodeExprScope = nullptr;
  1323. }
  1324. }
  1325. void Parser::PopFuncBlockScope(ParseNodePtr *ppnodeScopeSave, ParseNodePtr *ppnodeExprScopeSave)
  1326. {
  1327. bool blockHasScope = m_scriptContext->GetConfig()->IsBlockScopeEnabled();
  1328. if (blockHasScope)
  1329. {
  1330. Assert(m_ppnodeExprScope == nullptr || *m_ppnodeExprScope == nullptr);
  1331. m_ppnodeExprScope = ppnodeExprScopeSave;
  1332. AssertMem(m_ppnodeScope);
  1333. Assert(nullptr == *m_ppnodeScope);
  1334. m_ppnodeScope = ppnodeScopeSave;
  1335. }
  1336. }
  1337. template<bool buildAST>
  1338. ParseNodePtr Parser::ParseBlock(ParseNodePtr pnodeLabel, LabelId* pLabelId)
  1339. {
  1340. StmtNest stmt;
  1341. ParseNodePtr pnodeBlock = nullptr;
  1342. ParseNodePtr *ppnodeScopeSave = nullptr;
  1343. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  1344. if (buildAST || BindDeferredPidRefs())
  1345. {
  1346. pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Regular, ScopeType_Block, pnodeLabel, pLabelId);
  1347. }
  1348. else
  1349. {
  1350. PushStmt<buildAST>(&stmt, nullptr, knopBlock, pnodeLabel, pLabelId);
  1351. }
  1352. ChkCurTok(tkLCurly, ERRnoLcurly);
  1353. ParseNodePtr * ppnodeList = nullptr;
  1354. if (buildAST)
  1355. {
  1356. PushFuncBlockScope(pnodeBlock, &ppnodeScopeSave, &ppnodeExprScopeSave);
  1357. ppnodeList = &pnodeBlock->sxBlock.pnodeStmt;
  1358. }
  1359. ParseStmtList<buildAST>(ppnodeList);
  1360. if (buildAST)
  1361. {
  1362. PopFuncBlockScope(ppnodeScopeSave, ppnodeExprScopeSave);
  1363. }
  1364. if (buildAST || BindDeferredPidRefs())
  1365. {
  1366. FinishParseBlock(pnodeBlock);
  1367. }
  1368. else
  1369. {
  1370. PopStmt(&stmt);
  1371. }
  1372. ChkCurTok(tkRCurly, ERRnoRcurly);
  1373. return pnodeBlock;
  1374. }
  1375. void Parser::FinishParseBlock(ParseNode *pnodeBlock, bool needScanRCurly)
  1376. {
  1377. Assert(m_currentBlockInfo != nullptr && pnodeBlock == m_currentBlockInfo->pnodeBlock);
  1378. if (needScanRCurly)
  1379. {
  1380. // Only update the ichLim if we were expecting an RCurly. If there is an
  1381. // expression body without a necessary RCurly, the correct ichLim will
  1382. // have been set already.
  1383. pnodeBlock->ichLim = m_pscan->IchLimTok();
  1384. }
  1385. BindPidRefs<false>(GetCurrentBlockInfo(), m_nextBlockId - 1);
  1386. PopStmt(&m_currentBlockInfo->pstmt);
  1387. PopBlockInfo();
  1388. Scope *scope = pnodeBlock->sxBlock.scope;
  1389. if (scope)
  1390. {
  1391. PopScope(scope);
  1392. }
  1393. }
  1394. void Parser::FinishParseFncExprScope(ParseNodePtr pnodeFnc, ParseNodePtr pnodeFncExprScope)
  1395. {
  1396. int fncExprScopeId = pnodeFncExprScope->sxBlock.blockId;
  1397. ParseNodePtr pnodeName = pnodeFnc->sxFnc.pnodeName;
  1398. if (pnodeName)
  1399. {
  1400. Assert(pnodeName->nop == knopVarDecl);
  1401. BindPidRefsInScope(pnodeName->sxVar.pid, pnodeName->sxVar.sym, fncExprScopeId);
  1402. }
  1403. FinishParseBlock(pnodeFncExprScope);
  1404. }
  1405. template <const bool backgroundPidRef>
  1406. void Parser::BindPidRefs(BlockInfoStack *blockInfo, uint maxBlockId)
  1407. {
  1408. // We need to bind all assignments in order to emit assignment to 'const' error
  1409. int blockId = blockInfo->pnodeBlock->sxBlock.blockId;
  1410. Scope *scope = blockInfo->pnodeBlock->sxBlock.scope;
  1411. if (scope)
  1412. {
  1413. auto bindPidRefs = [blockId, maxBlockId, this](Symbol *sym)
  1414. {
  1415. ParseNodePtr pnode = sym->GetDecl();
  1416. IdentPtr pid;
  1417. #if PROFILE_DICTIONARY
  1418. int depth = 0;
  1419. #endif
  1420. Assert(pnode);
  1421. switch (pnode->nop)
  1422. {
  1423. case knopLetDecl:
  1424. case knopVarDecl:
  1425. pid = pnode->sxVar.pid;
  1426. if (backgroundPidRef)
  1427. {
  1428. pid = this->m_pscan->m_phtbl->FindExistingPid(pid->Psz(), pid->Cch(), pid->Hash(), nullptr, nullptr
  1429. #if PROFILE_DICTIONARY
  1430. , depth
  1431. #endif
  1432. );
  1433. if (pid == nullptr)
  1434. {
  1435. break;
  1436. }
  1437. }
  1438. this->BindPidRefsInScope(pid, sym, blockId, maxBlockId);
  1439. break;
  1440. case knopConstDecl:
  1441. pid = pnode->sxVar.pid;
  1442. if (backgroundPidRef)
  1443. {
  1444. pid = this->m_pscan->m_phtbl->FindExistingPid(pid->Psz(), pid->Cch(), pid->Hash(), nullptr, nullptr
  1445. #if PROFILE_DICTIONARY
  1446. , depth
  1447. #endif
  1448. );
  1449. if (pid == nullptr)
  1450. {
  1451. break;
  1452. }
  1453. }
  1454. this->BindConstPidRefsInScope(pid, sym, blockId, maxBlockId);
  1455. break;
  1456. case knopName:
  1457. pid = pnode->sxPid.pid;
  1458. if (backgroundPidRef)
  1459. {
  1460. pid = this->m_pscan->m_phtbl->FindExistingPid(pid->Psz(), pid->Cch(), pid->Hash(), nullptr, nullptr
  1461. #if PROFILE_DICTIONARY
  1462. , depth
  1463. #endif
  1464. );
  1465. if (pid == nullptr)
  1466. {
  1467. break;
  1468. }
  1469. }
  1470. this->BindPidRefsInScope(pid, sym, blockId, maxBlockId);
  1471. break;
  1472. default:
  1473. Assert(0);
  1474. break;
  1475. }
  1476. };
  1477. scope->ForEachSymbol(bindPidRefs);
  1478. }
  1479. }
  1480. void Parser::BindPidRefsInScope(IdentPtr pid, Symbol *sym, int blockId, uint maxBlockId)
  1481. {
  1482. this->BindPidRefsInScopeImpl<false>(pid, sym, blockId, maxBlockId);
  1483. }
  1484. void Parser::BindConstPidRefsInScope(IdentPtr pid, Symbol *sym, int blockId, uint maxBlockId)
  1485. {
  1486. this->BindPidRefsInScopeImpl<true>(pid, sym, blockId, maxBlockId);
  1487. }
  1488. template<const bool isConstBinding>
  1489. void Parser::BindPidRefsInScopeImpl(IdentPtr pid, Symbol *sym, int blockId, uint maxBlockId)
  1490. {
  1491. PidRefStack *ref, *nextRef, *lastRef = nullptr;
  1492. Assert(sym);
  1493. for (ref = pid->GetTopRef(); ref && ref->GetScopeId() >= blockId; ref = nextRef)
  1494. {
  1495. // Fix up sym* on PID ref.
  1496. Assert(!ref->GetSym() || ref->GetSym() == sym);
  1497. nextRef = ref->prev;
  1498. Assert(ref->GetScopeId() >= 0);
  1499. if ((uint)ref->GetScopeId() > maxBlockId)
  1500. {
  1501. lastRef = ref;
  1502. continue;
  1503. }
  1504. ref->SetSym(sym);
  1505. if (isConstBinding && ref->IsAssignment() && !ref->IsDynamicBinding())
  1506. {
  1507. if (pid->GetTopIchMin() < this->m_asgToConst.GetIchMin())
  1508. {
  1509. this->m_asgToConst.Set(pid->GetTopIchMin(), pid->GetTopIchLim());
  1510. }
  1511. }
  1512. this->RemovePrevPidRef(pid, lastRef);
  1513. if (ref->IsAssignment())
  1514. {
  1515. sym->PromoteAssignmentState();
  1516. }
  1517. if (ref->GetScopeId() == blockId)
  1518. {
  1519. break;
  1520. }
  1521. }
  1522. }
  1523. void Parser::PopStmt(StmtNest *pStmt)
  1524. {
  1525. Assert(pStmt == m_pstmtCur);
  1526. SetCurrentStatement(m_pstmtCur->pstmtOuter);
  1527. }
  1528. BlockInfoStack *Parser::PushBlockInfo(ParseNodePtr pnodeBlock)
  1529. {
  1530. BlockInfoStack *newBlockInfo = (BlockInfoStack *)m_nodeAllocator.Alloc(sizeof(BlockInfoStack));
  1531. Assert(nullptr != newBlockInfo);
  1532. newBlockInfo->pnodeBlock = pnodeBlock;
  1533. newBlockInfo->pBlockInfoOuter = m_currentBlockInfo;
  1534. newBlockInfo->m_ppnodeLex = &pnodeBlock->sxBlock.pnodeLexVars;
  1535. if (pnodeBlock->sxBlock.blockType != PnodeBlockType::Regular)
  1536. {
  1537. newBlockInfo->pBlockInfoFunction = newBlockInfo;
  1538. }
  1539. else
  1540. {
  1541. Assert(m_currentBlockInfo);
  1542. newBlockInfo->pBlockInfoFunction = m_currentBlockInfo->pBlockInfoFunction;
  1543. }
  1544. m_currentBlockInfo = newBlockInfo;
  1545. return newBlockInfo;
  1546. }
  1547. void Parser::PopBlockInfo()
  1548. {
  1549. Assert(m_currentBlockInfo);
  1550. PopDynamicBlock();
  1551. m_currentBlockInfo = m_currentBlockInfo->pBlockInfoOuter;
  1552. }
  1553. void Parser::PushDynamicBlock()
  1554. {
  1555. if (!m_scriptContext->GetConfig()->IsLetAndConstEnabled())
  1556. {
  1557. // Shortcut: we only need to track dynamically-bound blocks for const reassignment.
  1558. return;
  1559. }
  1560. Assert(GetCurrentBlock());
  1561. int blockId = GetCurrentBlock()->sxBlock.blockId;
  1562. if (m_currentDynamicBlock && m_currentDynamicBlock->id == blockId)
  1563. {
  1564. return;
  1565. }
  1566. BlockIdsStack *info = (BlockIdsStack *)m_nodeAllocator.Alloc(sizeof(BlockIdsStack));
  1567. if (nullptr == info)
  1568. {
  1569. Error(ERRnoMemory);
  1570. }
  1571. info->id = blockId;
  1572. info->prev = m_currentDynamicBlock;
  1573. m_currentDynamicBlock = info;
  1574. }
  1575. void Parser::PopDynamicBlock()
  1576. {
  1577. int blockId = GetCurrentDynamicBlockId();
  1578. if (GetCurrentBlock()->sxBlock.blockId != blockId || blockId == -1)
  1579. {
  1580. return;
  1581. }
  1582. Assert(m_currentDynamicBlock);
  1583. AssertMsg(m_scriptContext->GetConfig()->IsLetAndConstEnabled(), "Should only do this if let/const is enabled since only needed for const reassignment error checking");
  1584. for (BlockInfoStack *blockInfo = m_currentBlockInfo; blockInfo; blockInfo = blockInfo->pBlockInfoOuter)
  1585. {
  1586. for (ParseNodePtr pnodeDecl = blockInfo->pnodeBlock->sxBlock.pnodeLexVars;
  1587. pnodeDecl;
  1588. pnodeDecl = pnodeDecl->sxVar.pnodeNext)
  1589. {
  1590. this->SetPidRefsInScopeDynamic(pnodeDecl->sxVar.pid, blockId);
  1591. }
  1592. }
  1593. m_currentDynamicBlock = m_currentDynamicBlock->prev;
  1594. }
  1595. int Parser::GetCurrentDynamicBlockId() const
  1596. {
  1597. return m_currentDynamicBlock ? m_currentDynamicBlock->id : -1;
  1598. }
  1599. ParseNode *Parser::GetCurrentFunctionNode()
  1600. {
  1601. if (m_currentNodeDeferredFunc != nullptr)
  1602. {
  1603. return m_currentNodeDeferredFunc;
  1604. }
  1605. else if (m_currentNodeFunc != nullptr)
  1606. {
  1607. return m_currentNodeFunc;
  1608. }
  1609. else
  1610. {
  1611. AssertMsg(GetFunctionBlock()->sxBlock.blockType == PnodeBlockType::Global,
  1612. "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'");
  1613. return m_currentNodeProg;
  1614. }
  1615. }
  1616. ParseNode *Parser::GetCurrentNonLamdaFunctionNode()
  1617. {
  1618. if (m_currentNodeNonLambdaDeferredFunc != nullptr)
  1619. {
  1620. return m_currentNodeNonLambdaDeferredFunc;
  1621. }
  1622. return m_currentNodeNonLambdaFunc;
  1623. }
  1624. void Parser::RegisterRegexPattern(UnifiedRegex::RegexPattern *const regexPattern)
  1625. {
  1626. Assert(regexPattern);
  1627. // ensure a no-throw add behavior here, to catch out of memory exceptions, using the guest arena allocator
  1628. if (!m_registeredRegexPatterns.PrependNoThrow(m_scriptContext->GetGuestArena(), regexPattern))
  1629. {
  1630. Parser::Error(ERRnoMemory);
  1631. }
  1632. }
  1633. void Parser::AddToNodeListEscapedUse(ParseNode ** ppnodeList, ParseNode *** pppnodeLast,
  1634. ParseNode * pnodeAdd)
  1635. {
  1636. AddToNodeList(ppnodeList, pppnodeLast, pnodeAdd);
  1637. pnodeAdd->SetIsInList();
  1638. }
  1639. void Parser::AddToNodeList(ParseNode ** ppnodeList, ParseNode *** pppnodeLast,
  1640. ParseNode * pnodeAdd)
  1641. {
  1642. Assert(!this->m_deferringAST);
  1643. if (nullptr == *pppnodeLast)
  1644. {
  1645. // should be an empty list
  1646. Assert(nullptr == *ppnodeList);
  1647. *ppnodeList = pnodeAdd;
  1648. *pppnodeLast = ppnodeList;
  1649. }
  1650. else
  1651. {
  1652. //
  1653. AssertNodeMem(*ppnodeList);
  1654. AssertNodeMem(**pppnodeLast);
  1655. ParseNode *pnodeT = CreateBinNode(knopList, **pppnodeLast, pnodeAdd);
  1656. **pppnodeLast = pnodeT;
  1657. *pppnodeLast = &pnodeT->sxBin.pnode2;
  1658. }
  1659. }
  1660. // Check reference to "arguments" that indicates the object may escape.
  1661. void Parser::CheckArguments(ParseNodePtr pnode)
  1662. {
  1663. if (m_currentNodeFunc && this->NodeIsIdent(pnode, wellKnownPropertyPids.arguments))
  1664. {
  1665. m_currentNodeFunc->sxFnc.SetHasHeapArguments();
  1666. }
  1667. }
  1668. // Check use of "arguments" that requires instantiation of the object.
  1669. void Parser::CheckArgumentsUse(IdentPtr pid, ParseNodePtr pnodeFnc)
  1670. {
  1671. if (pid == wellKnownPropertyPids.arguments)
  1672. {
  1673. if (pnodeFnc != nullptr)
  1674. {
  1675. pnodeFnc->sxFnc.SetUsesArguments(TRUE);
  1676. }
  1677. else
  1678. {
  1679. m_UsesArgumentsAtGlobal = true;
  1680. }
  1681. }
  1682. }
  1683. void Parser::CheckStrictModeEvalArgumentsUsage(IdentPtr pid, ParseNodePtr pnode)
  1684. {
  1685. if (pid != nullptr)
  1686. {
  1687. // In strict mode, 'eval' / 'arguments' cannot be assigned to.
  1688. if ( pid == wellKnownPropertyPids.eval)
  1689. {
  1690. Error(ERREvalUsage, pnode);
  1691. }
  1692. if (pid == wellKnownPropertyPids.arguments)
  1693. {
  1694. Error(ERRArgsUsage, pnode);
  1695. }
  1696. }
  1697. }
  1698. void Parser::CheckStrictModeFncDeclNotSourceElement(const bool isSourceElement, const BOOL isDeclaration)
  1699. {
  1700. // In strict mode, only a SourceElement can expand to a FunctionDeclaration; a Statement cannot. That means a function
  1701. // declaration may only appear as a top-level statement in a program or function body, and otherwise may not be nested
  1702. // inside another statement or block.
  1703. //
  1704. // The only difference between a SourceElement and a Statement is that a SourceElement can include a FunctionDeclaration, so
  1705. // we just use ParseStmtList and ParseStatement and pass in a flag indicating whether the statements are source elements.
  1706. Assert(!(isSourceElement && !isDeclaration));
  1707. if(IsStrictMode() && !isSourceElement && isDeclaration &&
  1708. !this->GetScriptContext()->GetConfig()->IsBlockScopeEnabled())
  1709. {
  1710. Error(ERRFncDeclNotSourceElement);
  1711. }
  1712. }
  1713. void Parser::ReduceDeferredScriptLength(size_t chars)
  1714. {
  1715. // If we're in deferred mode, subtract the given char count from the total length,
  1716. // and see if this puts us under the deferral threshold.
  1717. if (m_grfscr & fscrDeferFncParse)
  1718. {
  1719. if (m_length > chars)
  1720. {
  1721. m_length -= chars;
  1722. }
  1723. else
  1724. {
  1725. m_length = 0;
  1726. }
  1727. if (m_length < Parser::GetDeferralThreshold(this->m_sourceContextInfo->IsSourceProfileLoaded()))
  1728. {
  1729. // Stop deferring.
  1730. m_grfscr &= ~fscrDeferFncParse;
  1731. m_stoppedDeferredParse = TRUE;
  1732. }
  1733. }
  1734. }
  1735. /***************************************************************************
  1736. Look for an existing label with the given name.
  1737. ***************************************************************************/
  1738. BOOL Parser::PnodeLabelNoAST(IdentToken* pToken, LabelId* pLabelIdList)
  1739. {
  1740. StmtNest* pStmt;
  1741. LabelId* pLabelId;
  1742. // Look in the label stack.
  1743. for (pStmt = m_pstmtCur; pStmt != nullptr; pStmt = pStmt->pstmtOuter)
  1744. {
  1745. for (pLabelId = pStmt->pLabelId; pLabelId != nullptr; pLabelId = pLabelId->next)
  1746. {
  1747. if (pLabelId->pid == pToken->pid)
  1748. return TRUE;
  1749. }
  1750. }
  1751. // Also look in the pnodeLabels list.
  1752. for (pLabelId = pLabelIdList; pLabelId != nullptr; pLabelId = pLabelId->next)
  1753. {
  1754. if (pLabelId->pid == pToken->pid)
  1755. return TRUE;
  1756. }
  1757. return FALSE;
  1758. }
  1759. void Parser::EnsureStackAvailable()
  1760. {
  1761. if (!m_scriptContext->GetThreadContext()->IsStackAvailable(Js::Constants::MinStackCompile))
  1762. {
  1763. Error(ERRnoMemory);
  1764. }
  1765. }
  1766. void Parser::ThrowNewTargetSyntaxErrForGlobalScope()
  1767. {
  1768. //TODO: (falotfi) we need reliably distinguish eval in global scope vs in a function
  1769. // The rule for this syntax error is any time new.target is called at global scope
  1770. // we are excluding new.target in eval at global scope for now.
  1771. if(GetCurrentNonLamdaFunctionNode() == nullptr && (this->m_grfscr & fscrEvalCode) == 0)
  1772. {
  1773. Error(ERRInvalidNewTarget);
  1774. }
  1775. }
  1776. template<bool buildAST>
  1777. ParseNodePtr Parser::ParseMetaProperty(tokens metaParentKeyword, charcount_t ichMin, _Out_opt_ BOOL* pfCanAssign)
  1778. {
  1779. AssertMsg(metaParentKeyword == tkNEW, "Only supported for tkNEW parent keywords");
  1780. AssertMsg(this->m_token.tk == tkDot, "We must be currently sitting on the dot after the parent keyword");
  1781. m_pscan->Scan();
  1782. if (this->m_token.tk == tkID && this->m_token.GetIdentifier(m_phtbl) == this->GetTargetPid())
  1783. {
  1784. ThrowNewTargetSyntaxErrForGlobalScope();
  1785. if (pfCanAssign)
  1786. {
  1787. *pfCanAssign = FALSE;
  1788. }
  1789. if (buildAST)
  1790. {
  1791. return CreateNodeWithScanner<knopNewTarget>(ichMin);
  1792. }
  1793. }
  1794. else
  1795. {
  1796. Error(ERRsyntax);
  1797. }
  1798. return nullptr;
  1799. }
  1800. /***************************************************************************
  1801. Parse an expression term.
  1802. ***************************************************************************/
  1803. template<bool buildAST>
  1804. ParseNodePtr Parser::ParseTerm(BOOL fAllowCall,
  1805. LPCOLESTR pNameHint,
  1806. ulong *pHintLength,
  1807. ulong *pShortNameOffset,
  1808. _Inout_opt_ IdentToken* pToken/*= nullptr*/,
  1809. bool fUnaryOrParen /*= false*/,
  1810. _Out_opt_ BOOL* pfCanAssign /* = nullptr*/,
  1811. _Inout_opt_ BOOL* pfLikelyPattern /* = nullptr*/)
  1812. {
  1813. ParseNodePtr pnode = nullptr;
  1814. charcount_t ichMin = 0;
  1815. size_t iecpMin = 0;
  1816. size_t iuMin;
  1817. IdentToken term;
  1818. BOOL fInNew = FALSE;
  1819. BOOL fCanAssign = TRUE;
  1820. bool isAsyncExpr = false;
  1821. bool isLambdaExpr = false;
  1822. Assert(pToken == nullptr || pToken->tk == tkNone); // Must be empty initially
  1823. if (this->IsBackgroundParser())
  1824. {
  1825. PROBE_STACK_NO_DISPOSE(m_scriptContext, Js::Constants::MinStackParseOneTerm);
  1826. }
  1827. else
  1828. {
  1829. PROBE_STACK(m_scriptContext, Js::Constants::MinStackParseOneTerm);
  1830. }
  1831. switch (m_token.tk)
  1832. {
  1833. case tkID:
  1834. {
  1835. PidRefStack *ref = nullptr;
  1836. IdentPtr pid = m_token.GetIdentifier(m_phtbl);
  1837. charcount_t ichLim = m_pscan->IchLimTok();
  1838. size_t iecpLim = m_pscan->IecpLimTok();
  1839. ichMin = m_pscan->IchMinTok();
  1840. iecpMin = m_pscan->IecpMinTok();
  1841. m_pscan->Scan();
  1842. // We search for an Async expression (a function declaration or an async lambda expression)
  1843. if (pid == wellKnownPropertyPids.async &&
  1844. !m_pscan->FHadNewLine() &&
  1845. m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
  1846. {
  1847. if (m_token.tk == tkFUNCTION)
  1848. {
  1849. isAsyncExpr = true;
  1850. goto LFunction;
  1851. }
  1852. else if (m_token.tk == tkID)
  1853. {
  1854. isLambdaExpr = true;
  1855. isAsyncExpr = true;
  1856. goto LFunction;
  1857. }
  1858. }
  1859. if (buildAST || BindDeferredPidRefs())
  1860. {
  1861. ref = this->PushPidRef(pid);
  1862. }
  1863. if (buildAST)
  1864. {
  1865. pnode = CreateNameNode(pid);
  1866. pnode->ichMin = ichMin;
  1867. pnode->ichLim = ichLim;
  1868. pnode->sxPid.SetSymRef(ref);
  1869. CheckArgumentsUse(pid, m_currentNodeFunc);
  1870. }
  1871. else
  1872. {
  1873. // Remember the identifier start and end in case it turns out to be a statement label.
  1874. term.tk = tkID;
  1875. term.pid = pid; // Record the identifier for detection of eval
  1876. term.ichMin = static_cast<charcount_t>(iecpMin);
  1877. term.ichLim = static_cast<charcount_t>(iecpLim);
  1878. }
  1879. break;
  1880. }
  1881. case tkTHIS:
  1882. if (buildAST)
  1883. {
  1884. pnode = CreateNodeWithScanner<knopThis>();
  1885. }
  1886. fCanAssign = FALSE;
  1887. m_pscan->Scan();
  1888. break;
  1889. case tkLParen:
  1890. ichMin = m_pscan->IchMinTok();
  1891. iuMin = m_pscan->IecpMinTok();
  1892. m_pscan->Scan();
  1893. if (m_token.tk == tkRParen)
  1894. {
  1895. // Empty parens can only be legal as an empty parameter list to a lambda declaration.
  1896. // We're in a lambda if the next token is =>.
  1897. fAllowCall = FALSE;
  1898. m_pscan->Scan();
  1899. // If the token after the right paren is not => or if there was a newline between () and => this is a syntax error
  1900. if (!m_doingFastScan && (m_token.tk != tkDArrow || m_pscan->FHadNewLine()))
  1901. {
  1902. Error(ERRsyntax);
  1903. }
  1904. if (buildAST)
  1905. {
  1906. pnode = CreateNodeWithScanner<knopEmpty>();
  1907. }
  1908. break;
  1909. }
  1910. this->m_parenDepth++;
  1911. pnode = ParseExpr<buildAST>(koplNo, &fCanAssign, TRUE, FALSE, nullptr, nullptr /*nameLength*/, nullptr /*pShortNameOffset*/, &term, true);
  1912. this->m_parenDepth--;
  1913. ChkCurTok(tkRParen, ERRnoRparen);
  1914. // Emit a deferred ... error if one was parsed.
  1915. if (m_deferEllipsisError && m_token.tk != tkDArrow)
  1916. {
  1917. m_pscan->SeekTo(m_EllipsisErrLoc);
  1918. Error(ERRInvalidSpreadUse);
  1919. }
  1920. else
  1921. {
  1922. m_deferEllipsisError = false;
  1923. }
  1924. break;
  1925. case tkIntCon:
  1926. if (IsStrictMode() && m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  1927. {
  1928. Error(ERRES5NoOctal);
  1929. }
  1930. if (buildAST)
  1931. {
  1932. pnode = CreateIntNodeWithScanner(m_token.GetLong());
  1933. }
  1934. fCanAssign = FALSE;
  1935. m_pscan->Scan();
  1936. break;
  1937. case tkFltCon:
  1938. if (IsStrictMode() && m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  1939. {
  1940. Error(ERRES5NoOctal);
  1941. }
  1942. if (buildAST)
  1943. {
  1944. pnode = CreateNodeWithScanner<knopFlt>();
  1945. pnode->sxFlt.dbl = m_token.GetDouble();
  1946. pnode->sxFlt.maybeInt = m_token.GetDoubleMayBeInt();
  1947. }
  1948. fCanAssign = FALSE;
  1949. m_pscan->Scan();
  1950. break;
  1951. case tkStrCon:
  1952. if (IsStrictMode() && m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  1953. {
  1954. Error(ERRES5NoOctal);
  1955. }
  1956. if (buildAST)
  1957. {
  1958. pnode = CreateStrNodeWithScanner(m_token.GetStr());
  1959. }
  1960. else
  1961. {
  1962. // Subtract the string literal length from the total char count for the purpose
  1963. // of deciding whether to defer parsing and byte code generation.
  1964. this->ReduceDeferredScriptLength(m_pscan->IchLimTok() - m_pscan->IchMinTok());
  1965. }
  1966. fCanAssign = FALSE;
  1967. m_pscan->Scan();
  1968. break;
  1969. case tkTRUE:
  1970. if (buildAST)
  1971. {
  1972. pnode = CreateNodeWithScanner<knopTrue>();
  1973. }
  1974. fCanAssign = FALSE;
  1975. m_pscan->Scan();
  1976. break;
  1977. case tkFALSE:
  1978. if (buildAST)
  1979. {
  1980. pnode = CreateNodeWithScanner<knopFalse>();
  1981. }
  1982. fCanAssign = FALSE;
  1983. m_pscan->Scan();
  1984. break;
  1985. case tkNULL:
  1986. if (buildAST)
  1987. {
  1988. pnode = CreateNodeWithScanner<knopNull>();
  1989. }
  1990. fCanAssign = FALSE;
  1991. m_pscan->Scan();
  1992. break;
  1993. case tkDiv:
  1994. case tkAsgDiv:
  1995. pnode = ParseRegExp<buildAST>();
  1996. fCanAssign = FALSE;
  1997. m_pscan->Scan();
  1998. break;
  1999. case tkNEW:
  2000. {
  2001. ichMin = m_pscan->IchMinTok();
  2002. m_pscan->Scan();
  2003. if (m_token.tk == tkDot && m_scriptContext->GetConfig()->IsES6ClassAndExtendsEnabled())
  2004. {
  2005. pnode = ParseMetaProperty<buildAST>(tkNEW, ichMin, &fCanAssign);
  2006. m_pscan->Scan();
  2007. }
  2008. else
  2009. {
  2010. ParseNodePtr pnodeExpr = ParseTerm<buildAST>(FALSE, pNameHint, pHintLength, pShortNameOffset);
  2011. if (buildAST)
  2012. {
  2013. pnode = CreateCallNode(knopNew, pnodeExpr, nullptr);
  2014. pnode->ichMin = ichMin;
  2015. }
  2016. fInNew = TRUE;
  2017. fCanAssign = FALSE;
  2018. }
  2019. break;
  2020. }
  2021. case tkLBrack:
  2022. {
  2023. ichMin = m_pscan->IchMinTok();
  2024. m_pscan->Scan();
  2025. pnode = ParseArrayLiteral<buildAST>();
  2026. if (buildAST)
  2027. {
  2028. pnode->ichMin = ichMin;
  2029. pnode->ichLim = m_pscan->IchLimTok();
  2030. }
  2031. if (this->m_arrayDepth == 0)
  2032. {
  2033. Assert(m_pscan->IchLimTok() - ichMin > m_funcInArray);
  2034. this->ReduceDeferredScriptLength(m_pscan->IchLimTok() - ichMin - this->m_funcInArray);
  2035. this->m_funcInArray = 0;
  2036. this->m_funcInArrayDepth = 0;
  2037. }
  2038. ChkCurTok(tkRBrack, ERRnoRbrack);
  2039. if (!IsES6DestructuringEnabled())
  2040. {
  2041. fCanAssign = FALSE;
  2042. }
  2043. else if (pfLikelyPattern != nullptr && !IsPostFixOperators())
  2044. {
  2045. *pfLikelyPattern = TRUE;
  2046. }
  2047. break;
  2048. }
  2049. case tkLCurly:
  2050. {
  2051. ichMin = m_pscan->IchMinTok();
  2052. m_pscan->ScanForcingPid();
  2053. ParseNodePtr pnodeMemberList = ParseMemberList<buildAST>(pNameHint, pHintLength);
  2054. if (buildAST)
  2055. {
  2056. pnode = CreateUniNode(knopObject, pnodeMemberList);
  2057. pnode->ichMin = ichMin;
  2058. pnode->ichLim = m_pscan->IchLimTok();
  2059. }
  2060. ChkCurTok(tkRCurly, ERRnoRcurly);
  2061. if (!IsES6DestructuringEnabled())
  2062. {
  2063. fCanAssign = FALSE;
  2064. }
  2065. else if (pfLikelyPattern != nullptr && !IsPostFixOperators())
  2066. {
  2067. *pfLikelyPattern = TRUE;
  2068. }
  2069. break;
  2070. }
  2071. case tkFUNCTION:
  2072. {
  2073. LFunction :
  2074. if (m_grfscr & fscrDeferredFncExpression)
  2075. {
  2076. // The top-level deferred function body was defined by a function expression whose parsing was deferred. We are now
  2077. // parsing it, so unset the flag so that any nested functions are parsed normally. This flag is only applicable the
  2078. // first time we see it.
  2079. //
  2080. // Normally, deferred functions will be parsed in ParseStatement upon encountering the 'function' token. The first
  2081. // token of the source code of the function may not a 'function' token though, so we still need to reset this flag
  2082. // for the first function we parse. This can happen in compat modes, for instance, for a function expression enclosed
  2083. // in parentheses, where the legacy behavior was to include the parentheses in the function's source code.
  2084. m_grfscr &= ~fscrDeferredFncExpression;
  2085. }
  2086. ushort flags = fFncNoFlgs;
  2087. if (isLambdaExpr)
  2088. {
  2089. flags |= fFncLambda;
  2090. }
  2091. if (isAsyncExpr)
  2092. {
  2093. flags |= fFncAsync;
  2094. }
  2095. pnode = ParseFncDecl<buildAST>(flags, pNameHint, false, false, true, fUnaryOrParen);
  2096. if (isAsyncExpr)
  2097. {
  2098. pnode->sxFnc.cbMin = iecpMin;
  2099. pnode->ichMin = ichMin;
  2100. }
  2101. fCanAssign = FALSE;
  2102. break;
  2103. }
  2104. case tkCLASS:
  2105. fAllowCall = FALSE;
  2106. if (m_scriptContext->GetConfig()->IsES6ClassAndExtendsEnabled())
  2107. {
  2108. pnode = ParseClassDecl<buildAST>(FALSE, pNameHint, pHintLength, pShortNameOffset);
  2109. }
  2110. else
  2111. {
  2112. goto LUnknown;
  2113. }
  2114. fCanAssign = FALSE;
  2115. break;
  2116. case tkStrTmplBasic:
  2117. case tkStrTmplBegin:
  2118. Assert(m_scriptContext->GetConfig()->IsES6StringTemplateEnabled());
  2119. pnode = ParseStringTemplateDecl<buildAST>(nullptr);
  2120. fCanAssign = FALSE;
  2121. break;
  2122. case tkSUPER:
  2123. if (m_scriptContext->GetConfig()->IsES6ClassAndExtendsEnabled())
  2124. {
  2125. pnode = ParseSuper<buildAST>(pnode, !!fAllowCall);
  2126. }
  2127. else
  2128. {
  2129. goto LUnknown;
  2130. }
  2131. break;
  2132. case tkCASE:
  2133. {
  2134. if (!m_doingFastScan)
  2135. {
  2136. goto LUnknown;
  2137. }
  2138. ParseNodePtr pnodeUnused;
  2139. pnode = ParseCase<buildAST>(&pnodeUnused);
  2140. break;
  2141. }
  2142. case tkELSE:
  2143. if (!m_doingFastScan)
  2144. {
  2145. goto LUnknown;
  2146. }
  2147. m_pscan->Scan();
  2148. ParseStatement<buildAST>();
  2149. break;
  2150. default:
  2151. LUnknown :
  2152. Error(ERRsyntax);
  2153. break;
  2154. }
  2155. pnode = ParsePostfixOperators<buildAST>(pnode, fAllowCall, fInNew, &fCanAssign, &term);
  2156. // Pass back identifier if requested
  2157. if (pToken && term.tk == tkID)
  2158. {
  2159. *pToken = term;
  2160. }
  2161. if (pfCanAssign)
  2162. {
  2163. *pfCanAssign = fCanAssign;
  2164. }
  2165. return pnode;
  2166. }
  2167. template <bool buildAST>
  2168. ParseNodePtr Parser::ParseRegExp()
  2169. {
  2170. ParseNodePtr pnode = nullptr;
  2171. if (buildAST || m_doingFastScan)
  2172. {
  2173. m_pscan->RescanRegExp();
  2174. BOOL saveDeferringAST = this->m_deferringAST;
  2175. if (m_doingFastScan)
  2176. {
  2177. this->m_deferringAST = false;
  2178. }
  2179. pnode = CreateNodeWithScanner<knopRegExp>();
  2180. pnode->sxPid.regexPattern = m_token.GetRegex();
  2181. if (m_doingFastScan)
  2182. {
  2183. this->m_deferringAST = saveDeferringAST;
  2184. this->AddFastScannedRegExpNode(pnode);
  2185. if (!buildAST)
  2186. {
  2187. pnode = nullptr;
  2188. }
  2189. }
  2190. #if ENABLE_BACKGROUND_PARSING
  2191. else if (this->IsBackgroundParser())
  2192. {
  2193. Assert(pnode->sxPid.regexPattern == nullptr);
  2194. this->AddBackgroundRegExpNode(pnode);
  2195. }
  2196. #endif
  2197. }
  2198. else
  2199. {
  2200. m_pscan->RescanRegExpNoAST();
  2201. }
  2202. Assert(m_token.tk == tkRegExp);
  2203. return pnode;
  2204. }
  2205. BOOL Parser::NodeIsEvalName(ParseNodePtr pnode)
  2206. {
  2207. //WOOB 1107758 Special case of indirect eval binds to local scope in standards mode
  2208. return pnode->nop == knopName && (pnode->sxPid.pid == wellKnownPropertyPids.eval);
  2209. }
  2210. BOOL Parser::NodeEqualsName(ParseNodePtr pnode, LPCOLESTR sz, ulong cch)
  2211. {
  2212. return pnode->nop == knopName &&
  2213. pnode->sxPid.pid->Cch() == cch &&
  2214. !wmemcmp(pnode->sxPid.pid->Psz(), sz, cch);
  2215. }
  2216. BOOL Parser::NodeIsIdent(ParseNodePtr pnode, IdentPtr pid)
  2217. {
  2218. for (;;)
  2219. {
  2220. switch (pnode->nop)
  2221. {
  2222. case knopName:
  2223. return (pnode->sxPid.pid == pid);
  2224. case knopComma:
  2225. pnode = pnode->sxBin.pnode2;
  2226. break;
  2227. default:
  2228. return FALSE;
  2229. }
  2230. }
  2231. }
  2232. template<bool buildAST>
  2233. ParseNodePtr Parser::ParsePostfixOperators(
  2234. ParseNodePtr pnode,
  2235. BOOL fAllowCall,
  2236. BOOL fInNew,
  2237. BOOL *pfCanAssign,
  2238. _Inout_ IdentToken* pToken)
  2239. {
  2240. uint16 count = 0;
  2241. bool callOfConstants = false;
  2242. for (;;)
  2243. {
  2244. uint16 spreadArgCount = 0;
  2245. switch (m_token.tk)
  2246. {
  2247. case tkLParen:
  2248. {
  2249. if (fInNew)
  2250. {
  2251. ParseNodePtr pnodeArgs = ParseArgList<buildAST>(&callOfConstants, &spreadArgCount, &count);
  2252. if (buildAST)
  2253. {
  2254. Assert(pnode->nop == knopNew);
  2255. Assert(pnode->sxCall.pnodeArgs == nullptr);
  2256. pnode->sxCall.pnodeArgs = pnodeArgs;
  2257. pnode->sxCall.callOfConstants = callOfConstants;
  2258. pnode->sxCall.isApplyCall = false;
  2259. pnode->sxCall.isEvalCall = false;
  2260. pnode->sxCall.argCount = count;
  2261. pnode->sxCall.spreadArgCount = spreadArgCount;
  2262. pnode->ichLim = m_pscan->IchLimTok();
  2263. }
  2264. else
  2265. {
  2266. pToken->tk = tkNone; // This is no longer an identifier
  2267. }
  2268. fInNew = FALSE;
  2269. }
  2270. else
  2271. {
  2272. bool fCallIsEval = false;
  2273. if (!fAllowCall)
  2274. {
  2275. return pnode;
  2276. }
  2277. ParseNodePtr pnodeArgs = ParseArgList<buildAST>(&callOfConstants, &spreadArgCount, &count);
  2278. // We used to un-defer a deferred function body here if it was called as part of the expression that declared it.
  2279. // We now detect this case up front in ParseFncDecl, which is cheaper and simpler.
  2280. if (buildAST)
  2281. {
  2282. pnode = CreateCallNode(knopCall, pnode, pnodeArgs);
  2283. Assert(pnode);
  2284. // Detect call to "eval" and record it on the function.
  2285. // Note: we used to leave it up to the byte code generator to detect eval calls
  2286. // at global scope, but now it relies on the flag the parser sets, so set it here.
  2287. if (count > 0 && this->NodeIsEvalName(pnode->sxCall.pnodeTarget))
  2288. {
  2289. this->MarkEvalCaller();
  2290. fCallIsEval = true;
  2291. }
  2292. pnode->sxCall.callOfConstants = callOfConstants;
  2293. pnode->sxCall.spreadArgCount = spreadArgCount;
  2294. pnode->sxCall.isApplyCall = false;
  2295. pnode->sxCall.isEvalCall = fCallIsEval;
  2296. pnode->sxCall.argCount = count;
  2297. pnode->ichLim = m_pscan->IchLimTok();
  2298. }
  2299. else
  2300. {
  2301. if (pToken->tk == tkID && pToken->pid == wellKnownPropertyPids.eval) // Detect eval
  2302. {
  2303. this->MarkEvalCaller();
  2304. }
  2305. pToken->tk = tkNone; // This is no longer an identifier
  2306. }
  2307. }
  2308. ChkCurTok(tkRParen, ERRnoRparen);
  2309. if (pfCanAssign)
  2310. {
  2311. *pfCanAssign = FALSE;
  2312. }
  2313. break;
  2314. }
  2315. case tkLBrack:
  2316. {
  2317. m_pscan->Scan();
  2318. ParseNodePtr pnodeExpr = ParseExpr<buildAST>();
  2319. if (buildAST)
  2320. {
  2321. pnode = CreateBinNode(knopIndex, pnode, pnodeExpr);
  2322. pnode->ichLim = m_pscan->IchLimTok();
  2323. }
  2324. else
  2325. {
  2326. pToken->tk = tkNone; // This is no longer an identifier
  2327. }
  2328. ChkCurTok(tkRBrack, ERRnoRbrack);
  2329. if (pfCanAssign)
  2330. {
  2331. *pfCanAssign = TRUE;
  2332. }
  2333. if (!buildAST)
  2334. {
  2335. break;
  2336. }
  2337. bool shouldConvertToDot = false;
  2338. if (pnode->sxBin.pnode2->nop == knopStr)
  2339. {
  2340. // if the string is empty or contains escape character, we will not convert them to dot node
  2341. shouldConvertToDot = pnode->sxBin.pnode2->sxPid.pid->Cch() > 0 && !m_pscan->IsEscapeOnLastTkStrCon();
  2342. }
  2343. if (shouldConvertToDot)
  2344. {
  2345. LPCOLESTR str = pnode->sxBin.pnode2->sxPid.pid->Psz();
  2346. // See if we can convert o["p"] into o.p and o["0"] into o[0] since they're equivalent and the latter forms
  2347. // are faster
  2348. uint32 uintValue;
  2349. if(Js::JavascriptOperators::TryConvertToUInt32(
  2350. str,
  2351. pnode->sxBin.pnode2->sxPid.pid->Cch(),
  2352. &uintValue) &&
  2353. !Js::TaggedInt::IsOverflow(uintValue)) // the optimization is not very useful if the number can't be represented as a TaggedInt
  2354. {
  2355. // No need to verify that uintValue != JavascriptArray::InvalidIndex since all nonnegative TaggedInts are valid indexes
  2356. auto intNode = CreateIntNodeWithScanner(uintValue); // implicit conversion from uint32 to long
  2357. pnode->sxBin.pnode2 = intNode;
  2358. }
  2359. // Field optimization (see GlobOpt::KillLiveElems) checks for value being a Number,
  2360. // and since NaN/Infinity is a number it won't kill o.NaN/o.Infinity which would cause a problem
  2361. // if we decide to hoist o.NaN/o.Infinity.
  2362. // We need to keep o["NaN"] and o["+/-Infinity"] as array element access (we don't hoist that but we may hoist field access),
  2363. // so no matter if it's killed by o[x] inside a loop, we make sure that we never hoist these.
  2364. // We need to follow same logic for strings that convert to a floating point number.
  2365. else
  2366. {
  2367. bool doConvertToProperty = false; // Convert a["x"] -> a.x.
  2368. if (!Parser::IsNaNOrInfinityLiteral<true>(str))
  2369. {
  2370. const OLECHAR* terminalChar;
  2371. double dbl = Js::NumberUtilities::StrToDbl(str, &terminalChar, m_scriptContext);
  2372. bool convertsToFloat = !Js::NumberUtilities::IsNan(dbl);
  2373. doConvertToProperty = !convertsToFloat;
  2374. }
  2375. if (doConvertToProperty)
  2376. {
  2377. pnode->sxBin.pnode2->nop = knopName;
  2378. pnode->nop = knopDot;
  2379. pnode->grfpn |= PNodeFlags::fpnIndexOperator;
  2380. }
  2381. }
  2382. }
  2383. }
  2384. break;
  2385. case tkDot:
  2386. {
  2387. ParseNodePtr name = nullptr;
  2388. OpCode opCode = knopDot;
  2389. m_pscan->Scan();
  2390. if (!m_token.IsIdentifier())
  2391. {
  2392. //allow reserved words in ES5 mode
  2393. if (!(m_token.IsReservedWord()))
  2394. {
  2395. IdentifierExpectedError(m_token);
  2396. }
  2397. }
  2398. // Note: see comment above about field optimization WRT NaN/Infinity/-Infinity.
  2399. // Convert a.Nan, a.Infinity into a["NaN"], a["Infinity"].
  2400. // We don't care about -Infinity case here because x.-Infinity is invalid in JavaScript.
  2401. // Both NaN and Infinity are identifiers.
  2402. else if (buildAST && Parser::IsNaNOrInfinityLiteral<false>(m_token.GetIdentifier(m_phtbl)->Psz()))
  2403. {
  2404. opCode = knopIndex;
  2405. }
  2406. if (buildAST)
  2407. {
  2408. if (opCode == knopDot)
  2409. {
  2410. name = CreateNameNode(m_token.GetIdentifier(m_phtbl));
  2411. }
  2412. else
  2413. {
  2414. Assert(opCode == knopIndex);
  2415. name = CreateStrNodeWithScanner(m_token.GetIdentifier(m_phtbl));
  2416. }
  2417. pnode = CreateBinNode(opCode, pnode, name);
  2418. }
  2419. else
  2420. {
  2421. pToken->tk = tkNone;
  2422. }
  2423. if (pfCanAssign)
  2424. {
  2425. *pfCanAssign = TRUE;
  2426. }
  2427. m_pscan->Scan();
  2428. break;
  2429. }
  2430. case tkStrTmplBasic:
  2431. case tkStrTmplBegin:
  2432. {
  2433. Assert(m_scriptContext->GetConfig()->IsES6StringTemplateEnabled());
  2434. ParseNode* templateNode = ParseStringTemplateDecl<buildAST>(pnode);
  2435. if (!buildAST)
  2436. {
  2437. pToken->tk = tkNone; // This is no longer an identifier
  2438. }
  2439. pnode = templateNode;
  2440. if (pfCanAssign)
  2441. {
  2442. *pfCanAssign = FALSE;
  2443. }
  2444. break;
  2445. }
  2446. default:
  2447. return pnode;
  2448. }
  2449. }
  2450. }
  2451. /***************************************************************************
  2452. Look for an existing label with the given name.
  2453. ***************************************************************************/
  2454. ParseNodePtr Parser::PnodeLabel(IdentPtr pid, ParseNodePtr pnodeLabels)
  2455. {
  2456. AssertMem(pid);
  2457. AssertNodeMemN(pnodeLabels);
  2458. StmtNest *pstmt;
  2459. ParseNodePtr pnodeT;
  2460. // Look in the statement stack.
  2461. for (pstmt = m_pstmtCur; nullptr != pstmt; pstmt = pstmt->pstmtOuter)
  2462. {
  2463. AssertNodeMem(pstmt->pnodeStmt);
  2464. AssertNodeMemN(pstmt->pnodeLab);
  2465. for (pnodeT = pstmt->pnodeLab; nullptr != pnodeT;
  2466. pnodeT = pnodeT->sxLabel.pnodeNext)
  2467. {
  2468. Assert(knopLabel == pnodeT->nop);
  2469. if (pid == pnodeT->sxLabel.pid)
  2470. return pnodeT;
  2471. }
  2472. }
  2473. // Also look in the pnodeLabels list.
  2474. for (pnodeT = pnodeLabels; nullptr != pnodeT;
  2475. pnodeT = pnodeT->sxLabel.pnodeNext)
  2476. {
  2477. Assert(knopLabel == pnodeT->nop);
  2478. if (pid == pnodeT->sxLabel.pid)
  2479. return pnodeT;
  2480. }
  2481. return nullptr;
  2482. }
  2483. // Currently only ints and floats are treated as constants in function call
  2484. // TODO: Check if we need for other constants as well
  2485. BOOL Parser::IsConstantInFunctionCall(ParseNodePtr pnode)
  2486. {
  2487. if (pnode->nop == knopInt && !Js::TaggedInt::IsOverflow(pnode->sxInt.lw))
  2488. {
  2489. return TRUE;
  2490. }
  2491. if (pnode->nop == knopFlt)
  2492. {
  2493. return TRUE;
  2494. }
  2495. return FALSE;
  2496. }
  2497. /***************************************************************************
  2498. Parse a list of arguments.
  2499. ***************************************************************************/
  2500. template<bool buildAST>
  2501. ParseNodePtr Parser::ParseArgList( bool *pCallOfConstants, uint16 *pSpreadArgCount, uint16 * pCount)
  2502. {
  2503. ParseNodePtr pnodeArg;
  2504. ParseNodePtr pnodeList = nullptr;
  2505. ParseNodePtr *lastNodeRef = nullptr;
  2506. // Check for an empty list
  2507. Assert(m_token.tk == tkLParen);
  2508. if (m_pscan->Scan() == tkRParen)
  2509. {
  2510. return nullptr;
  2511. }
  2512. *pCallOfConstants = true;
  2513. *pSpreadArgCount = 0;
  2514. int count=0;
  2515. while (true)
  2516. {
  2517. // the count of arguments has to fit in an unsigned short
  2518. if (count > 0xffffU)
  2519. Error(ERRnoMemory);
  2520. // Allow spread in argument lists.
  2521. pnodeArg = ParseExpr<buildAST>(koplCma, nullptr, TRUE, /* fAllowEllipsis */TRUE);
  2522. if (buildAST)
  2523. {
  2524. this->CheckArguments(pnodeArg);
  2525. if (*pCallOfConstants && !IsConstantInFunctionCall(pnodeArg))
  2526. {
  2527. *pCallOfConstants = false;
  2528. }
  2529. if (pnodeArg->nop == knopEllipsis)
  2530. {
  2531. (*pSpreadArgCount)++;
  2532. }
  2533. ++count;
  2534. AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeArg);
  2535. }
  2536. if (m_token.tk != tkComma)
  2537. {
  2538. break;
  2539. }
  2540. m_pscan->Scan();
  2541. if (m_token.tk == tkRParen && m_scriptContext->GetConfig()->IsES7TrailingCommaEnabled())
  2542. {
  2543. break;
  2544. }
  2545. }
  2546. if (pSpreadArgCount!=nullptr && (*pSpreadArgCount) > 0){
  2547. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(SpreadFeatureCount, m_scriptContext);
  2548. }
  2549. if (buildAST)
  2550. {
  2551. *pCount = (uint16)count;
  2552. AssertMem(lastNodeRef);
  2553. AssertNodeMem(*lastNodeRef);
  2554. pnodeList->ichLim = (*lastNodeRef)->ichLim;
  2555. }
  2556. return pnodeList;
  2557. }
  2558. // Currently only ints are treated as constants in ArrayLiterals
  2559. BOOL Parser::IsConstantInArrayLiteral(ParseNodePtr pnode)
  2560. {
  2561. if (pnode->nop == knopInt && !Js::TaggedInt::IsOverflow(pnode->sxInt.lw))
  2562. {
  2563. return TRUE;
  2564. }
  2565. return FALSE;
  2566. }
  2567. template<bool buildAST>
  2568. ParseNodePtr Parser::ParseArrayLiteral()
  2569. {
  2570. ParseNodePtr pnode = nullptr;
  2571. bool arrayOfTaggedInts = false;
  2572. bool arrayOfInts = false;
  2573. bool arrayOfNumbers = false;
  2574. bool hasMissingValues = false;
  2575. uint count = 0;
  2576. uint spreadCount = 0;
  2577. ParseNodePtr pnode1 = ParseArrayList<buildAST>(&arrayOfTaggedInts, &arrayOfInts, &arrayOfNumbers, &hasMissingValues, &count, &spreadCount);
  2578. if (buildAST)
  2579. {
  2580. pnode = CreateNodeWithScanner<knopArray>();
  2581. pnode->sxArrLit.pnode1 = pnode1;
  2582. pnode->sxArrLit.arrayOfTaggedInts = arrayOfTaggedInts;
  2583. pnode->sxArrLit.arrayOfInts = arrayOfInts;
  2584. pnode->sxArrLit.arrayOfNumbers = arrayOfNumbers;
  2585. pnode->sxArrLit.hasMissingValues = hasMissingValues;
  2586. pnode->sxArrLit.count = count;
  2587. pnode->sxArrLit.spreadCount = spreadCount;
  2588. if (pnode->sxArrLit.pnode1)
  2589. {
  2590. this->CheckArguments(pnode->sxArrLit.pnode1);
  2591. }
  2592. }
  2593. return pnode;
  2594. }
  2595. /***************************************************************************
  2596. Create an ArrayLiteral node
  2597. Parse a list of array elements. [ a, b, , c, ]
  2598. ***************************************************************************/
  2599. template<bool buildAST>
  2600. ParseNodePtr Parser::ParseArrayList(bool *pArrayOfTaggedInts, bool *pArrayOfInts, bool *pArrayOfNumbers, bool *pHasMissingValues, uint *count, uint *spreadCount)
  2601. {
  2602. ParseNodePtr pnodeArg = nullptr;
  2603. ParseNodePtr pnodeList = nullptr;
  2604. ParseNodePtr *lastNodeRef = nullptr;
  2605. *count = 0;
  2606. // Check for an empty list
  2607. if (tkRBrack == m_token.tk)
  2608. {
  2609. return nullptr;
  2610. }
  2611. this->m_arrayDepth++;
  2612. bool arrayOfTaggedInts = buildAST;
  2613. bool arrayOfInts = buildAST;
  2614. bool arrayOfNumbers = buildAST;
  2615. bool arrayOfVarInts = false;
  2616. bool hasMissingValues = false;
  2617. for (;;)
  2618. {
  2619. (*count)++;
  2620. if (tkComma == m_token.tk || tkRBrack == m_token.tk)
  2621. {
  2622. hasMissingValues = true;
  2623. arrayOfTaggedInts = false;
  2624. arrayOfInts = false;
  2625. arrayOfNumbers = false;
  2626. if (buildAST)
  2627. {
  2628. pnodeArg = CreateNodeWithScanner<knopEmpty>();
  2629. }
  2630. }
  2631. else
  2632. {
  2633. // Allow Spread in array literals.
  2634. pnodeArg = ParseExpr<buildAST>(koplCma, nullptr, TRUE, /* fAllowEllipsis */ TRUE);
  2635. if (buildAST)
  2636. {
  2637. if (pnodeArg->nop == knopEllipsis)
  2638. {
  2639. (*spreadCount)++;
  2640. }
  2641. this->CheckArguments(pnodeArg);
  2642. }
  2643. }
  2644. #if DEBUG
  2645. if(m_grfscr & fscrEnforceJSON && !IsJSONValid(pnodeArg))
  2646. {
  2647. Error(ERRsyntax);
  2648. }
  2649. #endif
  2650. if (buildAST)
  2651. {
  2652. if (arrayOfNumbers)
  2653. {
  2654. if (pnodeArg->nop != knopInt)
  2655. {
  2656. arrayOfTaggedInts = false;
  2657. if (pnodeArg->nop != knopFlt)
  2658. {
  2659. // Not an array of constants.
  2660. arrayOfInts = false;
  2661. arrayOfNumbers = false;
  2662. }
  2663. else if (arrayOfInts && Js::JavascriptNumber::IsInt32OrUInt32(pnodeArg->sxFlt.dbl) && (!Js::JavascriptNumber::IsInt32(pnodeArg->sxFlt.dbl) || pnodeArg->sxFlt.dbl == -2147483648.0))
  2664. {
  2665. // We've seen nothing but ints, and this is a uint32 but not an int32.
  2666. // Unless we see an actual float at some point, we want an array of vars
  2667. // so we can work with tagged ints.
  2668. arrayOfVarInts = true;
  2669. }
  2670. else
  2671. {
  2672. // Not an int array, but it may still be a float array.
  2673. arrayOfInts = false;
  2674. }
  2675. }
  2676. else
  2677. {
  2678. if (Js::SparseArraySegment<int32>::IsMissingItem((int32*)&pnodeArg->sxInt.lw))
  2679. {
  2680. arrayOfInts = false;
  2681. }
  2682. if (Js::TaggedInt::IsOverflow(pnodeArg->sxInt.lw))
  2683. {
  2684. arrayOfTaggedInts = false;
  2685. }
  2686. }
  2687. }
  2688. AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeArg);
  2689. }
  2690. if (tkComma != m_token.tk)
  2691. {
  2692. break;
  2693. }
  2694. m_pscan->Scan();
  2695. if (tkRBrack == m_token.tk)
  2696. {
  2697. break;
  2698. }
  2699. }
  2700. if (spreadCount != nullptr && *spreadCount > 0){
  2701. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(SpreadFeatureCount, m_scriptContext);
  2702. }
  2703. if (buildAST)
  2704. {
  2705. AssertMem(lastNodeRef);
  2706. AssertNodeMem(*lastNodeRef);
  2707. pnodeList->ichLim = (*lastNodeRef)->ichLim;
  2708. if (arrayOfVarInts && arrayOfInts)
  2709. {
  2710. arrayOfInts = false;
  2711. arrayOfNumbers = false;
  2712. }
  2713. *pArrayOfTaggedInts = arrayOfTaggedInts;
  2714. *pArrayOfInts = arrayOfInts;
  2715. *pArrayOfNumbers = arrayOfNumbers;
  2716. *pHasMissingValues = hasMissingValues;
  2717. }
  2718. this->m_arrayDepth--;
  2719. return pnodeList;
  2720. }
  2721. Parser::MemberNameToTypeMap* Parser::CreateMemberNameMap(ArenaAllocator* pAllocator)
  2722. {
  2723. Assert(pAllocator);
  2724. return Anew(pAllocator, MemberNameToTypeMap, pAllocator, 5);
  2725. }
  2726. template<bool buildAST> void Parser::ParseComputedName(ParseNodePtr* ppnodeName, LPCOLESTR* ppNameHint, LPCOLESTR* ppFullNameHint, ulong *pNameLength, ulong *pShortNameOffset)
  2727. {
  2728. m_pscan->Scan();
  2729. ParseNodePtr pnodeNameExpr = ParseExpr<buildAST>(koplNo, nullptr, TRUE, FALSE, *ppNameHint, pNameLength, pShortNameOffset);
  2730. if (buildAST)
  2731. {
  2732. *ppnodeName = CreateNodeT<knopComputedName>(pnodeNameExpr->ichMin, pnodeNameExpr->ichLim);
  2733. (*ppnodeName)->sxUni.pnode1 = pnodeNameExpr;
  2734. }
  2735. if (ppFullNameHint && buildAST && CONFIG_FLAG(UseFullName))
  2736. {
  2737. *ppFullNameHint = FormatPropertyString(*ppNameHint, pnodeNameExpr, pNameLength, pShortNameOffset);
  2738. }
  2739. ChkCurTokNoScan(tkRBrack, ERRsyntax);
  2740. }
  2741. /***************************************************************************
  2742. Parse a list of object set/get members, e.g.:
  2743. { get foo(){ ... }, set bar(arg) { ... } }
  2744. ***************************************************************************/
  2745. template<bool buildAST>
  2746. ParseNodePtr Parser::ParseMemberGetSet(OpCode nop, LPCOLESTR* ppNameHint)
  2747. {
  2748. ParseNodePtr pnodeName = nullptr;
  2749. Assert(nop == knopGetMember || nop == knopSetMember);
  2750. AssertMem(ppNameHint);
  2751. IdentPtr pid = nullptr;
  2752. bool isComputedName = false;
  2753. *ppNameHint=nullptr;
  2754. switch(m_token.tk)
  2755. {
  2756. default:
  2757. if (!m_token.IsReservedWord())
  2758. {
  2759. Error(ERRnoMemberIdent);
  2760. }
  2761. // fall through
  2762. case tkID:
  2763. pid = m_token.GetIdentifier(m_phtbl);
  2764. *ppNameHint = pid->Psz();
  2765. if (buildAST)
  2766. {
  2767. pnodeName = CreateStrNodeWithScanner(pid);
  2768. }
  2769. break;
  2770. case tkStrCon:
  2771. if (IsStrictMode() && m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  2772. {
  2773. Error(ERRES5NoOctal);
  2774. }
  2775. pid = m_token.GetStr();
  2776. *ppNameHint = pid->Psz();
  2777. if (buildAST)
  2778. {
  2779. pnodeName = CreateStrNodeWithScanner(pid);
  2780. }
  2781. break;
  2782. case tkIntCon:
  2783. if (IsStrictMode() && m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  2784. {
  2785. Error(ERRES5NoOctal);
  2786. }
  2787. pid = m_pscan->PidFromLong(m_token.GetLong());
  2788. if (buildAST)
  2789. {
  2790. pnodeName = CreateStrNodeWithScanner(pid);
  2791. }
  2792. break;
  2793. case tkFltCon:
  2794. if (IsStrictMode() && m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  2795. {
  2796. Error(ERRES5NoOctal);
  2797. }
  2798. pid = m_pscan->PidFromDbl(m_token.GetDouble());
  2799. if (buildAST)
  2800. {
  2801. pnodeName = CreateStrNodeWithScanner(pid);
  2802. }
  2803. break;
  2804. case tkLBrack:
  2805. // Computed property name: get|set [expr] () { }
  2806. if (!m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
  2807. {
  2808. Error(ERRnoMemberIdent);
  2809. }
  2810. LPCOLESTR emptyHint = nullptr;
  2811. ulong offset = 0;
  2812. ParseComputedName<buildAST>(&pnodeName, &emptyHint, ppNameHint, &offset);
  2813. isComputedName = true;
  2814. break;
  2815. }
  2816. MemberType memberType;
  2817. ushort flags;
  2818. if(nop == knopGetMember)
  2819. {
  2820. memberType = MemberTypeGetter;
  2821. flags = fFncNoArg | fFncNoName;
  2822. }
  2823. else
  2824. {
  2825. Assert(nop == knopSetMember);
  2826. memberType = MemberTypeSetter;
  2827. flags = fFncOneArg | fFncNoName;
  2828. }
  2829. this->m_parsingSuperRestrictionState = ParsingSuperRestrictionState_SuperPropertyAllowed;
  2830. ParseNodePtr pnodeFnc = ParseFncDecl<buildAST>(flags | fFncMethod | (nop == knopSetMember ? fFncSetter : fFncNoFlgs), *ppNameHint,
  2831. /*isSourceElement*/ false, /*needsPIDOnRCurlyScan*/ false, /*resetParsingSuperRestrictionState*/ false);
  2832. if (buildAST)
  2833. {
  2834. pnodeFnc->sxFnc.SetIsAccessor();
  2835. return CreateBinNode(nop, pnodeName, pnodeFnc);
  2836. }
  2837. else
  2838. {
  2839. return nullptr;
  2840. }
  2841. }
  2842. /***************************************************************************
  2843. Parse a list of object members. e.g. { x:foo, 'y me':bar }
  2844. ***************************************************************************/
  2845. template<bool buildAST>
  2846. ParseNodePtr Parser::ParseMemberList(LPCOLESTR pNameHint, ulong* pNameHintLength, tokens declarationType)
  2847. {
  2848. ParseNodePtr pnodeArg;
  2849. ParseNodePtr pnodeName = nullptr;
  2850. ParseNodePtr pnodeList = nullptr;
  2851. ParseNodePtr *lastNodeRef = nullptr;
  2852. LPCOLESTR pFullNameHint = nullptr; // A calculated full name
  2853. ulong fullNameHintLength = pNameHintLength ? *pNameHintLength : 0;
  2854. ulong shortNameOffset = 0;
  2855. bool isProtoDeclared = false;
  2856. // we get declaration tkLCurly - when the possible object pattern found under the expression.
  2857. bool isObjectPattern = (declarationType == tkVAR || declarationType == tkLET || declarationType == tkCONST || declarationType == tkLCurly) && IsES6DestructuringEnabled();
  2858. // Check for an empty list
  2859. if (tkRCurly == m_token.tk)
  2860. {
  2861. return nullptr;
  2862. }
  2863. ArenaAllocator tempAllocator(L"MemberNames", m_nodeAllocator.GetPageAllocator(), Parser::OutOfMemory);
  2864. for (;;)
  2865. {
  2866. bool isComputedName = false;
  2867. #if DEBUG
  2868. if((m_grfscr & fscrEnforceJSON) && (tkStrCon != m_token.tk || !(m_pscan->IsDoubleQuoteOnLastTkStrCon())))
  2869. {
  2870. Error(ERRsyntax);
  2871. }
  2872. #endif
  2873. bool isAsyncMethod = false;
  2874. charcount_t ichMin = 0;
  2875. size_t iecpMin = 0;
  2876. if (m_token.tk == tkID && m_token.GetIdentifier(m_phtbl) == wellKnownPropertyPids.async && m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
  2877. {
  2878. RestorePoint parsedAsync;
  2879. m_pscan->Capture(&parsedAsync);
  2880. ichMin = m_pscan->IchMinTok();
  2881. iecpMin = m_pscan->IecpMinTok();
  2882. m_pscan->ScanForcingPid();
  2883. if (m_token.tk == tkLParen || m_token.tk == tkColon || m_token.tk == tkRCurly || m_pscan->FHadNewLine())
  2884. {
  2885. m_pscan->SeekTo(parsedAsync);
  2886. }
  2887. else
  2888. {
  2889. isAsyncMethod = true;
  2890. }
  2891. }
  2892. bool isGenerator = m_scriptContext->GetConfig()->IsES6GeneratorsEnabled() &&
  2893. m_token.tk == tkStar;
  2894. ushort fncDeclFlags = fFncNoName | fFncMethod;
  2895. if (isGenerator)
  2896. {
  2897. if (isAsyncMethod)
  2898. {
  2899. Error(ERRsyntax);
  2900. }
  2901. m_pscan->ScanForcingPid();
  2902. fncDeclFlags |= fFncGenerator;
  2903. }
  2904. IdentPtr pidHint = nullptr; // A name scoped to current expression
  2905. Token tkHint = m_token;
  2906. charcount_t idHintIchMin = static_cast<charcount_t>(m_pscan->IecpMinTok());
  2907. charcount_t idHintIchLim = static_cast< charcount_t >(m_pscan->IecpLimTok());
  2908. bool wrapInBrackets = false;
  2909. switch (m_token.tk)
  2910. {
  2911. default:
  2912. if (!m_token.IsReservedWord())
  2913. {
  2914. Error(ERRnoMemberIdent);
  2915. }
  2916. // allow reserved words
  2917. wrapInBrackets = true;
  2918. // fall-through
  2919. case tkID:
  2920. pidHint = m_token.GetIdentifier(m_phtbl);
  2921. if (buildAST)
  2922. {
  2923. pnodeName = CreateStrNodeWithScanner(pidHint);
  2924. }
  2925. break;
  2926. case tkStrCon:
  2927. if (IsStrictMode() && m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  2928. {
  2929. Error(ERRES5NoOctal);
  2930. }
  2931. wrapInBrackets = true;
  2932. pidHint = m_token.GetStr();
  2933. if (buildAST)
  2934. {
  2935. pnodeName = CreateStrNodeWithScanner(pidHint);
  2936. }
  2937. break;
  2938. case tkIntCon:
  2939. // Object initializers with numeric labels allowed in JS6
  2940. if (IsStrictMode() && m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  2941. {
  2942. Error(ERRES5NoOctal);
  2943. }
  2944. pidHint = m_pscan->PidFromLong(m_token.GetLong());
  2945. if (buildAST)
  2946. {
  2947. pnodeName = CreateStrNodeWithScanner(pidHint);
  2948. }
  2949. break;
  2950. case tkFltCon:
  2951. if (IsStrictMode() && m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  2952. {
  2953. Error(ERRES5NoOctal);
  2954. }
  2955. pidHint = m_pscan->PidFromDbl(m_token.GetDouble());
  2956. if (buildAST)
  2957. {
  2958. pnodeName = CreateStrNodeWithScanner(pidHint);
  2959. }
  2960. wrapInBrackets = true;
  2961. break;
  2962. case tkLBrack:
  2963. // Computed property name: [expr] : value
  2964. if (!m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
  2965. {
  2966. Error(ERRnoMemberIdent);
  2967. }
  2968. ParseComputedName<buildAST>(&pnodeName, &pNameHint, &pFullNameHint, &fullNameHintLength, &shortNameOffset);
  2969. isComputedName = true;
  2970. break;
  2971. }
  2972. if (pFullNameHint == nullptr)
  2973. {
  2974. if (CONFIG_FLAG(UseFullName))
  2975. {
  2976. pFullNameHint = AppendNameHints(pNameHint, pidHint, &fullNameHintLength, &shortNameOffset, false, wrapInBrackets);
  2977. }
  2978. else
  2979. {
  2980. pFullNameHint = pidHint? pidHint->Psz() : nullptr;
  2981. fullNameHintLength = pidHint ? pidHint->Cch() : 0;
  2982. shortNameOffset = 0;
  2983. }
  2984. }
  2985. RestorePoint atPid;
  2986. m_pscan->Capture(&atPid);
  2987. m_pscan->ScanForcingPid();
  2988. if (isGenerator && m_token.tk != tkLParen)
  2989. {
  2990. Error(ERRnoLparen);
  2991. }
  2992. if (tkColon == m_token.tk)
  2993. {
  2994. // It is a syntax error is the production of the form __proto__ : <> occurs more than once. From B.3.1 in spec.
  2995. // Note that previous scan is important because only after that we can determine we have a variable.
  2996. if (!isComputedName && pidHint == wellKnownPropertyPids.__proto__)
  2997. {
  2998. if (isProtoDeclared)
  2999. {
  3000. Error(ERRsyntax);
  3001. }
  3002. else
  3003. {
  3004. isProtoDeclared = true;
  3005. }
  3006. }
  3007. m_pscan->Scan();
  3008. ParseNodePtr pnodeExpr = nullptr;
  3009. if (isObjectPattern)
  3010. {
  3011. pnodeExpr = ParseDestructuredVarDecl<buildAST>(declarationType, declarationType != tkLCurly, nullptr/* *hasSeenRest*/, false /*topLevel*/);
  3012. if (m_token.tk != tkComma && m_token.tk != tkRCurly)
  3013. {
  3014. if (m_token.IsOperator())
  3015. {
  3016. Error(ERRDestructNoOper);
  3017. }
  3018. Error(ERRsyntax);
  3019. }
  3020. }
  3021. else
  3022. {
  3023. pnodeExpr = ParseExpr<buildAST>(koplCma, nullptr, TRUE, FALSE, pFullNameHint, &fullNameHintLength, &shortNameOffset);
  3024. }
  3025. #if DEBUG
  3026. if((m_grfscr & fscrEnforceJSON) && !IsJSONValid(pnodeExpr))
  3027. {
  3028. Error(ERRsyntax);
  3029. }
  3030. #endif
  3031. if (buildAST)
  3032. {
  3033. pnodeArg = CreateBinNode(isObjectPattern ? knopObjectPatternMember : knopMember, pnodeName, pnodeExpr);
  3034. if (pnodeArg->sxBin.pnode1->nop == knopStr)
  3035. {
  3036. pnodeArg->sxBin.pnode1->sxPid.pid->PromoteAssignmentState();
  3037. }
  3038. }
  3039. }
  3040. else if (m_token.tk == tkLParen && m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
  3041. {
  3042. if (isObjectPattern)
  3043. {
  3044. Error(ERRInvalidAssignmentTarget);
  3045. }
  3046. // Shorthand syntax: foo() {} -> foo: function() {}
  3047. // Rewind to the PID and parse a function expression.
  3048. m_pscan->SeekTo(atPid);
  3049. this->m_parsingSuperRestrictionState = ParsingSuperRestrictionState_SuperPropertyAllowed;
  3050. ParseNodePtr pnodeFunc = ParseFncDecl<buildAST>(fncDeclFlags | (isAsyncMethod ? fFncAsync : fFncNoFlgs), pFullNameHint,
  3051. /*isSourceElement*/ false, /*needsPIDOnRCurlyScan*/ false, /*resetParsingSuperRestrictionState*/ false);
  3052. if (isAsyncMethod)
  3053. {
  3054. pnodeFunc->sxFnc.cbMin = iecpMin;
  3055. pnodeFunc->ichMin = ichMin;
  3056. }
  3057. if (buildAST)
  3058. {
  3059. pnodeArg = CreateBinNode(knopMember, pnodeName, pnodeFunc);
  3060. }
  3061. }
  3062. else if (nullptr != pidHint) //Its either tkID/tkStrCon/tkFloatCon/tkIntCon
  3063. {
  3064. Assert(pidHint->Psz() != nullptr);
  3065. if (pidHint == wellKnownPropertyPids.getter && tkHint.tk == tkID)
  3066. {
  3067. if (isObjectPattern)
  3068. {
  3069. Error(ERRInvalidAssignmentTarget);
  3070. }
  3071. LPCOLESTR pNameGet = nullptr;
  3072. pnodeArg = ParseMemberGetSet<buildAST>(knopGetMember, &pNameGet);
  3073. if (CONFIG_FLAG(UseFullName) && buildAST && pnodeArg->sxBin.pnode2->nop == knopFncDecl)
  3074. {
  3075. if (m_scriptContext->GetConfig()->IsES6FunctionNameEnabled())
  3076. {
  3077. // displays as get object.funcname
  3078. ulong getOffset = 0;
  3079. pFullNameHint = AppendNameHints(wellKnownPropertyPids.getter, AppendNameHints(pNameHint, pNameGet, &fullNameHintLength, &shortNameOffset), &fullNameHintLength, &getOffset, true);
  3080. shortNameOffset += getOffset;
  3081. }
  3082. else
  3083. {
  3084. // displays as object.funcname.get
  3085. pFullNameHint = AppendNameHints(pNameHint, AppendNameHints(pNameGet, wellKnownPropertyPids.getter, &fullNameHintLength, &shortNameOffset), &fullNameHintLength, &shortNameOffset);
  3086. }
  3087. }
  3088. }
  3089. else if (pidHint == wellKnownPropertyPids.setter && tkHint.tk == tkID)
  3090. {
  3091. if (isObjectPattern)
  3092. {
  3093. Error(ERRInvalidAssignmentTarget);
  3094. }
  3095. LPCOLESTR pNameSet = nullptr;
  3096. pnodeArg = ParseMemberGetSet<buildAST>(knopSetMember, &pNameSet);
  3097. if (CONFIG_FLAG(UseFullName) && buildAST && pnodeArg->sxBin.pnode2->nop == knopFncDecl)
  3098. {
  3099. if (m_scriptContext->GetConfig()->IsES6FunctionNameEnabled())
  3100. {
  3101. // displays as set object.funcname
  3102. ulong setOffset = 0;
  3103. pFullNameHint = AppendNameHints(wellKnownPropertyPids.setter, AppendNameHints(pNameHint, pNameSet, &fullNameHintLength, &shortNameOffset), &fullNameHintLength, &setOffset, true);
  3104. shortNameOffset += setOffset;
  3105. }
  3106. else
  3107. {
  3108. // displays as object.funcname.set
  3109. pFullNameHint = AppendNameHints(pNameHint, AppendNameHints(pNameSet, wellKnownPropertyPids.setter, &fullNameHintLength, &shortNameOffset), &fullNameHintLength, &shortNameOffset);
  3110. }
  3111. }
  3112. }
  3113. else if ((m_token.tk == tkRCurly || m_token.tk == tkComma || (isObjectPattern && m_token.tk == tkAsg)) && m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
  3114. {
  3115. // Shorthand {foo} -> {foo:foo} syntax.
  3116. // {foo = <initializer>} supported only when on object pattern rules are being applied
  3117. if (tkHint.tk != tkID)
  3118. {
  3119. Assert(tkHint.IsReservedWord()
  3120. || tkHint.tk == tkIntCon || tkHint.tk == tkFltCon || tkHint.tk == tkStrCon);
  3121. // All keywords are banned in non-strict mode.
  3122. // Future reserved words are banned in strict mode.
  3123. if (IsStrictMode() || !tkHint.IsFutureReservedWord(true))
  3124. {
  3125. IdentifierExpectedError(tkHint);
  3126. }
  3127. }
  3128. if (buildAST)
  3129. {
  3130. CheckArgumentsUse(pidHint, GetCurrentFunctionNode());
  3131. }
  3132. ParseNodePtr pnodeIdent = nullptr;
  3133. if (isObjectPattern)
  3134. {
  3135. m_pscan->SeekTo(atPid);
  3136. pnodeIdent = ParseDestructuredVarDecl<buildAST>(declarationType, declarationType != tkLCurly, nullptr/* *hasSeenRest*/, false /*topLevel*/);
  3137. if (m_token.tk != tkComma && m_token.tk != tkRCurly)
  3138. {
  3139. if (m_token.IsOperator())
  3140. {
  3141. Error(ERRDestructNoOper);
  3142. }
  3143. Error(ERRsyntax);
  3144. }
  3145. }
  3146. if (buildAST)
  3147. {
  3148. if (!isObjectPattern)
  3149. {
  3150. pnodeIdent = CreateNameNode(pidHint, idHintIchMin, idHintIchLim);
  3151. PidRefStack *ref = PushPidRef(pidHint);
  3152. pnodeIdent->sxPid.SetSymRef(ref);
  3153. }
  3154. pnodeArg = CreateBinNode(isObjectPattern ? knopObjectPatternMember : knopMemberShort, pnodeName, pnodeIdent);
  3155. }
  3156. }
  3157. else
  3158. {
  3159. Error(ERRnoColon);
  3160. }
  3161. }
  3162. else
  3163. {
  3164. Error(ERRnoColon);
  3165. }
  3166. if (buildAST)
  3167. {
  3168. Assert(pnodeArg->sxBin.pnode2 != nullptr);
  3169. if (pnodeArg->sxBin.pnode2->nop == knopFncDecl)
  3170. {
  3171. Assert(fullNameHintLength >= shortNameOffset);
  3172. pnodeArg->sxBin.pnode2->sxFnc.hint = pFullNameHint;
  3173. pnodeArg->sxBin.pnode2->sxFnc.hintLength = fullNameHintLength;
  3174. pnodeArg->sxBin.pnode2->sxFnc.hintOffset = shortNameOffset;
  3175. }
  3176. AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeArg);
  3177. }
  3178. pidHint = nullptr;
  3179. pFullNameHint = nullptr;
  3180. if (tkComma != m_token.tk)
  3181. {
  3182. break;
  3183. }
  3184. m_pscan->ScanForcingPid();
  3185. if (tkRCurly == m_token.tk)
  3186. {
  3187. break;
  3188. }
  3189. }
  3190. if (buildAST)
  3191. {
  3192. AssertMem(lastNodeRef);
  3193. AssertNodeMem(*lastNodeRef);
  3194. pnodeList->ichLim = (*lastNodeRef)->ichLim;
  3195. }
  3196. return pnodeList;
  3197. }
  3198. BOOL Parser::DeferredParse(Js::LocalFunctionId functionId)
  3199. {
  3200. if ((m_grfscr & fscrDeferFncParse) != 0)
  3201. {
  3202. if (m_stoppedDeferredParse)
  3203. {
  3204. return false;
  3205. }
  3206. if (PHASE_OFF_RAW(Js::DeferParsePhase, m_sourceContextInfo->sourceContextId, functionId))
  3207. {
  3208. return false;
  3209. }
  3210. if (PHASE_FORCE_RAW(Js::DeferParsePhase, m_sourceContextInfo->sourceContextId, functionId))
  3211. {
  3212. return true;
  3213. }
  3214. #if ENABLE_PROFILE_INFO
  3215. #ifndef DISABLE_DYNAMIC_PROFILE_DEFER_PARSE
  3216. if (m_sourceContextInfo->sourceDynamicProfileManager != nullptr)
  3217. {
  3218. Js::ExecutionFlags flags = m_sourceContextInfo->sourceDynamicProfileManager->IsFunctionExecuted(functionId);
  3219. return flags != Js::ExecutionFlags_Executed;
  3220. }
  3221. #endif
  3222. #endif
  3223. return true;
  3224. }
  3225. return false;
  3226. }
  3227. //
  3228. // Call this in ParseFncDecl only to check (and reset) if ParseFncDecl is re-parsing a deferred
  3229. // function body. If a deferred function is called and being re-parsed, it shouldn't be deferred again.
  3230. //
  3231. BOOL Parser::IsDeferredFnc()
  3232. {
  3233. if (m_grfscr & fscrDeferredFnc)
  3234. {
  3235. m_grfscr &= ~fscrDeferredFnc;
  3236. return true;
  3237. }
  3238. return false;
  3239. }
  3240. template<bool buildAST>
  3241. ParseNodePtr Parser::ParseFncDecl(ushort flags, LPCOLESTR pNameHint, const bool isSourceElement, const bool needsPIDOnRCurlyScan, bool resetParsingSuperRestrictionState, bool fUnaryOrParen)
  3242. {
  3243. AutoParsingSuperRestrictionStateRestorer restorer(this);
  3244. if (resetParsingSuperRestrictionState)
  3245. {
  3246. // ParseFncDecl will always reset m_parsingSuperRestrictionState to super disallowed unless explicitly disabled
  3247. this->m_parsingSuperRestrictionState = ParsingSuperRestrictionState_SuperDisallowed;
  3248. }
  3249. ParseNodePtr pnodeFnc = nullptr;
  3250. ParseNodePtr *ppnodeVarSave = nullptr;
  3251. ParseNodePtr pnodeFncSave = nullptr;
  3252. ParseNodePtr pnodeFncSaveNonLambda = nullptr;
  3253. ParseNodePtr pnodeFncBlockScope = nullptr;
  3254. ParseNodePtr *ppnodeScopeSave = nullptr;
  3255. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  3256. bool funcHasName = false;
  3257. bool fDeclaration = flags & fFncDeclaration;
  3258. bool fLambda = (flags & fFncLambda) != 0;
  3259. charcount_t ichMin = this->m_pscan->IchMinTok();
  3260. bool wasInDeferredNestedFunc = false;
  3261. CatchPidRefList *catchPidRefList = nullptr;
  3262. uint tryCatchOrFinallyDepthSave = this->m_tryCatchOrFinallyDepth;
  3263. this->m_tryCatchOrFinallyDepth = 0;
  3264. CheckStrictModeFncDeclNotSourceElement(isSourceElement, fDeclaration);
  3265. if (this->m_arrayDepth)
  3266. {
  3267. this->m_funcInArrayDepth++; // Count function depth within array literal
  3268. }
  3269. // Update the count of functions nested in the current parent.
  3270. Assert(m_pnestedCount || !buildAST);
  3271. uint *pnestedCountSave = m_pnestedCount;
  3272. if (buildAST || m_pnestedCount)
  3273. {
  3274. (*m_pnestedCount)++;
  3275. }
  3276. uint scopeCountNoAstSave = m_scopeCountNoAst;
  3277. m_scopeCountNoAst = 0;
  3278. long* pAstSizeSave = m_pCurrentAstSize;
  3279. bool noStmtContext = false;
  3280. if (buildAST || BindDeferredPidRefs())
  3281. {
  3282. if (fDeclaration && m_scriptContext->GetConfig()->IsBlockScopeEnabled())
  3283. {
  3284. noStmtContext =
  3285. (m_pstmtCur->isDeferred && m_pstmtCur->op != knopBlock) ||
  3286. (!m_pstmtCur->isDeferred && m_pstmtCur->pnodeStmt->nop != knopBlock);
  3287. if (noStmtContext)
  3288. {
  3289. // We have a function declaration like "if (a) function f() {}". We didn't see
  3290. // a block scope on the way in, so we need to pretend we did. Note that this is a syntax error
  3291. // in strict mode.
  3292. if (!this->FncDeclAllowedWithoutContext(flags))
  3293. {
  3294. Error(ERRsyntax);
  3295. }
  3296. pnodeFncBlockScope = StartParseBlock<buildAST>(PnodeBlockType::Regular, ScopeType_Block);
  3297. if (buildAST)
  3298. {
  3299. PushFuncBlockScope(pnodeFncBlockScope, &ppnodeScopeSave, &ppnodeExprScopeSave);
  3300. }
  3301. }
  3302. }
  3303. // Create the node.
  3304. pnodeFnc = CreateNode(knopFncDecl);
  3305. pnodeFnc->sxFnc.ClearFlags();
  3306. pnodeFnc->sxFnc.SetDeclaration(fDeclaration);
  3307. pnodeFnc->sxFnc.astSize = 0;
  3308. pnodeFnc->sxFnc.pnodeName = nullptr;
  3309. pnodeFnc->sxFnc.pnodeScopes = nullptr;
  3310. pnodeFnc->sxFnc.pnodeRest = nullptr;
  3311. pnodeFnc->sxFnc.pid = nullptr;
  3312. pnodeFnc->sxFnc.hint = nullptr;
  3313. pnodeFnc->sxFnc.hintOffset = 0;
  3314. pnodeFnc->sxFnc.hintLength = 0;
  3315. pnodeFnc->sxFnc.isNameIdentifierRef = true;
  3316. pnodeFnc->sxFnc.pnodeNext = nullptr;
  3317. pnodeFnc->sxFnc.pnodeArgs = nullptr;
  3318. pnodeFnc->sxFnc.pnodeVars = nullptr;
  3319. pnodeFnc->sxFnc.funcInfo = nullptr;
  3320. pnodeFnc->sxFnc.deferredStub = nullptr;
  3321. pnodeFnc->sxFnc.nestedCount = 0;
  3322. pnodeFnc->sxFnc.cbMin = m_pscan->IecpMinTok();
  3323. pnodeFnc->sxFnc.functionId = (*m_nextFunctionId)++;
  3324. // Push new parser state with this new function node
  3325. AppendFunctionToScopeList(fDeclaration, pnodeFnc);
  3326. // Start the argument list.
  3327. ppnodeVarSave = m_ppnodeVar;
  3328. }
  3329. else
  3330. {
  3331. (*m_nextFunctionId)++;
  3332. }
  3333. if (buildAST)
  3334. {
  3335. pnodeFnc->sxFnc.lineNumber = m_pscan->LineCur();
  3336. pnodeFnc->sxFnc.columnNumber = CalculateFunctionColumnNumber();
  3337. pnodeFnc->sxFnc.SetNested(m_currentNodeFunc != nullptr); // If there is a current function, then we're a nested function.
  3338. pnodeFnc->sxFnc.SetStrictMode(IsStrictMode()); // Inherit current strict mode -- may be overridden by the function itself if it contains a strict mode directive.
  3339. pnodeFnc->sxFnc.firstDefaultArg = 0;
  3340. m_pCurrentAstSize = &pnodeFnc->sxFnc.astSize;
  3341. // Make this the current function and start its sub-function list.
  3342. pnodeFncSave = m_currentNodeFunc;
  3343. m_currentNodeFunc = pnodeFnc;
  3344. if (!fLambda)
  3345. {
  3346. pnodeFncSaveNonLambda = m_currentNodeNonLambdaFunc;
  3347. m_currentNodeNonLambdaFunc = pnodeFnc;
  3348. }
  3349. m_pnestedCount = &pnodeFnc->sxFnc.nestedCount;
  3350. catchPidRefList = this->GetCatchPidRefList();
  3351. if (catchPidRefList)
  3352. {
  3353. Assert(!m_scriptContext->GetConfig()->IsBlockScopeEnabled());
  3354. if (fDeclaration)
  3355. {
  3356. // We're starting a function declaration, and we're inside some number
  3357. // of catches, and the catch has its own scope but the function gets hoisted
  3358. // outside it. We have to fiddle with the PidRefStack's to simulate hoisting.
  3359. // For each catch object in scope here, do the following:
  3360. // - Remove the portion of the PID ref stack that holds references inside the catch.
  3361. // - Save that portion of the stack in the catchPidRef list entry. Do this by:
  3362. // - Letting the list entry point to the current top of the PID ref stack;
  3363. // - Setting the prev pointer of the PID ref at the bottom of the removed portion to null.
  3364. // Now we can accumulate references inside the function declaration without getting them
  3365. // interspersed with the references that should bind to the catch variable.
  3366. FOREACH_SLISTBASE_ENTRY(CatchPidRef, catchPidRef, catchPidRefList)
  3367. {
  3368. IdentPtr pidCatch = catchPidRef.pid;
  3369. PidRefStack *topRef = pidCatch->GetTopRef();
  3370. PidRefStack *catchScopeRef = catchPidRef.ref;
  3371. catchPidRef.ref = topRef;
  3372. pidCatch->SetTopRef(catchScopeRef->prev);
  3373. catchScopeRef->prev = nullptr;
  3374. }
  3375. NEXT_SLISTBASE_ENTRY;
  3376. catchPidRefList->Reverse();
  3377. }
  3378. this->SetCatchPidRefList(nullptr);
  3379. }
  3380. }
  3381. else // if !buildAST
  3382. {
  3383. wasInDeferredNestedFunc = m_inDeferredNestedFunc;
  3384. m_inDeferredNestedFunc = true;
  3385. if (BindDeferredPidRefs())
  3386. {
  3387. AnalysisAssert(pnodeFnc);
  3388. if (!fLambda)
  3389. {
  3390. pnodeFncSaveNonLambda = m_currentNodeNonLambdaDeferredFunc;
  3391. m_currentNodeNonLambdaDeferredFunc = pnodeFnc;
  3392. }
  3393. pnodeFncSave = m_currentNodeDeferredFunc;
  3394. m_currentNodeDeferredFunc = pnodeFnc;
  3395. m_pnestedCount = &pnodeFnc->sxFnc.nestedCount;
  3396. }
  3397. else
  3398. {
  3399. m_pnestedCount = nullptr;
  3400. }
  3401. }
  3402. if (buildAST || BindDeferredPidRefs())
  3403. {
  3404. AnalysisAssert(pnodeFnc);
  3405. pnodeFnc->sxFnc.SetIsAsync((flags & fFncAsync) != 0);
  3406. pnodeFnc->sxFnc.SetIsLambda(fLambda);
  3407. pnodeFnc->sxFnc.SetIsMethod((flags & fFncMethod) != 0);
  3408. pnodeFnc->sxFnc.SetIsClassMember((flags & fFncClassMember) != 0);
  3409. }
  3410. bool needScanRCurly = true;
  3411. bool result = ParseFncDeclHelper<buildAST>(pnodeFnc, pnodeFncSave, pNameHint, flags, &funcHasName, fUnaryOrParen, noStmtContext, &needScanRCurly);
  3412. if (!result)
  3413. {
  3414. Assert(!pnodeFncBlockScope);
  3415. return pnodeFnc;
  3416. }
  3417. if (buildAST || BindDeferredPidRefs())
  3418. {
  3419. AnalysisAssert(pnodeFnc);
  3420. *m_ppnodeVar = nullptr;
  3421. m_ppnodeVar = ppnodeVarSave;
  3422. // Restore the current function.
  3423. if (buildAST)
  3424. {
  3425. Assert(pnodeFnc == m_currentNodeFunc);
  3426. m_currentNodeFunc = pnodeFncSave;
  3427. m_pCurrentAstSize = pAstSizeSave;
  3428. if (!fLambda)
  3429. {
  3430. Assert(pnodeFnc == m_currentNodeNonLambdaFunc);
  3431. m_currentNodeNonLambdaFunc = pnodeFncSaveNonLambda;
  3432. }
  3433. }
  3434. else
  3435. {
  3436. Assert(pnodeFnc == m_currentNodeDeferredFunc);
  3437. if (!fLambda)
  3438. {
  3439. Assert(pnodeFnc == m_currentNodeNonLambdaDeferredFunc);
  3440. m_currentNodeNonLambdaDeferredFunc = pnodeFncSaveNonLambda;
  3441. }
  3442. m_currentNodeDeferredFunc = pnodeFncSave;
  3443. if (m_currentNodeFunc && pnodeFnc->sxFnc.HasWithStmt())
  3444. {
  3445. GetCurrentFunctionNode()->sxFnc.SetHasWithStmt(true);
  3446. }
  3447. }
  3448. if (m_currentNodeFunc && (pnodeFnc->sxFnc.CallsEval() || pnodeFnc->sxFnc.ChildCallsEval()))
  3449. {
  3450. GetCurrentFunctionNode()->sxFnc.SetChildCallsEval(true);
  3451. }
  3452. // Lambdas do not have "arguments" and instead capture their parent's
  3453. // binding of "arguments. To ensure the arguments object of the enclosing
  3454. // non-lambda function is loaded propagate the UsesArguments flag up to
  3455. // the parent function
  3456. if ((flags & fFncLambda) != 0 && pnodeFnc->sxFnc.UsesArguments())
  3457. {
  3458. if (pnodeFncSave != nullptr)
  3459. {
  3460. pnodeFncSave->sxFnc.SetUsesArguments();
  3461. }
  3462. else
  3463. {
  3464. m_UsesArgumentsAtGlobal = true;
  3465. }
  3466. }
  3467. }
  3468. if (needScanRCurly)
  3469. {
  3470. // Consume the next token now that we're back in the enclosing function (whose strictness may be
  3471. // different from the function we just finished).
  3472. #if DBG
  3473. bool expectedTokenValid = m_token.tk == tkRCurly;
  3474. AssertMsg(expectedTokenValid, "Invalid token expected for RCurly match");
  3475. #endif
  3476. // The next token may need to have a PID created in !buildAST mode, as we may be parsing a method with a string name.
  3477. if (needsPIDOnRCurlyScan)
  3478. {
  3479. m_pscan->ScanForcingPid();
  3480. }
  3481. else
  3482. {
  3483. m_pscan->Scan();
  3484. }
  3485. }
  3486. m_pnestedCount = pnestedCountSave;
  3487. Assert(!buildAST || !wasInDeferredNestedFunc);
  3488. m_inDeferredNestedFunc = wasInDeferredNestedFunc;
  3489. if (this->m_arrayDepth)
  3490. {
  3491. this->m_funcInArrayDepth--;
  3492. if (this->m_funcInArrayDepth == 0 && !this->m_parsingDuplicate)
  3493. {
  3494. // We disable deferred parsing if array literals dominate.
  3495. // But don't do this if the array literal is dominated by function bodies.
  3496. if (flags & (fFncMethod | fFncClassMember) && m_token.tk != tkSColon)
  3497. {
  3498. // Class member methods have optional separators. We need to check whether we are
  3499. // getting the IchLim of the correct token.
  3500. Assert(m_pscan->m_tkPrevious == tkRCurly && needScanRCurly);
  3501. this->m_funcInArray += m_pscan->IchMinTok() - /*tkRCurly*/ 1 - ichMin;
  3502. }
  3503. else
  3504. {
  3505. this->m_funcInArray += m_pscan->IchLimTok() - ichMin;
  3506. }
  3507. }
  3508. }
  3509. m_scopeCountNoAst = scopeCountNoAstSave;
  3510. if (buildAST)
  3511. {
  3512. if (catchPidRefList)
  3513. {
  3514. if (this->GetCatchPidRefList())
  3515. {
  3516. // We may have had catches inside the function we just finished. If so, we should be done
  3517. // with them all (so the ref list should be empty), and we can throw away the list.
  3518. Assert(this->GetCatchPidRefList()->Empty());
  3519. Adelete(&m_nodeAllocator, this->GetCatchPidRefList());
  3520. }
  3521. this->SetCatchPidRefList(catchPidRefList);
  3522. if (fDeclaration)
  3523. {
  3524. // We're finishing a function declaration inside a catch. For each catch variable that's in
  3525. // scope here, put the portion of the PID ref stack that we removed and saved back on the top
  3526. // of the stack. When we finish the catch, the references in this restored portion of the stack
  3527. // will be bound to the catch variable, but those that belong the function body will
  3528. // be left behind to be bound to the context outside the catch.
  3529. FOREACH_SLISTBASE_ENTRY(CatchPidRef, catchPidRef, catchPidRefList)
  3530. {
  3531. IdentPtr pidCatch = catchPidRef.pid;
  3532. PidRefStack *oldTopRef = pidCatch->GetTopRef();
  3533. PidRefStack *ref = catchPidRef.ref;
  3534. pidCatch->SetTopRef(ref);
  3535. while (ref->prev)
  3536. {
  3537. ref = ref->prev;
  3538. }
  3539. ref->prev = oldTopRef;
  3540. catchPidRef.ref = ref;
  3541. }
  3542. NEXT_SLISTBASE_ENTRY;
  3543. catchPidRefList->Reverse();
  3544. }
  3545. }
  3546. }
  3547. if (buildAST && fDeclaration && m_scriptContext->GetConfig()->IsBlockScopeEnabled() && !IsStrictMode())
  3548. {
  3549. if (pnodeFnc->sxFnc.pnodeName != nullptr && pnodeFnc->sxFnc.pnodeName->nop == knopVarDecl &&
  3550. GetCurrentBlock()->sxBlock.blockType == PnodeBlockType::Regular)
  3551. {
  3552. // Add a function-scoped VarDecl with the same name as the function for
  3553. // back compat with pre-ES6 code that declares functions in blocks. The
  3554. // idea is that the last executed declaration wins at the function scope
  3555. // level and we accomplish this by having each block scoped function
  3556. // declaration assign to both the block scoped "let" binding, as well
  3557. // as the function scoped "var" binding.
  3558. ParseNodePtr vardecl = CreateVarDeclNode(pnodeFnc->sxFnc.pnodeName->sxVar.pid, STVariable, false, nullptr, false);
  3559. vardecl->sxVar.isBlockScopeFncDeclVar = true;
  3560. }
  3561. }
  3562. if (pnodeFncBlockScope)
  3563. {
  3564. Assert(pnodeFncBlockScope->sxBlock.pnodeStmt == nullptr);
  3565. pnodeFncBlockScope->sxBlock.pnodeStmt = pnodeFnc;
  3566. if (buildAST)
  3567. {
  3568. PopFuncBlockScope(ppnodeScopeSave, ppnodeExprScopeSave);
  3569. }
  3570. FinishParseBlock(pnodeFncBlockScope);
  3571. return pnodeFncBlockScope;
  3572. }
  3573. this->m_tryCatchOrFinallyDepth = tryCatchOrFinallyDepthSave;
  3574. return pnodeFnc;
  3575. }
  3576. bool Parser::FncDeclAllowedWithoutContext(ushort flags)
  3577. {
  3578. // Statement context required for strict mode, async functions, and generators.
  3579. // Note that generators aren't detected yet when this method is called; they're checked elsewhere.
  3580. return !IsStrictMode() && !(flags & fFncAsync);
  3581. }
  3582. uint Parser::CalculateFunctionColumnNumber()
  3583. {
  3584. uint columnNumber;
  3585. if (m_pscan->IchMinTok() >= m_pscan->IchMinLine())
  3586. {
  3587. // In scenarios involving defer parse IchMinLine() can be incorrect for the first line after defer parse
  3588. columnNumber = m_pscan->IchMinTok() - m_pscan->IchMinLine();
  3589. if (m_functionBody != nullptr && m_functionBody->GetRelativeLineNumber() == m_pscan->LineCur())
  3590. {
  3591. // Adjust the column if it falls on the first line, where the re-parse is happening.
  3592. columnNumber += m_functionBody->GetRelativeColumnNumber();
  3593. }
  3594. }
  3595. else if (m_currentNodeFunc)
  3596. {
  3597. // For the first line after defer parse, compute the column relative to the column number
  3598. // of the lexically parent function.
  3599. ULONG offsetFromCurrentFunction = m_pscan->IchMinTok() - m_currentNodeFunc->ichMin;
  3600. columnNumber = m_currentNodeFunc->sxFnc.columnNumber + offsetFromCurrentFunction ;
  3601. }
  3602. else
  3603. {
  3604. // if there is no current function, lets give a default of 0.
  3605. columnNumber = 0;
  3606. }
  3607. return columnNumber;
  3608. }
  3609. void Parser::AppendFunctionToScopeList(bool fDeclaration, ParseNodePtr pnodeFnc)
  3610. {
  3611. if (!fDeclaration && m_ppnodeExprScope)
  3612. {
  3613. // We're tracking function expressions separately from declarations in this scope
  3614. // (e.g., inside a catch scope in standards mode).
  3615. Assert(*m_ppnodeExprScope == nullptr);
  3616. *m_ppnodeExprScope = pnodeFnc;
  3617. m_ppnodeExprScope = &pnodeFnc->sxFnc.pnodeNext;
  3618. }
  3619. else
  3620. {
  3621. Assert(*m_ppnodeScope == nullptr);
  3622. *m_ppnodeScope = pnodeFnc;
  3623. m_ppnodeScope = &pnodeFnc->sxFnc.pnodeNext;
  3624. }
  3625. }
  3626. /***************************************************************************
  3627. Parse a function definition.
  3628. ***************************************************************************/
  3629. template<bool buildAST>
  3630. bool Parser::ParseFncDeclHelper(ParseNodePtr pnodeFnc, ParseNodePtr pnodeFncParent, LPCOLESTR pNameHint, ushort flags, bool *pHasName, bool fUnaryOrParen, bool noStmtContext, bool *pNeedScanRCurly)
  3631. {
  3632. bool fDeclaration = (flags & fFncDeclaration) != 0;
  3633. bool fLambda = (flags & fFncLambda) != 0;
  3634. bool fAsync = (flags & fFncAsync) != 0;
  3635. bool fDeferred = false;
  3636. StmtNest *pstmtSave;
  3637. ParseNodePtr *lastNodeRef = nullptr;
  3638. bool fFunctionInBlock = false;
  3639. if (buildAST)
  3640. {
  3641. fFunctionInBlock = GetCurrentBlockInfo() != GetCurrentFunctionBlockInfo() &&
  3642. (GetCurrentBlockInfo()->pnodeBlock->sxBlock.scope == nullptr ||
  3643. GetCurrentBlockInfo()->pnodeBlock->sxBlock.scope->GetScopeType() != ScopeType_GlobalEvalBlock);
  3644. }
  3645. // Save the position of the scanner in case we need to inspect the name hint later
  3646. RestorePoint beginNameHint;
  3647. m_pscan->Capture(&beginNameHint);
  3648. ParseNodePtr pnodeFncExprScope = nullptr;
  3649. Scope *fncExprScope = nullptr;
  3650. if ((buildAST || BindDeferredPidRefs()) &&
  3651. !fDeclaration)
  3652. {
  3653. pnodeFncExprScope = StartParseBlock<buildAST>(PnodeBlockType::Function, ScopeType_FuncExpr);
  3654. fncExprScope = pnodeFncExprScope->sxBlock.scope;
  3655. }
  3656. *pHasName = !fLambda && this->ParseFncNames<buildAST>(pnodeFnc, pnodeFncParent, flags, &lastNodeRef);
  3657. if (noStmtContext && pnodeFnc->sxFnc.IsGenerator())
  3658. {
  3659. // Generator decl not allowed outside stmt context. (We have to wait until we've parsed the '*' to
  3660. // detect generator.)
  3661. Error(ERRsyntax, pnodeFnc);
  3662. }
  3663. // switch scanner to treat 'yield' as keyword in generator functions
  3664. // or as an identifier in non-generator functions
  3665. bool fPreviousYieldIsKeyword = m_pscan->SetYieldIsKeyword(pnodeFnc && pnodeFnc->sxFnc.IsGenerator());
  3666. bool fPreviousAwaitIsKeyword = m_pscan->SetAwaitIsKeyword(fAsync);
  3667. if (pnodeFnc && pnodeFnc->sxFnc.IsGenerator())
  3668. {
  3669. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(GeneratorCount, m_scriptContext);
  3670. }
  3671. if (fncExprScope && !*pHasName)
  3672. {
  3673. FinishParseBlock(pnodeFncExprScope);
  3674. m_nextBlockId--;
  3675. Adelete(&m_nodeAllocator, fncExprScope);
  3676. fncExprScope = nullptr;
  3677. pnodeFncExprScope = nullptr;
  3678. }
  3679. if (pnodeFnc)
  3680. {
  3681. pnodeFnc->sxFnc.scope = fncExprScope;
  3682. }
  3683. // Start a new statement stack.
  3684. bool topLevelStmt =
  3685. buildAST &&
  3686. !fFunctionInBlock &&
  3687. (this->m_pstmtCur == nullptr || this->m_pstmtCur->pnodeStmt->nop == knopBlock);
  3688. pstmtSave = m_pstmtCur;
  3689. SetCurrentStatement(nullptr);
  3690. RestorePoint beginFormals;
  3691. m_pscan->Capture(&beginFormals);
  3692. BOOL fWasAlreadyStrictMode = IsStrictMode();
  3693. BOOL oldStrictMode = this->m_fUseStrictMode;
  3694. if (fLambda)
  3695. {
  3696. // lambda formals are parsed in strict mode always
  3697. m_fUseStrictMode = TRUE;
  3698. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(LambdaCount, m_scriptContext);
  3699. }
  3700. uint uDeferSave = m_grfscr & fscrDeferFncParse;
  3701. if ((!fDeclaration && m_ppnodeExprScope) ||
  3702. (m_scriptContext->GetConfig()->IsBlockScopeEnabled() && fFunctionInBlock) ||
  3703. (flags & (fFncNoName | fFncLambda)))
  3704. {
  3705. // NOTE: Don't defer if this is a function expression inside a construct that induces
  3706. // a scope nested within the current function (like a with, or a catch in ES5 mode, or
  3707. // any function declared inside a nested lexical block in ES6 mode).
  3708. // We won't be able to reconstruct the scope chain properly when we come back and
  3709. // try to compile just the function expression.
  3710. // Also shut off deferring on getter/setter or other construct with unusual text bounds
  3711. // (fFncNoName|fFncLambda) as these are usually trivial, and re-parsing is problematic.
  3712. m_grfscr &= ~fscrDeferFncParse;
  3713. }
  3714. bool isTopLevelDeferredFunc = false;
  3715. struct AutoFastScanFlag {
  3716. bool savedDoingFastScan;
  3717. AutoFastScanFlag(Parser *parser) : m_parser(parser) { savedDoingFastScan = m_parser->m_doingFastScan; }
  3718. ~AutoFastScanFlag() { m_parser->m_doingFastScan = savedDoingFastScan; }
  3719. Parser *m_parser;
  3720. } flag(this);
  3721. bool doParallel = false;
  3722. bool parallelJobStarted = false;
  3723. if (buildAST)
  3724. {
  3725. bool isLikelyModulePattern =
  3726. !fDeclaration && pnodeFnc && pnodeFnc->sxFnc.pnodeName == nullptr && fUnaryOrParen;
  3727. BOOL isDeferredFnc = IsDeferredFnc();
  3728. AnalysisAssert(isDeferredFnc || pnodeFnc);
  3729. isTopLevelDeferredFunc =
  3730. (!isDeferredFnc
  3731. && DeferredParse(pnodeFnc->sxFnc.functionId)
  3732. && (!pnodeFnc->sxFnc.IsNested() || CONFIG_FLAG(DeferNested))
  3733. // Don't defer if this is a function expression not contained in a statement or other expression.
  3734. // Assume it will be called as part of this expression.
  3735. && (!isLikelyModulePattern || !topLevelStmt || PHASE_FORCE1(Js::DeferParsePhase))
  3736. && !m_InAsmMode
  3737. );
  3738. if (!fLambda &&
  3739. !isDeferredFnc &&
  3740. !isLikelyModulePattern &&
  3741. !this->IsBackgroundParser() &&
  3742. !this->m_doingFastScan &&
  3743. !(pnodeFncParent && m_currDeferredStub) &&
  3744. !(this->m_parseType == ParseType_Deferred && this->m_functionBody && this->m_functionBody->GetScopeInfo() && !isTopLevelDeferredFunc))
  3745. {
  3746. doParallel = DoParallelParse(pnodeFnc);
  3747. #if ENABLE_BACKGROUND_PARSING
  3748. if (doParallel)
  3749. {
  3750. BackgroundParser *bgp = m_scriptContext->GetBackgroundParser();
  3751. Assert(bgp);
  3752. if (bgp->HasFailedBackgroundParseItem())
  3753. {
  3754. Error(ERRsyntax);
  3755. }
  3756. doParallel = bgp->ParseBackgroundItem(this, pnodeFnc, isTopLevelDeferredFunc);
  3757. if (doParallel)
  3758. {
  3759. parallelJobStarted = true;
  3760. this->m_hasParallelJob = true;
  3761. this->m_doingFastScan = true;
  3762. doParallel = FastScanFormalsAndBody();
  3763. if (doParallel)
  3764. {
  3765. // Let the foreground thread take care of marking the limit on the function node,
  3766. // because in some cases this function's caller will want to change that limit,
  3767. // so we don't want the background thread to try and touch it.
  3768. pnodeFnc->ichLim = m_pscan->IchLimTok();
  3769. pnodeFnc->sxFnc.cbLim = m_pscan->IecpLimTok();
  3770. }
  3771. }
  3772. }
  3773. #endif
  3774. }
  3775. }
  3776. if (!doParallel)
  3777. {
  3778. // We don't want to, or couldn't, let the main thread scan past this function body, so parse
  3779. // it for real.
  3780. ParseNodePtr pnodeRealFnc = pnodeFnc;
  3781. if (parallelJobStarted)
  3782. {
  3783. // We have to deal with a failure to fast-scan the function (due to syntax error? "/"?) when
  3784. // a background thread may already have begun to work on the job. Both threads can't be allowed to
  3785. // operate on the same node.
  3786. pnodeFnc = CreateDummyFuncNode(fDeclaration);
  3787. }
  3788. ParseNodePtr pnodeBlock = nullptr;
  3789. if (buildAST || BindDeferredPidRefs())
  3790. {
  3791. AnalysisAssert(pnodeFnc);
  3792. pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Parameter, ScopeType_Parameter);
  3793. pnodeFnc->sxFnc.pnodeScopes = pnodeBlock;
  3794. m_ppnodeVar = &pnodeFnc->sxFnc.pnodeArgs;
  3795. }
  3796. ParseNodePtr *ppnodeScopeSave = nullptr;
  3797. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  3798. ppnodeScopeSave = m_ppnodeScope;
  3799. if (pnodeBlock)
  3800. {
  3801. // This synthetic block scope will contain all the nested scopes.
  3802. m_ppnodeScope = &pnodeBlock->sxBlock.pnodeScopes;
  3803. pnodeBlock->sxBlock.pnodeStmt = pnodeFnc;
  3804. }
  3805. // Keep nested function declarations and expressions in the same list at function scope.
  3806. // (Indicate this by nulling out the current function expressions list.)
  3807. ppnodeExprScopeSave = m_ppnodeExprScope;
  3808. m_ppnodeExprScope = nullptr;
  3809. this->ParseFncFormals<buildAST>(pnodeFnc, flags);
  3810. m_fUseStrictMode = oldStrictMode;
  3811. // Create function body scope
  3812. ParseNodePtr pnodeInnerBlock = nullptr;
  3813. if (buildAST || BindDeferredPidRefs())
  3814. {
  3815. pnodeInnerBlock = StartParseBlock<buildAST>(PnodeBlockType::Function, ScopeType_FunctionBody);
  3816. // Set the parameter block's child to the function body block.
  3817. *m_ppnodeScope = pnodeInnerBlock;
  3818. AnalysisAssert(pnodeFnc);
  3819. pnodeFnc->sxFnc.pnodeBodyScope = pnodeInnerBlock;
  3820. // This synthetic block scope will contain all the nested scopes.
  3821. m_ppnodeScope = &pnodeInnerBlock->sxBlock.pnodeScopes;
  3822. pnodeInnerBlock->sxBlock.pnodeStmt = pnodeFnc;
  3823. }
  3824. // DEFER: Begin deferral here (after names are parsed and name nodes created).
  3825. // Create no more AST nodes until we're done.
  3826. // Try to defer this func if all these are true:
  3827. // 0. We are not already in deferred parsing (i.e. buildAST is true)
  3828. // 1. We are not re-parsing a deferred func which is being invoked.
  3829. // 2. Dynamic profile suggests this func can be deferred (and deferred parse is on).
  3830. // 3. This func is top level or defer nested func is on.
  3831. // 4. Optionally, the function is non-nested and not in eval, or the deferral decision was based on cached profile info,
  3832. // or the function is sufficiently long. (I.e., don't defer little nested functions unless we're
  3833. // confident they'll never be executed, because un-deferring nested functions is more expensive.)
  3834. // NOTE: I'm disabling #4 by default, because we've found other ways to reduce the cost of un-deferral,
  3835. // and we don't want to create function bodies aggressively for little functions.
  3836. // We will also temporarily defer all asm.js functions, except for the asm.js
  3837. // module itself, which we will never defer
  3838. bool strictModeTurnedOn = false;
  3839. if (isTopLevelDeferredFunc &&
  3840. !(this->m_grfscr & fscrEvalCode) &&
  3841. pnodeFnc->sxFnc.IsNested() &&
  3842. #ifndef DISABLE_DYNAMIC_PROFILE_DEFER_PARSE
  3843. m_sourceContextInfo->sourceDynamicProfileManager == nullptr &&
  3844. #endif
  3845. PHASE_ON_RAW(Js::ScanAheadPhase, m_sourceContextInfo->sourceContextId, pnodeFnc->sxFnc.functionId) &&
  3846. (
  3847. !PHASE_FORCE_RAW(Js::DeferParsePhase, m_sourceContextInfo->sourceContextId, pnodeFnc->sxFnc.functionId) ||
  3848. PHASE_FORCE_RAW(Js::ScanAheadPhase, m_sourceContextInfo->sourceContextId, pnodeFnc->sxFnc.functionId)
  3849. ))
  3850. {
  3851. // Try to scan ahead to the end of the function. If we get there before we've scanned a minimum
  3852. // number of tokens, don't bother deferring, because it's too small.
  3853. if (this->ScanAheadToFunctionEnd(CONFIG_FLAG(MinDeferredFuncTokenCount)))
  3854. {
  3855. isTopLevelDeferredFunc = false;
  3856. }
  3857. }
  3858. if (fAsync)
  3859. {
  3860. if (!buildAST || isTopLevelDeferredFunc)
  3861. {
  3862. // We increment m_nextFunctionId when there is an Async function to counterbalance the functionId because of the added generator to the AST with an async function that we use to keep deferred parsing in sync with non-deferred parsing
  3863. (*m_nextFunctionId)++;
  3864. }
  3865. // Same than before, we increment the nestedCount because we will have a Generator inside any async function.
  3866. pnodeFnc->sxFnc.nestedCount++;
  3867. }
  3868. if (isTopLevelDeferredFunc || (m_InAsmMode && m_deferAsmJs))
  3869. {
  3870. AssertMsg(!fLambda, "Deferring function parsing of a function does not handle lambda syntax");
  3871. fDeferred = true;
  3872. this->ParseTopLevelDeferredFunc(pnodeFnc, pnodeFncParent, pNameHint);
  3873. }
  3874. else
  3875. {
  3876. if (m_token.tk == tkRParen) // This might be false due to error recovery or lambda.
  3877. {
  3878. m_pscan->Scan();
  3879. }
  3880. if (fLambda)
  3881. {
  3882. BOOL hadNewLine = m_pscan->FHadNewLine();
  3883. // it can be the case we do not have a fat arrow here if there is a valid expression on the left hand side
  3884. // of the fat arrow, but that expression does not parse as a parameter list. E.g.
  3885. // a.x => { }
  3886. // Therefore check for it and error if not found.
  3887. // LS Mode : since this is a lambda we supposed to get the fat arrow, if not we will skip till we get that fat arrow.
  3888. ChkCurTok(tkDArrow, ERRnoDArrow);
  3889. // Newline character between arrow parameters and fat arrow is a syntax error but we want to check for
  3890. // this after verifying there was a => token. Otherwise we would throw the wrong error.
  3891. if (hadNewLine)
  3892. {
  3893. Error(ERRsyntax);
  3894. }
  3895. }
  3896. if (buildAST || BindDeferredPidRefs())
  3897. {
  3898. AnalysisAssert(pnodeFnc);
  3899. // Shouldn't be any temps in the arg list.
  3900. Assert(*m_ppnodeVar == nullptr);
  3901. // Start the var list.
  3902. pnodeFnc->sxFnc.pnodeVars = nullptr;
  3903. m_ppnodeVar = &pnodeFnc->sxFnc.pnodeVars;
  3904. }
  3905. // Keep nested function declarations and expressions in the same list at function scope.
  3906. // (Indicate this by nulling out the current function expressions list.)
  3907. m_ppnodeExprScope = nullptr;
  3908. if (buildAST)
  3909. {
  3910. DeferredFunctionStub *saveCurrentStub = m_currDeferredStub;
  3911. if (pnodeFncParent && m_currDeferredStub)
  3912. {
  3913. m_currDeferredStub = (m_currDeferredStub + (pnodeFncParent->sxFnc.nestedCount - 1))->deferredStubs;
  3914. }
  3915. if (m_token.tk != tkLCurly && fLambda)
  3916. {
  3917. if (fAsync)
  3918. {
  3919. TransformAsyncFncDeclAST(&pnodeFnc, true);
  3920. }
  3921. else
  3922. {
  3923. ParseExpressionLambdaBody<true>(pnodeFnc);
  3924. }
  3925. *pNeedScanRCurly = false;
  3926. }
  3927. else
  3928. {
  3929. this->FinishFncDecl(pnodeFnc, pNameHint, lastNodeRef);
  3930. }
  3931. m_currDeferredStub = saveCurrentStub;
  3932. }
  3933. else
  3934. {
  3935. this->ParseNestedDeferredFunc(pnodeFnc, fLambda, pNeedScanRCurly, &strictModeTurnedOn);
  3936. }
  3937. }
  3938. if (pnodeInnerBlock)
  3939. {
  3940. FinishParseBlock(pnodeInnerBlock, *pNeedScanRCurly);
  3941. }
  3942. if ((buildAST || BindDeferredPidRefs()) && !(m_token.tk != tkLCurly && fLambda))
  3943. {
  3944. this->AddArgumentsNodeToVars(pnodeFnc);
  3945. }
  3946. // Restore the lists of scopes that contain function expressions.
  3947. Assert(m_ppnodeExprScope == nullptr || *m_ppnodeExprScope == nullptr);
  3948. m_ppnodeExprScope = ppnodeExprScopeSave;
  3949. AssertMem(m_ppnodeScope);
  3950. Assert(nullptr == *m_ppnodeScope);
  3951. m_ppnodeScope = ppnodeScopeSave;
  3952. if (pnodeBlock)
  3953. {
  3954. FinishParseBlock(pnodeBlock, *pNeedScanRCurly);
  3955. }
  3956. if (IsStrictMode() || strictModeTurnedOn)
  3957. {
  3958. this->m_fUseStrictMode = TRUE; // Now we know this function is in strict mode
  3959. if (!fLambda && !fWasAlreadyStrictMode)
  3960. {
  3961. // If this function turned on strict mode then we didn't check the formal
  3962. // parameters or function name hint for future reserved word usage. So do that now.
  3963. // Except for lambdas which always treat formal parameters as strict and do not have
  3964. // a name.
  3965. RestorePoint afterFnc;
  3966. m_pscan->Capture(&afterFnc);
  3967. if (*pHasName)
  3968. {
  3969. // Rewind to the function name hint and check if the token is a reserved word.
  3970. m_pscan->SeekTo(beginNameHint);
  3971. m_pscan->Scan();
  3972. if (pnodeFnc->sxFnc.IsGenerator())
  3973. {
  3974. Assert(m_token.tk == tkStar);
  3975. Assert(m_scriptContext->GetConfig()->IsES6GeneratorsEnabled());
  3976. Assert(!(flags & fFncClassMember));
  3977. m_pscan->Scan();
  3978. }
  3979. if (m_token.IsReservedWord())
  3980. {
  3981. IdentifierExpectedError(m_token);
  3982. }
  3983. CheckStrictModeEvalArgumentsUsage(m_token.GetIdentifier(m_phtbl));
  3984. }
  3985. // Fast forward to formal parameter list, check for future reserved words,
  3986. // then restore scanner as it was.
  3987. m_pscan->SeekTo(beginFormals);
  3988. CheckStrictFormalParameters();
  3989. m_pscan->SeekTo(afterFnc);
  3990. }
  3991. if (buildAST)
  3992. {
  3993. if (pnodeFnc->sxFnc.pnodeName != nullptr && knopVarDecl == pnodeFnc->sxFnc.pnodeName->nop)
  3994. {
  3995. CheckStrictModeEvalArgumentsUsage(pnodeFnc->sxFnc.pnodeName->sxVar.pid, pnodeFnc->sxFnc.pnodeName);
  3996. }
  3997. }
  3998. this->m_fUseStrictMode = oldStrictMode;
  3999. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(StrictModeFunctionCount, m_scriptContext);
  4000. }
  4001. if (fDeferred)
  4002. {
  4003. AnalysisAssert(pnodeFnc);
  4004. pnodeFnc->sxFnc.pnodeVars = nullptr;
  4005. }
  4006. if (parallelJobStarted)
  4007. {
  4008. pnodeFnc = pnodeRealFnc;
  4009. m_currentNodeFunc = pnodeRealFnc;
  4010. // Let the foreground thread take care of marking the limit on the function node,
  4011. // because in some cases this function's caller will want to change that limit,
  4012. // so we don't want the background thread to try and touch it.
  4013. pnodeFnc->ichLim = m_pscan->IchLimTok();
  4014. pnodeFnc->sxFnc.cbLim = m_pscan->IecpLimTok();
  4015. }
  4016. }
  4017. // after parsing asm.js module, we want to reset asm.js state before continuing
  4018. AnalysisAssert(pnodeFnc);
  4019. if (pnodeFnc->sxFnc.GetAsmjsMode())
  4020. {
  4021. m_InAsmMode = false;
  4022. }
  4023. // Restore the statement stack.
  4024. Assert(nullptr == m_pstmtCur);
  4025. SetCurrentStatement(pstmtSave);
  4026. if (pnodeFncExprScope)
  4027. {
  4028. FinishParseFncExprScope(pnodeFnc, pnodeFncExprScope);
  4029. }
  4030. if (!m_stoppedDeferredParse)
  4031. {
  4032. m_grfscr |= uDeferSave;
  4033. }
  4034. m_pscan->SetYieldIsKeyword(fPreviousYieldIsKeyword);
  4035. m_pscan->SetAwaitIsKeyword(fPreviousAwaitIsKeyword);
  4036. return true;
  4037. }
  4038. void Parser::ParseTopLevelDeferredFunc(ParseNodePtr pnodeFnc, ParseNodePtr pnodeFncParent, LPCOLESTR pNameHint)
  4039. {
  4040. // Parse a function body that is a transition point from building AST to doing fast syntax check.
  4041. pnodeFnc->sxFnc.pnodeVars = nullptr;
  4042. pnodeFnc->sxFnc.pnodeBody = nullptr;
  4043. this->m_deferringAST = TRUE;
  4044. // Put the scanner into "no hashing" mode.
  4045. BYTE deferFlags = m_pscan->SetDeferredParse(TRUE);
  4046. m_pscan->Scan();
  4047. ChkCurTok(tkLCurly, ERRnoLcurly);
  4048. ParseNodePtr *ppnodeVarSave = m_ppnodeVar;
  4049. if (BindDeferredPidRefs())
  4050. {
  4051. m_ppnodeVar = &pnodeFnc->sxFnc.pnodeVars;
  4052. }
  4053. if (pnodeFncParent != nullptr
  4054. && m_currDeferredStub != nullptr
  4055. // We don't create stubs for function bodies in parameter scope.
  4056. && pnodeFnc->sxFnc.pnodeScopes->sxBlock.blockType != PnodeBlockType::Parameter)
  4057. {
  4058. // We've already parsed this function body for syntax errors on the initial parse of the script.
  4059. // We have information that allows us to skip it, so do so.
  4060. DeferredFunctionStub *stub = m_currDeferredStub + (pnodeFncParent->sxFnc.nestedCount - 1);
  4061. Assert(pnodeFnc->ichMin == stub->ichMin);
  4062. if (stub->fncFlags & kFunctionCallsEval)
  4063. {
  4064. this->MarkEvalCaller();
  4065. }
  4066. if (stub->fncFlags & kFunctionChildCallsEval)
  4067. {
  4068. pnodeFnc->sxFnc.SetChildCallsEval(true);
  4069. }
  4070. if (stub->fncFlags & kFunctionHasWithStmt)
  4071. {
  4072. pnodeFnc->sxFnc.SetHasWithStmt(true);
  4073. }
  4074. PHASE_PRINT_TRACE1(
  4075. Js::SkipNestedDeferredPhase,
  4076. L"Skipping nested deferred function %d. %s: %d...%d\n",
  4077. pnodeFnc->sxFnc.functionId, GetFunctionName(pnodeFnc, pNameHint), pnodeFnc->ichMin, stub->restorePoint.m_ichMinTok);
  4078. m_pscan->SeekTo(stub->restorePoint, m_nextFunctionId);
  4079. pnodeFnc->sxFnc.nestedCount = stub->nestedCount;
  4080. pnodeFnc->sxFnc.deferredStub = stub->deferredStubs;
  4081. if (stub->fncFlags & kFunctionStrictMode)
  4082. {
  4083. pnodeFnc->sxFnc.SetStrictMode(true);
  4084. }
  4085. }
  4086. else
  4087. {
  4088. ParseStmtList<false>(nullptr, nullptr, SM_DeferredParse, true /* isSourceElementList */);
  4089. }
  4090. pnodeFnc->ichLim = m_pscan->IchLimTok();
  4091. pnodeFnc->sxFnc.cbLim = m_pscan->IecpLimTok();
  4092. if (BindDeferredPidRefs())
  4093. {
  4094. m_ppnodeVar = ppnodeVarSave;
  4095. }
  4096. // Restore the scanner's default hashing mode.
  4097. // Do this before we consume the next token.
  4098. m_pscan->SetDeferredParseFlags(deferFlags);
  4099. ChkCurTokNoScan(tkRCurly, ERRnoRcurly);
  4100. #if DBG
  4101. pnodeFnc->sxFnc.deferredParseNextFunctionId = *this->m_nextFunctionId;
  4102. #endif
  4103. this->m_deferringAST = FALSE;
  4104. }
  4105. bool Parser::DoParallelParse(ParseNodePtr pnodeFnc) const
  4106. {
  4107. #if ENABLE_BACKGROUND_PARSING
  4108. if (!PHASE_ON_RAW(Js::ParallelParsePhase, m_sourceContextInfo->sourceContextId, pnodeFnc->sxFnc.functionId))
  4109. {
  4110. return false;
  4111. }
  4112. BackgroundParser *bgp = m_scriptContext->GetBackgroundParser();
  4113. return bgp != nullptr;
  4114. #else
  4115. return false;
  4116. #endif
  4117. }
  4118. bool Parser::ScanAheadToFunctionEnd(uint count)
  4119. {
  4120. bool found = false;
  4121. uint curlyDepth = 0;
  4122. RestorePoint funcStart;
  4123. m_pscan->Capture(&funcStart);
  4124. for (uint i = 0; i < count; i++)
  4125. {
  4126. switch (m_token.tk)
  4127. {
  4128. case tkStrTmplBegin:
  4129. case tkStrTmplMid:
  4130. case tkStrTmplEnd:
  4131. case tkDiv:
  4132. case tkAsgDiv:
  4133. case tkScanError:
  4134. case tkEOF:
  4135. goto LEnd;
  4136. case tkLCurly:
  4137. UInt32Math::Inc(curlyDepth, Parser::OutOfMemory);
  4138. break;
  4139. case tkRCurly:
  4140. if (curlyDepth == 1)
  4141. {
  4142. found = true;
  4143. goto LEnd;
  4144. }
  4145. if (curlyDepth == 0)
  4146. {
  4147. goto LEnd;
  4148. }
  4149. curlyDepth--;
  4150. break;
  4151. }
  4152. m_pscan->ScanAhead();
  4153. }
  4154. LEnd:
  4155. m_pscan->SeekTo(funcStart);
  4156. return found;
  4157. }
  4158. bool Parser::FastScanFormalsAndBody()
  4159. {
  4160. // The scanner is currently pointing just past the name of a function.
  4161. // The idea here is to find the end of the function body as quickly as possible,
  4162. // by tokenizing and tracking {}'s if possible.
  4163. // String templates require some extra logic but can be handled.
  4164. // The real wrinkle is "/" and "/=", which may indicate either a RegExp literal or a division, depending
  4165. // on the context.
  4166. // To handle this with minimal work, keep track of the last ";" seen at each {} depth. If we see one of the
  4167. // difficult tokens, rewind to the last ";" at the current {} depth and parse statements until we pass the
  4168. // point where we had to rewind. This will process the "/" as required.
  4169. RestorePoint funcStart;
  4170. m_pscan->Capture(&funcStart);
  4171. const int maxRestorePointDepth = 16;
  4172. struct FastScanRestorePoint
  4173. {
  4174. RestorePoint restorePoint;
  4175. uint parenDepth;
  4176. Js::LocalFunctionId functionId;
  4177. int blockId;
  4178. FastScanRestorePoint() : restorePoint(), parenDepth(0) {};
  4179. };
  4180. FastScanRestorePoint lastSColonAtCurlyDepth[maxRestorePointDepth];
  4181. charcount_t ichStart = m_pscan->IchMinTok();
  4182. uint blockIdSave = m_nextBlockId;
  4183. uint functionIdSave = *m_nextFunctionId;
  4184. uint curlyDepth = 0;
  4185. uint strTmplDepth = 0;
  4186. for (;;)
  4187. {
  4188. switch (m_token.tk)
  4189. {
  4190. case tkStrTmplBegin:
  4191. UInt32Math::Inc(strTmplDepth, Parser::OutOfMemory);
  4192. // Fall through
  4193. case tkStrTmplMid:
  4194. case tkLCurly:
  4195. UInt32Math::Inc(curlyDepth, Parser::OutOfMemory);
  4196. Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
  4197. break;
  4198. case tkStrTmplEnd:
  4199. // We can assert here, because the scanner will only return this token if we've told it we're
  4200. // in a string template.
  4201. Assert(strTmplDepth > 0);
  4202. strTmplDepth--;
  4203. break;
  4204. case tkRCurly:
  4205. if (curlyDepth == 1)
  4206. {
  4207. Assert(strTmplDepth == 0);
  4208. if (PHASE_TRACE1(Js::ParallelParsePhase))
  4209. {
  4210. Output::Print(L"Finished fast seek: %d. %s -- %d...%d\n",
  4211. m_currentNodeFunc->sxFnc.functionId,
  4212. GetFunctionName(m_currentNodeFunc, m_currentNodeFunc->sxFnc.hint),
  4213. ichStart, m_pscan->IchLimTok());
  4214. }
  4215. return true;
  4216. }
  4217. if (curlyDepth < maxRestorePointDepth)
  4218. {
  4219. lastSColonAtCurlyDepth[curlyDepth].restorePoint.m_ichMinTok = (uint)-1;
  4220. }
  4221. curlyDepth--;
  4222. if (strTmplDepth > 0)
  4223. {
  4224. m_pscan->SetScanState(Scanner_t::ScanState::ScanStateStringTemplateMiddleOrEnd);
  4225. }
  4226. break;
  4227. case tkSColon:
  4228. // Track the location of the ";" (if it's outside parens, as we don't, for instance, want
  4229. // to track the ";"'s in a for-loop header. If we find it's important to rewind within a paren
  4230. // expression, we can do something more sophisticated.)
  4231. if (curlyDepth < maxRestorePointDepth && lastSColonAtCurlyDepth[curlyDepth].parenDepth == 0)
  4232. {
  4233. m_pscan->Capture(&lastSColonAtCurlyDepth[curlyDepth].restorePoint);
  4234. lastSColonAtCurlyDepth[curlyDepth].functionId = *this->m_nextFunctionId;
  4235. lastSColonAtCurlyDepth[curlyDepth].blockId = m_nextBlockId;
  4236. }
  4237. break;
  4238. case tkLParen:
  4239. if (curlyDepth < maxRestorePointDepth)
  4240. {
  4241. UInt32Math::Inc(lastSColonAtCurlyDepth[curlyDepth].parenDepth);
  4242. }
  4243. break;
  4244. case tkRParen:
  4245. if (curlyDepth < maxRestorePointDepth)
  4246. {
  4247. Assert(lastSColonAtCurlyDepth[curlyDepth].parenDepth != 0);
  4248. lastSColonAtCurlyDepth[curlyDepth].parenDepth--;
  4249. }
  4250. break;
  4251. case tkID:
  4252. {
  4253. charcount_t tokLength = m_pscan->IchLimTok() - m_pscan->IchMinTok();
  4254. // Detect the function and class keywords so we can track function ID's.
  4255. // (In fast mode, the scanner doesn't distinguish keywords and doesn't point the token
  4256. // to a PID.)
  4257. // Detect try/catch/for to increment block count for them.
  4258. switch (tokLength)
  4259. {
  4260. case 3:
  4261. if (!memcmp(m_pscan->PchMinTok(), "try", 3) || !memcmp(m_pscan->PchMinTok(), "for", 3))
  4262. {
  4263. Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
  4264. }
  4265. break;
  4266. case 5:
  4267. if (!memcmp(m_pscan->PchMinTok(), "catch", 5))
  4268. {
  4269. Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
  4270. }
  4271. else if (!memcmp(m_pscan->PchMinTok(), "class", 5))
  4272. {
  4273. Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
  4274. Int32Math::Inc(*this->m_nextFunctionId, (int*)this->m_nextFunctionId);
  4275. }
  4276. break;
  4277. case 8:
  4278. if (!memcmp(m_pscan->PchMinTok(), "function", 8))
  4279. {
  4280. // Account for the possible func expr scope or dummy block for missing {}'s around a declaration
  4281. Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
  4282. Int32Math::Inc(*this->m_nextFunctionId, (int*)this->m_nextFunctionId);
  4283. }
  4284. break;
  4285. }
  4286. break;
  4287. }
  4288. case tkDArrow:
  4289. Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
  4290. Int32Math::Inc(*this->m_nextFunctionId, (int*)this->m_nextFunctionId);
  4291. break;
  4292. case tkDiv:
  4293. case tkAsgDiv:
  4294. {
  4295. int opl;
  4296. OpCode nop;
  4297. tokens tkPrev = m_pscan->m_tkPrevious;
  4298. if ((m_pscan->m_phtbl->TokIsBinop(tkPrev, &opl, &nop) && nop != knopNone) ||
  4299. (m_pscan->m_phtbl->TokIsUnop(tkPrev, &opl, &nop) &&
  4300. nop != knopNone &&
  4301. tkPrev != tkInc &&
  4302. tkPrev != tkDec) ||
  4303. tkPrev == tkColon ||
  4304. tkPrev == tkLParen ||
  4305. tkPrev == tkLBrack ||
  4306. tkPrev == tkRETURN)
  4307. {
  4308. // Previous token indicates that we're starting an expression here and can't have a
  4309. // binary operator now.
  4310. // Assume this is a RegExp.
  4311. ParseRegExp<false>();
  4312. break;
  4313. }
  4314. uint tempCurlyDepth = curlyDepth < maxRestorePointDepth ? curlyDepth : maxRestorePointDepth - 1;
  4315. for (; tempCurlyDepth != (uint)-1; tempCurlyDepth--)
  4316. {
  4317. // We don't know whether we've got a RegExp or a divide. Rewind to the last safe ";"
  4318. // if we can and parse statements until we pass this point.
  4319. if (lastSColonAtCurlyDepth[tempCurlyDepth].restorePoint.m_ichMinTok != -1)
  4320. {
  4321. break;
  4322. }
  4323. }
  4324. if (tempCurlyDepth != (uint)-1)
  4325. {
  4326. ParseNodePtr pnodeFncSave = m_currentNodeFunc;
  4327. long *pastSizeSave = m_pCurrentAstSize;
  4328. uint *pnestedCountSave = m_pnestedCount;
  4329. ParseNodePtr *ppnodeScopeSave = m_ppnodeScope;
  4330. ParseNodePtr *ppnodeExprScopeSave = m_ppnodeExprScope;
  4331. ParseNodePtr pnodeFnc = CreateDummyFuncNode(true);
  4332. m_ppnodeScope = &pnodeFnc->sxFnc.pnodeScopes;
  4333. m_ppnodeExprScope = nullptr;
  4334. charcount_t ichStop = m_pscan->IchLimTok();
  4335. curlyDepth = tempCurlyDepth;
  4336. m_pscan->SeekTo(lastSColonAtCurlyDepth[tempCurlyDepth].restorePoint);
  4337. m_nextBlockId = lastSColonAtCurlyDepth[tempCurlyDepth].blockId;
  4338. *this->m_nextFunctionId = lastSColonAtCurlyDepth[tempCurlyDepth].functionId;
  4339. ParseNodePtr pnodeBlock = StartParseBlock<true>(PnodeBlockType::Function, ScopeType_FunctionBody);
  4340. m_pscan->Scan();
  4341. do
  4342. {
  4343. ParseStatement<false>(true);
  4344. }
  4345. while(m_pscan->IchMinTok() < ichStop);
  4346. FinishParseBlock(pnodeBlock);
  4347. m_currentNodeFunc = pnodeFncSave;
  4348. m_pCurrentAstSize = pastSizeSave;
  4349. m_pnestedCount = pnestedCountSave;
  4350. m_ppnodeScope = ppnodeScopeSave;
  4351. m_ppnodeExprScope = ppnodeExprScopeSave;
  4352. // We've already consumed the first token of the next statement, so just continue
  4353. // without a further scan.
  4354. continue;
  4355. }
  4356. }
  4357. // fall through to rewind to function start
  4358. case tkScanError:
  4359. case tkEOF:
  4360. // Unexpected token.
  4361. if (PHASE_TRACE1(Js::ParallelParsePhase))
  4362. {
  4363. Output::Print(L"Failed fast seek: %d. %s -- %d...%d\n",
  4364. m_currentNodeFunc->sxFnc.functionId,
  4365. GetFunctionName(m_currentNodeFunc, m_currentNodeFunc->sxFnc.hint),
  4366. ichStart, m_pscan->IchLimTok());
  4367. }
  4368. m_nextBlockId = blockIdSave;
  4369. *m_nextFunctionId = functionIdSave;
  4370. m_pscan->SeekTo(funcStart);
  4371. return false;
  4372. }
  4373. m_pscan->ScanNoKeywords();
  4374. }
  4375. }
  4376. ParseNodePtr Parser::CreateDummyFuncNode(bool fDeclaration)
  4377. {
  4378. // Create a dummy node and make it look like the current function declaration.
  4379. // Do this in situations where we want to parse statements without impacting
  4380. // the state of the "real" AST.
  4381. ParseNodePtr pnodeFnc = CreateNode(knopFncDecl);
  4382. pnodeFnc->sxFnc.ClearFlags();
  4383. pnodeFnc->sxFnc.SetDeclaration(fDeclaration);
  4384. pnodeFnc->sxFnc.astSize = 0;
  4385. pnodeFnc->sxFnc.pnodeName = nullptr;
  4386. pnodeFnc->sxFnc.pnodeScopes = nullptr;
  4387. pnodeFnc->sxFnc.pnodeRest = nullptr;
  4388. pnodeFnc->sxFnc.pid = nullptr;
  4389. pnodeFnc->sxFnc.hint = nullptr;
  4390. pnodeFnc->sxFnc.hintOffset = 0;
  4391. pnodeFnc->sxFnc.hintLength = 0;
  4392. pnodeFnc->sxFnc.isNameIdentifierRef = true;
  4393. pnodeFnc->sxFnc.pnodeNext = nullptr;
  4394. pnodeFnc->sxFnc.pnodeArgs = nullptr;
  4395. pnodeFnc->sxFnc.pnodeVars = nullptr;
  4396. pnodeFnc->sxFnc.funcInfo = nullptr;
  4397. pnodeFnc->sxFnc.deferredStub = nullptr;
  4398. pnodeFnc->sxFnc.nestedCount = 0;
  4399. pnodeFnc->sxFnc.SetNested(m_currentNodeFunc != nullptr); // If there is a current function, then we're a nested function.
  4400. pnodeFnc->sxFnc.SetStrictMode(IsStrictMode()); // Inherit current strict mode -- may be overridden by the function itself if it contains a strict mode directive.
  4401. pnodeFnc->sxFnc.firstDefaultArg = 0;
  4402. m_pCurrentAstSize = &pnodeFnc->sxFnc.astSize;
  4403. m_currentNodeFunc = pnodeFnc;
  4404. m_pnestedCount = &pnodeFnc->sxFnc.nestedCount;
  4405. return pnodeFnc;
  4406. }
  4407. void Parser::ParseNestedDeferredFunc(ParseNodePtr pnodeFnc, bool fLambda, bool *pNeedScanRCurly, bool *pStrictModeTurnedOn)
  4408. {
  4409. // Parse a function nested inside another deferred function.
  4410. size_t lengthBeforeBody = this->GetSourceLength();
  4411. if (m_token.tk != tkLCurly && fLambda)
  4412. {
  4413. ParseExpressionLambdaBody<false>(pnodeFnc);
  4414. *pNeedScanRCurly = false;
  4415. }
  4416. else
  4417. {
  4418. ChkCurTok(tkLCurly, ERRnoLcurly);
  4419. bool* detectStrictModeOn = IsStrictMode() ? nullptr : pStrictModeTurnedOn;
  4420. if (BindDeferredPidRefs())
  4421. {
  4422. m_ppnodeVar = &m_currentNodeDeferredFunc->sxFnc.pnodeVars;
  4423. }
  4424. ParseStmtList<false>(nullptr, nullptr, SM_DeferredParse, true /* isSourceElementList */, detectStrictModeOn);
  4425. ChkCurTokNoScan(tkRCurly, ERRnoRcurly);
  4426. }
  4427. if (BindDeferredPidRefs())
  4428. {
  4429. pnodeFnc->ichLim = m_pscan->IchLimTok();
  4430. pnodeFnc->sxFnc.cbLim = m_pscan->IecpLimTok();
  4431. if (*pStrictModeTurnedOn)
  4432. {
  4433. pnodeFnc->sxFnc.SetStrictMode(true);
  4434. }
  4435. if (!PHASE_OFF1(Js::SkipNestedDeferredPhase))
  4436. {
  4437. // Record the end of the function and the function ID increment that happens inside the function.
  4438. // Byte code gen will use this to build stub information to allow us to skip this function when the
  4439. // enclosing function is fully parsed.
  4440. RestorePoint *restorePoint = Anew(&m_nodeAllocator, RestorePoint);
  4441. m_pscan->Capture(restorePoint,
  4442. *m_nextFunctionId - pnodeFnc->sxFnc.functionId - 1,
  4443. lengthBeforeBody - this->GetSourceLength());
  4444. pnodeFnc->sxFnc.pRestorePoint = restorePoint;
  4445. }
  4446. }
  4447. }
  4448. template<bool buildAST>
  4449. bool Parser::ParseFncNames(ParseNodePtr pnodeFnc, ParseNodePtr pnodeFncParent, ushort flags, ParseNodePtr **pLastNodeRef)
  4450. {
  4451. BOOL fDeclaration = flags & fFncDeclaration;
  4452. BOOL fIsAsync = flags & fFncAsync;
  4453. ParseNodePtr pnodeT;
  4454. charcount_t ichMinNames, ichLimNames;
  4455. // Get the names to bind to.
  4456. /*
  4457. * KaushiS [5/15/08]:
  4458. * ECMAScript defines a FunctionExpression as follows:
  4459. *
  4460. * "function" [Identifier] ( [FormalParameterList] ) { FunctionBody }
  4461. *
  4462. * The function name being optional is omitted by most real world
  4463. * code that uses a FunctionExpression to define a function. This however
  4464. * is problematic for tools because there isn't a function name that
  4465. * the runtime can provide.
  4466. *
  4467. * To fix this (primarily for the profiler), I'm adding simple, static
  4468. * name inferencing logic to the parser. When it encounters the following
  4469. * productions
  4470. *
  4471. * "var" Identifier "=" FunctionExpression
  4472. * "var" IdentifierA.IdentifierB...Identifier "=" FunctionExpression
  4473. * Identifier = FunctionExpression
  4474. * "{" Identifier: FunctionExpression "}"
  4475. *
  4476. * it associates Identifier with the function created by the
  4477. * FunctionExpression. This identifier is *not* the function's name. It
  4478. * is ignored by the runtime and is only an additional piece of information
  4479. * about the function (function name hint) that tools could opt to
  4480. * surface.
  4481. */
  4482. m_pscan->Scan();
  4483. // If generators are enabled then we are in a recent enough version
  4484. // that deferred parsing will create a parse node for pnodeFnc and
  4485. // it is safe to assume it is not null.
  4486. if (flags & fFncGenerator)
  4487. {
  4488. Assert(m_scriptContext->GetConfig()->IsES6GeneratorsEnabled());
  4489. pnodeFnc->sxFnc.SetIsGenerator();
  4490. }
  4491. else if (m_scriptContext->GetConfig()->IsES6GeneratorsEnabled() &&
  4492. m_token.tk == tkStar &&
  4493. !(flags & fFncClassMember))
  4494. {
  4495. if (!fDeclaration)
  4496. {
  4497. bool fPreviousYieldIsKeyword = m_pscan->SetYieldIsKeyword(!fDeclaration);
  4498. m_pscan->Scan();
  4499. m_pscan->SetYieldIsKeyword(fPreviousYieldIsKeyword);
  4500. }
  4501. else
  4502. {
  4503. m_pscan->Scan();
  4504. }
  4505. pnodeFnc->sxFnc.SetIsGenerator();
  4506. }
  4507. if (fIsAsync)
  4508. {
  4509. if (pnodeFnc->sxFnc.IsGenerator())
  4510. {
  4511. Error(ERRsyntax);
  4512. }
  4513. pnodeFnc->sxFnc.SetIsAsync();
  4514. }
  4515. if (pnodeFnc)
  4516. {
  4517. pnodeFnc->sxFnc.pnodeName = nullptr;
  4518. }
  4519. if ((m_token.tk != tkID || flags & fFncNoName)
  4520. && (IsStrictMode() || (pnodeFnc && pnodeFnc->sxFnc.IsGenerator()) || m_token.tk != tkYIELD || fDeclaration)) // Function expressions can have the name yield even inside generator functions
  4521. {
  4522. if (fDeclaration ||
  4523. m_token.IsReservedWord()) // For example: var x = (function break(){});
  4524. {
  4525. IdentifierExpectedError(m_token);
  4526. }
  4527. return false;
  4528. }
  4529. ichMinNames = m_pscan->IchMinTok();
  4530. Assert(m_token.tk == tkID || (m_token.tk == tkYIELD && !fDeclaration));
  4531. if (IsStrictMode())
  4532. {
  4533. CheckStrictModeEvalArgumentsUsage(m_token.GetIdentifier(m_phtbl));
  4534. }
  4535. Token tokenBase = m_token;
  4536. charcount_t ichMinBase = m_pscan->IchMinTok();
  4537. charcount_t ichLimBase = m_pscan->IchLimTok();
  4538. m_pscan->Scan();
  4539. if (buildAST || BindDeferredPidRefs())
  4540. {
  4541. IdentPtr pidBase = tokenBase.GetIdentifier(m_phtbl);
  4542. pnodeT = CreateDeclNode(knopVarDecl, pidBase, STFunction);
  4543. pnodeT->ichMin = ichMinBase;
  4544. pnodeT->ichLim = ichLimBase;
  4545. if (fDeclaration &&
  4546. pnodeFncParent &&
  4547. pnodeFncParent->sxFnc.pnodeName &&
  4548. pnodeFncParent->sxFnc.pnodeName->nop == knopVarDecl &&
  4549. pnodeFncParent->sxFnc.pnodeName->sxVar.pid == pidBase)
  4550. {
  4551. pnodeFncParent->sxFnc.SetNameIsHidden();
  4552. }
  4553. }
  4554. if (buildAST)
  4555. {
  4556. AnalysisAssert(pnodeFnc);
  4557. ichLimNames = pnodeT->ichLim;
  4558. AddToNodeList(&pnodeFnc->sxFnc.pnodeName, pLastNodeRef, pnodeT);
  4559. pnodeFnc->sxFnc.pnodeName->ichMin = ichMinNames;
  4560. pnodeFnc->sxFnc.pnodeName->ichLim = ichLimNames;
  4561. if (knopVarDecl == pnodeFnc->sxFnc.pnodeName->nop)
  4562. {
  4563. // Only one name (the common case).
  4564. pnodeFnc->sxFnc.pid = pnodeFnc->sxFnc.pnodeName->sxVar.pid;
  4565. }
  4566. else
  4567. {
  4568. // Multiple names. Turn the source into an IdentPtr.
  4569. pnodeFnc->sxFnc.pid = m_phtbl->PidHashNameLen(
  4570. m_pscan->PchBase() + ichMinNames, ichLimNames - ichMinNames);
  4571. }
  4572. if(pnodeFnc->sxFnc.pid == wellKnownPropertyPids.arguments && fDeclaration && pnodeFncParent)
  4573. {
  4574. // This function declaration (or function expression in compat modes) overrides the built-in arguments object of the
  4575. // parent function
  4576. pnodeFncParent->grfpn |= PNodeFlags::fpnArguments_overriddenByDecl;
  4577. }
  4578. }
  4579. return true;
  4580. }
  4581. void Parser::ValidateFormals()
  4582. {
  4583. ParseFncFormals<false>(NULL, fFncNoFlgs);
  4584. // Eat the tkRParen. The ParseFncDeclHelper caller expects to see it.
  4585. m_pscan->Scan();
  4586. }
  4587. void Parser::ValidateSourceElementList()
  4588. {
  4589. ParseStmtList<false>(NULL, NULL, SM_NotUsed, true);
  4590. }
  4591. void Parser::UpdateOrCheckForDuplicateInFormals(IdentPtr pid, SList<IdentPtr> *formals)
  4592. {
  4593. bool isStrictMode = IsStrictMode();
  4594. if (isStrictMode)
  4595. {
  4596. CheckStrictModeEvalArgumentsUsage(pid);
  4597. }
  4598. if (formals->Has(pid))
  4599. {
  4600. if (isStrictMode)
  4601. {
  4602. Error(ERRES5ArgSame);
  4603. }
  4604. else
  4605. {
  4606. Error(ERRFormalSame);
  4607. }
  4608. }
  4609. else
  4610. {
  4611. formals->Prepend(pid);
  4612. }
  4613. }
  4614. template<bool buildAST>
  4615. void Parser::ParseFncFormals(ParseNodePtr pnodeFnc, ushort flags)
  4616. {
  4617. // In strict mode we need to detect duplicated formals so force PID creation (unless the function should take 0 or 1 arg).
  4618. BOOL forcePid = IsStrictMode() && ((flags & (fFncNoArg | fFncOneArg)) == 0);
  4619. AutoTempForcePid autoForcePid(m_pscan, forcePid);
  4620. // Lambda's allow single formal specified by a single binding identifier without parentheses, special case it.
  4621. if (m_token.tk == tkID && (flags & fFncLambda))
  4622. {
  4623. if (buildAST || BindDeferredPidRefs())
  4624. {
  4625. IdentPtr pid = m_token.GetIdentifier(m_phtbl);
  4626. CreateVarDeclNode(pid, STFormal, false, nullptr, false);
  4627. CheckPidIsValid(pid);
  4628. m_pscan->Scan();
  4629. if (m_token.tk != tkDArrow)
  4630. {
  4631. Error(ERRsyntax, m_pscan->IchMinTok(), m_pscan->IchLimTok());
  4632. }
  4633. return;
  4634. }
  4635. }
  4636. // Otherwise, must have a parameter list within parens.
  4637. ChkCurTok(tkLParen, ERRnoLparen);
  4638. // Now parse the list of arguments, if present
  4639. Assert((flags & (fFncNoArg | fFncOneArg)) != (fFncNoArg | fFncOneArg)); // fFncNoArg and fFncOneArg can never be at same time.
  4640. if (m_token.tk == tkRParen)
  4641. {
  4642. if (flags & fFncOneArg)
  4643. {
  4644. Error(ERRSetterMustHaveOneArgument);
  4645. }
  4646. }
  4647. else
  4648. {
  4649. if (flags & fFncNoArg)
  4650. {
  4651. Error(ERRnoRparen); //enforce no arguments
  4652. // No recovery necessary since this is a semantic, not structural, error
  4653. }
  4654. SList<IdentPtr> formals(&m_nodeAllocator);
  4655. ParseNodePtr pnodeT = nullptr;
  4656. bool seenRestParameter = false;
  4657. bool isNonSimpleParameterList = false;
  4658. for (Js::ArgSlot argPos = 0; ; ++argPos)
  4659. {
  4660. bool isBindingPattern = false;
  4661. if (m_scriptContext->GetConfig()->IsES6RestEnabled() && m_token.tk == tkEllipsis)
  4662. {
  4663. // Possible rest parameter
  4664. m_pscan->Scan();
  4665. seenRestParameter = true;
  4666. }
  4667. if (m_token.tk != tkID)
  4668. {
  4669. if (IsES6DestructuringEnabled() && IsPossiblePatternStart())
  4670. {
  4671. ParseNodePtr *const ppnodeVarSave = m_ppnodeVar;
  4672. m_ppnodeVar = &pnodeFnc->sxFnc.pnodeVars;
  4673. ParseNodePtr paramPattern = nullptr;
  4674. ParseNodePtr pnodePattern = ParseDestructuredLiteral<buildAST>(tkLET, true /*isDecl*/, false /*topLevel*/);
  4675. if (buildAST)
  4676. {
  4677. // Instead of passing the STFormal all the way on many methods, it seems it is better to change the symbol type afterward.
  4678. Parser::MapBindIdentifier(pnodePattern, [&](ParseNodePtr item) {
  4679. Assert(item->IsVarLetOrConst());
  4680. UpdateOrCheckForDuplicateInFormals(item->sxVar.pid, &formals);
  4681. item->sxVar.sym->SetSymbolType(STFormal);
  4682. });
  4683. Assert(pnodePattern->IsPattern() || pnodePattern->nop == knopAsg);
  4684. }
  4685. m_ppnodeVar = ppnodeVarSave;
  4686. if (buildAST)
  4687. {
  4688. paramPattern = CreateParamPatternNode(pnodePattern);
  4689. // Linking the current formal parameter (which is pattern parameter) with other formals.
  4690. *m_ppnodeVar = paramPattern;
  4691. paramPattern->sxParamPattern.pnodeNext = nullptr;
  4692. m_ppnodeVar = &paramPattern->sxParamPattern.pnodeNext;
  4693. m_currentNodeFunc->sxFnc.SetHasDestructuringPattern();
  4694. }
  4695. isBindingPattern = true;
  4696. isNonSimpleParameterList = true;
  4697. }
  4698. else
  4699. {
  4700. IdentifierExpectedError(m_token);
  4701. }
  4702. }
  4703. if (!isBindingPattern)
  4704. {
  4705. if (seenRestParameter)
  4706. {
  4707. if (flags & fFncSetter)
  4708. {
  4709. // The parameter of a setter cannot be a rest parameter.
  4710. Error(ERRUnexpectedEllipsis);
  4711. }
  4712. if (buildAST || BindDeferredPidRefs())
  4713. {
  4714. pnodeT = CreateDeclNode(knopVarDecl, m_token.GetIdentifier(m_phtbl), STFormal, false);
  4715. pnodeT->sxVar.sym->SetIsNonSimpleParameter(true);
  4716. if (buildAST)
  4717. {
  4718. // When only validating formals, we won't have a function node.
  4719. pnodeFnc->sxFnc.pnodeRest = pnodeT;
  4720. if (!isNonSimpleParameterList)
  4721. {
  4722. // This is the first non-simple parameter we've seen. We need to go back
  4723. // and set the Symbols of all previous parameters.
  4724. MapFormalsWithoutRest(m_currentNodeFunc, [&](ParseNodePtr pnodeArg) { pnodeArg->sxVar.sym->SetIsNonSimpleParameter(true); });
  4725. }
  4726. }
  4727. }
  4728. isNonSimpleParameterList = true;
  4729. }
  4730. else
  4731. {
  4732. if (buildAST || BindDeferredPidRefs())
  4733. {
  4734. pnodeT = CreateVarDeclNode(m_token.GetIdentifier(m_phtbl), STFormal, false, nullptr, false);
  4735. if (isNonSimpleParameterList)
  4736. {
  4737. pnodeT->sxVar.sym->SetIsNonSimpleParameter(true);
  4738. }
  4739. }
  4740. }
  4741. if (buildAST && m_token.GetIdentifier(m_phtbl) == wellKnownPropertyPids.arguments)
  4742. {
  4743. // This formal parameter overrides the built-in 'arguments' object
  4744. m_currentNodeFunc->grfpn |= PNodeFlags::fpnArguments_overriddenByDecl;
  4745. }
  4746. if (IsStrictMode() || isNonSimpleParameterList)
  4747. {
  4748. IdentPtr pid = m_token.GetIdentifier(m_phtbl);
  4749. UpdateOrCheckForDuplicateInFormals(pid, &formals);
  4750. }
  4751. m_pscan->Scan();
  4752. if (seenRestParameter && m_token.tk != tkRParen && m_token.tk != tkAsg)
  4753. {
  4754. Error(ERRRestLastArg);
  4755. }
  4756. if (flags & fFncOneArg)
  4757. {
  4758. if (m_token.tk != tkRParen)
  4759. {
  4760. Error(ERRSetterMustHaveOneArgument);
  4761. }
  4762. break; //enforce only one arg
  4763. }
  4764. if (m_token.tk == tkAsg && m_scriptContext->GetConfig()->IsES6DefaultArgsEnabled())
  4765. {
  4766. if (seenRestParameter && m_scriptContext->GetConfig()->IsES6RestEnabled())
  4767. {
  4768. Error(ERRRestWithDefault);
  4769. }
  4770. m_pscan->Scan();
  4771. ParseNodePtr pnodeInit = ParseExpr<buildAST>(koplCma);
  4772. if (buildAST || BindDeferredPidRefs())
  4773. {
  4774. AnalysisAssert(pnodeT);
  4775. pnodeT->sxVar.sym->SetIsNonSimpleParameter(true);
  4776. if (!isNonSimpleParameterList)
  4777. {
  4778. if (buildAST)
  4779. {
  4780. // This is the first non-simple parameter we've seen. We need to go back
  4781. // and set the Symbols of all previous parameters.
  4782. MapFormalsWithoutRest(m_currentNodeFunc, [&](ParseNodePtr pnodeArg) { pnodeArg->sxVar.sym->SetIsNonSimpleParameter(true); });
  4783. }
  4784. // There may be previous parameters that need to be checked for duplicates.
  4785. isNonSimpleParameterList = true;
  4786. }
  4787. }
  4788. // In defer parse mode we have to flag the function node to indicate that it has default arguments
  4789. // so that it will be considered for any syntax error scenario.
  4790. ParseNode* currentFncNode = GetCurrentFunctionNode();
  4791. if (!currentFncNode->sxFnc.HasDefaultArguments())
  4792. {
  4793. currentFncNode->sxFnc.SetHasDefaultArguments();
  4794. currentFncNode->sxFnc.firstDefaultArg = argPos;
  4795. }
  4796. if (buildAST)
  4797. {
  4798. if (!m_currentNodeFunc->sxFnc.HasDefaultArguments())
  4799. {
  4800. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(DefaultArgFunctionCount, m_scriptContext);
  4801. }
  4802. pnodeT->sxVar.pnodeInit = pnodeInit;
  4803. pnodeT->ichLim = m_pscan->IchLimTok();
  4804. }
  4805. }
  4806. }
  4807. if (isNonSimpleParameterList && m_currentScope->GetHasDuplicateFormals())
  4808. {
  4809. Error(ERRFormalSame);
  4810. }
  4811. if (m_token.tk != tkComma)
  4812. {
  4813. break;
  4814. }
  4815. m_pscan->Scan();
  4816. if (m_token.tk == tkRParen && m_scriptContext->GetConfig()->IsES7TrailingCommaEnabled())
  4817. {
  4818. break;
  4819. }
  4820. }
  4821. if (seenRestParameter)
  4822. {
  4823. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(RestCount, m_scriptContext);
  4824. }
  4825. if (m_token.tk != tkRParen)
  4826. {
  4827. Error(ERRnoRparen);
  4828. }
  4829. }
  4830. Assert(m_token.tk == tkRParen);
  4831. }
  4832. template<bool buildAST>
  4833. ParseNodePtr Parser::GenerateEmptyConstructor(bool extends)
  4834. {
  4835. ParseNodePtr pnodeFnc;
  4836. if (buildAST || BindDeferredPidRefs())
  4837. {
  4838. // Create the node.
  4839. pnodeFnc = CreateNode(knopFncDecl);
  4840. pnodeFnc->sxFnc.ClearFlags();
  4841. pnodeFnc->sxFnc.SetNested(NULL != m_currentNodeFunc);
  4842. pnodeFnc->sxFnc.SetStrictMode();
  4843. pnodeFnc->sxFnc.SetDeclaration(TRUE);
  4844. pnodeFnc->sxFnc.SetIsMethod(TRUE);
  4845. pnodeFnc->sxFnc.SetIsClassMember(TRUE);
  4846. pnodeFnc->sxFnc.SetIsClassConstructor(TRUE);
  4847. pnodeFnc->sxFnc.SetIsBaseClassConstructor(!extends);
  4848. pnodeFnc->sxFnc.SetHasNonThisStmt(extends);
  4849. pnodeFnc->sxFnc.SetIsGeneratedDefault(TRUE);
  4850. pnodeFnc->ichLim = m_pscan->IchLimTok();
  4851. pnodeFnc->ichMin = m_pscan->IchMinTok();
  4852. pnodeFnc->sxFnc.cbLim = m_pscan->IecpLimTok();
  4853. pnodeFnc->sxFnc.cbMin = m_pscan->IecpMinTok();
  4854. pnodeFnc->sxFnc.astSize = 0;
  4855. pnodeFnc->sxFnc.lineNumber = m_pscan->LineCur();
  4856. pnodeFnc->sxFnc.functionId = (*m_nextFunctionId);
  4857. pnodeFnc->sxFnc.pid = nullptr;
  4858. pnodeFnc->sxFnc.hint = nullptr;
  4859. pnodeFnc->sxFnc.hintOffset = 0;
  4860. pnodeFnc->sxFnc.hintLength = 0;
  4861. pnodeFnc->sxFnc.isNameIdentifierRef = true;
  4862. pnodeFnc->sxFnc.pnodeName = nullptr;
  4863. pnodeFnc->sxFnc.pnodeScopes = nullptr;
  4864. pnodeFnc->sxFnc.pnodeArgs = nullptr;
  4865. pnodeFnc->sxFnc.pnodeVars = nullptr;
  4866. pnodeFnc->sxFnc.pnodeBody = nullptr;
  4867. pnodeFnc->sxFnc.nestedCount = 0;
  4868. pnodeFnc->sxFnc.pnodeNext = nullptr;
  4869. pnodeFnc->sxFnc.pnodeRest = nullptr;
  4870. pnodeFnc->sxFnc.deferredStub = nullptr;
  4871. pnodeFnc->sxFnc.funcInfo = nullptr;
  4872. #ifdef DBG
  4873. pnodeFnc->sxFnc.deferredParseNextFunctionId = *(this->m_nextFunctionId);
  4874. #endif
  4875. AppendFunctionToScopeList(true, pnodeFnc);
  4876. }
  4877. if (m_nextFunctionId)
  4878. {
  4879. (*m_nextFunctionId)++;
  4880. }
  4881. // Update the count of functions nested in the current parent.
  4882. if (m_pnestedCount)
  4883. {
  4884. (*m_pnestedCount)++;
  4885. }
  4886. if (!buildAST)
  4887. {
  4888. return NULL;
  4889. }
  4890. if (m_pscan->IchMinTok() >= m_pscan->IchMinLine())
  4891. {
  4892. // In scenarios involving defer parse IchMinLine() can be incorrect for the first line after defer parse
  4893. pnodeFnc->sxFnc.columnNumber = m_pscan->IchMinTok() - m_pscan->IchMinLine();
  4894. }
  4895. else if (m_currentNodeFunc)
  4896. {
  4897. // For the first line after defer parse, compute the column relative to the column number
  4898. // of the lexically parent function.
  4899. ULONG offsetFromCurrentFunction = m_pscan->IchMinTok() - m_currentNodeFunc->ichMin;
  4900. pnodeFnc->sxFnc.columnNumber = m_currentNodeFunc->sxFnc.columnNumber + offsetFromCurrentFunction;
  4901. }
  4902. else
  4903. {
  4904. // if there is no current function, lets give a default of 0.
  4905. pnodeFnc->sxFnc.columnNumber = 0;
  4906. }
  4907. long * pAstSizeSave = m_pCurrentAstSize;
  4908. m_pCurrentAstSize = &(pnodeFnc->sxFnc.astSize);
  4909. // Make this the current function.
  4910. ParseNodePtr pnodeFncSave = m_currentNodeFunc;
  4911. m_currentNodeFunc = pnodeFnc;
  4912. ParseNodePtr pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Parameter, ScopeType_Parameter);
  4913. ParseNodePtr pnodeInnerBlock = StartParseBlock<buildAST>(PnodeBlockType::Function, ScopeType_FunctionBody);
  4914. pnodeBlock->sxBlock.pnodeScopes = pnodeInnerBlock;
  4915. pnodeFnc->sxFnc.pnodeBodyScope = pnodeInnerBlock;
  4916. pnodeFnc->sxFnc.pnodeScopes = pnodeBlock;
  4917. ParseNodePtr *lastNodeRef = nullptr;
  4918. if (extends)
  4919. {
  4920. // constructor() { super(...arguments); } (equivalent to constructor(...args) { super(...args); } )
  4921. PidRefStack *ref = this->PushPidRef(wellKnownPropertyPids.arguments);
  4922. ParseNodePtr argumentsId = CreateNameNode(wellKnownPropertyPids.arguments, pnodeFnc->ichMin, pnodeFnc->ichLim);
  4923. argumentsId->sxPid.symRef = ref->GetSymRef();
  4924. pnodeFnc->sxFnc.SetUsesArguments(true);
  4925. pnodeFnc->sxFnc.SetHasReferenceableBuiltInArguments(true);
  4926. ParseNodePtr *const ppnodeVarSave = m_ppnodeVar;
  4927. m_ppnodeVar = &pnodeFnc->sxFnc.pnodeVars;
  4928. CreateVarDeclNode(wellKnownPropertyPids.arguments, STVariable, true, pnodeFnc)->grfpn |= PNodeFlags::fpnArguments;
  4929. m_ppnodeVar = ppnodeVarSave;
  4930. ParseNodePtr spreadArg = CreateUniNode(knopEllipsis, argumentsId, pnodeFnc->ichMin, pnodeFnc->ichLim);
  4931. ParseNodePtr superRef = CreateNodeWithScanner<knopSuper>();
  4932. pnodeFnc->sxFnc.SetHasSuperReference(TRUE);
  4933. ParseNodePtr callNode = CreateCallNode(knopCall, superRef, spreadArg);
  4934. callNode->sxCall.spreadArgCount = 1;
  4935. AddToNodeList(&pnodeFnc->sxFnc.pnodeBody, &lastNodeRef, callNode);
  4936. }
  4937. AddToNodeList(&pnodeFnc->sxFnc.pnodeBody, &lastNodeRef, CreateNodeWithScanner<knopEndCode>());
  4938. FinishParseBlock(pnodeInnerBlock);
  4939. FinishParseBlock(pnodeBlock);
  4940. m_currentNodeFunc = pnodeFncSave;
  4941. m_pCurrentAstSize = pAstSizeSave;
  4942. return pnodeFnc;
  4943. }
  4944. template<bool buildAST>
  4945. void Parser::ParseExpressionLambdaBody(ParseNodePtr pnodeLambda)
  4946. {
  4947. ParseNodePtr *lastNodeRef = nullptr;
  4948. // The lambda body is a single expression, the result of which is the return value.
  4949. ParseNodePtr pnodeRet = nullptr;
  4950. if (buildAST)
  4951. {
  4952. pnodeRet = CreateNodeWithScanner<knopReturn>();
  4953. pnodeRet->grfpn |= PNodeFlags::fpnSyntheticNode;
  4954. pnodeLambda->sxFnc.pnodeScopes->sxBlock.pnodeStmt = pnodeRet;
  4955. }
  4956. ParseNodePtr result = ParseExpr<buildAST>(koplAsg, nullptr, TRUE, FALSE, nullptr);
  4957. if (buildAST)
  4958. {
  4959. pnodeRet->sxReturn.pnodeExpr = result;
  4960. pnodeRet->ichMin = pnodeRet->sxReturn.pnodeExpr->ichMin;
  4961. pnodeRet->ichLim = pnodeRet->sxReturn.pnodeExpr->ichLim;
  4962. // Pushing a statement node with PushStmt<>() normally does this initialization
  4963. // but do it here manually since we know there is no outer statement node.
  4964. pnodeRet->sxStmt.grfnop = 0;
  4965. pnodeRet->sxStmt.pnodeOuter = nullptr;
  4966. pnodeLambda->ichLim = pnodeRet->ichLim;
  4967. pnodeLambda->sxFnc.cbLim = m_pscan->IecpLimTokPrevious();
  4968. pnodeLambda->sxFnc.pnodeScopes->ichLim = pnodeRet->ichLim;
  4969. pnodeLambda->sxFnc.pnodeBody = nullptr;
  4970. AddToNodeList(&pnodeLambda->sxFnc.pnodeBody, &lastNodeRef, pnodeLambda->sxFnc.pnodeScopes);
  4971. // Append an EndCode node.
  4972. ParseNodePtr end = CreateNodeWithScanner<knopEndCode>(pnodeRet->ichLim);
  4973. end->ichLim = end->ichMin; // make end code zero width at the immediate end of lambda body
  4974. AddToNodeList(&pnodeLambda->sxFnc.pnodeBody, &lastNodeRef, end);
  4975. // Lambda's do not have arguments binding
  4976. pnodeLambda->sxFnc.SetHasReferenceableBuiltInArguments(false);
  4977. }
  4978. }
  4979. void Parser::CheckStrictFormalParameters()
  4980. {
  4981. Assert(m_token.tk == tkLParen);
  4982. m_pscan->ScanForcingPid();
  4983. if (m_token.tk != tkRParen)
  4984. {
  4985. SList<IdentPtr> formals(&m_nodeAllocator);
  4986. for (;;)
  4987. {
  4988. if (m_token.tk != tkID)
  4989. {
  4990. IdentifierExpectedError(m_token);
  4991. }
  4992. IdentPtr pid = m_token.GetIdentifier(m_phtbl);
  4993. CheckStrictModeEvalArgumentsUsage(pid);
  4994. if (formals.Has(pid))
  4995. {
  4996. Error(ERRES5ArgSame, m_pscan->IchMinTok(), m_pscan->IchLimTok());
  4997. }
  4998. else
  4999. {
  5000. formals.Prepend(pid);
  5001. }
  5002. m_pscan->Scan();
  5003. if (m_token.tk == tkAsg && m_scriptContext->GetConfig()->IsES6DefaultArgsEnabled())
  5004. {
  5005. m_pscan->Scan();
  5006. // We can avoid building the AST since we are just checking the default expression.
  5007. ParseNodePtr pnodeInit = ParseExpr<false>(koplCma);
  5008. Assert(pnodeInit == nullptr);
  5009. }
  5010. if (m_token.tk != tkComma)
  5011. {
  5012. break;
  5013. }
  5014. m_pscan->ScanForcingPid();
  5015. if (m_token.tk == tkRParen && m_scriptContext->GetConfig()->IsES7TrailingCommaEnabled())
  5016. {
  5017. break;
  5018. }
  5019. }
  5020. }
  5021. Assert(m_token.tk == tkRParen);
  5022. }
  5023. void Parser::FinishFncNode(ParseNodePtr pnodeFnc)
  5024. {
  5025. AnalysisAssert(pnodeFnc);
  5026. // Finish the AST for a function that was deferred earlier, but which we decided
  5027. // to finish after the fact.
  5028. // We assume that the name(s) and arg(s) have already got parse nodes, so
  5029. // we just have to do the function body.
  5030. // Save the current next function Id, and resume from the old one.
  5031. Js::LocalFunctionId * nextFunctionIdSave = m_nextFunctionId;
  5032. Js::LocalFunctionId tempNextFunctionId = pnodeFnc->sxFnc.functionId + 1;
  5033. this->m_nextFunctionId = &tempNextFunctionId;
  5034. ParseNodePtr pnodeFncSave = m_currentNodeFunc;
  5035. uint *pnestedCountSave = m_pnestedCount;
  5036. long* pAstSizeSave = m_pCurrentAstSize;
  5037. m_currentNodeFunc = pnodeFnc;
  5038. m_pCurrentAstSize = & (pnodeFnc->sxFnc.astSize);
  5039. pnodeFnc->sxFnc.nestedCount = 0;
  5040. m_pnestedCount = &pnodeFnc->sxFnc.nestedCount;
  5041. // Cue up the parser to the start of the function body.
  5042. if (pnodeFnc->sxFnc.pnodeName)
  5043. {
  5044. // Skip the name(s).
  5045. m_pscan->SetCurrentCharacter(pnodeFnc->sxFnc.pnodeName->ichLim, pnodeFnc->sxFnc.lineNumber);
  5046. }
  5047. else
  5048. {
  5049. m_pscan->SetCurrentCharacter(pnodeFnc->ichMin, pnodeFnc->sxFnc.lineNumber);
  5050. if (pnodeFnc->sxFnc.IsAccessor())
  5051. {
  5052. // Getter/setter. The node text starts with the name, so eat that.
  5053. m_pscan->ScanNoKeywords();
  5054. }
  5055. else
  5056. {
  5057. // Anonymous function. Skip any leading "("'s and "function".
  5058. for (;;)
  5059. {
  5060. m_pscan->Scan();
  5061. if (m_token.tk == tkFUNCTION)
  5062. {
  5063. break;
  5064. }
  5065. Assert(m_token.tk == tkLParen || m_token.tk == tkStar);
  5066. }
  5067. }
  5068. }
  5069. // switch scanner to treat 'yield' as keyword in generator functions
  5070. // or as an identifier in non-generator functions
  5071. bool fPreviousYieldIsKeyword = m_pscan->SetYieldIsKeyword(pnodeFnc && pnodeFnc->sxFnc.IsGenerator());
  5072. bool fPreviousAwaitIsKeyword = m_pscan->SetAwaitIsKeyword(pnodeFnc && pnodeFnc->sxFnc.IsAsync());
  5073. // Skip the arg list.
  5074. m_pscan->ScanNoKeywords();
  5075. if (m_token.tk == tkStar)
  5076. {
  5077. Assert(pnodeFnc->sxFnc.IsGenerator());
  5078. m_pscan->ScanNoKeywords();
  5079. }
  5080. Assert(m_token.tk == tkLParen);
  5081. m_pscan->ScanNoKeywords();
  5082. if (m_token.tk != tkRParen)
  5083. {
  5084. for (;;)
  5085. {
  5086. if (m_token.tk == tkEllipsis)
  5087. {
  5088. m_pscan->ScanNoKeywords();
  5089. }
  5090. if (m_token.tk == tkID)
  5091. {
  5092. m_pscan->ScanNoKeywords();
  5093. if (m_token.tk == tkAsg)
  5094. {
  5095. // Eat the default expression
  5096. m_pscan->ScanNoKeywords();
  5097. ParseExpr<false>(koplCma);
  5098. }
  5099. }
  5100. else if (IsPossiblePatternStart())
  5101. {
  5102. ParseDestructuredLiteralWithScopeSave(tkLET, false/*isDecl*/, false /*topLevel*/);
  5103. }
  5104. else
  5105. {
  5106. AssertMsg(false, "Unexpected identifier prefix while fast-scanning formals");
  5107. }
  5108. if (m_token.tk != tkComma)
  5109. {
  5110. break;
  5111. }
  5112. m_pscan->ScanNoKeywords();
  5113. if (m_token.tk == tkRParen && m_scriptContext->GetConfig()->IsES7TrailingCommaEnabled())
  5114. {
  5115. break;
  5116. }
  5117. }
  5118. }
  5119. if (m_token.tk == tkRParen) // This might be false due to a lambda => token.
  5120. {
  5121. m_pscan->Scan();
  5122. }
  5123. // Finish the function body.
  5124. {
  5125. // Note that in IE8- modes, surrounding parentheses are considered part of function body. e.g. "( function x(){} )".
  5126. // We lose that context here since we start from middle of function body. So save and restore source range info.
  5127. ParseNodePtr* lastNodeRef = NULL;
  5128. const charcount_t ichLim = pnodeFnc->ichLim;
  5129. const size_t cbLim = pnodeFnc->sxFnc.cbLim;
  5130. this->FinishFncDecl(pnodeFnc, NULL, lastNodeRef);
  5131. #if DBG
  5132. // The pnode extent may not match the original extent.
  5133. // We expect this to happen only when there are trailing ")"'s.
  5134. // Consume them and make sure that's all we've got.
  5135. if (pnodeFnc->ichLim != ichLim)
  5136. {
  5137. Assert(pnodeFnc->ichLim < ichLim);
  5138. m_pscan->SetCurrentCharacter(pnodeFnc->ichLim);
  5139. while (m_pscan->IchLimTok() != ichLim)
  5140. {
  5141. m_pscan->ScanNoKeywords();
  5142. Assert(m_token.tk == tkRParen);
  5143. }
  5144. }
  5145. #endif
  5146. pnodeFnc->ichLim = ichLim;
  5147. pnodeFnc->sxFnc.cbLim = cbLim;
  5148. }
  5149. m_currentNodeFunc = pnodeFncSave;
  5150. m_pCurrentAstSize = pAstSizeSave;
  5151. m_pnestedCount = pnestedCountSave;
  5152. Assert(m_pnestedCount);
  5153. Assert(tempNextFunctionId == pnodeFnc->sxFnc.deferredParseNextFunctionId);
  5154. this->m_nextFunctionId = nextFunctionIdSave;
  5155. m_pscan->SetYieldIsKeyword(fPreviousYieldIsKeyword);
  5156. m_pscan->SetAwaitIsKeyword(fPreviousAwaitIsKeyword);
  5157. }
  5158. void Parser::FinishFncDecl(ParseNodePtr pnodeFnc, LPCOLESTR pNameHint, ParseNodePtr *lastNodeRef)
  5159. {
  5160. LPCOLESTR name = NULL;
  5161. JS_ETW(long startAstSize = *m_pCurrentAstSize);
  5162. if(IS_JS_ETW(EventEnabledJSCRIPT_PARSE_METHOD_START()) || PHASE_TRACE1(Js::DeferParsePhase))
  5163. {
  5164. name = GetFunctionName(pnodeFnc, pNameHint);
  5165. m_functionBody = NULL; // for nested functions we do not want to get the name of the top deferred function return name;
  5166. JS_ETW(EventWriteJSCRIPT_PARSE_METHOD_START(m_sourceContextInfo->dwHostSourceContext, GetScriptContext(), pnodeFnc->sxFnc.functionId, 0, m_parseType, name));
  5167. OUTPUT_TRACE(Js::DeferParsePhase, L"Parsing function (%s) : %s (%d)\n", GetParseType(), name, pnodeFnc->sxFnc.functionId);
  5168. }
  5169. JS_ETW(EventWriteJSCRIPT_PARSE_FUNC(GetScriptContext(), pnodeFnc->sxFnc.functionId, /*Undefer*/FALSE));
  5170. // Do the work of creating an AST for a function body.
  5171. // This is common to the un-deferred case and the case in which we un-defer late in the game.
  5172. Assert(pnodeFnc->nop == knopFncDecl);
  5173. ChkCurTok(tkLCurly, ERRnoLcurly);
  5174. if (pnodeFnc->sxFnc.IsAsync())
  5175. {
  5176. TransformAsyncFncDeclAST(&pnodeFnc->sxFnc.pnodeBody, false);
  5177. }
  5178. else
  5179. {
  5180. ParseStmtList<true>(&pnodeFnc->sxFnc.pnodeBody, &lastNodeRef, SM_OnFunctionCode, true /* isSourceElementList */);
  5181. // Append an EndCode node.
  5182. AddToNodeList(&pnodeFnc->sxFnc.pnodeBody, &lastNodeRef, CreateNodeWithScanner<knopEndCode>());
  5183. }
  5184. ChkCurTokNoScan(tkRCurly, ERRnoRcurly);
  5185. pnodeFnc->ichLim = m_pscan->IchLimTok();
  5186. pnodeFnc->sxFnc.cbLim = m_pscan->IecpLimTok();
  5187. // Restore the lists of scopes that contain function expressions.
  5188. // Save the temps and restore the outer scope's list.
  5189. // NOTE: Eze makes no use of this.
  5190. //pnodeFnc->sxFnc.pnodeTmps = *m_ppnodeVar;
  5191. #ifdef ENABLE_JS_ETW
  5192. long astSize = *m_pCurrentAstSize - startAstSize;
  5193. EventWriteJSCRIPT_PARSE_METHOD_STOP(m_sourceContextInfo->dwHostSourceContext, GetScriptContext(), pnodeFnc->sxFnc.functionId, astSize, m_parseType, name);
  5194. #endif
  5195. }
  5196. void Parser::AddArgumentsNodeToVars(ParseNodePtr pnodeFnc)
  5197. {
  5198. if((pnodeFnc->grfpn & PNodeFlags::fpnArguments_overriddenByDecl) || pnodeFnc->sxFnc.IsLambda())
  5199. {
  5200. // In any of the following cases, there is no way to reference the built-in 'arguments' variable (in the order of checks
  5201. // above):
  5202. // - A function parameter is named 'arguments'
  5203. // - There is a nested function declaration (or named function expression in compat modes) named 'arguments'
  5204. // - In compat modes, the function is named arguments, does not have a var declaration named 'arguments', and does
  5205. // not call 'eval'
  5206. pnodeFnc->sxFnc.SetHasReferenceableBuiltInArguments(false);
  5207. }
  5208. else
  5209. {
  5210. if(m_ppnodeVar == &pnodeFnc->sxFnc.pnodeVars)
  5211. {
  5212. // There were no var declarations in the function
  5213. CreateVarDeclNode(wellKnownPropertyPids.arguments, STVariable, true, pnodeFnc)->grfpn |= PNodeFlags::fpnArguments;
  5214. }
  5215. else
  5216. {
  5217. // There were var declarations in the function, so insert an 'arguments' local at the beginning of the var list.
  5218. // This is done because the built-in 'arguments' variable overrides an 'arguments' var declaration until the
  5219. // 'arguments' variable is assigned. By putting our built-in var declaration at the beginning, an 'arguments'
  5220. // identifier will resolve to this symbol, which has the fpnArguments flag set, and will be the built-in arguments
  5221. // object until it is replaced with something else.
  5222. ParseNodePtr *const ppnodeVarSave = m_ppnodeVar;
  5223. m_ppnodeVar = &pnodeFnc->sxFnc.pnodeVars;
  5224. CreateVarDeclNode(wellKnownPropertyPids.arguments, STVariable, true, pnodeFnc)->grfpn |= PNodeFlags::fpnArguments;
  5225. m_ppnodeVar = ppnodeVarSave;
  5226. }
  5227. pnodeFnc->sxFnc.SetHasReferenceableBuiltInArguments(true);
  5228. }
  5229. }
  5230. LPCOLESTR Parser::GetFunctionName(ParseNodePtr pnodeFnc, LPCOLESTR pNameHint)
  5231. {
  5232. LPCOLESTR name = nullptr;
  5233. if(pnodeFnc->sxFnc.pnodeName != nullptr && knopVarDecl == pnodeFnc->sxFnc.pnodeName->nop)
  5234. {
  5235. name = pnodeFnc->sxFnc.pnodeName->sxVar.pid->Psz();
  5236. }
  5237. if(name == nullptr && pNameHint != nullptr)
  5238. {
  5239. name = pNameHint;
  5240. }
  5241. if(name == nullptr && m_functionBody != nullptr)
  5242. {
  5243. name = m_functionBody->GetExternalDisplayName();
  5244. }
  5245. else if(name == nullptr)
  5246. {
  5247. name = Js::Constants::AnonymousFunction;
  5248. }
  5249. return name;
  5250. }
  5251. IdentPtr Parser::ParseClassPropertyName(IdentPtr * pidHint)
  5252. {
  5253. if (m_token.tk == tkID || m_token.tk == tkStrCon || m_token.IsReservedWord())
  5254. {
  5255. IdentPtr pid;
  5256. if (m_token.tk == tkStrCon)
  5257. {
  5258. if (m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  5259. {
  5260. Error(ERRES5NoOctal);
  5261. }
  5262. pid = m_token.GetStr();
  5263. }
  5264. else
  5265. {
  5266. pid = m_token.GetIdentifier(m_phtbl);
  5267. }
  5268. *pidHint = pid;
  5269. return pid;
  5270. }
  5271. else if (m_token.tk == tkIntCon)
  5272. {
  5273. if (m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  5274. {
  5275. Error(ERRES5NoOctal);
  5276. }
  5277. return m_pscan->PidFromLong(m_token.GetLong());
  5278. }
  5279. else if (m_token.tk == tkFltCon)
  5280. {
  5281. if (m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  5282. {
  5283. Error(ERRES5NoOctal);
  5284. }
  5285. return m_pscan->PidFromDbl(m_token.GetDouble());
  5286. }
  5287. Error(ERRnoMemberIdent);
  5288. }
  5289. LPCOLESTR Parser::ConstructFinalHintNode(IdentPtr pClassName, IdentPtr pMemberName, IdentPtr pGetSet, bool isStatic, ulong* nameLength, ulong* pShortNameOffset, bool isComputedName, LPCOLESTR pMemberNameHint)
  5290. {
  5291. if ((pMemberName == nullptr && !isComputedName) ||
  5292. (pMemberNameHint == nullptr && isComputedName) ||
  5293. !CONFIG_FLAG(UseFullName))
  5294. {
  5295. return nullptr;
  5296. }
  5297. LPCOLESTR pFinalName = isComputedName? pMemberNameHint : pMemberName->Psz();
  5298. ulong fullNameHintLength = 0;
  5299. ulong shortNameOffset = 0;
  5300. if (!isStatic)
  5301. {
  5302. // Add prototype.
  5303. pFinalName = AppendNameHints(wellKnownPropertyPids.prototype, pFinalName, &fullNameHintLength, &shortNameOffset);
  5304. }
  5305. if (pClassName)
  5306. {
  5307. pFinalName = AppendNameHints(pClassName, pFinalName, &fullNameHintLength, &shortNameOffset);
  5308. }
  5309. if (pGetSet)
  5310. {
  5311. if (m_scriptContext->GetConfig()->IsES6FunctionNameEnabled())
  5312. {
  5313. // displays as get/set prototype.funcname
  5314. ulong getSetOffset = 0;
  5315. pFinalName = AppendNameHints(pGetSet, pFinalName, &fullNameHintLength, &getSetOffset, true);
  5316. shortNameOffset += getSetOffset;
  5317. }
  5318. else
  5319. {
  5320. pFinalName = AppendNameHints(pFinalName, pGetSet, &fullNameHintLength, &shortNameOffset);
  5321. }
  5322. }
  5323. if (fullNameHintLength > *nameLength)
  5324. {
  5325. *nameLength = fullNameHintLength;
  5326. }
  5327. if (shortNameOffset > *pShortNameOffset)
  5328. {
  5329. *pShortNameOffset = shortNameOffset;
  5330. }
  5331. return pFinalName;
  5332. }
  5333. class AutoParsingSuperRestrictionStateRestorer
  5334. {
  5335. public:
  5336. AutoParsingSuperRestrictionStateRestorer(Parser* parser) : m_parser(parser)
  5337. {
  5338. AssertMsg(this->m_parser != nullptr, "This just should not happen");
  5339. this->m_originalParsingSuperRestrictionState = this->m_parser->m_parsingSuperRestrictionState;
  5340. }
  5341. ~AutoParsingSuperRestrictionStateRestorer()
  5342. {
  5343. AssertMsg(this->m_parser != nullptr, "This just should not happen");
  5344. this->m_parser->m_parsingSuperRestrictionState = m_originalParsingSuperRestrictionState;
  5345. }
  5346. private:
  5347. Parser* m_parser;
  5348. int m_originalParsingSuperRestrictionState;
  5349. };
  5350. template<bool buildAST>
  5351. ParseNodePtr Parser::ParseClassDecl(BOOL isDeclaration, LPCOLESTR pNameHint, ulong *pHintLength, ulong *pShortNameOffset)
  5352. {
  5353. bool hasConstructor = false;
  5354. bool hasExtends = false;
  5355. IdentPtr name = nullptr;
  5356. ParseNodePtr pnodeName = nullptr;
  5357. ParseNodePtr pnodeConstructor = nullptr;
  5358. ParseNodePtr pnodeExtends = nullptr;
  5359. ParseNodePtr pnodeMembers = nullptr;
  5360. ParseNodePtr *lastMemberNodeRef = nullptr;
  5361. ParseNodePtr pnodeStaticMembers = nullptr;
  5362. ParseNodePtr *lastStaticMemberNodeRef = nullptr;
  5363. ulong nameHintLength = pHintLength ? *pHintLength : 0;
  5364. ulong nameHintOffset = pShortNameOffset ? *pShortNameOffset : 0;
  5365. ArenaAllocator tempAllocator(L"ClassMemberNames", m_nodeAllocator.GetPageAllocator(), Parser::OutOfMemory);
  5366. ParseNodePtr pnodeClass = nullptr;
  5367. if (buildAST)
  5368. {
  5369. pnodeClass = CreateNode(knopClassDecl);
  5370. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ClassCount, m_scriptContext);
  5371. }
  5372. m_pscan->Scan();
  5373. if (m_token.tk == tkID)
  5374. {
  5375. name = m_token.GetIdentifier(m_phtbl);
  5376. m_pscan->Scan();
  5377. }
  5378. else if (isDeclaration)
  5379. {
  5380. IdentifierExpectedError(m_token);
  5381. }
  5382. if (isDeclaration && name == wellKnownPropertyPids.arguments && GetCurrentBlockInfo()->pnodeBlock->sxBlock.blockType == Function)
  5383. {
  5384. GetCurrentFunctionNode()->grfpn |= PNodeFlags::fpnArguments_overriddenByDecl;
  5385. }
  5386. BOOL strictSave = m_fUseStrictMode;
  5387. m_fUseStrictMode = TRUE;
  5388. if (m_token.tk == tkEXTENDS)
  5389. {
  5390. m_pscan->Scan();
  5391. pnodeExtends = ParseExpr<buildAST>();
  5392. hasExtends = true;
  5393. }
  5394. if (m_token.tk != tkLCurly)
  5395. {
  5396. Error(ERRnoLcurly);
  5397. }
  5398. OUTPUT_TRACE_DEBUGONLY(Js::ES6VerboseFlag, L"Parsing class (%s) : %s\n", GetParseType(), name ? name->Psz() : L"anonymous class");
  5399. ParseNodePtr pnodeDeclName = nullptr;
  5400. if (isDeclaration)
  5401. {
  5402. pnodeDeclName = CreateBlockScopedDeclNode(name, knopLetDecl);
  5403. }
  5404. ParseNodePtr *ppnodeScopeSave = nullptr;
  5405. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  5406. ParseNodePtr pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Regular, ScopeType_Block);
  5407. if (buildAST)
  5408. {
  5409. PushFuncBlockScope(pnodeBlock, &ppnodeScopeSave, &ppnodeExprScopeSave);
  5410. pnodeClass->sxClass.pnodeBlock = pnodeBlock;
  5411. }
  5412. if (name)
  5413. {
  5414. pnodeName = CreateBlockScopedDeclNode(name, knopConstDecl);
  5415. }
  5416. RestorePoint beginClass;
  5417. m_pscan->Capture(&beginClass);
  5418. m_pscan->ScanForcingPid();
  5419. IdentPtr pClassNamePid = pnodeName ? pnodeName->sxVar.pid : nullptr;
  5420. for (;;)
  5421. {
  5422. if (m_token.tk == tkSColon)
  5423. {
  5424. m_pscan->ScanForcingPid();
  5425. continue;
  5426. }
  5427. if (m_token.tk == tkRCurly)
  5428. {
  5429. break;
  5430. }
  5431. bool isStatic = m_token.tk == tkSTATIC;
  5432. if (isStatic)
  5433. {
  5434. m_pscan->ScanForcingPid();
  5435. }
  5436. ushort fncDeclFlags = fFncNoName | fFncMethod | fFncClassMember;
  5437. charcount_t ichMin = 0;
  5438. size_t iecpMin = 0;
  5439. ParseNodePtr pnodeMemberName = nullptr;
  5440. IdentPtr pidHint = nullptr;
  5441. IdentPtr memberPid = nullptr;
  5442. LPCOLESTR pMemberNameHint = nullptr;
  5443. ulong memberNameHintLength = 0;
  5444. ulong memberNameOffset = 0;
  5445. bool isComputedName = false;
  5446. bool isAsyncMethod = false;
  5447. if (m_token.tk == tkID && m_token.GetIdentifier(m_phtbl) == wellKnownPropertyPids.async && m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
  5448. {
  5449. RestorePoint parsedAsync;
  5450. m_pscan->Capture(&parsedAsync);
  5451. ichMin = m_pscan->IchMinTok();
  5452. iecpMin = m_pscan->IecpMinTok();
  5453. m_pscan->Scan();
  5454. if (m_token.tk == tkLParen || m_pscan->FHadNewLine())
  5455. {
  5456. m_pscan->SeekTo(parsedAsync);
  5457. }
  5458. else
  5459. {
  5460. isAsyncMethod = true;
  5461. }
  5462. }
  5463. bool isGenerator = m_scriptContext->GetConfig()->IsES6GeneratorsEnabled() &&
  5464. m_token.tk == tkStar;
  5465. if (isGenerator)
  5466. {
  5467. fncDeclFlags |= fFncGenerator;
  5468. m_pscan->ScanForcingPid();
  5469. }
  5470. if (m_token.tk == tkLBrack && m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
  5471. {
  5472. // Computed member name: [expr] () { }
  5473. LPCOLESTR emptyHint = nullptr;
  5474. ParseComputedName<buildAST>(&pnodeMemberName, &emptyHint, &pMemberNameHint, &memberNameHintLength, &memberNameOffset);
  5475. isComputedName = true;
  5476. }
  5477. else // not computed name
  5478. {
  5479. memberPid = this->ParseClassPropertyName(&pidHint);
  5480. if (pidHint)
  5481. {
  5482. pMemberNameHint = pidHint->Psz();
  5483. memberNameHintLength = pidHint->Cch();
  5484. }
  5485. }
  5486. if (buildAST && memberPid)
  5487. {
  5488. pnodeMemberName = CreateStrNodeWithScanner(memberPid);
  5489. }
  5490. if (!isStatic && memberPid == wellKnownPropertyPids.constructor)
  5491. {
  5492. if (hasConstructor || isAsyncMethod)
  5493. {
  5494. Error(ERRsyntax);
  5495. }
  5496. hasConstructor = true;
  5497. LPCOLESTR pConstructorName = nullptr;
  5498. ulong constructorNameLength = 0;
  5499. ulong constructorShortNameHintOffset = 0;
  5500. if (pnodeName && pnodeName->sxVar.pid)
  5501. {
  5502. pConstructorName = pnodeName->sxVar.pid->Psz();
  5503. constructorNameLength = pnodeName->sxVar.pid->Cch();
  5504. }
  5505. else
  5506. {
  5507. pConstructorName = pNameHint;
  5508. constructorNameLength = nameHintLength;
  5509. constructorShortNameHintOffset = nameHintOffset;
  5510. }
  5511. {
  5512. AutoParsingSuperRestrictionStateRestorer restorer(this);
  5513. this->m_parsingSuperRestrictionState = hasExtends ? ParsingSuperRestrictionState_SuperCallAndPropertyAllowed : ParsingSuperRestrictionState_SuperPropertyAllowed;
  5514. pnodeConstructor = ParseFncDecl<buildAST>(fncDeclFlags, pConstructorName, false, /* needsPIDOnRCurlyScan */ true, /* resetParsingSuperRestrictionState = */false);
  5515. }
  5516. if (pnodeConstructor->sxFnc.IsGenerator())
  5517. {
  5518. Error(ERRConstructorCannotBeGenerator);
  5519. }
  5520. Assert(constructorNameLength >= constructorShortNameHintOffset);
  5521. // The constructor function will get the same name as class.
  5522. pnodeConstructor->sxFnc.hint = pConstructorName;
  5523. pnodeConstructor->sxFnc.hintLength = constructorNameLength;
  5524. pnodeConstructor->sxFnc.hintOffset = constructorShortNameHintOffset;
  5525. pnodeConstructor->sxFnc.pid = pnodeName && pnodeName->sxVar.pid ? pnodeName->sxVar.pid : wellKnownPropertyPids.constructor;
  5526. pnodeConstructor->sxFnc.SetIsClassConstructor(TRUE);
  5527. pnodeConstructor->sxFnc.SetIsBaseClassConstructor(pnodeExtends == nullptr);
  5528. }
  5529. else
  5530. {
  5531. ParseNodePtr pnodeMember = nullptr;
  5532. bool isMemberNamedGetOrSet = false;
  5533. RestorePoint beginMethodName;
  5534. m_pscan->Capture(&beginMethodName);
  5535. if (memberPid == wellKnownPropertyPids.getter || memberPid == wellKnownPropertyPids.setter)
  5536. {
  5537. m_pscan->ScanForcingPid();
  5538. }
  5539. if (m_token.tk == tkLParen)
  5540. {
  5541. m_pscan->SeekTo(beginMethodName);
  5542. isMemberNamedGetOrSet = true;
  5543. }
  5544. if ((memberPid == wellKnownPropertyPids.getter || memberPid == wellKnownPropertyPids.setter) && !isMemberNamedGetOrSet)
  5545. {
  5546. bool isGetter = (memberPid == wellKnownPropertyPids.getter);
  5547. if (m_token.tk == tkLBrack && m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
  5548. {
  5549. // Computed get/set member name: get|set [expr] () { }
  5550. LPCOLESTR emptyHint = nullptr;
  5551. ParseComputedName<buildAST>(&pnodeMemberName, &emptyHint, &pMemberNameHint, &memberNameHintLength, &memberNameOffset);
  5552. isComputedName = true;
  5553. }
  5554. else // not computed name
  5555. {
  5556. memberPid = this->ParseClassPropertyName(&pidHint);
  5557. }
  5558. if ((isStatic ? (memberPid == wellKnownPropertyPids.prototype) : (memberPid == wellKnownPropertyPids.constructor)) || isAsyncMethod)
  5559. {
  5560. Error(ERRsyntax);
  5561. }
  5562. if (buildAST && memberPid && !isComputedName)
  5563. {
  5564. pnodeMemberName = CreateStrNodeWithScanner(memberPid);
  5565. }
  5566. ParseNodePtr pnodeFnc = nullptr;
  5567. {
  5568. AutoParsingSuperRestrictionStateRestorer restorer(this);
  5569. this->m_parsingSuperRestrictionState = ParsingSuperRestrictionState_SuperPropertyAllowed;
  5570. pnodeFnc = ParseFncDecl<buildAST>((isGetter ? fFncNoArg : fFncSetter) | fncDeclFlags, pidHint ? pidHint->Psz() : nullptr, false, /* needsPIDOnRCurlyScan */ true, /* resetParsingSuperRestrictionState */false);
  5571. }
  5572. pnodeFnc->sxFnc.SetIsStaticMember(isStatic);
  5573. if (buildAST)
  5574. {
  5575. pnodeFnc->sxFnc.SetIsAccessor();
  5576. pnodeMember = CreateBinNode(isGetter ? knopGetMember : knopSetMember, pnodeMemberName, pnodeFnc);
  5577. pMemberNameHint = ConstructFinalHintNode(pClassNamePid, pidHint, isGetter ? wellKnownPropertyPids.getter : wellKnownPropertyPids.setter, isStatic, &memberNameHintLength, &memberNameOffset, isComputedName, pMemberNameHint);
  5578. }
  5579. }
  5580. else
  5581. {
  5582. if (isStatic && (memberPid == wellKnownPropertyPids.prototype))
  5583. {
  5584. Error(ERRsyntax);
  5585. }
  5586. ParseNodePtr pnodeFnc = nullptr;
  5587. {
  5588. AutoParsingSuperRestrictionStateRestorer restorer(this);
  5589. this->m_parsingSuperRestrictionState = ParsingSuperRestrictionState_SuperPropertyAllowed;
  5590. if (isAsyncMethod)
  5591. {
  5592. fncDeclFlags |= fFncAsync;
  5593. }
  5594. pnodeFnc = ParseFncDecl<buildAST>(fncDeclFlags, pidHint ? pidHint->Psz() : nullptr, false, /* needsPIDOnRCurlyScan */ true, /* resetParsingSuperRestrictionState */false);
  5595. if (isAsyncMethod)
  5596. {
  5597. pnodeFnc->sxFnc.cbMin = iecpMin;
  5598. pnodeFnc->ichMin = ichMin;
  5599. }
  5600. }
  5601. pnodeFnc->sxFnc.SetIsStaticMember(isStatic);
  5602. if (buildAST)
  5603. {
  5604. pnodeMember = CreateBinNode(knopMember, pnodeMemberName, pnodeFnc);
  5605. pMemberNameHint = ConstructFinalHintNode(pClassNamePid, pidHint, nullptr /*pgetset*/, isStatic, &memberNameHintLength, &memberNameOffset, isComputedName, pMemberNameHint);
  5606. }
  5607. }
  5608. if (buildAST)
  5609. {
  5610. Assert(memberNameHintLength >= memberNameOffset);
  5611. pnodeMember->sxBin.pnode2->sxFnc.hint = pMemberNameHint; // Fully qualified name
  5612. pnodeMember->sxBin.pnode2->sxFnc.hintLength = memberNameHintLength;
  5613. pnodeMember->sxBin.pnode2->sxFnc.hintOffset = memberNameOffset;
  5614. pnodeMember->sxBin.pnode2->sxFnc.pid = memberPid; // Short name
  5615. AddToNodeList(isStatic ? &pnodeStaticMembers : &pnodeMembers, isStatic ? &lastStaticMemberNodeRef : &lastMemberNodeRef, pnodeMember);
  5616. }
  5617. }
  5618. }
  5619. if (buildAST)
  5620. {
  5621. pnodeClass->ichLim = m_pscan->IchLimTok();
  5622. }
  5623. if (!hasConstructor)
  5624. {
  5625. OUTPUT_TRACE_DEBUGONLY(Js::ES6VerboseFlag, L"Generating constructor (%s) : %s\n", GetParseType(), name ? name->Psz() : L"anonymous class");
  5626. RestorePoint endClass;
  5627. m_pscan->Capture(&endClass);
  5628. m_pscan->SeekTo(beginClass);
  5629. pnodeConstructor = GenerateEmptyConstructor<buildAST>(pnodeExtends != nullptr);
  5630. if (buildAST)
  5631. {
  5632. if (pClassNamePid)
  5633. {
  5634. pnodeConstructor->sxFnc.hint = pClassNamePid->Psz();
  5635. pnodeConstructor->sxFnc.hintLength = pClassNamePid->Cch();
  5636. pnodeConstructor->sxFnc.hintOffset = 0;
  5637. }
  5638. else
  5639. {
  5640. Assert(nameHintLength >= nameHintOffset);
  5641. pnodeConstructor->sxFnc.hint = pNameHint;
  5642. pnodeConstructor->sxFnc.hintLength = nameHintLength;
  5643. pnodeConstructor->sxFnc.hintOffset = nameHintOffset;
  5644. }
  5645. pnodeConstructor->sxFnc.pid = pClassNamePid;
  5646. }
  5647. m_pscan->SeekTo(endClass);
  5648. }
  5649. if (buildAST)
  5650. {
  5651. pnodeConstructor->sxFnc.cbMin = pnodeClass->ichMin;
  5652. pnodeConstructor->sxFnc.cbLim = pnodeClass->ichLim;
  5653. pnodeConstructor->ichMin = pnodeClass->ichMin;
  5654. pnodeConstructor->ichLim = pnodeClass->ichLim;
  5655. PopFuncBlockScope(ppnodeScopeSave, ppnodeExprScopeSave);
  5656. pnodeClass->sxClass.pnodeDeclName = pnodeDeclName;
  5657. pnodeClass->sxClass.pnodeName = pnodeName;
  5658. pnodeClass->sxClass.pnodeConstructor = pnodeConstructor;
  5659. pnodeClass->sxClass.pnodeExtends = pnodeExtends;
  5660. pnodeClass->sxClass.pnodeMembers = pnodeMembers;
  5661. pnodeClass->sxClass.pnodeStaticMembers = pnodeStaticMembers;
  5662. }
  5663. FinishParseBlock(pnodeBlock);
  5664. m_fUseStrictMode = strictSave;
  5665. m_pscan->Scan();
  5666. return pnodeClass;
  5667. }
  5668. template<bool buildAST>
  5669. ParseNodePtr Parser::ParseStringTemplateDecl(ParseNodePtr pnodeTagFnc)
  5670. {
  5671. ParseNodePtr pnodeStringLiterals = nullptr;
  5672. ParseNodePtr* lastStringLiteralNodeRef = nullptr;
  5673. ParseNodePtr pnodeRawStringLiterals = nullptr;
  5674. ParseNodePtr* lastRawStringLiteralNodeRef = nullptr;
  5675. ParseNodePtr pnodeSubstitutionExpressions = nullptr;
  5676. ParseNodePtr* lastSubstitutionExpressionNodeRef = nullptr;
  5677. ParseNodePtr pnodeTagFncArgs = nullptr;
  5678. ParseNodePtr* lastTagFncArgNodeRef = nullptr;
  5679. ParseNodePtr stringLiteral = nullptr;
  5680. ParseNodePtr stringLiteralRaw = nullptr;
  5681. ParseNodePtr pnodeStringTemplate = nullptr;
  5682. bool templateClosed = false;
  5683. const bool isTagged = pnodeTagFnc != nullptr;
  5684. uint16 stringConstantCount = 0;
  5685. charcount_t ichMin = 0;
  5686. Assert(m_token.tk == tkStrTmplBasic || m_token.tk == tkStrTmplBegin);
  5687. if (buildAST)
  5688. {
  5689. pnodeStringTemplate = CreateNode(knopStrTemplate);
  5690. pnodeStringTemplate->sxStrTemplate.countStringLiterals = 0;
  5691. pnodeStringTemplate->sxStrTemplate.isTaggedTemplate = isTagged ? TRUE : FALSE;
  5692. // If this is a tagged string template, we need to start building the arg list for the call
  5693. if (isTagged)
  5694. {
  5695. ichMin = pnodeTagFnc->ichMin;
  5696. AddToNodeListEscapedUse(&pnodeTagFncArgs, &lastTagFncArgNodeRef, pnodeStringTemplate);
  5697. }
  5698. }
  5699. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(StringTemplatesCount, m_scriptContext);
  5700. OUTPUT_TRACE_DEBUGONLY(
  5701. Js::StringTemplateParsePhase,
  5702. L"Starting to parse a string template (%s)...\n\tis tagged = %s\n",
  5703. GetParseType(),
  5704. isTagged ? L"true" : L"false (Raw and cooked strings will not differ!)");
  5705. // String template grammar
  5706. // `...` Simple string template
  5707. // `...${ String template beginning
  5708. // }...${ String template middle
  5709. // }...` String template end
  5710. while (!templateClosed)
  5711. {
  5712. // First, extract the string constant part - we always have one
  5713. if (IsStrictMode() && m_pscan->IsOctOrLeadingZeroOnLastTKNumber())
  5714. {
  5715. Error(ERRES5NoOctal);
  5716. }
  5717. // We are not able to pass more than a ushort worth of arguments to the tag
  5718. // so use that as a logical limit on the number of string constant pieces.
  5719. if (stringConstantCount >= USHORT_MAX)
  5720. {
  5721. Error(ERRnoMemory);
  5722. }
  5723. // Keep track of the string literal count (must be the same for raw strings)
  5724. // We use this in code gen so we don't need to count the string literals list
  5725. stringConstantCount++;
  5726. // If we are not creating parse nodes, there is no need to create strings
  5727. if (buildAST)
  5728. {
  5729. stringLiteral = CreateStrNodeWithScanner(m_token.GetStr());
  5730. AddToNodeList(&pnodeStringLiterals, &lastStringLiteralNodeRef, stringLiteral);
  5731. // We only need to collect a raw string when we are going to pass the string template to a tag
  5732. if (isTagged)
  5733. {
  5734. // Make the scanner create a PID for the raw string constant for the preceding scan
  5735. IdentPtr pid = m_pscan->GetSecondaryBufferAsPid();
  5736. stringLiteralRaw = CreateStrNodeWithScanner(pid);
  5737. // Should have gotten a raw string literal above
  5738. AddToNodeList(&pnodeRawStringLiterals, &lastRawStringLiteralNodeRef, stringLiteralRaw);
  5739. }
  5740. else
  5741. {
  5742. #if DBG
  5743. // Assign the raw string for debug tracing below
  5744. stringLiteralRaw = stringLiteral;
  5745. #endif
  5746. }
  5747. OUTPUT_TRACE_DEBUGONLY(
  5748. Js::StringTemplateParsePhase,
  5749. L"Parsed string constant: \n\tcooked = \"%s\" \n\traw = \"%s\" \n\tdiffer = %d\n",
  5750. stringLiteral->sxPid.pid->Psz(),
  5751. stringLiteralRaw->sxPid.pid->Psz(),
  5752. stringLiteral->sxPid.pid->Psz() == stringLiteralRaw->sxPid.pid->Psz() ? 0 : 1);
  5753. }
  5754. switch (m_token.tk)
  5755. {
  5756. case tkStrTmplEnd:
  5757. case tkStrTmplBasic:
  5758. // We do not need to parse an expression for either the end or basic string template tokens
  5759. templateClosed = true;
  5760. break;
  5761. case tkStrTmplBegin:
  5762. case tkStrTmplMid:
  5763. {
  5764. // In the middle or begin string template token case, we need to parse an expression next
  5765. m_pscan->Scan();
  5766. // Parse the contents of the curly braces as an expression
  5767. ParseNodePtr expression = ParseExpr<buildAST>(0);
  5768. // After parsing expression, scan should leave us with an RCurly token.
  5769. // Use the NoScan version so we do not automatically perform a scan - we need to
  5770. // set the scan state before next scan but we don't want to set that state if
  5771. // the token is not as expected since we'll error in that case.
  5772. ChkCurTokNoScan(tkRCurly, ERRnoRcurly);
  5773. // Notify the scanner that it should scan for a middle or end string template token
  5774. m_pscan->SetScanState(Scanner_t::ScanState::ScanStateStringTemplateMiddleOrEnd);
  5775. m_pscan->Scan();
  5776. if (buildAST)
  5777. {
  5778. // If we are going to call the tag function, add this expression into the list of args
  5779. if (isTagged)
  5780. {
  5781. AddToNodeListEscapedUse(&pnodeTagFncArgs, &lastTagFncArgNodeRef, expression);
  5782. }
  5783. else
  5784. {
  5785. // Otherwise add it to the substitution expression list
  5786. // TODO: Store the arguments and substitution expressions in a single list?
  5787. AddToNodeList(&pnodeSubstitutionExpressions, &lastSubstitutionExpressionNodeRef, expression);
  5788. }
  5789. }
  5790. if (!(m_token.tk == tkStrTmplMid || m_token.tk == tkStrTmplEnd))
  5791. {
  5792. // Scan with ScanState ScanStateStringTemplateMiddleOrEnd should only return
  5793. // tkStrTmpMid/End unless it is EOF or tkScanError
  5794. Assert(m_token.tk == tkEOF || m_token.tk == tkScanError);
  5795. Error(ERRsyntax);
  5796. }
  5797. OUTPUT_TRACE_DEBUGONLY(Js::StringTemplateParsePhase, L"Parsed expression\n");
  5798. }
  5799. break;
  5800. default:
  5801. Assert(false);
  5802. break;
  5803. }
  5804. }
  5805. if (buildAST)
  5806. {
  5807. pnodeStringTemplate->sxStrTemplate.pnodeStringLiterals = pnodeStringLiterals;
  5808. pnodeStringTemplate->sxStrTemplate.pnodeStringRawLiterals = pnodeRawStringLiterals;
  5809. pnodeStringTemplate->sxStrTemplate.pnodeSubstitutionExpressions = pnodeSubstitutionExpressions;
  5810. pnodeStringTemplate->sxStrTemplate.countStringLiterals = stringConstantCount;
  5811. // We should still have the last string literal.
  5812. // Use the char offset of the end of that constant as the end of the string template.
  5813. pnodeStringTemplate->ichLim = stringLiteral->ichLim;
  5814. // If this is a tagged template, we now have the argument list and can construct a call node
  5815. if (isTagged)
  5816. {
  5817. // Return the call node here and let the byte code generator Emit the string template automagically
  5818. pnodeStringTemplate = CreateCallNode(knopCall, pnodeTagFnc, pnodeTagFncArgs, ichMin, pnodeStringTemplate->ichLim);
  5819. // We need to set the arg count explicitly
  5820. pnodeStringTemplate->sxCall.argCount = stringConstantCount;
  5821. }
  5822. }
  5823. m_pscan->Scan();
  5824. return pnodeStringTemplate;
  5825. }
  5826. void Parser::TransformAsyncFncDeclAST(ParseNodePtr *pnodeBody, bool fLambda)
  5827. {
  5828. StmtNest *pstmtSave;
  5829. ParseNodePtr pnodeReturn;
  5830. ParseNodePtr pnodeAsyncSpawn;
  5831. ParseNodePtr pnodeFncGenerator = nullptr;
  5832. ParseNodePtr pnodeFncSave = nullptr;
  5833. ParseNodePtr pnodeDeferredFncSave = nullptr;
  5834. ParseNodePtr pnodeInnerBlock = nullptr;
  5835. ParseNodePtr pnodeBlock = nullptr;
  5836. ParseNodePtr *lastNodeRef = nullptr;
  5837. ParseNodePtr *ppnodeScopeSave = nullptr;
  5838. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  5839. AutoParsingSuperRestrictionStateRestorer restorer(this);
  5840. // Create the generator : function*() {}
  5841. uint tryCatchOrFinallyDepthSave = this->m_tryCatchOrFinallyDepth;
  5842. this->m_tryCatchOrFinallyDepth = 0;
  5843. uint scopeCountNoAstSave = m_scopeCountNoAst;
  5844. m_scopeCountNoAst = 0;
  5845. long* pAstSizeSave = m_pCurrentAstSize;
  5846. pnodeFncSave = m_currentNodeFunc;
  5847. pnodeDeferredFncSave = m_currentNodeDeferredFunc;
  5848. pnodeFncGenerator = CreateAsyncSpawnGenerator();
  5849. m_currentNodeDeferredFunc = pnodeFncGenerator;
  5850. m_inDeferredNestedFunc = true;
  5851. pstmtSave = m_pstmtCur;
  5852. SetCurrentStatement(nullptr);
  5853. bool fPreviousYieldIsKeyword = m_pscan->SetYieldIsKeyword(FALSE);
  5854. BOOL oldStrictMode = this->m_fUseStrictMode;
  5855. uint uDeferSave = m_grfscr & fscrDeferFncParse;
  5856. pnodeBlock = StartParseBlock<true>(PnodeBlockType::Parameter, ScopeType_Parameter);
  5857. pnodeFncGenerator->sxFnc.pnodeScopes = pnodeBlock;
  5858. m_ppnodeVar = &pnodeFncGenerator->sxFnc.pnodeArgs;
  5859. ppnodeScopeSave = m_ppnodeScope;
  5860. m_ppnodeScope = &pnodeBlock->sxBlock.pnodeScopes;
  5861. pnodeBlock->sxBlock.pnodeStmt = pnodeFncGenerator;
  5862. ppnodeExprScopeSave = m_ppnodeExprScope;
  5863. m_ppnodeExprScope = nullptr;
  5864. m_fUseStrictMode = oldStrictMode;
  5865. pnodeInnerBlock = StartParseBlock<true>(PnodeBlockType::Function, ScopeType_FunctionBody);
  5866. *m_ppnodeScope = pnodeInnerBlock;
  5867. pnodeFncGenerator->sxFnc.pnodeBodyScope = pnodeInnerBlock;
  5868. m_ppnodeScope = &pnodeInnerBlock->sxBlock.pnodeScopes;
  5869. pnodeInnerBlock->sxBlock.pnodeStmt = pnodeFncGenerator;
  5870. Assert(*m_ppnodeVar == nullptr);
  5871. pnodeFncGenerator->sxFnc.pnodeVars = nullptr;
  5872. m_ppnodeVar = &pnodeFncGenerator->sxFnc.pnodeVars;
  5873. DeferredFunctionStub *saveCurrentStub = m_currDeferredStub;
  5874. if (pnodeFncSave && m_currDeferredStub)
  5875. {
  5876. m_currDeferredStub = (m_currDeferredStub + (pnodeFncSave->sxFnc.nestedCount - 1))->deferredStubs;
  5877. }
  5878. pnodeFncGenerator->sxFnc.pnodeBody = nullptr;
  5879. if (fLambda)
  5880. {
  5881. // Parse and set the function body
  5882. ParseExpressionLambdaBody<true>(*pnodeBody);
  5883. AddToNodeList(&pnodeFncGenerator->sxFnc.pnodeBody, &lastNodeRef, (*pnodeBody)->sxFnc.pnodeScopes->sxBlock.pnodeStmt);
  5884. }
  5885. else
  5886. {
  5887. // Parse the function body
  5888. ParseStmtList<true>(&pnodeFncGenerator->sxFnc.pnodeBody, &lastNodeRef, SM_OnFunctionCode, true);
  5889. ChkCurTokNoScan(tkRCurly, ERRnoRcurly);
  5890. }
  5891. AddToNodeList(&pnodeFncGenerator->sxFnc.pnodeBody, &lastNodeRef, CreateNodeWithScanner<knopEndCode>());
  5892. lastNodeRef = NULL;
  5893. pnodeFncGenerator->ichLim = m_pscan->IchLimTok();
  5894. pnodeFncGenerator->sxFnc.cbLim = m_pscan->IecpLimTok();
  5895. m_currDeferredStub = saveCurrentStub;
  5896. FinishParseBlock(pnodeInnerBlock, true);
  5897. this->AddArgumentsNodeToVars(pnodeFncGenerator);
  5898. Assert(m_ppnodeExprScope == nullptr || *m_ppnodeExprScope == nullptr);
  5899. m_ppnodeExprScope = ppnodeExprScopeSave;
  5900. AssertMem(m_ppnodeScope);
  5901. Assert(nullptr == *m_ppnodeScope);
  5902. m_ppnodeScope = ppnodeScopeSave;
  5903. FinishParseBlock(pnodeBlock, true);
  5904. Assert(nullptr == m_pstmtCur);
  5905. SetCurrentStatement(pstmtSave);
  5906. if (!m_stoppedDeferredParse)
  5907. {
  5908. m_grfscr |= uDeferSave;
  5909. }
  5910. m_pscan->SetYieldIsKeyword(fPreviousYieldIsKeyword);
  5911. Assert(pnodeFncGenerator == m_currentNodeFunc);
  5912. m_currentNodeFunc = pnodeFncSave;
  5913. m_currentNodeDeferredFunc = pnodeDeferredFncSave;
  5914. m_pCurrentAstSize = pAstSizeSave;
  5915. m_inDeferredNestedFunc = false;
  5916. m_scopeCountNoAst = scopeCountNoAstSave;
  5917. this->m_tryCatchOrFinallyDepth = tryCatchOrFinallyDepthSave;
  5918. // Create the call : spawn(function*() {}, this)
  5919. pnodeAsyncSpawn = CreateBinNode(knopAsyncSpawn, pnodeFncGenerator, CreateNodeWithScanner<knopThis>());
  5920. // Create the return : return spawn(function*() {}, this)
  5921. pnodeReturn = CreateNodeWithScanner<knopReturn>();
  5922. pnodeReturn->sxStmt.grfnop = 0;
  5923. pnodeReturn->sxStmt.pnodeOuter = nullptr;
  5924. pnodeReturn->sxReturn.pnodeExpr = pnodeAsyncSpawn;
  5925. if (fLambda)
  5926. {
  5927. (*pnodeBody)->sxFnc.pnodeScopes->sxBlock.pnodeStmt = nullptr;
  5928. AddToNodeList(&(*pnodeBody)->sxFnc.pnodeScopes->sxBlock.pnodeStmt, &lastNodeRef, pnodeReturn);
  5929. }
  5930. else
  5931. {
  5932. *pnodeBody = nullptr;
  5933. AddToNodeList(pnodeBody, &lastNodeRef, pnodeReturn);
  5934. AddToNodeList(pnodeBody, &lastNodeRef, CreateNodeWithScanner<knopEndCode>());
  5935. }
  5936. lastNodeRef = NULL;
  5937. }
  5938. ParseNodePtr Parser::CreateAsyncSpawnGenerator()
  5939. {
  5940. ParseNodePtr pnodeFncGenerator = nullptr;
  5941. pnodeFncGenerator = CreateDummyFuncNode(false);
  5942. pnodeFncGenerator->sxFnc.functionId = (*m_nextFunctionId)++;
  5943. pnodeFncGenerator->sxFnc.cbMin = m_pscan->IecpMinTok();
  5944. pnodeFncGenerator->sxFnc.cbLim = m_pscan->IecpLimTok();
  5945. pnodeFncGenerator->sxFnc.lineNumber = m_pscan->LineCur();
  5946. pnodeFncGenerator->sxFnc.columnNumber = CalculateFunctionColumnNumber();
  5947. pnodeFncGenerator->sxFnc.SetNested(m_currentNodeFunc != nullptr);
  5948. pnodeFncGenerator->sxFnc.SetStrictMode(IsStrictMode());
  5949. pnodeFncGenerator->sxFnc.SetIsGenerator();
  5950. pnodeFncGenerator->sxFnc.scope = nullptr;
  5951. AppendFunctionToScopeList(false, pnodeFncGenerator);
  5952. return pnodeFncGenerator;
  5953. }
  5954. LPCOLESTR Parser::FormatPropertyString(LPCOLESTR propertyString, ParseNodePtr pNode, ulong *fullNameHintLength, ulong *pShortNameOffset)
  5955. {
  5956. // propertyString could be null, such as 'this.foo' =
  5957. // propertyString could be empty, found in pattern as in (-1)[""][(x = z)]
  5958. OpCode op = pNode->nop;
  5959. LPCOLESTR rightNode = nullptr;
  5960. if (propertyString == nullptr)
  5961. {
  5962. propertyString = L"";
  5963. }
  5964. if (op != knopInt && op != knopFlt && op != knopName && op != knopStr)
  5965. {
  5966. rightNode = L"";
  5967. }
  5968. else if (op == knopStr)
  5969. {
  5970. return AppendNameHints(propertyString, pNode->sxPid.pid, fullNameHintLength, pShortNameOffset, false, true/*add brackets*/);
  5971. }
  5972. else if(op == knopFlt)
  5973. {
  5974. rightNode = m_pscan->StringFromDbl(pNode->sxFlt.dbl);
  5975. }
  5976. else
  5977. {
  5978. rightNode = op == knopInt ? m_pscan->StringFromLong(pNode->sxInt.lw)
  5979. : pNode->sxPid.pid->Psz();
  5980. }
  5981. return AppendNameHints(propertyString, rightNode, fullNameHintLength, pShortNameOffset, false, true/*add brackets*/);
  5982. }
  5983. LPCOLESTR Parser::ConstructNameHint(ParseNodePtr pNode, ulong* fullNameHintLength, ulong *pShortNameOffset)
  5984. {
  5985. Assert(pNode != nullptr);
  5986. Assert(pNode->nop == knopDot || pNode->nop == knopIndex);
  5987. LPCOLESTR leftNode = nullptr;
  5988. if (pNode->sxBin.pnode1->nop == knopDot || pNode->sxBin.pnode1->nop == knopIndex)
  5989. {
  5990. leftNode = ConstructNameHint(pNode->sxBin.pnode1, fullNameHintLength, pShortNameOffset);
  5991. }
  5992. else if (pNode->sxBin.pnode1->nop == knopName)
  5993. {
  5994. leftNode = pNode->sxBin.pnode1->sxPid.pid->Psz();
  5995. *fullNameHintLength = pNode->sxBin.pnode1->sxPid.pid->Cch();
  5996. *pShortNameOffset = 0;
  5997. }
  5998. if (pNode->nop == knopIndex)
  5999. {
  6000. return FormatPropertyString(
  6001. leftNode ? leftNode : Js::Constants::AnonymousFunction, // e.g. f()[0] = function () {}
  6002. pNode->sxBin.pnode2, fullNameHintLength, pShortNameOffset);
  6003. }
  6004. Assert(pNode->sxBin.pnode2->nop == knopDot || pNode->sxBin.pnode2->nop == knopName);
  6005. LPCOLESTR rightNode = nullptr;
  6006. bool wrapWithBrackets = false;
  6007. if (pNode->sxBin.pnode2->nop == knopDot)
  6008. {
  6009. rightNode = ConstructNameHint(pNode->sxBin.pnode2, fullNameHintLength, pShortNameOffset);
  6010. }
  6011. else
  6012. {
  6013. rightNode = pNode->sxBin.pnode2->sxPid.pid->Psz();
  6014. wrapWithBrackets = PNodeFlags::fpnIndexOperator == (pNode->grfpn & PNodeFlags::fpnIndexOperator);
  6015. }
  6016. Assert(rightNode != nullptr);
  6017. return AppendNameHints(leftNode, rightNode, fullNameHintLength, pShortNameOffset, false, wrapWithBrackets);
  6018. }
  6019. LPCOLESTR Parser::AppendNameHints(LPCOLESTR leftStr, ulong leftLen, LPCOLESTR rightStr, ulong rightLen, ulong *pNameLength, ulong *pShortNameOffset, bool ignoreAddDotWithSpace, bool wrapInBrackets)
  6020. {
  6021. Assert(rightStr != nullptr);
  6022. Assert(leftLen != 0 || wrapInBrackets);
  6023. Assert(rightLen != 0 || wrapInBrackets);
  6024. bool ignoreDot = rightStr[0] == L'[' && !wrapInBrackets;//if we wrap in brackets it can be a string literal which can have brackets at the first char
  6025. ulong totalLength = leftLen + rightLen + ((ignoreDot) ? 1 : 2); // 1 (for dot or [) + 1 (for null termination)
  6026. if (wrapInBrackets)
  6027. {
  6028. totalLength++; //1 for ']';
  6029. }
  6030. WCHAR * finalName = AllocateStringOfLength(totalLength);
  6031. if (leftStr != nullptr && leftLen != 0)
  6032. {
  6033. wcscpy_s(finalName, leftLen + 1, leftStr);
  6034. }
  6035. if (ignoreAddDotWithSpace)
  6036. {
  6037. finalName[leftLen++] = (OLECHAR)L' ';
  6038. }
  6039. // mutually exclusive from ignoreAddDotWithSpace which is used for getters/setters
  6040. else if (wrapInBrackets)
  6041. {
  6042. finalName[leftLen++] = (OLECHAR)L'[';
  6043. finalName[totalLength-2] = (OLECHAR)L']';
  6044. }
  6045. else if (!ignoreDot)
  6046. {
  6047. finalName[leftLen++] = (OLECHAR)L'.';
  6048. }
  6049. //ignore case falls through
  6050. js_wmemcpy_s(finalName + leftLen, rightLen, rightStr, rightLen);
  6051. finalName[totalLength-1] = (OLECHAR)L'\0';
  6052. if (pNameLength != nullptr)
  6053. {
  6054. *pNameLength = totalLength - 1;
  6055. }
  6056. if (pShortNameOffset != nullptr)
  6057. {
  6058. *pShortNameOffset = leftLen;
  6059. }
  6060. return finalName;
  6061. }
  6062. WCHAR * Parser::AllocateStringOfLength(ulong length)
  6063. {
  6064. Assert(length > 0);
  6065. ULONG totalBytes;
  6066. if (ULongMult(length, sizeof(OLECHAR), &totalBytes) != S_OK)
  6067. {
  6068. Error(ERRnoMemory);
  6069. }
  6070. WCHAR* finalName = (WCHAR*)m_phtbl->GetAllocator()->Alloc(totalBytes);
  6071. if (finalName == nullptr)
  6072. {
  6073. Error(ERRnoMemory);
  6074. }
  6075. return finalName;
  6076. }
  6077. LPCOLESTR Parser::AppendNameHints(IdentPtr left, IdentPtr right, ulong *pNameLength, ulong *pShortNameOffset, bool ignoreAddDotWithSpace, bool wrapInBrackets)
  6078. {
  6079. if (pShortNameOffset != nullptr)
  6080. {
  6081. *pShortNameOffset = 0;
  6082. }
  6083. if (left == nullptr && !wrapInBrackets)
  6084. {
  6085. if (right)
  6086. {
  6087. *pNameLength = right->Cch();
  6088. return right->Psz();
  6089. }
  6090. return nullptr;
  6091. }
  6092. ulong leftLen = 0;
  6093. LPCOLESTR leftStr = L"";
  6094. if (left != nullptr) // if wrapInBrackets is true
  6095. {
  6096. leftStr = left->Psz();
  6097. leftLen = left->Cch();
  6098. }
  6099. if (right == nullptr)
  6100. {
  6101. *pNameLength = leftLen;
  6102. return left->Psz();
  6103. }
  6104. ulong rightLen = right->Cch();
  6105. return AppendNameHints(leftStr, leftLen, right->Psz(), rightLen, pNameLength, pShortNameOffset, ignoreAddDotWithSpace, wrapInBrackets);
  6106. }
  6107. LPCOLESTR Parser::AppendNameHints(IdentPtr left, LPCOLESTR right, ulong *pNameLength, ulong *pShortNameOffset, bool ignoreAddDotWithSpace, bool wrapInBrackets)
  6108. {
  6109. ulong rightLen = (right == nullptr) ? 0 : (ulong) wcslen(right);
  6110. if (pShortNameOffset != nullptr)
  6111. {
  6112. *pShortNameOffset = 0;
  6113. }
  6114. Assert(rightLen <= ULONG_MAX); // name hints should not exceed ULONG_MAX characters
  6115. if (left == nullptr && !wrapInBrackets)
  6116. {
  6117. *pNameLength = rightLen;
  6118. return right;
  6119. }
  6120. LPCOLESTR leftStr = L"";
  6121. ulong leftLen = 0;
  6122. if (left != nullptr) // if wrapInBrackets is true
  6123. {
  6124. leftStr = left->Psz();
  6125. leftLen = left->Cch();
  6126. }
  6127. if (rightLen == 0 && !wrapInBrackets)
  6128. {
  6129. *pNameLength = leftLen;
  6130. return left->Psz();
  6131. }
  6132. return AppendNameHints(leftStr, leftLen, right, rightLen, pNameLength, pShortNameOffset, ignoreAddDotWithSpace, wrapInBrackets);
  6133. }
  6134. LPCOLESTR Parser::AppendNameHints(LPCOLESTR left, IdentPtr right, ulong *pNameLength, ulong *pShortNameOffset, bool ignoreAddDotWithSpace, bool wrapInBrackets)
  6135. {
  6136. ulong leftLen = (left == nullptr) ? 0 : (ulong) wcslen(left);
  6137. if (pShortNameOffset != nullptr)
  6138. {
  6139. *pShortNameOffset = 0;
  6140. }
  6141. Assert(leftLen <= ULONG_MAX); // name hints should not exceed ULONG_MAX characters
  6142. if (left == nullptr || leftLen == 0 && !wrapInBrackets)
  6143. {
  6144. if (right != nullptr)
  6145. {
  6146. *pNameLength = right->Cch();
  6147. return right->Psz();
  6148. }
  6149. return nullptr;
  6150. }
  6151. if (right == nullptr)
  6152. {
  6153. *pNameLength = leftLen;
  6154. return left;
  6155. }
  6156. ulong rightLen = right->Cch();
  6157. return AppendNameHints(left, leftLen, right->Psz(), rightLen, pNameLength, pShortNameOffset, ignoreAddDotWithSpace, wrapInBrackets);
  6158. }
  6159. LPCOLESTR Parser::AppendNameHints(LPCOLESTR left, LPCOLESTR right, ulong *pNameLength, ulong *pShortNameOffset, bool ignoreAddDotWithSpace, bool wrapInBrackets)
  6160. {
  6161. ulong leftLen = (left == nullptr) ? 0 : (ulong) wcslen(left);
  6162. ulong rightLen = (right == nullptr) ? 0 : (ulong) wcslen(right);
  6163. if (pShortNameOffset != nullptr)
  6164. {
  6165. *pShortNameOffset = 0;
  6166. }
  6167. Assert(rightLen <= ULONG_MAX && leftLen <= ULONG_MAX); // name hints should not exceed ULONG_MAX characters
  6168. if (leftLen == 0 && !wrapInBrackets)
  6169. {
  6170. *pNameLength = right ? rightLen : 0;
  6171. return right;
  6172. }
  6173. if (rightLen == 0 && !wrapInBrackets)
  6174. {
  6175. *pNameLength = leftLen;
  6176. return left;
  6177. }
  6178. return AppendNameHints(left, leftLen, right, rightLen, pNameLength, pShortNameOffset, ignoreAddDotWithSpace, wrapInBrackets);
  6179. }
  6180. /**
  6181. * Emits a spread error if there is no ambiguity, or marks defers the error for
  6182. * when we can determine if it is a rest error or a spread error.
  6183. *
  6184. * The ambiguity arises when we are parsing a lambda parameter list but we have
  6185. * not seen the => token. At this point, we are either in a parenthesized
  6186. * expression or a parameter list, and cannot issue an error until the matching
  6187. * RParen has been scanned.
  6188. *
  6189. * The actual emission of the error happens in ParseExpr, when we first know if
  6190. * the expression is a lambda parameter list or not.
  6191. *
  6192. */
  6193. void Parser::DeferOrEmitPotentialSpreadError(ParseNodePtr pnodeT)
  6194. {
  6195. if (m_parenDepth > 0)
  6196. {
  6197. if (m_token.tk == tkRParen)
  6198. {
  6199. if (!m_deferEllipsisError)
  6200. {
  6201. // Capture only the first error instance.
  6202. m_pscan->Capture(&m_EllipsisErrLoc);
  6203. m_deferEllipsisError = true;
  6204. }
  6205. }
  6206. else
  6207. {
  6208. Error(ERRUnexpectedEllipsis);
  6209. }
  6210. }
  6211. else
  6212. {
  6213. Error(ERRInvalidSpreadUse);
  6214. }
  6215. }
  6216. /***************************************************************************
  6217. Parse an optional sub expression returning null if there was no expression.
  6218. Checks for no expression by looking for a token that can follow an
  6219. Expression grammar production.
  6220. ***************************************************************************/
  6221. template<bool buildAST>
  6222. bool Parser::ParseOptionalExpr(ParseNodePtr* pnode, bool fUnaryOrParen, int oplMin, BOOL *pfCanAssign, BOOL fAllowIn, BOOL fAllowEllipsis, _Inout_opt_ IdentToken* pToken)
  6223. {
  6224. *pnode = nullptr;
  6225. if (m_token.tk == tkRCurly ||
  6226. m_token.tk == tkRBrack ||
  6227. m_token.tk == tkRParen ||
  6228. m_token.tk == tkSColon ||
  6229. m_token.tk == tkColon ||
  6230. m_token.tk == tkComma ||
  6231. m_token.tk == tkLimKwd ||
  6232. m_pscan->FHadNewLine())
  6233. {
  6234. return false;
  6235. }
  6236. *pnode = ParseExpr<buildAST>(oplMin, pfCanAssign, fAllowIn, fAllowEllipsis, nullptr /*pNameHint*/, nullptr /*pHintLength*/, nullptr /*pShortNameOffset*/, pToken, fUnaryOrParen);
  6237. return true;
  6238. }
  6239. /***************************************************************************
  6240. Parse a sub expression.
  6241. 'fAllowIn' indicates if the 'in' operator should be allowed in the initializing
  6242. expression ( it is not allowed in the context of the first expression in a 'for' loop).
  6243. ***************************************************************************/
  6244. template<bool buildAST>
  6245. ParseNodePtr Parser::ParseExpr(int oplMin,
  6246. BOOL *pfCanAssign,
  6247. BOOL fAllowIn,
  6248. BOOL fAllowEllipsis,
  6249. LPCOLESTR pNameHint,
  6250. ulong *pHintLength,
  6251. ulong *pShortNameOffset,
  6252. _Inout_opt_ IdentToken* pToken,
  6253. bool fUnaryOrParen,
  6254. _Inout_opt_ bool* pfLikelyPattern)
  6255. {
  6256. Assert(pToken == nullptr || pToken->tk == tkNone); // Must be empty initially
  6257. int opl;
  6258. OpCode nop;
  6259. charcount_t ichMin;
  6260. ParseNodePtr pnode = nullptr;
  6261. ParseNodePtr pnodeT = nullptr;
  6262. BOOL fCanAssign = TRUE;
  6263. bool assignmentStmt = false;
  6264. IdentToken term;
  6265. RestorePoint termStart;
  6266. ulong hintLength = 0;
  6267. ulong hintOffset = 0;
  6268. if (pHintLength != nullptr)
  6269. {
  6270. hintLength = *pHintLength;
  6271. }
  6272. if (pShortNameOffset != nullptr)
  6273. {
  6274. hintOffset = *pShortNameOffset;
  6275. }
  6276. EnsureStackAvailable();
  6277. m_pscan->Capture(&termStart);
  6278. // Is the current token a unary operator?
  6279. if (m_phtbl->TokIsUnop(m_token.tk, &opl, &nop) && nop != knopNone)
  6280. {
  6281. IdentToken operandToken;
  6282. ichMin = m_pscan->IchMinTok();
  6283. if (nop == knopYield)
  6284. {
  6285. if (!m_pscan->YieldIsKeyword() || oplMin > opl)
  6286. {
  6287. // The case where 'yield' is scanned as a keyword (tkYIELD) but the scanner
  6288. // is not treating yield as a keyword (!m_pscan->YieldIsKeyword()) occurs
  6289. // in strict mode non-generator function contexts.
  6290. //
  6291. // That is, 'yield' is a keyword because of strict mode, but YieldExpression
  6292. // is not a grammar production outside of generator functions.
  6293. //
  6294. // Otherwise it is an error for a yield to appear in the context of a higher level
  6295. // binding operator, be it unary or binary.
  6296. Error(ERRsyntax);
  6297. }
  6298. if (m_currentNodeFunc->sxFnc.IsGenerator()
  6299. && m_currentBlockInfo->pnodeBlock->sxBlock.blockType == PnodeBlockType::Parameter)
  6300. {
  6301. Error(ERRsyntax);
  6302. }
  6303. }
  6304. else if (nop == knopAwait)
  6305. {
  6306. if (!m_pscan->AwaitIsKeyword() ||
  6307. (GetCurrentFunctionNode()->sxFnc.IsAsync() && m_currentScope->GetScopeType() == ScopeType_Parameter))
  6308. {
  6309. // As with the 'yield' keyword, the case where 'await' is scanned as a keyword (tkAWAIT)
  6310. // but the scanner is not treating await as a keyword (!m_pscan->AwaitIsKeyword())
  6311. // occurs in strict mode non-async function contexts.
  6312. //
  6313. // That is, 'await' is a keyword because of strict mode, but AwaitExpression
  6314. // is not a grammar production outside of async functions.
  6315. //
  6316. // Further, await expressions are disallowed within parameter scopes.
  6317. Error(ERRbadAwait);
  6318. }
  6319. }
  6320. m_pscan->Scan();
  6321. if (nop == knopYield && !m_pscan->FHadNewLine() && m_token.tk == tkStar)
  6322. {
  6323. m_pscan->Scan();
  6324. nop = knopYieldStar;
  6325. }
  6326. if (nop == knopYield)
  6327. {
  6328. if (!ParseOptionalExpr<buildAST>(&pnodeT, false, opl, NULL, TRUE, fAllowEllipsis))
  6329. {
  6330. nop = knopYieldLeaf;
  6331. if (buildAST)
  6332. {
  6333. pnode = CreateNodeT<knopYieldLeaf>(ichMin, m_pscan->IchLimTok());
  6334. }
  6335. }
  6336. }
  6337. else
  6338. {
  6339. // Disallow spread after an Ellipsis token. This prevents chaining, and ensures spread is the top level expression.
  6340. pnodeT = ParseExpr<buildAST>(opl, &fCanAssign, TRUE, nop != knopEllipsis && fAllowEllipsis, nullptr /*hint*/, nullptr /*hintLength*/, nullptr /*hintOffset*/, &operandToken, true);
  6341. }
  6342. if (nop != knopYieldLeaf)
  6343. {
  6344. if (nop == knopIncPre || nop == knopDecPre)
  6345. {
  6346. if (!fCanAssign && PHASE_ON1(Js::EarlyReferenceErrorsPhase))
  6347. {
  6348. Error(JSERR_CantAssignTo);
  6349. }
  6350. TrackAssignment<buildAST>(pnodeT, &operandToken, ichMin, m_pscan->IchLimTok());
  6351. if (buildAST)
  6352. {
  6353. if (IsStrictMode() && pnodeT->nop == knopName)
  6354. {
  6355. CheckStrictModeEvalArgumentsUsage(pnodeT->sxPid.pid);
  6356. }
  6357. }
  6358. else
  6359. {
  6360. if (IsStrictMode() && operandToken.tk == tkID)
  6361. {
  6362. CheckStrictModeEvalArgumentsUsage(operandToken.pid);
  6363. }
  6364. }
  6365. }
  6366. else if (nop == knopEllipsis && !fAllowEllipsis)
  6367. {
  6368. DeferOrEmitPotentialSpreadError(pnodeT);
  6369. }
  6370. if (buildAST)
  6371. {
  6372. //Do not do the folding for Asm in case of KnopPos as we need this to determine the type
  6373. if (nop == knopPos && (pnodeT->nop == knopInt || pnodeT->nop == knopFlt) && !this->m_InAsmMode)
  6374. {
  6375. // Fold away a unary '+' on a number.
  6376. pnode = pnodeT;
  6377. }
  6378. else if (nop == knopNeg &&
  6379. ((pnodeT->nop == knopInt && pnodeT->sxInt.lw != 0) ||
  6380. (pnodeT->nop == knopFlt && (pnodeT->sxFlt.dbl != 0 || this->m_InAsmMode))))
  6381. {
  6382. // Fold a unary '-' on a number into the value of the number itself.
  6383. pnode = pnodeT;
  6384. if (pnode->nop == knopInt)
  6385. {
  6386. pnode->sxInt.lw = -pnode->sxInt.lw;
  6387. }
  6388. else
  6389. {
  6390. pnode->sxFlt.dbl = -pnode->sxFlt.dbl;
  6391. }
  6392. }
  6393. else
  6394. {
  6395. pnode = CreateUniNode(nop, pnodeT);
  6396. this->CheckArguments(pnode->sxUni.pnode1);
  6397. }
  6398. pnode->ichMin = ichMin;
  6399. }
  6400. if (nop == knopDelete)
  6401. {
  6402. if (IsStrictMode())
  6403. {
  6404. if ((buildAST && pnode->sxUni.pnode1->nop == knopName) ||
  6405. (!buildAST && operandToken.tk == tkID))
  6406. {
  6407. Error(ERRInvalidDelete);
  6408. }
  6409. }
  6410. if (buildAST)
  6411. {
  6412. ParseNodePtr pnode1 = pnode->sxUni.pnode1;
  6413. if (m_currentNodeFunc)
  6414. {
  6415. if (pnode1->nop == knopDot || pnode1->nop == knopIndex)
  6416. {
  6417. // If we delete an arguments property, use the conservative,
  6418. // heap-allocated arguments object.
  6419. this->CheckArguments(pnode1->sxBin.pnode1);
  6420. }
  6421. }
  6422. }
  6423. }
  6424. }
  6425. fCanAssign = FALSE;
  6426. }
  6427. else
  6428. {
  6429. ichMin = m_pscan->IchMinTok();
  6430. BOOL fLikelyPattern = FALSE;
  6431. pnode = ParseTerm<buildAST>(TRUE, pNameHint, &hintLength, &hintOffset, &term, fUnaryOrParen, &fCanAssign, IsES6DestructuringEnabled() ? &fLikelyPattern : nullptr);
  6432. if (pfLikelyPattern != nullptr)
  6433. {
  6434. *pfLikelyPattern = !!fLikelyPattern;
  6435. }
  6436. if (m_token.tk == tkAsg && oplMin <= koplAsg && fLikelyPattern)
  6437. {
  6438. m_pscan->SeekTo(termStart);
  6439. ParseDestructuredLiteralWithScopeSave(tkLCurly, false/*isDecl*/, false /*topLevel*/, DIC_ShouldNotParseInitializer);
  6440. if (buildAST)
  6441. {
  6442. pnode = ConvertToPattern(pnode);
  6443. }
  6444. }
  6445. if (buildAST)
  6446. {
  6447. pNameHint = NULL;
  6448. if (pnode->nop == knopName)
  6449. {
  6450. pNameHint = pnode->sxPid.pid->Psz();
  6451. hintLength = pnode->sxPid.pid->Cch();
  6452. hintOffset = 0;
  6453. }
  6454. else if (pnode->nop == knopDot || pnode->nop == knopIndex)
  6455. {
  6456. if (CONFIG_FLAG(UseFullName))
  6457. {
  6458. pNameHint = ConstructNameHint(pnode, &hintLength, &hintOffset);
  6459. }
  6460. else
  6461. {
  6462. ParseNodePtr pnodeName = pnode;
  6463. while (pnodeName->nop == knopDot)
  6464. {
  6465. pnodeName = pnodeName->sxBin.pnode2;
  6466. }
  6467. if (pnodeName->nop == knopName)
  6468. {
  6469. pNameHint = pnodeName->sxPid.pid->Psz();
  6470. hintLength = pnodeName->sxPid.pid->Cch();
  6471. hintOffset = 0;
  6472. }
  6473. }
  6474. }
  6475. }
  6476. // Check for postfix unary operators.
  6477. if (!m_pscan->FHadNewLine() &&
  6478. (tkInc == m_token.tk || tkDec == m_token.tk))
  6479. {
  6480. if (!fCanAssign && PHASE_ON1(Js::EarlyReferenceErrorsPhase))
  6481. {
  6482. Error(JSERR_CantAssignTo);
  6483. }
  6484. TrackAssignment<buildAST>(pnode, &term, ichMin, m_pscan->IchLimTok());
  6485. fCanAssign = FALSE;
  6486. if (buildAST)
  6487. {
  6488. if (IsStrictMode() && pnode->nop == knopName)
  6489. {
  6490. CheckStrictModeEvalArgumentsUsage(pnode->sxPid.pid);
  6491. }
  6492. this->CheckArguments(pnode);
  6493. pnode = CreateUniNode(tkInc == m_token.tk ? knopIncPost : knopDecPost, pnode);
  6494. pnode->ichLim = m_pscan->IchLimTok();
  6495. }
  6496. else
  6497. {
  6498. if (IsStrictMode() && term.tk == tkID)
  6499. {
  6500. CheckStrictModeEvalArgumentsUsage(term.pid);
  6501. }
  6502. // This expression is not an identifier
  6503. term.tk = tkNone;
  6504. }
  6505. m_pscan->Scan();
  6506. }
  6507. }
  6508. // Process a sequence of operators and operands.
  6509. for (;;)
  6510. {
  6511. if (!m_phtbl->TokIsBinop(m_token.tk, &opl, &nop) || nop == knopNone)
  6512. {
  6513. break;
  6514. }
  6515. if ( ! fAllowIn && nop == knopIn )
  6516. {
  6517. break;
  6518. }
  6519. Assert(opl != koplNo);
  6520. if (opl == koplAsg)
  6521. {
  6522. if (m_token.tk != tkDArrow)
  6523. {
  6524. // Assignment operator. These are the only right associative
  6525. // binary operators. We also need to special case the left
  6526. // operand - it should only be a LeftHandSideExpression.
  6527. Assert(ParseNode::Grfnop(nop) & fnopAsg || nop == knopFncDecl);
  6528. TrackAssignment<buildAST>(pnode, &term, ichMin, m_pscan->IchLimTok());
  6529. if (buildAST)
  6530. {
  6531. if (IsStrictMode() && pnode->nop == knopName)
  6532. {
  6533. CheckStrictModeEvalArgumentsUsage(pnode->sxPid.pid);
  6534. }
  6535. // Assignment stmt of the form "this.<id> = <expr>"
  6536. if (nop == knopAsg && pnode->nop == knopDot && pnode->sxBin.pnode1->nop == knopThis && pnode->sxBin.pnode2->nop == knopName)
  6537. {
  6538. if (pnode->sxBin.pnode2->sxPid.pid != wellKnownPropertyPids.__proto__)
  6539. {
  6540. assignmentStmt = true;
  6541. }
  6542. }
  6543. }
  6544. else
  6545. {
  6546. if (IsStrictMode() && term.tk == tkID)
  6547. {
  6548. CheckStrictModeEvalArgumentsUsage(term.pid);
  6549. }
  6550. }
  6551. }
  6552. if (opl < oplMin)
  6553. {
  6554. break;
  6555. }
  6556. if (m_token.tk != tkDArrow && !fCanAssign && PHASE_ON1(Js::EarlyReferenceErrorsPhase))
  6557. {
  6558. Error(JSERR_CantAssignTo);
  6559. // No recovery necessary since this is a semantic, not structural, error.
  6560. }
  6561. }
  6562. else if (opl == koplExpo)
  6563. {
  6564. // ** operator is right associative
  6565. if (opl < oplMin)
  6566. {
  6567. break;
  6568. }
  6569. }
  6570. else if (opl <= oplMin)
  6571. {
  6572. break;
  6573. }
  6574. // This expression is not an identifier
  6575. term.tk = tkNone;
  6576. // Precedence is high enough. Consume the operator token.
  6577. m_pscan->Scan();
  6578. fCanAssign = FALSE;
  6579. // Special case the "?:" operator
  6580. if (nop == knopQmark)
  6581. {
  6582. pnodeT = ParseExpr<buildAST>(koplAsg, NULL, fAllowIn);
  6583. ChkCurTok(tkColon, ERRnoColon);
  6584. ParseNodePtr pnodeT2 = ParseExpr<buildAST>(koplAsg, NULL, fAllowIn);
  6585. if (buildAST)
  6586. {
  6587. pnode = CreateTriNode(nop, pnode, pnodeT, pnodeT2);
  6588. this->CheckArguments(pnode->sxTri.pnode2);
  6589. this->CheckArguments(pnode->sxTri.pnode3);
  6590. }
  6591. }
  6592. else if (nop == knopFncDecl)
  6593. {
  6594. ushort flags = fFncLambda;
  6595. size_t iecpMin = 0;
  6596. bool isAsyncMethod = false;
  6597. m_pscan->SeekTo(termStart);
  6598. if (m_token.tk == tkID && m_token.GetIdentifier(m_phtbl) == wellKnownPropertyPids.async && m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
  6599. {
  6600. ichMin = m_pscan->IchMinTok();
  6601. iecpMin = m_pscan->IecpMinTok();
  6602. m_pscan->Scan();
  6603. if ((m_token.tk == tkID || m_token.tk == tkLParen) && !m_pscan->FHadNewLine())
  6604. {
  6605. flags |= fFncAsync;
  6606. isAsyncMethod = true;
  6607. }
  6608. else
  6609. {
  6610. m_pscan->SeekTo(termStart);
  6611. }
  6612. }
  6613. pnode = ParseFncDecl<buildAST>(flags, nullptr, /* isSourceElement = */ false, /* needsPIDOnRCurlyScan = */false, /* resetParsingSuperRestrictionState = */false);
  6614. if (isAsyncMethod)
  6615. {
  6616. pnode->sxFnc.cbMin = iecpMin;
  6617. pnode->ichMin = ichMin;
  6618. }
  6619. }
  6620. else
  6621. {
  6622. // Parse the operand, make a new node, and look for more
  6623. pnodeT = ParseExpr<buildAST>(opl, NULL, fAllowIn, FALSE, pNameHint, &hintLength, &hintOffset, nullptr);
  6624. if (buildAST)
  6625. {
  6626. pnode = CreateBinNode(nop, pnode, pnodeT);
  6627. Assert(pnode->sxBin.pnode2 != NULL);
  6628. if (pnode->sxBin.pnode2->nop == knopFncDecl)
  6629. {
  6630. Assert(hintLength >= hintOffset);
  6631. pnode->sxBin.pnode2->sxFnc.hint = pNameHint;
  6632. pnode->sxBin.pnode2->sxFnc.hintLength = hintLength;
  6633. pnode->sxBin.pnode2->sxFnc.hintOffset = hintOffset;
  6634. if (pnode->sxBin.pnode1->nop == knopDot)
  6635. {
  6636. pnode->sxBin.pnode2->sxFnc.isNameIdentifierRef = false;
  6637. }
  6638. }
  6639. if (pnode->sxBin.pnode2->nop == knopClassDecl && pnode->sxBin.pnode1->nop == knopDot)
  6640. {
  6641. Assert(pnode->sxBin.pnode2->sxClass.pnodeConstructor);
  6642. pnode->sxBin.pnode2->sxClass.pnodeConstructor->sxFnc.isNameIdentifierRef = false;
  6643. }
  6644. }
  6645. pNameHint = NULL;
  6646. }
  6647. }
  6648. if (buildAST)
  6649. {
  6650. if (!assignmentStmt)
  6651. {
  6652. // Don't set the flag for following nodes
  6653. switch (pnode->nop)
  6654. {
  6655. case knopName:
  6656. case knopInt:
  6657. case knopFlt:
  6658. case knopStr:
  6659. case knopRegExp:
  6660. case knopNull:
  6661. case knopFalse:
  6662. case knopTrue:
  6663. break;
  6664. default:
  6665. if (m_currentNodeFunc)
  6666. {
  6667. m_currentNodeFunc->sxFnc.SetHasNonThisStmt();
  6668. }
  6669. else if (m_currentNodeProg)
  6670. {
  6671. m_currentNodeProg->sxFnc.SetHasNonThisStmt();
  6672. }
  6673. }
  6674. }
  6675. }
  6676. if (NULL != pfCanAssign)
  6677. {
  6678. *pfCanAssign = fCanAssign;
  6679. }
  6680. // Pass back identifier if requested
  6681. if (pToken && term.tk == tkID)
  6682. {
  6683. *pToken = term;
  6684. }
  6685. //Track "obj.a" assignment patterns here - Promote the Assignment state for the property's PID.
  6686. // This includes =, += etc.
  6687. if (pnode != NULL)
  6688. {
  6689. uint nodeType = ParseNode::Grfnop(pnode->nop);
  6690. if (nodeType & fnopAsg)
  6691. {
  6692. if (nodeType & fnopBin)
  6693. {
  6694. ParseNodePtr lhs = pnode->sxBin.pnode1;
  6695. Assert(lhs);
  6696. if (lhs->nop == knopDot)
  6697. {
  6698. ParseNodePtr propertyNode = lhs->sxBin.pnode2;
  6699. if (propertyNode->nop == knopName)
  6700. {
  6701. propertyNode->sxPid.pid->PromoteAssignmentState();
  6702. }
  6703. }
  6704. }
  6705. else if (nodeType & fnopUni)
  6706. {
  6707. // cases like obj.a++, ++obj.a
  6708. ParseNodePtr lhs = pnode->sxUni.pnode1;
  6709. if (lhs->nop == knopDot)
  6710. {
  6711. ParseNodePtr propertyNode = lhs->sxBin.pnode2;
  6712. if (propertyNode->nop == knopName)
  6713. {
  6714. propertyNode->sxPid.pid->PromoteAssignmentState();
  6715. }
  6716. }
  6717. }
  6718. }
  6719. }
  6720. return pnode;
  6721. }
  6722. template<bool buildAST>
  6723. void Parser::TrackAssignment(ParseNodePtr pnodeT, IdentToken* pToken, charcount_t ichMin, charcount_t ichLim)
  6724. {
  6725. if (buildAST)
  6726. {
  6727. Assert(pnodeT != NULL);
  6728. if (pnodeT->nop == knopName)
  6729. {
  6730. PidRefStack *ref = pnodeT->sxPid.pid->GetTopRef();
  6731. Assert(ref);
  6732. ref->TrackAssignment(pnodeT->ichMin, pnodeT->ichLim);
  6733. }
  6734. }
  6735. else
  6736. {
  6737. Assert(pToken != NULL);
  6738. if (BindDeferredPidRefs() && pToken->tk == tkID)
  6739. {
  6740. PidRefStack *ref = pToken->pid->GetTopRef();
  6741. Assert(ref);
  6742. ref->TrackAssignment(ichMin, ichLim);
  6743. }
  6744. }
  6745. }
  6746. void PidRefStack::TrackAssignment(charcount_t ichMin, charcount_t ichLim)
  6747. {
  6748. if (this->isAsg)
  6749. {
  6750. if (this->GetIchMin() <= ichMin)
  6751. {
  6752. return;
  6753. }
  6754. Assert(ichMin <= this->GetIchMin() && this->GetIchLim() <= ichLim);
  6755. }
  6756. this->isAsg = true;
  6757. this->span.Set(ichMin, ichLim);
  6758. }
  6759. void PnPid::SetSymRef(PidRefStack *ref)
  6760. {
  6761. Assert(symRef == nullptr);
  6762. this->symRef = ref->GetSymRef();
  6763. }
  6764. Js::PropertyId PnPid::PropertyIdFromNameNode() const
  6765. {
  6766. Js::PropertyId propertyId;
  6767. Symbol *sym = this->sym;
  6768. if (sym)
  6769. {
  6770. propertyId = sym->GetPosition();
  6771. }
  6772. else
  6773. {
  6774. propertyId = this->pid->GetPropertyId();
  6775. }
  6776. return propertyId;
  6777. }
  6778. PidRefStack* Parser::PushPidRef(IdentPtr pid)
  6779. {
  6780. if (PHASE_ON1(Js::ParallelParsePhase))
  6781. {
  6782. // NOTE: the phase check is here to protect perf. See OSG 1020424.
  6783. // In some LS AST-rewrite cases we lose a lot of perf searching the PID ref stack rather
  6784. // than just pushing on the top. This hasn't shown up as a perf issue in non-LS benchmarks.
  6785. return pid->FindOrAddPidRef(&m_nodeAllocator, GetCurrentBlock()->sxBlock.blockId);
  6786. }
  6787. Assert(GetCurrentBlock() != nullptr);
  6788. AssertMsg(pid != nullptr, "PID should be created");
  6789. PidRefStack *ref = pid->GetTopRef();
  6790. if (!ref || (ref->GetScopeId() < GetCurrentBlock()->sxBlock.blockId
  6791. // We could have the ref from the parameter scope. In that case we can skip creating a new one.
  6792. && !(m_currentBlockInfo->pBlockInfoOuter->pnodeBlock->sxBlock.blockType == PnodeBlockType::Parameter
  6793. && m_currentBlockInfo->pBlockInfoOuter->pnodeBlock->sxBlock.blockId == ref->GetScopeId())))
  6794. {
  6795. ref = Anew(&m_nodeAllocator, PidRefStack);
  6796. if (ref == nullptr)
  6797. {
  6798. Error(ERRnoMemory);
  6799. }
  6800. pid->PushPidRef(GetCurrentBlock()->sxBlock.blockId, ref);
  6801. }
  6802. return ref;
  6803. }
  6804. PidRefStack* Parser::FindOrAddPidRef(IdentPtr pid, int scopeId, int maxScopeId)
  6805. {
  6806. PidRefStack *ref = pid->FindOrAddPidRef(&m_nodeAllocator, scopeId, maxScopeId);
  6807. if (ref == NULL)
  6808. {
  6809. Error(ERRnoMemory);
  6810. }
  6811. return ref;
  6812. }
  6813. void Parser::RemovePrevPidRef(IdentPtr pid, PidRefStack *ref)
  6814. {
  6815. PidRefStack *prevRef = pid->RemovePrevPidRef(ref);
  6816. Assert(prevRef);
  6817. if (prevRef->GetSym() == nullptr)
  6818. {
  6819. AllocatorDelete(ArenaAllocator, &m_nodeAllocator, prevRef);
  6820. }
  6821. }
  6822. void Parser::SetPidRefsInScopeDynamic(IdentPtr pid, int blockId)
  6823. {
  6824. PidRefStack *ref = pid->GetTopRef();
  6825. while (ref && ref->GetScopeId() >= blockId)
  6826. {
  6827. ref->SetDynamicBinding();
  6828. ref = ref->prev;
  6829. }
  6830. }
  6831. ParseNode* Parser::GetFunctionBlock()
  6832. {
  6833. Assert(m_currentBlockInfo != nullptr);
  6834. return m_currentBlockInfo->pBlockInfoFunction->pnodeBlock;
  6835. }
  6836. ParseNode* Parser::GetCurrentBlock()
  6837. {
  6838. return m_currentBlockInfo != nullptr ? m_currentBlockInfo->pnodeBlock : nullptr;
  6839. }
  6840. BlockInfoStack* Parser::GetCurrentBlockInfo()
  6841. {
  6842. return m_currentBlockInfo;
  6843. }
  6844. BlockInfoStack* Parser::GetCurrentFunctionBlockInfo()
  6845. {
  6846. return m_currentBlockInfo->pBlockInfoFunction;
  6847. }
  6848. /***************************************************************************
  6849. Parse a variable declaration.
  6850. 'fAllowIn' indicates if the 'in' operator should be allowed in the initializing
  6851. expression ( it is not allowed in the context of the first expression in a 'for' loop).
  6852. ***************************************************************************/
  6853. template<bool buildAST>
  6854. ParseNodePtr Parser::ParseVariableDeclaration(
  6855. tokens declarationType, charcount_t ichMin,
  6856. BOOL fAllowIn/* = TRUE*/,
  6857. BOOL* pfForInOk/* = nullptr*/,
  6858. BOOL singleDefOnly/* = FALSE*/,
  6859. BOOL allowInit/* = TRUE*/,
  6860. BOOL isTopVarParse/* = TRUE*/,
  6861. BOOL isFor/* = FALSE*/,
  6862. BOOL* nativeForOk /*= nullptr*/)
  6863. {
  6864. ParseNodePtr pnodeThis = nullptr;
  6865. ParseNodePtr pnodeInit;
  6866. ParseNodePtr pnodeList = nullptr;
  6867. ParseNodePtr *lastNodeRef = nullptr;
  6868. LPCOLESTR pNameHint = nullptr;
  6869. ulong nameHintLength = 0;
  6870. ulong nameHintOffset = 0;
  6871. Assert(declarationType == tkVAR || declarationType == tkCONST || declarationType == tkLET);
  6872. for (;;)
  6873. {
  6874. if (IsES6DestructuringEnabled() && IsPossiblePatternStart())
  6875. {
  6876. pnodeThis = ParseDestructuredLiteral<buildAST>(declarationType, true, !!isTopVarParse, DIC_None, !!fAllowIn, pfForInOk, nativeForOk);
  6877. if (pnodeThis != nullptr)
  6878. {
  6879. pnodeThis->ichMin = ichMin;
  6880. }
  6881. }
  6882. else
  6883. {
  6884. if (m_token.tk != tkID)
  6885. {
  6886. IdentifierExpectedError(m_token);
  6887. }
  6888. IdentPtr pid = m_token.GetIdentifier(m_phtbl);
  6889. Assert(pid);
  6890. pNameHint = pid->Psz();
  6891. nameHintLength = pid->Cch();
  6892. nameHintOffset = 0;
  6893. if (buildAST || BindDeferredPidRefs())
  6894. {
  6895. if (declarationType == tkVAR)
  6896. {
  6897. pnodeThis = CreateVarDeclNode(pid, STVariable);
  6898. }
  6899. else if (declarationType == tkCONST)
  6900. {
  6901. pnodeThis = CreateBlockScopedDeclNode(pid, knopConstDecl);
  6902. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ConstCount, m_scriptContext);
  6903. }
  6904. else
  6905. {
  6906. pnodeThis = CreateBlockScopedDeclNode(pid, knopLetDecl);
  6907. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(LetCount, m_scriptContext);
  6908. }
  6909. }
  6910. else if (!buildAST)
  6911. {
  6912. CheckPidIsValid(pid);
  6913. }
  6914. if (pid == wellKnownPropertyPids.arguments && m_currentNodeFunc)
  6915. {
  6916. // This var declaration may change the way an 'arguments' identifier in the function is resolved
  6917. if (declarationType == tkVAR)
  6918. {
  6919. m_currentNodeFunc->grfpn |= PNodeFlags::fpnArguments_varDeclaration;
  6920. }
  6921. else
  6922. {
  6923. if (GetCurrentBlockInfo()->pnodeBlock->sxBlock.blockType == Function)
  6924. {
  6925. // Only override arguments if we are at the function block level.
  6926. m_currentNodeFunc->grfpn |= PNodeFlags::fpnArguments_overriddenByDecl;
  6927. }
  6928. }
  6929. }
  6930. if (pnodeThis)
  6931. {
  6932. pnodeThis->ichMin = ichMin;
  6933. }
  6934. m_pscan->Scan();
  6935. if (m_token.tk == tkAsg)
  6936. {
  6937. if (!allowInit)
  6938. {
  6939. Error(ERRUnexpectedDefault);
  6940. }
  6941. if (pfForInOk && (declarationType == tkLET || declarationType == tkCONST))
  6942. {
  6943. *pfForInOk = FALSE;
  6944. }
  6945. m_pscan->Scan();
  6946. pnodeInit = ParseExpr<buildAST>(koplCma, nullptr, fAllowIn, FALSE, pNameHint, &nameHintLength, &nameHintOffset);
  6947. if (buildAST)
  6948. {
  6949. AnalysisAssert(pnodeThis);
  6950. pnodeThis->sxVar.pnodeInit = pnodeInit;
  6951. pnodeThis->ichLim = pnodeInit->ichLim;
  6952. if (pnodeInit->nop == knopFncDecl)
  6953. {
  6954. Assert(nameHintLength >= nameHintOffset);
  6955. pnodeInit->sxFnc.hint = pNameHint;
  6956. pnodeInit->sxFnc.hintLength = nameHintLength;
  6957. pnodeInit->sxFnc.hintOffset = nameHintOffset;
  6958. }
  6959. else
  6960. {
  6961. this->CheckArguments(pnodeInit);
  6962. }
  6963. pNameHint = nullptr;
  6964. }
  6965. //Track var a =, let a= , const a =
  6966. // This is for FixedFields Constant Heuristics
  6967. if (pnodeThis && pnodeThis->sxVar.pnodeInit != nullptr)
  6968. {
  6969. pnodeThis->sxVar.sym->PromoteAssignmentState();
  6970. }
  6971. }
  6972. else if (declarationType == tkCONST /*pnodeThis->nop == knopConstDecl*/
  6973. && !singleDefOnly
  6974. && !(isFor && TokIsForInOrForOf()))
  6975. {
  6976. Error(ERRUninitializedConst);
  6977. }
  6978. }
  6979. if (singleDefOnly)
  6980. {
  6981. return pnodeThis;
  6982. }
  6983. if (buildAST)
  6984. {
  6985. AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeThis);
  6986. }
  6987. if (m_token.tk != tkComma)
  6988. {
  6989. return pnodeList;
  6990. }
  6991. if (pfForInOk)
  6992. {
  6993. // don't allow "for (var a, b in c)"
  6994. *pfForInOk = FALSE;
  6995. }
  6996. m_pscan->Scan();
  6997. ichMin = m_pscan->IchMinTok();
  6998. }
  6999. }
  7000. /***************************************************************************
  7001. Parse try-catch-finally statement
  7002. ***************************************************************************/
  7003. // Eze try-catch-finally tree nests the try-catch within a try-finally.
  7004. // This matches the new runtime implementation.
  7005. template<bool buildAST>
  7006. ParseNodePtr Parser::ParseTryCatchFinally()
  7007. {
  7008. this->m_tryCatchOrFinallyDepth++;
  7009. ParseNodePtr pnodeT = ParseTry<buildAST>();
  7010. ParseNodePtr pnodeTC = nullptr;
  7011. StmtNest stmt;
  7012. bool hasCatch = false;
  7013. if (tkCATCH == m_token.tk)
  7014. {
  7015. hasCatch = true;
  7016. if (buildAST)
  7017. {
  7018. pnodeTC = CreateNodeWithScanner<knopTryCatch>();
  7019. pnodeT->sxStmt.pnodeOuter = pnodeTC;
  7020. pnodeTC->sxTryCatch.pnodeTry = pnodeT;
  7021. }
  7022. PushStmt<buildAST>(&stmt, pnodeTC, knopTryCatch, nullptr, nullptr);
  7023. ParseNodePtr pnodeCatch = ParseCatch<buildAST>();
  7024. if (buildAST)
  7025. {
  7026. pnodeTC->sxTryCatch.pnodeCatch = pnodeCatch;
  7027. }
  7028. PopStmt(&stmt);
  7029. }
  7030. if (tkFINALLY != m_token.tk)
  7031. {
  7032. if (!hasCatch)
  7033. {
  7034. Error(ERRnoCatch);
  7035. }
  7036. Assert(!buildAST || pnodeTC);
  7037. return pnodeTC;
  7038. }
  7039. ParseNodePtr pnodeTF = nullptr;
  7040. if (buildAST)
  7041. {
  7042. pnodeTF = CreateNode(knopTryFinally);
  7043. }
  7044. PushStmt<buildAST>(&stmt, pnodeTF, knopTryFinally, nullptr, nullptr);
  7045. ParseNodePtr pnodeFinally = ParseFinally<buildAST>();
  7046. if (buildAST)
  7047. {
  7048. if (!hasCatch)
  7049. {
  7050. pnodeTF->sxTryFinally.pnodeTry = pnodeT;
  7051. pnodeT->sxStmt.pnodeOuter = pnodeTF;
  7052. }
  7053. else
  7054. {
  7055. pnodeTF->sxTryFinally.pnodeTry = CreateNode(knopTry);
  7056. pnodeTF->sxTryFinally.pnodeTry->sxStmt.pnodeOuter = pnodeTF;
  7057. pnodeTF->sxTryFinally.pnodeTry->sxTry.pnodeBody = pnodeTC;
  7058. pnodeTC->sxStmt.pnodeOuter = pnodeTF->sxTryFinally.pnodeTry;
  7059. }
  7060. pnodeTF->sxTryFinally.pnodeFinally = pnodeFinally;
  7061. }
  7062. PopStmt(&stmt);
  7063. this->m_tryCatchOrFinallyDepth--;
  7064. return pnodeTF;
  7065. }
  7066. template<bool buildAST>
  7067. ParseNodePtr Parser::ParseTry()
  7068. {
  7069. ParseNodePtr pnode = nullptr;
  7070. StmtNest stmt;
  7071. Assert(tkTRY == m_token.tk);
  7072. if (buildAST)
  7073. {
  7074. pnode = CreateNode(knopTry);
  7075. }
  7076. m_pscan->Scan();
  7077. if (tkLCurly != m_token.tk)
  7078. {
  7079. Error(ERRnoLcurly);
  7080. }
  7081. PushStmt<buildAST>(&stmt, pnode, knopTry, nullptr, nullptr);
  7082. ParseNodePtr pnodeBody = ParseStatement<buildAST>();
  7083. if (buildAST)
  7084. {
  7085. pnode->sxTry.pnodeBody = pnodeBody;
  7086. if (pnode->sxTry.pnodeBody)
  7087. pnode->ichLim = pnode->sxTry.pnodeBody->ichLim;
  7088. }
  7089. PopStmt(&stmt);
  7090. return pnode;
  7091. }
  7092. template<bool buildAST>
  7093. ParseNodePtr Parser::ParseFinally()
  7094. {
  7095. ParseNodePtr pnode = nullptr;
  7096. StmtNest stmt;
  7097. Assert(tkFINALLY == m_token.tk);
  7098. if (buildAST)
  7099. {
  7100. pnode = CreateNode(knopFinally);
  7101. }
  7102. m_pscan->Scan();
  7103. if (tkLCurly != m_token.tk)
  7104. {
  7105. Error(ERRnoLcurly);
  7106. }
  7107. PushStmt<buildAST>(&stmt, pnode, knopFinally, nullptr, nullptr);
  7108. ParseNodePtr pnodeBody = ParseStatement<buildAST>();
  7109. if (buildAST)
  7110. {
  7111. pnode->sxFinally.pnodeBody = pnodeBody;
  7112. if (!pnode->sxFinally.pnodeBody)
  7113. // Will only occur due to error correction.
  7114. pnode->sxFinally.pnodeBody = CreateNodeWithScanner<knopEmpty>();
  7115. else
  7116. pnode->ichLim = pnode->sxFinally.pnodeBody->ichLim;
  7117. }
  7118. PopStmt(&stmt);
  7119. return pnode;
  7120. }
  7121. template<bool buildAST>
  7122. ParseNodePtr Parser::ParseCatch()
  7123. {
  7124. ParseNodePtr rootNode = nullptr;
  7125. ParseNodePtr* ppnode = &rootNode;
  7126. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  7127. ParseNodePtr pnode = nullptr;
  7128. ParseNodePtr pnodeCatchScope = nullptr;
  7129. StmtNest stmt;
  7130. IdentPtr pidCatch = nullptr;
  7131. //while (tkCATCH == m_token.tk)
  7132. if (tkCATCH == m_token.tk)
  7133. {
  7134. charcount_t ichMin;
  7135. if (buildAST)
  7136. {
  7137. ichMin = m_pscan->IchMinTok();
  7138. }
  7139. m_pscan->Scan(); //catch
  7140. ChkCurTok(tkLParen, ERRnoLparen); //catch(
  7141. bool isPattern = false;
  7142. if (tkID != m_token.tk)
  7143. {
  7144. isPattern = IsES6DestructuringEnabled() && IsPossiblePatternStart();
  7145. if (!isPattern)
  7146. {
  7147. IdentifierExpectedError(m_token);
  7148. }
  7149. }
  7150. if (buildAST)
  7151. {
  7152. pnode = CreateNodeWithScanner<knopCatch>(ichMin);
  7153. PushStmt<buildAST>(&stmt, pnode, knopCatch, nullptr, nullptr);
  7154. *ppnode = pnode;
  7155. ppnode = &pnode->sxCatch.pnodeNext;
  7156. *ppnode = nullptr;
  7157. }
  7158. if (buildAST || BindDeferredPidRefs())
  7159. {
  7160. pnodeCatchScope = StartParseBlock<buildAST>(PnodeBlockType::Regular, isPattern ? ScopeType_CatchParamPattern : ScopeType_Catch);
  7161. }
  7162. if (isPattern)
  7163. {
  7164. ParseNodePtr pnodePattern = ParseDestructuredLiteral<buildAST>(tkLET, true /*isDecl*/, true /*topLevel*/, DIC_ForceErrorOnInitializer);
  7165. if (buildAST)
  7166. {
  7167. pnode->sxCatch.pnodeParam = CreateParamPatternNode(pnodePattern);
  7168. Scope *scope = pnodeCatchScope->sxBlock.scope;
  7169. pnode->sxCatch.scope = scope;
  7170. }
  7171. }
  7172. else
  7173. {
  7174. if (IsStrictMode())
  7175. {
  7176. IdentPtr pid = m_token.GetIdentifier(m_phtbl);
  7177. if (pid == wellKnownPropertyPids.eval)
  7178. {
  7179. Error(ERREvalUsage);
  7180. }
  7181. else if (pid == wellKnownPropertyPids.arguments)
  7182. {
  7183. Error(ERRArgsUsage);
  7184. }
  7185. }
  7186. if (buildAST)
  7187. {
  7188. pidCatch = m_token.GetIdentifier(m_phtbl);
  7189. PidRefStack *ref = this->PushPidRef(pidCatch);
  7190. if (!m_scriptContext->GetConfig()->IsBlockScopeEnabled())
  7191. {
  7192. // Strange case: the catch adds a scope for the catch object, but function declarations
  7193. // are hoisted out of the catch, so references within a function declaration to "x" do
  7194. // not bind to "catch(x)". Extra bookkeeping is required.
  7195. CatchPidRefList *list = this->EnsureCatchPidRefList();
  7196. CatchPidRef *catchPidRef = list->PrependNode(&m_nodeAllocator);
  7197. catchPidRef->pid = pidCatch;
  7198. catchPidRef->ref = ref;
  7199. }
  7200. ParseNodePtr pnodeParam = CreateNameNode(pidCatch);
  7201. pnodeParam->sxPid.symRef = ref->GetSymRef();
  7202. pnode->sxCatch.pnodeParam = pnodeParam;
  7203. const wchar_t *name = reinterpret_cast<const wchar_t*>(pidCatch->Psz());
  7204. int nameLength = pidCatch->Cch();
  7205. SymbolName const symName(name, nameLength);
  7206. Symbol *sym = Anew(&m_nodeAllocator, Symbol, symName, pnodeParam, STVariable);
  7207. sym->SetPid(pidCatch);
  7208. if (sym == nullptr)
  7209. {
  7210. Error(ERRnoMemory);
  7211. }
  7212. Assert(ref->GetSym() == nullptr);
  7213. ref->SetSym(sym);
  7214. Scope *scope = pnodeCatchScope->sxBlock.scope;
  7215. scope->AddNewSymbol(sym);
  7216. pnode->sxCatch.scope = scope;
  7217. }
  7218. m_pscan->Scan();
  7219. }
  7220. if (buildAST)
  7221. {
  7222. // Add this catch to the current scope list.
  7223. if (m_ppnodeExprScope)
  7224. {
  7225. Assert(*m_ppnodeExprScope == nullptr);
  7226. *m_ppnodeExprScope = pnode;
  7227. m_ppnodeExprScope = &pnode->sxCatch.pnodeNext;
  7228. }
  7229. else
  7230. {
  7231. Assert(m_ppnodeScope);
  7232. Assert(*m_ppnodeScope == nullptr);
  7233. *m_ppnodeScope = pnode;
  7234. m_ppnodeScope = &pnode->sxCatch.pnodeNext;
  7235. }
  7236. // Keep a list of function expressions (not declarations) at this scope.
  7237. ppnodeExprScopeSave = m_ppnodeExprScope;
  7238. m_ppnodeExprScope = &pnode->sxCatch.pnodeScopes;
  7239. pnode->sxCatch.pnodeScopes = nullptr;
  7240. }
  7241. charcount_t ichLim;
  7242. if (buildAST)
  7243. {
  7244. ichLim = m_pscan->IchLimTok();
  7245. }
  7246. ChkCurTok(tkRParen, ERRnoRparen); //catch(id[:expr])
  7247. if (tkLCurly != m_token.tk)
  7248. {
  7249. Error(ERRnoLcurly);
  7250. }
  7251. ParseNodePtr pnodeBody = ParseStatement<buildAST>(); //catch(id[:expr]) {block}
  7252. if (buildAST)
  7253. {
  7254. pnode->sxCatch.pnodeBody = pnodeBody;
  7255. pnode->ichLim = ichLim;
  7256. }
  7257. if (pnodeCatchScope != nullptr)
  7258. {
  7259. FinishParseBlock(pnodeCatchScope);
  7260. }
  7261. if (buildAST)
  7262. {
  7263. PopStmt(&stmt);
  7264. // Restore the lists of function expression scopes.
  7265. AssertMem(m_ppnodeExprScope);
  7266. Assert(*m_ppnodeExprScope == nullptr);
  7267. m_ppnodeExprScope = ppnodeExprScopeSave;
  7268. if (!m_scriptContext->GetConfig()->IsBlockScopeEnabled())
  7269. {
  7270. // Remove the catch object from the list.
  7271. CatchPidRefList *list = this->GetCatchPidRefList();
  7272. Assert(list);
  7273. Assert(!list->Empty());
  7274. Assert(list->Head().pid == pidCatch);
  7275. list->RemoveHead(&m_nodeAllocator);
  7276. }
  7277. }
  7278. }
  7279. return rootNode;
  7280. }
  7281. template<bool buildAST>
  7282. ParseNodePtr Parser::ParseCase(ParseNodePtr *ppnodeBody)
  7283. {
  7284. ParseNodePtr pnodeT = nullptr;
  7285. charcount_t ichMinT = m_pscan->IchMinTok();
  7286. m_pscan->Scan();
  7287. ParseNodePtr pnodeExpr = ParseExpr<buildAST>();
  7288. charcount_t ichLim = m_pscan->IchLimTok();
  7289. ChkCurTok(tkColon, ERRnoColon);
  7290. if (buildAST)
  7291. {
  7292. pnodeT = CreateNodeWithScanner<knopCase>(ichMinT);
  7293. pnodeT->sxCase.pnodeExpr = pnodeExpr;
  7294. pnodeT->ichLim = ichLim;
  7295. }
  7296. ParseStmtList<buildAST>(ppnodeBody);
  7297. return pnodeT;
  7298. }
  7299. /***************************************************************************
  7300. Parse a single statement. Digest a trailing semicolon.
  7301. ***************************************************************************/
  7302. template<bool buildAST>
  7303. ParseNodePtr Parser::ParseStatement(bool isSourceElement/* = false*/)
  7304. {
  7305. ParseNodePtr *ppnodeT;
  7306. ParseNodePtr pnodeT;
  7307. ParseNodePtr pnode = nullptr;
  7308. LabelId* pLabelIdList = nullptr;
  7309. charcount_t ichMin = 0;
  7310. size_t iecpMin = 0;
  7311. StmtNest stmt;
  7312. StmtNest *pstmt;
  7313. BOOL fForInOrOfOkay;
  7314. BOOL fCanAssign;
  7315. IdentPtr pid;
  7316. uint fnop;
  7317. ParseNodePtr pnodeLabel = nullptr;
  7318. bool expressionStmt = false;
  7319. bool isAsyncMethod = false;
  7320. tokens tok;
  7321. #if EXCEPTION_RECOVERY
  7322. ParseNodePtr pParentTryCatch = nullptr;
  7323. ParseNodePtr pTryBlock = nullptr;
  7324. ParseNodePtr pTry = nullptr;
  7325. ParseNodePtr pParentTryCatchBlock = nullptr;
  7326. StmtNest stmtTryCatchBlock;
  7327. StmtNest stmtTryCatch;
  7328. StmtNest stmtTry;
  7329. StmtNest stmtTryBlock;
  7330. #endif
  7331. if (buildAST)
  7332. {
  7333. #if EXCEPTION_RECOVERY
  7334. if(Js::Configuration::Global.flags.SwallowExceptions)
  7335. {
  7336. // If we're swallowing exceptions, surround this statement with a try/catch block:
  7337. //
  7338. // Before: x.y = 3;
  7339. // After: try { x.y = 3; } catch(__ehobj) { }
  7340. //
  7341. // This is done to force the runtime to recover from exceptions at the most granular
  7342. // possible point. Recovering from EH dramatically improves coverage of testing via
  7343. // fault injection.
  7344. // create and push the try-catch node
  7345. pParentTryCatchBlock = CreateBlockNode();
  7346. PushStmt<buildAST>(&stmtTryCatchBlock, pParentTryCatchBlock, knopBlock, nullptr, nullptr);
  7347. pParentTryCatch = CreateNodeWithScanner<knopTryCatch>();
  7348. PushStmt<buildAST>(&stmtTryCatch, pParentTryCatch, knopTryCatch, nullptr, nullptr);
  7349. // create and push a try node
  7350. pTry = CreateNodeWithScanner<knopTry>();
  7351. PushStmt<buildAST>(&stmtTry, pTry, knopTry, nullptr, nullptr);
  7352. pTryBlock = CreateBlockNode();
  7353. PushStmt<buildAST>(&stmtTryBlock, pTryBlock, knopBlock, nullptr, nullptr);
  7354. // these nodes will be closed after the statement is parsed.
  7355. }
  7356. #endif // EXCEPTION_RECOVERY
  7357. }
  7358. EnsureStackAvailable();
  7359. LRestart:
  7360. tok = m_token.tk;
  7361. switch (tok)
  7362. {
  7363. case tkEOF:
  7364. if (buildAST)
  7365. {
  7366. pnode = nullptr;
  7367. }
  7368. break;
  7369. case tkFUNCTION:
  7370. {
  7371. LFunctionStatement:
  7372. if (m_grfscr & fscrDeferredFncExpression)
  7373. {
  7374. // The top-level deferred function body was defined by a function expression whose parsing was deferred. We are now
  7375. // parsing it, so unset the flag so that any nested functions are parsed normally. This flag is only applicable the
  7376. // first time we see it.
  7377. m_grfscr &= ~fscrDeferredFncExpression;
  7378. pnode = ParseFncDecl<buildAST>(isAsyncMethod ? fFncAsync : fFncNoFlgs, nullptr, isSourceElement);
  7379. }
  7380. else
  7381. {
  7382. pnode = ParseFncDecl<buildAST>(fFncDeclaration | (isAsyncMethod ? fFncAsync : fFncNoFlgs), nullptr, isSourceElement);
  7383. }
  7384. if (isAsyncMethod)
  7385. {
  7386. pnode->sxFnc.cbMin = iecpMin;
  7387. pnode->ichMin = ichMin;
  7388. }
  7389. break;
  7390. }
  7391. case tkCLASS:
  7392. if (m_scriptContext->GetConfig()->IsES6ClassAndExtendsEnabled())
  7393. {
  7394. pnode = ParseClassDecl<buildAST>(TRUE, nullptr, nullptr, nullptr);
  7395. }
  7396. else
  7397. {
  7398. goto LDefaultToken;
  7399. }
  7400. break;
  7401. case tkID:
  7402. if (m_token.GetIdentifier(m_phtbl) == wellKnownPropertyPids.let && m_scriptContext->GetConfig()->IsLetAndConstEnabled())
  7403. {
  7404. // We see "let" at the start of a statement. This could either be a declaration or an identifier
  7405. // reference. The next token determines which.
  7406. RestorePoint parsedLet;
  7407. m_pscan->Capture(&parsedLet);
  7408. ichMin = m_pscan->IchMinTok();
  7409. m_pscan->Scan();
  7410. if (this->NextTokenConfirmsLetDecl())
  7411. {
  7412. pnode = ParseVariableDeclaration<buildAST>(tkLET, ichMin);
  7413. goto LNeedTerminator;
  7414. }
  7415. m_pscan->SeekTo(parsedLet);
  7416. }
  7417. else if (m_token.GetIdentifier(m_phtbl) == wellKnownPropertyPids.async && m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
  7418. {
  7419. RestorePoint parsedAsync;
  7420. m_pscan->Capture(&parsedAsync);
  7421. ichMin = m_pscan->IchMinTok();
  7422. iecpMin = m_pscan->IecpMinTok();
  7423. m_pscan->Scan();
  7424. if (m_token.tk == tkFUNCTION && !m_pscan->FHadNewLine())
  7425. {
  7426. isAsyncMethod = true;
  7427. goto LFunctionStatement;
  7428. }
  7429. m_pscan->SeekTo(parsedAsync);
  7430. }
  7431. goto LDefaultToken;
  7432. case tkCONST:
  7433. case tkLET:
  7434. if (m_scriptContext->GetConfig()->IsLetAndConstEnabled())
  7435. {
  7436. ichMin = m_pscan->IchMinTok();
  7437. m_pscan->Scan();
  7438. pnode = ParseVariableDeclaration<buildAST>(tok, ichMin);
  7439. goto LNeedTerminator;
  7440. }
  7441. else
  7442. {
  7443. goto LDefaultToken;
  7444. }
  7445. case tkVAR:
  7446. ichMin = m_pscan->IchMinTok();
  7447. m_pscan->Scan();
  7448. pnode = ParseVariableDeclaration<buildAST>(tok, ichMin);
  7449. goto LNeedTerminator;
  7450. case tkFOR:
  7451. {
  7452. ParseNodePtr pnodeBlock = nullptr;
  7453. ParseNodePtr *ppnodeScopeSave = nullptr;
  7454. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  7455. ichMin = m_pscan->IchMinTok();
  7456. ChkNxtTok(tkLParen, ERRnoLparen);
  7457. if (buildAST || BindDeferredPidRefs())
  7458. {
  7459. pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Regular, ScopeType_Block);
  7460. if (buildAST)
  7461. {
  7462. PushFuncBlockScope(pnodeBlock, &ppnodeScopeSave, &ppnodeExprScopeSave);
  7463. }
  7464. }
  7465. RestorePoint startExprOrIdentifier;
  7466. fForInOrOfOkay = TRUE;
  7467. fCanAssign = TRUE;
  7468. tok = m_token.tk;
  7469. BOOL nativeForOkay = TRUE;
  7470. switch (tok)
  7471. {
  7472. case tkID:
  7473. if (m_token.GetIdentifier(m_phtbl) == wellKnownPropertyPids.let && m_scriptContext->GetConfig()->IsLetAndConstEnabled())
  7474. {
  7475. // We see "let" in the init part of a for loop. This could either be a declaration or an identifier
  7476. // reference. The next token determines which.
  7477. RestorePoint parsedLet;
  7478. m_pscan->Capture(&parsedLet);
  7479. auto ichMin = m_pscan->IchMinTok();
  7480. m_pscan->Scan();
  7481. if (IsPossiblePatternStart())
  7482. {
  7483. m_pscan->Capture(&startExprOrIdentifier);
  7484. }
  7485. if (this->NextTokenConfirmsLetDecl() && m_token.tk != tkIN)
  7486. {
  7487. pnodeT = ParseVariableDeclaration<buildAST>(tkLET, ichMin
  7488. , /*fAllowIn = */FALSE
  7489. , /*pfForInOk = */&fForInOrOfOkay
  7490. , /*singleDefOnly*/FALSE
  7491. , /*allowInit*/TRUE
  7492. , /*isTopVarParse*/TRUE
  7493. , /*isFor*/TRUE
  7494. , &nativeForOkay);
  7495. break;
  7496. }
  7497. m_pscan->SeekTo(parsedLet);
  7498. }
  7499. goto LDefaultTokenFor;
  7500. case tkLET:
  7501. case tkCONST:
  7502. if (!m_scriptContext->GetConfig()->IsLetAndConstEnabled())
  7503. {
  7504. goto LDefaultTokenFor;
  7505. }
  7506. case tkVAR:
  7507. {
  7508. auto ichMin = m_pscan->IchMinTok();
  7509. m_pscan->Scan();
  7510. if (IsPossiblePatternStart())
  7511. {
  7512. m_pscan->Capture(&startExprOrIdentifier);
  7513. }
  7514. pnodeT = ParseVariableDeclaration<buildAST>(tok, ichMin
  7515. , /*fAllowIn = */FALSE
  7516. , /*pfForInOk = */&fForInOrOfOkay
  7517. , /*singleDefOnly*/FALSE
  7518. , /*allowInit*/TRUE
  7519. , /*isTopVarParse*/TRUE
  7520. , /*isFor*/TRUE
  7521. , &nativeForOkay);
  7522. }
  7523. break;
  7524. case tkSColon:
  7525. pnodeT = nullptr;
  7526. fForInOrOfOkay = FALSE;
  7527. break;
  7528. default:
  7529. {
  7530. LDefaultTokenFor:
  7531. RestorePoint exprStart;
  7532. tokens beforeToken = tok;
  7533. m_pscan->Capture(&exprStart);
  7534. if (IsPossiblePatternStart())
  7535. {
  7536. m_pscan->Capture(&startExprOrIdentifier);
  7537. }
  7538. bool fLikelyPattern = false;
  7539. if (IsES6DestructuringEnabled() && (beforeToken == tkLBrack || beforeToken == tkLCurly))
  7540. {
  7541. pnodeT = ParseExpr<buildAST>(koplNo,
  7542. &fCanAssign,
  7543. /*fAllowIn = */FALSE,
  7544. /*fAllowEllipsis*/FALSE,
  7545. /*pHint*/nullptr,
  7546. /*pHintLength*/nullptr,
  7547. /*pShortNameOffset*/nullptr,
  7548. /*pToken*/nullptr,
  7549. /**fUnaryOrParen*/false,
  7550. &fLikelyPattern);
  7551. }
  7552. else
  7553. {
  7554. pnodeT = ParseExpr<buildAST>(koplNo, &fCanAssign, /*fAllowIn = */FALSE);
  7555. }
  7556. // 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
  7557. // has already converted them appropriately.
  7558. if (fLikelyPattern && TokIsForInOrForOf())
  7559. {
  7560. m_pscan->SeekTo(exprStart);
  7561. ParseDestructuredLiteralWithScopeSave(tkNone, false/*isDecl*/, false /*topLevel*/, DIC_None, false /*allowIn*/);
  7562. if (buildAST)
  7563. {
  7564. pnodeT = ConvertToPattern(pnodeT);
  7565. }
  7566. }
  7567. if (buildAST)
  7568. {
  7569. Assert(pnodeT);
  7570. pnodeT->isUsed = false;
  7571. }
  7572. }
  7573. break;
  7574. }
  7575. if (TokIsForInOrForOf())
  7576. {
  7577. bool isForOf = (m_token.tk != tkIN);
  7578. Assert(!isForOf || (m_token.tk == tkID && m_token.GetIdentifier(m_phtbl) == wellKnownPropertyPids.of));
  7579. if ((buildAST && nullptr == pnodeT) || !fForInOrOfOkay)
  7580. {
  7581. if (isForOf)
  7582. {
  7583. Error(ERRForOfNoInitAllowed);
  7584. }
  7585. else
  7586. {
  7587. Error(ERRForInNoInitAllowed);
  7588. }
  7589. }
  7590. if (!fCanAssign && PHASE_ON1(Js::EarlyReferenceErrorsPhase))
  7591. {
  7592. Error(JSERR_CantAssignTo);
  7593. }
  7594. m_pscan->Scan();
  7595. ParseNodePtr pnodeObj = ParseExpr<buildAST>();
  7596. charcount_t ichLim = m_pscan->IchLimTok();
  7597. ChkCurTok(tkRParen, ERRnoRparen);
  7598. if (buildAST)
  7599. {
  7600. if (isForOf)
  7601. {
  7602. pnode = CreateNodeWithScanner<knopForOf>(ichMin);
  7603. }
  7604. else
  7605. {
  7606. pnode = CreateNodeWithScanner<knopForIn>(ichMin);
  7607. }
  7608. pnode->sxForInOrForOf.pnodeBlock = pnodeBlock;
  7609. pnode->sxForInOrForOf.pnodeLval = pnodeT;
  7610. pnode->sxForInOrForOf.pnodeObj = pnodeObj;
  7611. pnode->ichLim = ichLim;
  7612. }
  7613. PushStmt<buildAST>(&stmt, pnode, isForOf ? knopForOf : knopForIn, pnodeLabel, pLabelIdList);
  7614. ParseNodePtr pnodeBody = ParseStatement<buildAST>();
  7615. if (buildAST)
  7616. {
  7617. pnode->sxForInOrForOf.pnodeBody = pnodeBody;
  7618. }
  7619. PopStmt(&stmt);
  7620. }
  7621. else
  7622. {
  7623. if (!nativeForOkay)
  7624. {
  7625. Error(ERRDestructInit);
  7626. }
  7627. ChkCurTok(tkSColon, ERRnoSemic);
  7628. ParseNodePtr pnodeCond = nullptr;
  7629. if (m_token.tk != tkSColon)
  7630. {
  7631. pnodeCond = ParseExpr<buildAST>();
  7632. if (m_token.tk != tkSColon)
  7633. {
  7634. Error(ERRnoSemic);
  7635. }
  7636. }
  7637. tokens tk;
  7638. tk = m_pscan->Scan();
  7639. ParseNodePtr pnodeIncr = nullptr;
  7640. if (tk != tkRParen)
  7641. {
  7642. pnodeIncr = ParseExpr<buildAST>();
  7643. if(pnodeIncr)
  7644. {
  7645. pnodeIncr->isUsed = false;
  7646. }
  7647. }
  7648. charcount_t ichLim = m_pscan->IchLimTok();
  7649. ChkCurTok(tkRParen, ERRnoRparen);
  7650. if (buildAST)
  7651. {
  7652. pnode = CreateNodeWithScanner<knopFor>(ichMin);
  7653. pnode->sxFor.pnodeBlock = pnodeBlock;
  7654. pnode->sxFor.pnodeInverted= nullptr;
  7655. pnode->sxFor.pnodeInit = pnodeT;
  7656. pnode->sxFor.pnodeCond = pnodeCond;
  7657. pnode->sxFor.pnodeIncr = pnodeIncr;
  7658. pnode->ichLim = ichLim;
  7659. }
  7660. PushStmt<buildAST>(&stmt, pnode, knopFor, pnodeLabel, pLabelIdList);
  7661. ParseNodePtr pnodeBody = ParseStatement<buildAST>();
  7662. if (buildAST)
  7663. {
  7664. pnode->sxFor.pnodeBody = pnodeBody;
  7665. }
  7666. PopStmt(&stmt);
  7667. }
  7668. if (buildAST)
  7669. {
  7670. PopFuncBlockScope(ppnodeScopeSave, ppnodeExprScopeSave);
  7671. FinishParseBlock(pnodeBlock);
  7672. }
  7673. else if (BindDeferredPidRefs())
  7674. {
  7675. FinishParseBlock(pnodeBlock);
  7676. }
  7677. break;
  7678. }
  7679. case tkSWITCH:
  7680. {
  7681. BOOL fSeenDefault = FALSE;
  7682. StmtNest stmtBlock;
  7683. ParseNodePtr pnodeBlock = nullptr;
  7684. ParseNodePtr *ppnodeScopeSave = nullptr;
  7685. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  7686. ichMin = m_pscan->IchMinTok();
  7687. ChkNxtTok(tkLParen, ERRnoLparen);
  7688. ParseNodePtr pnodeVal = ParseExpr<buildAST>();
  7689. charcount_t ichLim = m_pscan->IchLimTok();
  7690. ChkCurTok(tkRParen, ERRnoRparen);
  7691. ChkCurTok(tkLCurly, ERRnoLcurly);
  7692. if (buildAST)
  7693. {
  7694. pnode = CreateNodeWithScanner<knopSwitch>(ichMin);
  7695. }
  7696. PushStmt<buildAST>(&stmt, pnode, knopSwitch, pnodeLabel, pLabelIdList);
  7697. if (buildAST || BindDeferredPidRefs())
  7698. {
  7699. pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Regular, ScopeType_Block, nullptr, pLabelIdList);
  7700. }
  7701. else
  7702. {
  7703. PushStmt<buildAST>(&stmtBlock, nullptr, knopBlock, nullptr, pLabelIdList);
  7704. }
  7705. if (buildAST)
  7706. {
  7707. pnode->sxSwitch.pnodeVal = pnodeVal;
  7708. pnode->sxSwitch.pnodeBlock = pnodeBlock;
  7709. pnode->ichLim = ichLim;
  7710. PushFuncBlockScope(pnode->sxSwitch.pnodeBlock, &ppnodeScopeSave, &ppnodeExprScopeSave);
  7711. pnode->sxSwitch.pnodeDefault = nullptr;
  7712. ppnodeT = &pnode->sxSwitch.pnodeCases;
  7713. }
  7714. for (;;)
  7715. {
  7716. ParseNodePtr pnodeBody = nullptr;
  7717. switch (m_token.tk)
  7718. {
  7719. default:
  7720. goto LEndSwitch;
  7721. case tkCASE:
  7722. {
  7723. pnodeT = this->ParseCase<buildAST>(&pnodeBody);
  7724. break;
  7725. }
  7726. case tkDEFAULT:
  7727. if (fSeenDefault)
  7728. {
  7729. Error(ERRdupDefault);
  7730. // No recovery necessary since this is a semantic, not structural, error
  7731. }
  7732. fSeenDefault = TRUE;
  7733. charcount_t ichMinT = m_pscan->IchMinTok();
  7734. m_pscan->Scan();
  7735. charcount_t ichLim = m_pscan->IchLimTok();
  7736. ChkCurTok(tkColon, ERRnoColon);
  7737. if (buildAST)
  7738. {
  7739. pnodeT = CreateNodeWithScanner<knopCase>(ichMinT);
  7740. pnode->sxSwitch.pnodeDefault = pnodeT;
  7741. pnodeT->ichLim = ichLim;
  7742. pnodeT->sxCase.pnodeExpr = nullptr;
  7743. }
  7744. ParseStmtList<buildAST>(&pnodeBody);
  7745. break;
  7746. }
  7747. if (buildAST)
  7748. {
  7749. if (pnodeBody)
  7750. {
  7751. // Create a block node to contain the statement list for this case.
  7752. // This helps us insert byte code to return the right value from
  7753. // global/eval code.
  7754. pnodeT->sxCase.pnodeBody = CreateBlockNode(pnodeT->ichMin, pnodeT->ichLim);
  7755. pnodeT->sxCase.pnodeBody->grfpn |= PNodeFlags::fpnSyntheticNode; // block is not a user specifier block
  7756. pnodeT->sxCase.pnodeBody->sxBlock.pnodeStmt = pnodeBody;
  7757. }
  7758. else
  7759. {
  7760. pnodeT->sxCase.pnodeBody = nullptr;
  7761. }
  7762. *ppnodeT = pnodeT;
  7763. ppnodeT = &pnodeT->sxCase.pnodeNext;
  7764. }
  7765. }
  7766. LEndSwitch:
  7767. ChkCurTok(tkRCurly, ERRnoRcurly);
  7768. if (buildAST)
  7769. {
  7770. *ppnodeT = nullptr;
  7771. PopFuncBlockScope(ppnodeScopeSave, ppnodeExprScopeSave);
  7772. FinishParseBlock(pnode->sxSwitch.pnodeBlock);
  7773. }
  7774. else
  7775. {
  7776. if (BindDeferredPidRefs())
  7777. {
  7778. FinishParseBlock(pnodeBlock);
  7779. }
  7780. else
  7781. {
  7782. PopStmt(&stmtBlock);
  7783. }
  7784. }
  7785. PopStmt(&stmt);
  7786. break;
  7787. }
  7788. case tkWHILE:
  7789. {
  7790. ichMin = m_pscan->IchMinTok();
  7791. ChkNxtTok(tkLParen, ERRnoLparen);
  7792. ParseNodePtr pnodeCond = ParseExpr<buildAST>();
  7793. charcount_t ichLim = m_pscan->IchLimTok();
  7794. ChkCurTok(tkRParen, ERRnoRparen);
  7795. if (buildAST)
  7796. {
  7797. pnode = CreateNodeWithScanner<knopWhile>(ichMin);
  7798. pnode->sxWhile.pnodeCond = pnodeCond;
  7799. pnode->ichLim = ichLim;
  7800. }
  7801. PushStmt<buildAST>(&stmt, pnode, knopWhile, pnodeLabel, pLabelIdList);
  7802. ParseNodePtr pnodeBody = ParseStatement<buildAST>();
  7803. PopStmt(&stmt);
  7804. if (buildAST)
  7805. {
  7806. pnode->sxWhile.pnodeBody = pnodeBody;
  7807. }
  7808. break;
  7809. }
  7810. case tkDO:
  7811. {
  7812. if (buildAST)
  7813. {
  7814. pnode = CreateNodeWithScanner<knopDoWhile>();
  7815. }
  7816. PushStmt<buildAST>(&stmt, pnode, knopDoWhile, pnodeLabel, pLabelIdList);
  7817. m_pscan->Scan();
  7818. ParseNodePtr pnodeBody = ParseStatement<buildAST>();
  7819. PopStmt(&stmt);
  7820. charcount_t ichMinT = m_pscan->IchMinTok();
  7821. ChkCurTok(tkWHILE, ERRnoWhile);
  7822. ChkCurTok(tkLParen, ERRnoLparen);
  7823. ParseNodePtr pnodeCond = ParseExpr<buildAST>();
  7824. charcount_t ichLim = m_pscan->IchLimTok();
  7825. ChkCurTok(tkRParen, ERRnoRparen);
  7826. if (buildAST)
  7827. {
  7828. pnode->sxWhile.pnodeBody = pnodeBody;
  7829. pnode->sxWhile.pnodeCond = pnodeCond;
  7830. pnode->ichLim = ichLim;
  7831. pnode->ichMin = ichMinT;
  7832. }
  7833. // REVIEW: Allow do...while statements to be embedded in other compound statements like if..else, or do..while?
  7834. // goto LNeedTerminator;
  7835. // For now just eat the trailing semicolon if present.
  7836. if (m_token.tk == tkSColon)
  7837. {
  7838. if (pnode)
  7839. {
  7840. pnode->grfpn |= PNodeFlags::fpnExplicitSemicolon;
  7841. }
  7842. m_pscan->Scan();
  7843. }
  7844. else if (pnode)
  7845. {
  7846. pnode->grfpn |= PNodeFlags::fpnAutomaticSemicolon;
  7847. }
  7848. break;
  7849. }
  7850. case tkIF:
  7851. {
  7852. ichMin = m_pscan->IchMinTok();
  7853. ChkNxtTok(tkLParen, ERRnoLparen);
  7854. ParseNodePtr pnodeCond = ParseExpr<buildAST>();
  7855. if (buildAST)
  7856. {
  7857. pnode = CreateNodeWithScanner<knopIf>(ichMin);
  7858. pnode->ichLim = m_pscan->IchLimTok();
  7859. pnode->sxIf.pnodeCond = pnodeCond;
  7860. }
  7861. ChkCurTok(tkRParen, ERRnoRparen);
  7862. PushStmt<buildAST>(&stmt, pnode, knopIf, pnodeLabel, pLabelIdList);
  7863. ParseNodePtr pnodeTrue = ParseStatement<buildAST>();
  7864. ParseNodePtr pnodeFalse = nullptr;
  7865. if (m_token.tk == tkELSE)
  7866. {
  7867. m_pscan->Scan();
  7868. pnodeFalse = ParseStatement<buildAST>();
  7869. }
  7870. if (buildAST)
  7871. {
  7872. pnode->sxIf.pnodeTrue = pnodeTrue;
  7873. pnode->sxIf.pnodeFalse = pnodeFalse;
  7874. }
  7875. PopStmt(&stmt);
  7876. break;
  7877. }
  7878. case tkTRY:
  7879. {
  7880. if (buildAST)
  7881. {
  7882. pnode = CreateBlockNode();
  7883. pnode->grfpn |= PNodeFlags::fpnSyntheticNode; // block is not a user specifier block
  7884. }
  7885. PushStmt<buildAST>(&stmt, pnode, knopBlock, pnodeLabel, pLabelIdList);
  7886. ParseNodePtr pnodeStmt = ParseTryCatchFinally<buildAST>();
  7887. if (buildAST)
  7888. {
  7889. pnode->sxBlock.pnodeStmt = pnodeStmt;
  7890. }
  7891. PopStmt(&stmt);
  7892. break;
  7893. }
  7894. case tkWITH:
  7895. {
  7896. if ( IsStrictMode() )
  7897. {
  7898. Error(ERRES5NoWith);
  7899. }
  7900. if (m_currentNodeFunc)
  7901. {
  7902. GetCurrentFunctionNode()->sxFnc.SetHasWithStmt(); // Used by DeferNested
  7903. }
  7904. ichMin = m_pscan->IchMinTok();
  7905. ChkNxtTok(tkLParen, ERRnoLparen);
  7906. ParseNodePtr pnodeObj = ParseExpr<buildAST>();
  7907. if (!buildAST)
  7908. {
  7909. m_scopeCountNoAst++;
  7910. }
  7911. charcount_t ichLim = m_pscan->IchLimTok();
  7912. ChkCurTok(tkRParen, ERRnoRparen);
  7913. if (buildAST)
  7914. {
  7915. pnode = CreateNodeWithScanner<knopWith>(ichMin);
  7916. }
  7917. PushStmt<buildAST>(&stmt, pnode, knopWith, pnodeLabel, pLabelIdList);
  7918. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  7919. if (buildAST)
  7920. {
  7921. pnode->sxWith.pnodeObj = pnodeObj;
  7922. this->CheckArguments(pnode->sxWith.pnodeObj);
  7923. if (m_ppnodeExprScope)
  7924. {
  7925. Assert(*m_ppnodeExprScope == nullptr);
  7926. *m_ppnodeExprScope = pnode;
  7927. m_ppnodeExprScope = &pnode->sxWith.pnodeNext;
  7928. }
  7929. else
  7930. {
  7931. Assert(m_ppnodeScope);
  7932. Assert(*m_ppnodeScope == nullptr);
  7933. *m_ppnodeScope = pnode;
  7934. m_ppnodeScope = &pnode->sxWith.pnodeNext;
  7935. }
  7936. pnode->sxWith.pnodeNext = nullptr;
  7937. pnode->sxWith.scope = nullptr;
  7938. ppnodeExprScopeSave = m_ppnodeExprScope;
  7939. m_ppnodeExprScope = &pnode->sxWith.pnodeScopes;
  7940. pnode->sxWith.pnodeScopes = nullptr;
  7941. pnode->ichLim = ichLim;
  7942. }
  7943. if (buildAST || BindDeferredPidRefs())
  7944. {
  7945. PushBlockInfo(CreateBlockNode());
  7946. PushDynamicBlock();
  7947. }
  7948. ParseNodePtr pnodeBody = ParseStatement<buildAST>();
  7949. if (buildAST)
  7950. {
  7951. pnode->sxWith.pnodeBody = pnodeBody;
  7952. m_ppnodeExprScope = ppnodeExprScopeSave;
  7953. }
  7954. else
  7955. {
  7956. m_scopeCountNoAst--;
  7957. }
  7958. if (buildAST || BindDeferredPidRefs())
  7959. {
  7960. // The dynamic block is not stored in the actual parse tree and so will not
  7961. // be visited by the byte code generator. Grab the callsEval flag off it and
  7962. // pass on to outer block in case of:
  7963. // with (...) eval(...); // i.e. blockless form of with
  7964. bool callsEval = GetCurrentBlock()->sxBlock.GetCallsEval();
  7965. PopBlockInfo();
  7966. if (callsEval)
  7967. {
  7968. // be careful not to overwrite an existing true with false
  7969. GetCurrentBlock()->sxBlock.SetCallsEval(true);
  7970. }
  7971. }
  7972. PopStmt(&stmt);
  7973. break;
  7974. }
  7975. case tkLCurly:
  7976. pnode = ParseBlock<buildAST>(pnodeLabel, pLabelIdList);
  7977. break;
  7978. case tkSColon:
  7979. pnode = nullptr;
  7980. m_pscan->Scan();
  7981. break;
  7982. case tkBREAK:
  7983. if (buildAST)
  7984. {
  7985. pnode = CreateNodeWithScanner<knopBreak>();
  7986. }
  7987. fnop = fnopBreak;
  7988. goto LGetJumpStatement;
  7989. case tkCONTINUE:
  7990. if (buildAST)
  7991. {
  7992. pnode = CreateNode(knopContinue);
  7993. }
  7994. fnop = fnopContinue;
  7995. LGetJumpStatement:
  7996. m_pscan->ScanForcingPid();
  7997. if (tkID == m_token.tk && !m_pscan->FHadNewLine())
  7998. {
  7999. // Labeled break or continue.
  8000. pid = m_token.GetIdentifier(m_phtbl);
  8001. AssertMem(pid);
  8002. if (buildAST)
  8003. {
  8004. pnode->sxJump.hasExplicitTarget=true;
  8005. pnode->ichLim = m_pscan->IchLimTok();
  8006. m_pscan->Scan();
  8007. PushStmt<buildAST>(&stmt, pnode, pnode->nop, pnodeLabel, nullptr);
  8008. Assert(pnode->sxStmt.grfnop == 0);
  8009. for (pstmt = m_pstmtCur; nullptr != pstmt; pstmt = pstmt->pstmtOuter)
  8010. {
  8011. AssertNodeMem(pstmt->pnodeStmt);
  8012. AssertNodeMemN(pstmt->pnodeLab);
  8013. for (pnodeT = pstmt->pnodeLab; nullptr != pnodeT;
  8014. pnodeT = pnodeT->sxLabel.pnodeNext)
  8015. {
  8016. Assert(knopLabel == pnodeT->nop);
  8017. if (pid == pnodeT->sxLabel.pid)
  8018. {
  8019. // Found the label. Make sure we can use it. We can
  8020. // break out of any statement, but we can only
  8021. // continue loops.
  8022. if (fnop == fnopContinue &&
  8023. !(pstmt->pnodeStmt->Grfnop() & fnop))
  8024. {
  8025. Error(ERRbadContinue);
  8026. }
  8027. else
  8028. {
  8029. pstmt->pnodeStmt->sxStmt.grfnop |= fnop;
  8030. pnode->sxJump.pnodeTarget = pstmt->pnodeStmt;
  8031. }
  8032. PopStmt(&stmt);
  8033. goto LNeedTerminator;
  8034. }
  8035. }
  8036. pnode->sxStmt.grfnop |=
  8037. (pstmt->pnodeStmt->Grfnop() & fnopCleanup);
  8038. }
  8039. }
  8040. else
  8041. {
  8042. m_pscan->Scan();
  8043. for (pstmt = m_pstmtCur; pstmt; pstmt = pstmt->pstmtOuter)
  8044. {
  8045. LabelId* pLabelId;
  8046. for (pLabelId = pstmt->pLabelId; pLabelId; pLabelId = pLabelId->next)
  8047. {
  8048. if (pid == pLabelId->pid)
  8049. {
  8050. // Found the label. Make sure we can use it. We can
  8051. // break out of any statement, but we can only
  8052. // continue loops.
  8053. if (fnop == fnopContinue &&
  8054. !(ParseNode::Grfnop(pstmt->op) & fnop))
  8055. {
  8056. Error(ERRbadContinue);
  8057. }
  8058. goto LNeedTerminator;
  8059. }
  8060. }
  8061. }
  8062. }
  8063. Error(ERRnoLabel);
  8064. }
  8065. else
  8066. {
  8067. // If we're doing a fast scan, we're not tracking labels, so we can't accurately do this analysis.
  8068. // Let the thread that's doing the full parse detect the error, if there is one.
  8069. if (!this->m_doingFastScan)
  8070. {
  8071. // Unlabeled break or continue.
  8072. if (buildAST)
  8073. {
  8074. pnode->sxJump.hasExplicitTarget=false;
  8075. PushStmt<buildAST>(&stmt, pnode, pnode->nop, pnodeLabel, nullptr);
  8076. Assert(pnode->sxStmt.grfnop == 0);
  8077. }
  8078. for (pstmt = m_pstmtCur; nullptr != pstmt; pstmt = pstmt->pstmtOuter)
  8079. {
  8080. if (buildAST)
  8081. {
  8082. AnalysisAssert(pstmt->pnodeStmt);
  8083. if (pstmt->pnodeStmt->Grfnop() & fnop)
  8084. {
  8085. pstmt->pnodeStmt->sxStmt.grfnop |= fnop;
  8086. pnode->sxJump.pnodeTarget = pstmt->pnodeStmt;
  8087. PopStmt(&stmt);
  8088. goto LNeedTerminator;
  8089. }
  8090. pnode->sxStmt.grfnop |=
  8091. (pstmt->pnodeStmt->Grfnop() & fnopCleanup);
  8092. }
  8093. else
  8094. {
  8095. if (pstmt->isDeferred)
  8096. {
  8097. if (ParseNode::Grfnop(pstmt->op) & fnop)
  8098. {
  8099. goto LNeedTerminator;
  8100. }
  8101. }
  8102. else
  8103. {
  8104. AnalysisAssert(pstmt->pnodeStmt);
  8105. if (pstmt->pnodeStmt->Grfnop() & fnop)
  8106. {
  8107. pstmt->pnodeStmt->sxStmt.grfnop |= fnop;
  8108. goto LNeedTerminator;
  8109. }
  8110. }
  8111. }
  8112. }
  8113. Error(fnop == fnopBreak ? ERRbadBreak : ERRbadContinue);
  8114. }
  8115. goto LNeedTerminator;
  8116. }
  8117. case tkRETURN:
  8118. {
  8119. if (buildAST)
  8120. {
  8121. if (nullptr == m_currentNodeFunc)
  8122. {
  8123. Error(ERRbadReturn);
  8124. }
  8125. pnode = CreateNodeWithScanner<knopReturn>();
  8126. }
  8127. m_pscan->Scan();
  8128. ParseNodePtr pnodeExpr = nullptr;
  8129. ParseOptionalExpr<buildAST>(&pnodeExpr, true);
  8130. if (buildAST)
  8131. {
  8132. pnode->sxReturn.pnodeExpr = pnodeExpr;
  8133. if (pnodeExpr)
  8134. {
  8135. this->CheckArguments(pnode->sxReturn.pnodeExpr);
  8136. pnode->ichLim = pnode->sxReturn.pnodeExpr->ichLim;
  8137. }
  8138. // See if return should call finally
  8139. PushStmt<buildAST>(&stmt, pnode, knopReturn, pnodeLabel, nullptr);
  8140. Assert(pnode->sxStmt.grfnop == 0);
  8141. for (pstmt = m_pstmtCur; nullptr != pstmt; pstmt = pstmt->pstmtOuter)
  8142. {
  8143. AssertNodeMem(pstmt->pnodeStmt);
  8144. AssertNodeMemN(pstmt->pnodeLab);
  8145. if (pstmt->pnodeStmt->Grfnop() & fnopCleanup)
  8146. {
  8147. pnode->sxStmt.grfnop |= fnopCleanup;
  8148. break;
  8149. }
  8150. }
  8151. PopStmt(&stmt);
  8152. }
  8153. goto LNeedTerminator;
  8154. }
  8155. case tkTHROW:
  8156. {
  8157. if (buildAST)
  8158. {
  8159. pnode = CreateUniNode(knopThrow, nullptr);
  8160. }
  8161. m_pscan->Scan();
  8162. ParseNodePtr pnode1 = nullptr;
  8163. if (m_token.tk != tkSColon &&
  8164. m_token.tk != tkRCurly &&
  8165. !m_pscan->FHadNewLine())
  8166. {
  8167. pnode1 = ParseExpr<buildAST>();
  8168. }
  8169. else
  8170. {
  8171. Error(ERRdanglingThrow);
  8172. }
  8173. if (buildAST)
  8174. {
  8175. pnode->sxUni.pnode1 = pnode1;
  8176. if (pnode1)
  8177. {
  8178. this->CheckArguments(pnode->sxUni.pnode1);
  8179. pnode->ichLim = pnode->sxUni.pnode1->ichLim;
  8180. }
  8181. }
  8182. goto LNeedTerminator;
  8183. }
  8184. case tkDEBUGGER:
  8185. if (buildAST)
  8186. {
  8187. pnode = CreateNodeWithScanner<knopDebugger>();
  8188. }
  8189. m_pscan->Scan();
  8190. goto LNeedTerminator;
  8191. LDefaultToken:
  8192. default:
  8193. {
  8194. // An expression statement or a label.
  8195. IdentToken tok;
  8196. pnode = ParseExpr<buildAST>(koplNo, nullptr, TRUE, FALSE, nullptr, nullptr /*hintLength*/, nullptr /*hintOffset*/, &tok);
  8197. if (buildAST)
  8198. {
  8199. // Check for a label.
  8200. if (tkColon == m_token.tk &&
  8201. nullptr != pnode && knopName == pnode->nop)
  8202. {
  8203. // We have a label. See if it is already defined.
  8204. if (nullptr != PnodeLabel(pnode->sxPid.pid, pnodeLabel))
  8205. {
  8206. Error(ERRbadLabel);
  8207. // No recovery is necessary since this is a semantic, not structural, error
  8208. }
  8209. pnodeT = CreateNodeWithScanner<knopLabel>();
  8210. pnodeT->sxLabel.pid = pnode->sxPid.pid;
  8211. pnodeT->sxLabel.pnodeNext = pnodeLabel;
  8212. pnodeLabel = pnodeT;
  8213. m_pscan->Scan();
  8214. isSourceElement = false;
  8215. goto LRestart;
  8216. }
  8217. expressionStmt = true;
  8218. AnalysisAssert(pnode);
  8219. pnode->isUsed = false;
  8220. }
  8221. else
  8222. {
  8223. // Check for a label.
  8224. if (tkColon == m_token.tk && tok.tk == tkID)
  8225. {
  8226. tok.pid = m_pscan->PidAt(tok.ichMin, tok.ichLim);
  8227. if (PnodeLabelNoAST(&tok, pLabelIdList))
  8228. {
  8229. Error(ERRbadLabel);
  8230. }
  8231. LabelId* pLabelId = CreateLabelId(&tok);
  8232. pLabelId->next = pLabelIdList;
  8233. pLabelIdList = pLabelId;
  8234. m_pscan->Scan();
  8235. isSourceElement = false;
  8236. goto LRestart;
  8237. }
  8238. }
  8239. }
  8240. LNeedTerminator:
  8241. // Need a semicolon, new-line, } or end-of-file.
  8242. // We digest a semicolon if it's there.
  8243. switch (m_token.tk)
  8244. {
  8245. case tkSColon:
  8246. m_pscan->Scan();
  8247. if (pnode!= nullptr) pnode->grfpn |= PNodeFlags::fpnExplicitSemicolon;
  8248. break;
  8249. case tkEOF:
  8250. case tkRCurly:
  8251. if (pnode!= nullptr) pnode->grfpn |= PNodeFlags::fpnAutomaticSemicolon;
  8252. break;
  8253. default:
  8254. if (!m_pscan->FHadNewLine())
  8255. {
  8256. Error(ERRnoSemic);
  8257. }
  8258. else
  8259. {
  8260. if (pnode!= nullptr) pnode->grfpn |= PNodeFlags::fpnAutomaticSemicolon;
  8261. }
  8262. break;
  8263. }
  8264. break;
  8265. }
  8266. if (buildAST)
  8267. {
  8268. // All non expression statements excluded from the "this.x" optimization
  8269. // Another check while parsing expressions
  8270. if (!expressionStmt)
  8271. {
  8272. if (m_currentNodeFunc)
  8273. {
  8274. m_currentNodeFunc->sxFnc.SetHasNonThisStmt();
  8275. }
  8276. else if (m_currentNodeProg)
  8277. {
  8278. m_currentNodeProg->sxFnc.SetHasNonThisStmt();
  8279. }
  8280. }
  8281. #if EXCEPTION_RECOVERY
  8282. // close the try/catch block
  8283. if(Js::Configuration::Global.flags.SwallowExceptions)
  8284. {
  8285. // pop the try block and fill in the body
  8286. PopStmt(&stmtTryBlock);
  8287. pTryBlock->sxBlock.pnodeStmt = pnode;
  8288. PopStmt(&stmtTry);
  8289. if(pnode != nullptr)
  8290. {
  8291. pTry->ichLim = pnode->ichLim;
  8292. }
  8293. pTry->sxTry.pnodeBody = pTryBlock;
  8294. // create a catch block with an empty body
  8295. StmtNest stmtCatch;
  8296. ParseNodePtr pCatch;
  8297. pCatch = CreateNodeWithScanner<knopCatch>();
  8298. PushStmt<buildAST>(&stmtCatch, pCatch, knopCatch, nullptr, nullptr);
  8299. pCatch->sxCatch.pnodeBody = nullptr;
  8300. if(pnode != nullptr)
  8301. {
  8302. pCatch->ichLim = pnode->ichLim;
  8303. }
  8304. pCatch->sxCatch.grfnop = 0;
  8305. pCatch->sxCatch.pnodeNext = nullptr;
  8306. // create a fake name for the catch var.
  8307. WCHAR *uniqueNameStr = L"__ehobj";
  8308. IdentPtr uniqueName = m_phtbl->PidHashNameLen(uniqueNameStr, static_cast<long>(wcslen(uniqueNameStr)));
  8309. pCatch->sxCatch.pnodeParam = CreateNameNode(uniqueName);
  8310. // Add this catch to the current list. We don't bother adjusting the catch and function expression
  8311. // lists here because the catch is just an empty statement.
  8312. if (m_ppnodeExprScope)
  8313. {
  8314. Assert(*m_ppnodeExprScope == nullptr);
  8315. *m_ppnodeExprScope = pCatch;
  8316. m_ppnodeExprScope = &pCatch->sxCatch.pnodeNext;
  8317. }
  8318. else
  8319. {
  8320. Assert(m_ppnodeScope);
  8321. Assert(*m_ppnodeScope == nullptr);
  8322. *m_ppnodeScope = pCatch;
  8323. m_ppnodeScope = &pCatch->sxCatch.pnodeNext;
  8324. }
  8325. pCatch->sxCatch.pnodeScopes = nullptr;
  8326. PopStmt(&stmtCatch);
  8327. // fill in and pop the try-catch
  8328. pParentTryCatch->sxTryCatch.pnodeTry = pTry;
  8329. pParentTryCatch->sxTryCatch.pnodeCatch = pCatch;
  8330. PopStmt(&stmtTryCatch);
  8331. PopStmt(&stmtTryCatchBlock);
  8332. // replace the node that's being returned
  8333. pParentTryCatchBlock->sxBlock.pnodeStmt = pParentTryCatch;
  8334. pnode = pParentTryCatchBlock;
  8335. }
  8336. #endif // EXCEPTION_RECOVERY
  8337. }
  8338. return pnode;
  8339. }
  8340. BOOL
  8341. Parser::TokIsForInOrForOf()
  8342. {
  8343. return m_token.tk == tkIN ||
  8344. (m_scriptContext->GetConfig()->IsES6IteratorsEnabled() &&
  8345. m_token.tk == tkID &&
  8346. m_token.GetIdentifier(m_phtbl) == wellKnownPropertyPids.of);
  8347. }
  8348. /***************************************************************************
  8349. Parse a sequence of statements.
  8350. ***************************************************************************/
  8351. template<bool buildAST>
  8352. void Parser::ParseStmtList(ParseNodePtr *ppnodeList, ParseNodePtr **pppnodeLast, StrictModeEnvironment smEnvironment, const bool isSourceElementList, bool* strictModeOn)
  8353. {
  8354. BOOL doneDirectives = !isSourceElementList; // directives may only exist in a SourceElementList, not a StatementList
  8355. BOOL seenDirectiveContainingOctal = false; // Have we seen an octal directive before a use strict directive?
  8356. BOOL old_UseStrictMode = m_fUseStrictMode;
  8357. ParseNodePtr pnodeStmt;
  8358. ParseNodePtr *lastNodeRef = nullptr;
  8359. if (buildAST)
  8360. {
  8361. AssertMem(ppnodeList);
  8362. AssertMemN(pppnodeLast);
  8363. *ppnodeList = nullptr;
  8364. }
  8365. if(CONFIG_FLAG(ForceStrictMode))
  8366. {
  8367. m_fUseStrictMode = TRUE;
  8368. }
  8369. for (;;)
  8370. {
  8371. switch (m_token.tk)
  8372. {
  8373. case tkCASE:
  8374. case tkDEFAULT:
  8375. case tkRCurly:
  8376. case tkEOF:
  8377. if (buildAST && nullptr != pppnodeLast)
  8378. {
  8379. *pppnodeLast = lastNodeRef;
  8380. }
  8381. if (!buildAST)
  8382. {
  8383. m_fUseStrictMode = old_UseStrictMode;
  8384. }
  8385. return;
  8386. }
  8387. if (doneDirectives == FALSE)
  8388. {
  8389. bool isOctalInString = false;
  8390. bool isUseStrictDirective = false;
  8391. bool isUseAsmDirective = false;
  8392. if (smEnvironment != SM_NotUsed && CheckForDirective(&isUseStrictDirective, &isUseAsmDirective, &isOctalInString))
  8393. {
  8394. if (isUseStrictDirective)
  8395. {
  8396. // Functions with non-simple parameter list cannot be made strict mode
  8397. if (!GetCurrentFunctionNode()->sxFnc.IsSimpleParameterList())
  8398. {
  8399. Error(ERRNonSimpleParamListInStrictMode);
  8400. }
  8401. if (seenDirectiveContainingOctal)
  8402. {
  8403. // Directives seen before a "use strict" cannot contain an octal.
  8404. Error(ERRES5NoOctal);
  8405. }
  8406. if (!buildAST)
  8407. {
  8408. // Turning on strict mode in deferred code.
  8409. m_fUseStrictMode = TRUE;
  8410. if (!m_inDeferredNestedFunc)
  8411. {
  8412. // Top-level deferred function, so there's a parse node
  8413. Assert(m_currentNodeFunc != nullptr);
  8414. m_currentNodeFunc->sxFnc.SetStrictMode();
  8415. }
  8416. else if (strictModeOn)
  8417. {
  8418. // This turns on strict mode in a deferred function, we need to go back
  8419. // and re-check duplicated formals.
  8420. *strictModeOn = true;
  8421. }
  8422. }
  8423. else
  8424. {
  8425. if (smEnvironment == SM_OnGlobalCode)
  8426. {
  8427. // Turning on strict mode at the top level
  8428. m_fUseStrictMode = TRUE;
  8429. }
  8430. else
  8431. {
  8432. // i.e. smEnvironment == SM_OnFunctionCode
  8433. Assert(m_currentNodeFunc != nullptr);
  8434. m_currentNodeFunc->sxFnc.SetStrictMode();
  8435. }
  8436. }
  8437. }
  8438. else if (isUseAsmDirective)
  8439. {
  8440. if (smEnvironment != SM_OnGlobalCode) //Top level use asm doesn't mean anything.
  8441. {
  8442. // i.e. smEnvironment == SM_OnFunctionCode
  8443. Assert(m_currentNodeFunc != nullptr);
  8444. m_currentNodeFunc->sxFnc.SetAsmjsMode();
  8445. m_InAsmMode = true;
  8446. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(AsmJSFunctionCount, m_scriptContext);
  8447. }
  8448. }
  8449. else if (isOctalInString)
  8450. {
  8451. seenDirectiveContainingOctal = TRUE;
  8452. }
  8453. }
  8454. else
  8455. {
  8456. // The first time we see anything other than a directive we can have no more directives.
  8457. doneDirectives = TRUE;
  8458. }
  8459. }
  8460. if (nullptr != (pnodeStmt = ParseStatement<buildAST>(isSourceElementList)))
  8461. {
  8462. Assert(buildAST || BindDeferredPidRefs());
  8463. if (buildAST)
  8464. {
  8465. AddToNodeList(ppnodeList, &lastNodeRef, pnodeStmt);
  8466. }
  8467. }
  8468. }
  8469. }
  8470. template <class Fn>
  8471. void Parser::VisitFunctionsInScope(ParseNodePtr pnodeScopeList, Fn fn)
  8472. {
  8473. ParseNodePtr pnodeScope;
  8474. for (pnodeScope = pnodeScopeList; pnodeScope;)
  8475. {
  8476. switch (pnodeScope->nop)
  8477. {
  8478. case knopBlock:
  8479. VisitFunctionsInScope(pnodeScope->sxBlock.pnodeScopes, fn);
  8480. pnodeScope = pnodeScope->sxBlock.pnodeNext;
  8481. break;
  8482. case knopFncDecl:
  8483. fn(pnodeScope);
  8484. pnodeScope = pnodeScope->sxFnc.pnodeNext;
  8485. break;
  8486. case knopCatch:
  8487. VisitFunctionsInScope(pnodeScope->sxCatch.pnodeScopes, fn);
  8488. pnodeScope = pnodeScope->sxCatch.pnodeNext;
  8489. break;
  8490. case knopWith:
  8491. VisitFunctionsInScope(pnodeScope->sxWith.pnodeScopes, fn);
  8492. pnodeScope = pnodeScope->sxWith.pnodeNext;
  8493. break;
  8494. default:
  8495. AssertMsg(false, "Unexpected node with scope list");
  8496. return;
  8497. }
  8498. }
  8499. }
  8500. // Scripts above this size (minus string literals and comments) will have parsing of
  8501. // function bodies deferred.
  8502. ULONG Parser::GetDeferralThreshold(bool isProfileLoaded)
  8503. {
  8504. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  8505. if (CONFIG_FLAG(ForceDeferParse) ||
  8506. PHASE_FORCE1(Js::DeferParsePhase) ||
  8507. Js::Configuration::Global.flags.IsEnabled(Js::ForceUndoDeferFlag))
  8508. {
  8509. return 0;
  8510. }
  8511. else if (Js::Configuration::Global.flags.IsEnabled(Js::DeferParseFlag))
  8512. {
  8513. return Js::Configuration::Global.flags.DeferParse;
  8514. }
  8515. else
  8516. #endif
  8517. {
  8518. if (isProfileLoaded)
  8519. {
  8520. return DEFAULT_CONFIG_ProfileBasedDeferParseThreshold;
  8521. }
  8522. return DEFAULT_CONFIG_DeferParseThreshold;
  8523. }
  8524. }
  8525. void Parser::FinishDeferredFunction(ParseNodePtr pnodeScopeList)
  8526. {
  8527. VisitFunctionsInScope(pnodeScopeList,
  8528. [this](ParseNodePtr pnodeFnc)
  8529. {
  8530. Assert(pnodeFnc->nop == knopFncDecl);
  8531. if (pnodeFnc->sxFnc.pnodeBody == nullptr)
  8532. {
  8533. // Go back and generate an AST for this function.
  8534. JS_ETW(EventWriteJSCRIPT_PARSE_FUNC(this->GetScriptContext(), pnodeFnc->sxFnc.functionId, /*Undefer*/TRUE));
  8535. ParseNodePtr pnodeFncSave = this->m_currentNodeFunc;
  8536. this->m_currentNodeFunc = pnodeFnc;
  8537. ParseNodePtr pnodeFncExprBlock = nullptr;
  8538. if (pnodeFnc->sxFnc.pnodeName &&
  8539. !pnodeFnc->sxFnc.IsDeclaration())
  8540. {
  8541. // Set up the named function expression symbol so references inside the function can be bound.
  8542. ParseNodePtr pnodeName = pnodeFnc->sxFnc.pnodeName;
  8543. Assert(pnodeName->nop == knopVarDecl);
  8544. Assert(pnodeName->sxVar.pnodeNext == nullptr);
  8545. pnodeFncExprBlock = this->StartParseBlock<true>(PnodeBlockType::Function, ScopeType_FuncExpr);
  8546. PidRefStack *ref = this->PushPidRef(pnodeName->sxVar.pid);
  8547. pnodeName->sxVar.symRef = ref->GetSymRef();
  8548. ref->SetSym(pnodeName->sxVar.sym);
  8549. Scope *fncExprScope = pnodeFncExprBlock->sxBlock.scope;
  8550. fncExprScope->AddNewSymbol(pnodeName->sxVar.sym);
  8551. pnodeFnc->sxFnc.scope = fncExprScope;
  8552. }
  8553. ParseNodePtr pnodeBlock = this->StartParseBlock<true>(PnodeBlockType::Parameter, ScopeType_Parameter);
  8554. pnodeFnc->sxFnc.pnodeScopes = pnodeBlock;
  8555. m_ppnodeScope = &pnodeBlock->sxBlock.pnodeScopes;
  8556. pnodeBlock->sxBlock.pnodeStmt = pnodeFnc;
  8557. // Add the args to the scope, since we won't re-parse those.
  8558. Scope *scope = pnodeBlock->sxBlock.scope;
  8559. auto addArgsToScope = [&](ParseNodePtr pnodeArg) {
  8560. if (pnodeArg->IsVarLetOrConst())
  8561. {
  8562. PidRefStack *ref = this->PushPidRef(pnodeArg->sxVar.pid);
  8563. pnodeArg->sxVar.symRef = ref->GetSymRef();
  8564. if (ref->GetSym() != nullptr)
  8565. {
  8566. // Duplicate parameter in a configuration that allows them.
  8567. // The symbol is already in the scope, just point it to the right declaration.
  8568. Assert(ref->GetSym() == pnodeArg->sxVar.sym);
  8569. ref->GetSym()->SetDecl(pnodeArg);
  8570. }
  8571. else
  8572. {
  8573. ref->SetSym(pnodeArg->sxVar.sym);
  8574. scope->AddNewSymbol(pnodeArg->sxVar.sym);
  8575. }
  8576. }
  8577. };
  8578. MapFormals(pnodeFnc, addArgsToScope);
  8579. MapFormalsFromPattern(pnodeFnc, addArgsToScope);
  8580. ParseNodePtr pnodeInnerBlock = this->StartParseBlock<true>(PnodeBlockType::Function, ScopeType_FunctionBody);
  8581. pnodeFnc->sxFnc.pnodeBodyScope = pnodeInnerBlock;
  8582. // Set the parameter block's child to the function body block.
  8583. *m_ppnodeScope = pnodeInnerBlock;
  8584. ParseNodePtr *ppnodeScopeSave = nullptr;
  8585. ParseNodePtr *ppnodeExprScopeSave = nullptr;
  8586. ppnodeScopeSave = m_ppnodeScope;
  8587. // This synthetic block scope will contain all the nested scopes.
  8588. m_ppnodeScope = &pnodeInnerBlock->sxBlock.pnodeScopes;
  8589. pnodeInnerBlock->sxBlock.pnodeStmt = pnodeFnc;
  8590. // Keep nested function declarations and expressions in the same list at function scope.
  8591. // (Indicate this by nulling out the current function expressions list.)
  8592. ppnodeExprScopeSave = m_ppnodeExprScope;
  8593. m_ppnodeExprScope = nullptr;
  8594. // Shouldn't be any temps in the arg list.
  8595. Assert(*m_ppnodeVar == nullptr);
  8596. // Start the var list.
  8597. pnodeFnc->sxFnc.pnodeVars = nullptr;
  8598. m_ppnodeVar = &pnodeFnc->sxFnc.pnodeVars;
  8599. this->FinishFncNode(pnodeFnc);
  8600. m_ppnodeExprScope = ppnodeExprScopeSave;
  8601. AssertMem(m_ppnodeScope);
  8602. Assert(nullptr == *m_ppnodeScope);
  8603. m_ppnodeScope = ppnodeScopeSave;
  8604. this->FinishParseBlock(pnodeInnerBlock);
  8605. this->AddArgumentsNodeToVars(pnodeFnc);
  8606. this->FinishParseBlock(pnodeBlock);
  8607. if (pnodeFncExprBlock)
  8608. {
  8609. this->FinishParseBlock(pnodeFncExprBlock);
  8610. }
  8611. this->m_currentNodeFunc = pnodeFncSave;
  8612. }
  8613. });
  8614. }
  8615. void Parser::InitPids()
  8616. {
  8617. AssertMemN(m_phtbl);
  8618. wellKnownPropertyPids.arguments = m_phtbl->PidHashNameLen(g_ssym_arguments.sz, g_ssym_arguments.cch);
  8619. wellKnownPropertyPids.async = m_phtbl->PidHashNameLen(g_ssym_async.sz, g_ssym_async.cch);
  8620. wellKnownPropertyPids.eval = m_phtbl->PidHashNameLen(g_ssym_eval.sz, g_ssym_eval.cch);
  8621. wellKnownPropertyPids.getter = m_phtbl->PidHashNameLen(g_ssym_get.sz, g_ssym_get.cch);
  8622. wellKnownPropertyPids.setter = m_phtbl->PidHashNameLen(g_ssym_set.sz, g_ssym_set.cch);
  8623. wellKnownPropertyPids.let = m_phtbl->PidHashNameLen(g_ssym_let.sz, g_ssym_let.cch);
  8624. wellKnownPropertyPids.constructor = m_phtbl->PidHashNameLen(g_ssym_constructor.sz, g_ssym_constructor.cch);
  8625. wellKnownPropertyPids.prototype = m_phtbl->PidHashNameLen(g_ssym_prototype.sz, g_ssym_prototype.cch);
  8626. wellKnownPropertyPids.__proto__ = m_phtbl->PidHashNameLen(L"__proto__", sizeof("__proto__") - 1);
  8627. wellKnownPropertyPids.of = m_phtbl->PidHashNameLen(L"of", sizeof("of") - 1);
  8628. wellKnownPropertyPids.target = m_phtbl->PidHashNameLen(L"target", sizeof("target") - 1);
  8629. }
  8630. void Parser::RestoreScopeInfo(Js::FunctionBody* functionBody)
  8631. {
  8632. if (!functionBody)
  8633. {
  8634. return;
  8635. }
  8636. Js::ScopeInfo* scopeInfo = functionBody->GetScopeInfo();
  8637. if (!scopeInfo)
  8638. {
  8639. return;
  8640. }
  8641. if (this->IsBackgroundParser())
  8642. {
  8643. PROBE_STACK_NO_DISPOSE(m_scriptContext, Js::Constants::MinStackByteCodeVisitor);
  8644. }
  8645. else
  8646. {
  8647. PROBE_STACK(m_scriptContext, Js::Constants::MinStackByteCodeVisitor);
  8648. }
  8649. RestoreScopeInfo(scopeInfo->GetParent()); // Recursively restore outer func scope info
  8650. Js::ScopeInfo* funcExprScopeInfo = scopeInfo->GetFuncExprScopeInfo();
  8651. if (funcExprScopeInfo)
  8652. {
  8653. funcExprScopeInfo->SetScopeId(m_nextBlockId);
  8654. ParseNodePtr pnodeFncExprScope = StartParseBlockWithCapacity<true>(PnodeBlockType::Function, ScopeType_FuncExpr, funcExprScopeInfo->GetSymbolCount());
  8655. Scope *scope = pnodeFncExprScope->sxBlock.scope;
  8656. funcExprScopeInfo->GetScopeInfo(this, nullptr, nullptr, scope);
  8657. }
  8658. Js::ScopeInfo* paramScopeInfo = scopeInfo->GetParamScopeInfo();
  8659. if (paramScopeInfo)
  8660. {
  8661. paramScopeInfo->SetScopeId(m_nextBlockId);
  8662. ParseNodePtr pnodeFncExprScope = StartParseBlockWithCapacity<true>(PnodeBlockType::Parameter, ScopeType_Parameter, paramScopeInfo->GetSymbolCount());
  8663. Scope *scope = pnodeFncExprScope->sxBlock.scope;
  8664. paramScopeInfo->GetScopeInfo(this, nullptr, nullptr, scope);
  8665. }
  8666. scopeInfo->SetScopeId(m_nextBlockId);
  8667. ParseNodePtr pnodeFncScope = nullptr;
  8668. if (scopeInfo->IsGlobalEval())
  8669. {
  8670. pnodeFncScope = StartParseBlockWithCapacity<true>(PnodeBlockType::Regular, ScopeType_GlobalEvalBlock, scopeInfo->GetSymbolCount());
  8671. }
  8672. else
  8673. {
  8674. pnodeFncScope = StartParseBlockWithCapacity<true>(PnodeBlockType::Function, ScopeType_FunctionBody, scopeInfo->GetSymbolCount());
  8675. }
  8676. Scope *scope = pnodeFncScope->sxBlock.scope;
  8677. scopeInfo->GetScopeInfo(this, nullptr, nullptr, scope);
  8678. }
  8679. void Parser::FinishScopeInfo(Js::FunctionBody *functionBody)
  8680. {
  8681. if (!functionBody)
  8682. {
  8683. return;
  8684. }
  8685. Js::ScopeInfo* scopeInfo = functionBody->GetScopeInfo();
  8686. if (!scopeInfo)
  8687. {
  8688. return;
  8689. }
  8690. if (this->IsBackgroundParser())
  8691. {
  8692. PROBE_STACK_NO_DISPOSE(m_scriptContext, Js::Constants::MinStackByteCodeVisitor);
  8693. }
  8694. else
  8695. {
  8696. PROBE_STACK(m_scriptContext, Js::Constants::MinStackByteCodeVisitor);
  8697. }
  8698. int scopeId = scopeInfo->GetScopeId();
  8699. scopeInfo->GetScope()->ForEachSymbol([this, scopeId](Symbol *sym)
  8700. {
  8701. this->BindPidRefsInScope(sym->GetPid(), sym, scopeId);
  8702. });
  8703. PopScope(scopeInfo->GetScope());
  8704. PopStmt(&m_currentBlockInfo->pstmt);
  8705. PopBlockInfo();
  8706. Js::ScopeInfo *paramScopeInfo = scopeInfo->GetParamScopeInfo();
  8707. if (paramScopeInfo)
  8708. {
  8709. scopeId = paramScopeInfo->GetScopeId();
  8710. paramScopeInfo->GetScope()->ForEachSymbol([this, scopeId](Symbol *sym)
  8711. {
  8712. this->BindPidRefsInScope(sym->GetPid(), sym, scopeId);
  8713. });
  8714. PopScope(paramScopeInfo->GetScope());
  8715. PopStmt(&m_currentBlockInfo->pstmt);
  8716. PopBlockInfo();
  8717. }
  8718. Js::ScopeInfo *funcExprScopeInfo = scopeInfo->GetFuncExprScopeInfo();
  8719. if (funcExprScopeInfo)
  8720. {
  8721. scopeId = funcExprScopeInfo->GetScopeId();
  8722. funcExprScopeInfo->GetScope()->ForEachSymbol([this, scopeId](Symbol *sym)
  8723. {
  8724. this->BindPidRefsInScope(sym->GetPid(), sym, scopeId);
  8725. });
  8726. PopScope(funcExprScopeInfo->GetScope());
  8727. PopStmt(&m_currentBlockInfo->pstmt);
  8728. PopBlockInfo();
  8729. }
  8730. FinishScopeInfo(scopeInfo->GetParent());
  8731. }
  8732. /***************************************************************************
  8733. Parse the code.
  8734. ***************************************************************************/
  8735. ParseNodePtr Parser::Parse(LPCUTF8 pszSrc, size_t offset, size_t length, charcount_t charOffset, ULONG grfscr, ULONG lineNumber, Js::LocalFunctionId * nextFunctionId, CompileScriptException *pse)
  8736. {
  8737. ParseNodePtr pnodeProg;
  8738. ParseNodePtr *lastNodeRef = nullptr;
  8739. m_nextBlockId = 0;
  8740. // Scanner should run in Running mode and not syntax coloring mode
  8741. grfscr &= ~fscrSyntaxColor;
  8742. if (this->m_scriptContext->IsInDebugMode() || PHASE_OFF1(Js::Phase::DeferParsePhase)
  8743. #ifdef ENABLE_PREJIT
  8744. || Js::Configuration::Global.flags.Prejit
  8745. #endif
  8746. || ((grfscr & fscrNoDeferParse) != 0)
  8747. )
  8748. {
  8749. // Don't do deferred parsing if debugger is attached or feature is disabled
  8750. // by command-line switch.
  8751. grfscr &= ~fscrDeferFncParse;
  8752. }
  8753. bool isDeferred = (grfscr & fscrDeferredFnc) != 0;
  8754. m_grfscr = grfscr;
  8755. m_length = length;
  8756. m_originalLength = length;
  8757. m_nextFunctionId = nextFunctionId;
  8758. if(m_parseType != ParseType_Deferred)
  8759. {
  8760. JS_ETW(EventWriteJSCRIPT_PARSE_METHOD_START(m_sourceContextInfo->dwHostSourceContext, GetScriptContext(), *m_nextFunctionId, 0, m_parseType, Js::Constants::GlobalFunction));
  8761. OUTPUT_TRACE(Js::DeferParsePhase, L"Parsing function (%s) : %s (%d)\n", GetParseType(), Js::Constants::GlobalFunction, *m_nextFunctionId);
  8762. }
  8763. // Give the scanner the source and get the first token
  8764. m_pscan->SetText(pszSrc, offset, length, charOffset, grfscr, lineNumber);
  8765. m_pscan->Scan();
  8766. // Make the main 'knopProg' node
  8767. long initSize = 0;
  8768. m_pCurrentAstSize = &initSize;
  8769. pnodeProg = CreateNodeWithScanner<knopProg>();
  8770. pnodeProg->grfpn = PNodeFlags::fpnNone;
  8771. pnodeProg->sxFnc.pid = nullptr;
  8772. pnodeProg->sxFnc.pnodeName = nullptr;
  8773. pnodeProg->sxFnc.pnodeRest = nullptr;
  8774. pnodeProg->sxFnc.ClearFlags();
  8775. pnodeProg->sxFnc.SetNested(FALSE);
  8776. pnodeProg->sxFnc.astSize = 0;
  8777. pnodeProg->sxFnc.cbMin = m_pscan->IecpMinTok();
  8778. pnodeProg->sxFnc.lineNumber = lineNumber;
  8779. pnodeProg->sxFnc.columnNumber = 0;
  8780. if (!isDeferred || (isDeferred && grfscr & fscrGlobalCode))
  8781. {
  8782. // In the deferred case, if the global function is deferred parse (which is in no-refresh case),
  8783. // we will re-use the same function body, so start with the correct functionId.
  8784. pnodeProg->sxFnc.functionId = (*m_nextFunctionId)++;
  8785. }
  8786. else
  8787. {
  8788. pnodeProg->sxFnc.functionId = Js::Constants::NoFunctionId;
  8789. }
  8790. m_pCurrentAstSize = & (pnodeProg->sxFnc.astSize);
  8791. pnodeProg->sxFnc.hint = nullptr;
  8792. pnodeProg->sxFnc.hintLength = 0;
  8793. pnodeProg->sxFnc.hintOffset = 0;
  8794. pnodeProg->sxFnc.isNameIdentifierRef = true;
  8795. // initialize parsing variables
  8796. pnodeProg->sxFnc.pnodeNext = nullptr;
  8797. m_currentNodeFunc = nullptr;
  8798. m_currentNodeDeferredFunc = nullptr;
  8799. m_currentNodeProg = pnodeProg;
  8800. m_cactIdentToNodeLookup = 1;
  8801. pnodeProg->sxFnc.nestedCount = 0;
  8802. m_pnestedCount = &pnodeProg->sxFnc.nestedCount;
  8803. m_inDeferredNestedFunc = false;
  8804. pnodeProg->sxFnc.pnodeArgs = nullptr;
  8805. pnodeProg->sxFnc.pnodeVars = nullptr;
  8806. pnodeProg->sxFnc.pnodeRest = nullptr;
  8807. m_ppnodeVar = &pnodeProg->sxFnc.pnodeVars;
  8808. SetCurrentStatement(nullptr);
  8809. AssertMsg(m_pstmtCur == nullptr, "Statement stack should be empty when we start parse global code");
  8810. // Create block for const's and let's
  8811. ParseNodePtr pnodeGlobalBlock = StartParseBlock<true>(PnodeBlockType::Global, ScopeType_Global);
  8812. pnodeProg->sxProg.scope = pnodeGlobalBlock->sxBlock.scope;
  8813. ParseNodePtr pnodeGlobalEvalBlock = nullptr;
  8814. // Don't track function expressions separately from declarations at global scope.
  8815. m_ppnodeExprScope = nullptr;
  8816. // This synthetic block scope will contain all the nested scopes.
  8817. pnodeProg->sxFnc.pnodeBodyScope = nullptr;
  8818. pnodeProg->sxFnc.pnodeScopes = pnodeGlobalBlock;
  8819. m_ppnodeScope = &pnodeGlobalBlock->sxBlock.pnodeScopes;
  8820. if ((this->m_grfscr & fscrEvalCode) &&
  8821. m_scriptContext->GetConfig()->IsBlockScopeEnabled() &&
  8822. !(this->m_functionBody && this->m_functionBody->GetScopeInfo()))
  8823. {
  8824. pnodeGlobalEvalBlock = StartParseBlock<true>(PnodeBlockType::Regular, ScopeType_GlobalEvalBlock);
  8825. pnodeProg->sxFnc.pnodeScopes = pnodeGlobalEvalBlock;
  8826. m_ppnodeScope = &pnodeGlobalEvalBlock->sxBlock.pnodeScopes;
  8827. }
  8828. Js::ScopeInfo *scopeInfo = nullptr;
  8829. if (m_parseType == ParseType_Deferred && m_functionBody)
  8830. {
  8831. // this->m_functionBody can be cleared during parsing, but we need access to the scope info later.
  8832. scopeInfo = m_functionBody->GetScopeInfo();
  8833. if (scopeInfo)
  8834. {
  8835. this->RestoreScopeInfo(scopeInfo->GetParent());
  8836. }
  8837. }
  8838. // Process a sequence of statements/declarations
  8839. ParseStmtList<true>(
  8840. &pnodeProg->sxFnc.pnodeBody,
  8841. &lastNodeRef,
  8842. SM_OnGlobalCode,
  8843. !(m_grfscr & fscrDeferredFncExpression) /* isSourceElementList */);
  8844. if (m_parseType == ParseType_Deferred)
  8845. {
  8846. if (scopeInfo)
  8847. {
  8848. this->FinishScopeInfo(scopeInfo->GetParent());
  8849. }
  8850. }
  8851. pnodeProg->sxProg.m_UsesArgumentsAtGlobal = m_UsesArgumentsAtGlobal;
  8852. if (IsStrictMode())
  8853. {
  8854. pnodeProg->sxFnc.SetStrictMode();
  8855. }
  8856. #if DEBUG
  8857. if(m_grfscr & fscrEnforceJSON && !IsJSONValid(pnodeProg->sxFnc.pnodeBody))
  8858. {
  8859. Error(ERRsyntax);
  8860. }
  8861. #endif
  8862. if (tkEOF != m_token.tk)
  8863. Error(ERRsyntax);
  8864. // Append an EndCode node.
  8865. AddToNodeList(&pnodeProg->sxFnc.pnodeBody, &lastNodeRef,
  8866. CreateNodeWithScanner<knopEndCode>());
  8867. AssertMem(lastNodeRef);
  8868. AssertNodeMem(*lastNodeRef);
  8869. Assert((*lastNodeRef)->nop == knopEndCode);
  8870. (*lastNodeRef)->ichMin = 0;
  8871. (*lastNodeRef)->ichLim = 0;
  8872. // Get the extent of the code.
  8873. pnodeProg->ichLim = m_pscan->IchLimTok();
  8874. pnodeProg->sxFnc.cbLim = m_pscan->IecpLimTok();
  8875. // save the temps and terminate the local list
  8876. // NOTE: Eze makes no use of this.
  8877. //pnodeProg->sxFnc.pnodeTmps = *m_ppnodeVar;
  8878. *m_ppnodeVar = nullptr;
  8879. Assert(nullptr == *m_ppnodeScope);
  8880. Assert(nullptr == pnodeProg->sxFnc.pnodeNext);
  8881. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  8882. if (Js::Configuration::Global.flags.IsEnabled(Js::ForceUndoDeferFlag))
  8883. {
  8884. m_stoppedDeferredParse = true;
  8885. }
  8886. #endif
  8887. if (m_stoppedDeferredParse)
  8888. {
  8889. if (this->m_hasParallelJob)
  8890. {
  8891. #if ENABLE_BACKGROUND_PARSING
  8892. BackgroundParser *bgp = static_cast<BackgroundParser*>(m_scriptContext->GetBackgroundParser());
  8893. Assert(bgp);
  8894. this->WaitForBackgroundJobs(bgp, pse);
  8895. #endif
  8896. }
  8897. // Finally, see if there are any function bodies we now want to generate because we
  8898. // decided to stop deferring.
  8899. FinishDeferredFunction(pnodeProg->sxFnc.pnodeScopes);
  8900. }
  8901. if (pnodeGlobalEvalBlock)
  8902. {
  8903. FinishParseBlock(pnodeGlobalEvalBlock);
  8904. }
  8905. // Append block as body of pnodeProg
  8906. FinishParseBlock(pnodeGlobalBlock);
  8907. m_scriptContext->AddSourceSize(m_length);
  8908. if (m_asgToConst)
  8909. {
  8910. Error(ERRAssignmentToConst, m_asgToConst.GetIchMin(), m_asgToConst.GetIchLim());
  8911. }
  8912. if(!m_parseType != ParseType_Deferred)
  8913. {
  8914. JS_ETW(EventWriteJSCRIPT_PARSE_METHOD_STOP(m_sourceContextInfo->dwHostSourceContext, GetScriptContext(), pnodeProg->sxFnc.functionId, *m_pCurrentAstSize, false, Js::Constants::GlobalFunction));
  8915. }
  8916. return pnodeProg;
  8917. }
  8918. bool Parser::CheckForDirective(bool* pIsUseStrict, bool *pIsUseAsm, bool* pIsOctalInString)
  8919. {
  8920. // A directive is a string constant followed by a statement terminating token
  8921. if (m_token.tk != tkStrCon)
  8922. return false;
  8923. // Careful, need to check for octal before calling m_pscan->Scan()
  8924. // because Scan() clears the "had octal" flag on the scanner and
  8925. // m_pscan->Restore() does not restore this flag.
  8926. if (pIsOctalInString != nullptr)
  8927. {
  8928. *pIsOctalInString = m_pscan->IsOctOrLeadingZeroOnLastTKNumber();
  8929. }
  8930. Ident* pidDirective = m_token.GetStr();
  8931. RestorePoint start;
  8932. m_pscan->Capture(&start);
  8933. m_pscan->Scan();
  8934. bool isDirective = true;
  8935. switch (m_token.tk)
  8936. {
  8937. case tkSColon:
  8938. case tkEOF:
  8939. case tkLCurly:
  8940. case tkRCurly:
  8941. break;
  8942. default:
  8943. if (!m_pscan->FHadNewLine())
  8944. {
  8945. isDirective = false;
  8946. }
  8947. break;
  8948. }
  8949. if (isDirective)
  8950. {
  8951. if (pIsUseStrict != nullptr)
  8952. {
  8953. *pIsUseStrict = CheckStrictModeStrPid(pidDirective);
  8954. }
  8955. if (pIsUseAsm != nullptr)
  8956. {
  8957. *pIsUseAsm = CheckAsmjsModeStrPid(pidDirective);
  8958. }
  8959. }
  8960. m_pscan->SeekTo(start);
  8961. return isDirective;
  8962. }
  8963. bool Parser::CheckStrictModeStrPid(IdentPtr pid)
  8964. {
  8965. // If we're already in strict mode, no need to check if the string would put us in strict mode. So, this function would only
  8966. // return true if it detects a transition from non-strict to strict, which is what matters for callers.
  8967. // This is a minor optimization to avoid redundant string comparisons of nested "use strict" directives.
  8968. if (IsStrictMode())
  8969. {
  8970. return false;
  8971. }
  8972. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  8973. if (Js::Configuration::Global.flags.NoStrictMode)
  8974. return false;
  8975. #endif
  8976. return pid != nullptr &&
  8977. pid->Cch() == 10 &&
  8978. !m_pscan->IsEscapeOnLastTkStrCon() &&
  8979. wcsncmp(pid->Psz(), L"use strict", 10) == 0;
  8980. }
  8981. bool Parser::CheckAsmjsModeStrPid(IdentPtr pid)
  8982. {
  8983. #ifdef ASMJS_PLAT
  8984. if (!CONFIG_FLAG_RELEASE(Asmjs))
  8985. {
  8986. return false;
  8987. }
  8988. bool isAsmCandidate = (pid != nullptr &&
  8989. AutoSystemInfo::Data.SSE2Available() &&
  8990. pid->Cch() == 7 &&
  8991. !m_pscan->IsEscapeOnLastTkStrCon() &&
  8992. wcsncmp(pid->Psz(), L"use asm", 10) == 0);
  8993. if (isAsmCandidate && m_scriptContext->IsInDebugMode())
  8994. {
  8995. // We would like to report this to debugger - they may choose to disable debugging.
  8996. // TODO : localization of the string?
  8997. m_scriptContext->RaiseMessageToDebugger(DEIT_ASMJS_IN_DEBUGGING, L"AsmJs initialization error - AsmJs disabled due to script debugger", !m_sourceContextInfo->IsDynamic() ? m_sourceContextInfo->url : nullptr);
  8998. return false;
  8999. }
  9000. return isAsmCandidate && !(m_grfscr & fscrNoAsmJs);
  9001. #else
  9002. return false;
  9003. #endif
  9004. }
  9005. HRESULT Parser::ParseUtf8Source(__out ParseNodePtr* parseTree, LPCUTF8 pSrc, size_t length, ULONG grfsrc, CompileScriptException *pse,
  9006. Js::LocalFunctionId * nextFunctionId, SourceContextInfo * sourceContextInfo)
  9007. {
  9008. m_functionBody = nullptr;
  9009. m_parseType = ParseType_Upfront;
  9010. return ParseSourceInternal( parseTree, pSrc, 0, length, 0, true, grfsrc, pse, nextFunctionId, 0, sourceContextInfo);
  9011. }
  9012. HRESULT Parser::ParseCesu8Source(__out ParseNodePtr* parseTree, LPCUTF8 pSrc, size_t length, ULONG grfsrc, CompileScriptException *pse,
  9013. Js::LocalFunctionId * nextFunctionId, SourceContextInfo * sourceContextInfo)
  9014. {
  9015. m_functionBody = nullptr;
  9016. m_parseType = ParseType_Upfront;
  9017. return ParseSourceInternal( parseTree, pSrc, 0, length, 0, false, grfsrc, pse, nextFunctionId, 0, sourceContextInfo);
  9018. }
  9019. void Parser::PrepareScanner(bool fromExternal)
  9020. {
  9021. // NOTE: HashTbl and Scanner are currently allocated from the CRT heap. If we want to allocate them from the
  9022. // parser arena, then we also need to change the way the HashTbl allocates PID's from its underlying
  9023. // allocator (which also currently uses the CRT heap). This is not trivial, because we still need to support
  9024. // heap allocation for the colorizer interface.
  9025. // create the hash table and init PID members
  9026. if (nullptr == (m_phtbl = HashTbl::Create(HASH_TABLE_SIZE, &m_err)))
  9027. Error(ERRnoMemory);
  9028. InitPids();
  9029. // create the scanner
  9030. if (nullptr == (m_pscan = Scanner_t::Create(this, m_phtbl, &m_token, &m_err, m_scriptContext)))
  9031. Error(ERRnoMemory);
  9032. if (fromExternal)
  9033. m_pscan->FromExternalSource();
  9034. }
  9035. #if ENABLE_BACKGROUND_PARSING
  9036. void Parser::PrepareForBackgroundParse()
  9037. {
  9038. m_pscan->PrepareForBackgroundParse(m_scriptContext);
  9039. }
  9040. void Parser::AddBackgroundParseItem(BackgroundParseItem *const item)
  9041. {
  9042. if (currBackgroundParseItem == nullptr)
  9043. {
  9044. backgroundParseItems = item;
  9045. }
  9046. else
  9047. {
  9048. currBackgroundParseItem->SetNext(item);
  9049. }
  9050. currBackgroundParseItem = item;
  9051. }
  9052. #endif
  9053. void Parser::AddFastScannedRegExpNode(ParseNodePtr const pnode)
  9054. {
  9055. Assert(!IsBackgroundParser());
  9056. Assert(m_doingFastScan);
  9057. if (fastScannedRegExpNodes == nullptr)
  9058. {
  9059. fastScannedRegExpNodes = Anew(&m_nodeAllocator, NodeDList, &m_nodeAllocator);
  9060. }
  9061. fastScannedRegExpNodes->Append(pnode);
  9062. }
  9063. #if ENABLE_BACKGROUND_PARSING
  9064. void Parser::AddBackgroundRegExpNode(ParseNodePtr const pnode)
  9065. {
  9066. Assert(IsBackgroundParser());
  9067. Assert(currBackgroundParseItem != nullptr);
  9068. currBackgroundParseItem->AddRegExpNode(pnode, &m_nodeAllocator);
  9069. }
  9070. #endif
  9071. HRESULT Parser::ParseFunctionInBackground(ParseNodePtr pnodeFnc, ParseContext *parseContext, bool topLevelDeferred, CompileScriptException *pse)
  9072. {
  9073. m_functionBody = nullptr;
  9074. m_parseType = ParseType_Upfront;
  9075. HRESULT hr = S_OK;
  9076. SmartFPUControl smartFpuControl;
  9077. uint nextFunctionId = pnodeFnc->sxFnc.functionId + 1;
  9078. this->RestoreContext(parseContext);
  9079. DebugOnly( m_err.fInited = TRUE; )
  9080. m_nextFunctionId = &nextFunctionId;
  9081. m_deferringAST = topLevelDeferred;
  9082. m_inDeferredNestedFunc = false;
  9083. m_scopeCountNoAst = 0;
  9084. SetCurrentStatement(nullptr);
  9085. pnodeFnc->sxFnc.pnodeVars = nullptr;
  9086. pnodeFnc->sxFnc.pnodeArgs = nullptr;
  9087. pnodeFnc->sxFnc.pnodeBody = nullptr;
  9088. pnodeFnc->sxFnc.nestedCount = 0;
  9089. m_currentNodeFunc = pnodeFnc;
  9090. m_currentNodeDeferredFunc = nullptr;
  9091. m_ppnodeScope = nullptr;
  9092. m_ppnodeExprScope = nullptr;
  9093. m_pnestedCount = &pnodeFnc->sxFnc.nestedCount;
  9094. m_pCurrentAstSize = &pnodeFnc->sxFnc.astSize;
  9095. ParseNodePtr pnodeBlock = StartParseBlock<true>(PnodeBlockType::Function, ScopeType_FunctionBody);
  9096. pnodeFnc->sxFnc.pnodeScopes = pnodeBlock;
  9097. m_ppnodeScope = &pnodeBlock->sxBlock.pnodeScopes;
  9098. uint uDeferSave = m_grfscr & fscrDeferFncParse;
  9099. try
  9100. {
  9101. m_pscan->Scan();
  9102. m_ppnodeVar = &pnodeFnc->sxFnc.pnodeArgs;
  9103. this->ParseFncFormals<true>(pnodeFnc, fFncNoFlgs);
  9104. if (m_token.tk == tkRParen)
  9105. {
  9106. m_pscan->Scan();
  9107. }
  9108. ChkCurTok(tkLCurly, ERRnoLcurly);
  9109. m_ppnodeVar = &pnodeFnc->sxFnc.pnodeVars;
  9110. // Put the scanner into "no hashing" mode.
  9111. BYTE deferFlags = m_pscan->SetDeferredParse(topLevelDeferred);
  9112. // Process a sequence of statements/declarations
  9113. if (topLevelDeferred)
  9114. {
  9115. ParseStmtList<false>(nullptr, nullptr, SM_DeferredParse, true);
  9116. }
  9117. else
  9118. {
  9119. ParseNodePtr *lastNodeRef = nullptr;
  9120. ParseStmtList<true>(&pnodeFnc->sxFnc.pnodeBody, &lastNodeRef, SM_OnFunctionCode, true);
  9121. AddArgumentsNodeToVars(pnodeFnc);
  9122. // Append an EndCode node.
  9123. AddToNodeList(&pnodeFnc->sxFnc.pnodeBody, &lastNodeRef, CreateNodeWithScanner<knopEndCode>());
  9124. }
  9125. // Restore the scanner's default hashing mode.
  9126. m_pscan->SetDeferredParseFlags(deferFlags);
  9127. #if DBG
  9128. pnodeFnc->sxFnc.deferredParseNextFunctionId = *this->m_nextFunctionId;
  9129. #endif
  9130. this->m_deferringAST = FALSE;
  9131. // Append block as body of pnodeProg
  9132. FinishParseBlock(pnodeBlock);
  9133. if (m_asgToConst)
  9134. {
  9135. Error(ERRAssignmentToConst, m_asgToConst.GetIchMin(), m_asgToConst.GetIchLim());
  9136. }
  9137. }
  9138. catch(ParseExceptionObject& e)
  9139. {
  9140. m_err.m_hr = e.GetError();
  9141. hr = pse->ProcessError( m_pscan, m_err.m_hr, nullptr);
  9142. }
  9143. if (IsStrictMode())
  9144. {
  9145. pnodeFnc->sxFnc.SetStrictMode();
  9146. }
  9147. if (topLevelDeferred)
  9148. {
  9149. pnodeFnc->sxFnc.pnodeVars = nullptr;
  9150. }
  9151. m_grfscr |= uDeferSave;
  9152. Assert(nullptr == *m_ppnodeScope);
  9153. return hr;
  9154. }
  9155. HRESULT Parser::ParseSourceWithOffset(__out ParseNodePtr* parseTree, LPCUTF8 pSrc, size_t offset, size_t cbLength, charcount_t cchOffset,
  9156. bool isCesu8, ULONG grfscr, CompileScriptException *pse, Js::LocalFunctionId * nextFunctionId, ULONG lineNumber, SourceContextInfo * sourceContextInfo,
  9157. Js::ParseableFunctionInfo* functionInfo, bool isReparse)
  9158. {
  9159. m_functionBody = functionInfo;
  9160. if (m_functionBody)
  9161. {
  9162. m_currDeferredStub = m_functionBody->GetDeferredStubs();
  9163. m_InAsmMode = grfscr & fscrNoAsmJs ? false : m_functionBody->GetIsAsmjsMode();
  9164. }
  9165. m_deferAsmJs = !m_InAsmMode;
  9166. m_parseType = isReparse ? ParseType_Reparse : ParseType_Deferred;
  9167. return ParseSourceInternal( parseTree, pSrc, offset, cbLength, cchOffset, !isCesu8, grfscr, pse, nextFunctionId, lineNumber, sourceContextInfo);
  9168. }
  9169. bool Parser::IsStrictMode() const
  9170. {
  9171. return (m_fUseStrictMode ||
  9172. (m_currentNodeFunc != nullptr && m_currentNodeFunc->sxFnc.GetStrictMode()));
  9173. }
  9174. BOOL Parser::ExpectingExternalSource()
  9175. {
  9176. return m_fExpectExternalSource;
  9177. }
  9178. Symbol *PnFnc::GetFuncSymbol()
  9179. {
  9180. if (pnodeName &&
  9181. pnodeName->nop == knopVarDecl)
  9182. {
  9183. return pnodeName->sxVar.sym;
  9184. }
  9185. return nullptr;
  9186. }
  9187. void PnFnc::SetFuncSymbol(Symbol *sym)
  9188. {
  9189. Assert(pnodeName &&
  9190. pnodeName->nop == knopVarDecl);
  9191. pnodeName->sxVar.sym = sym;
  9192. }
  9193. ParseNodePtr PnFnc::GetParamScope() const
  9194. {
  9195. if (this->pnodeScopes == nullptr)
  9196. {
  9197. return nullptr;
  9198. }
  9199. Assert(this->pnodeScopes->nop == knopBlock &&
  9200. this->pnodeScopes->sxBlock.pnodeNext == nullptr);
  9201. return this->pnodeScopes->sxBlock.pnodeScopes;
  9202. }
  9203. ParseNodePtr * PnFnc::GetParamScopeRef() const
  9204. {
  9205. if (this->pnodeScopes == nullptr)
  9206. {
  9207. return nullptr;
  9208. }
  9209. Assert(this->pnodeScopes->nop == knopBlock &&
  9210. this->pnodeScopes->sxBlock.pnodeNext == nullptr);
  9211. return &this->pnodeScopes->sxBlock.pnodeScopes;
  9212. }
  9213. ParseNodePtr PnFnc::GetBodyScope() const
  9214. {
  9215. if (this->pnodeBodyScope == nullptr)
  9216. {
  9217. return nullptr;
  9218. }
  9219. Assert(this->pnodeBodyScope->nop == knopBlock &&
  9220. this->pnodeBodyScope->sxBlock.pnodeNext == nullptr);
  9221. return this->pnodeBodyScope->sxBlock.pnodeScopes;
  9222. }
  9223. ParseNodePtr * PnFnc::GetBodyScopeRef() const
  9224. {
  9225. if (this->pnodeBodyScope == nullptr)
  9226. {
  9227. return nullptr;
  9228. }
  9229. Assert(this->pnodeBodyScope->nop == knopBlock &&
  9230. this->pnodeBodyScope->sxBlock.pnodeNext == nullptr);
  9231. return &this->pnodeBodyScope->sxBlock.pnodeScopes;
  9232. }
  9233. // Create node versions with explicit token limits
  9234. ParseNodePtr Parser::CreateNode(OpCode nop, charcount_t ichMin, charcount_t ichLim)
  9235. {
  9236. Assert(!this->m_deferringAST);
  9237. Assert(nop >= 0 && nop < knopLim);
  9238. ParseNodePtr pnode;
  9239. __analysis_assume(nop < knopLim);
  9240. int cb = nop >= 0 && nop < knopLim ? g_mpnopcbNode[nop] : kcbPnNone;
  9241. pnode = (ParseNodePtr)m_nodeAllocator.Alloc(cb);
  9242. Assert(pnode);
  9243. Assert(m_pCurrentAstSize != NULL);
  9244. *m_pCurrentAstSize += cb;
  9245. InitNode(nop,pnode);
  9246. pnode->ichMin = ichMin;
  9247. pnode->ichLim = ichLim;
  9248. return pnode;
  9249. }
  9250. ParseNodePtr Parser::CreateNameNode(IdentPtr pid,charcount_t ichMin,charcount_t ichLim) {
  9251. ParseNodePtr pnode = CreateNodeT<knopName>(ichMin,ichLim);
  9252. pnode->sxPid.pid = pid;
  9253. pnode->sxPid.sym=NULL;
  9254. pnode->sxPid.symRef=NULL;
  9255. return pnode;
  9256. }
  9257. ParseNodePtr Parser::CreateUniNode(OpCode nop, ParseNodePtr pnode1, charcount_t ichMin,charcount_t ichLim)
  9258. {
  9259. Assert(!this->m_deferringAST);
  9260. DebugOnly(VerifyNodeSize(nop, kcbPnUni));
  9261. ParseNodePtr pnode = (ParseNodePtr)m_nodeAllocator.Alloc(kcbPnUni);
  9262. Assert(m_pCurrentAstSize != NULL);
  9263. *m_pCurrentAstSize += kcbPnUni;
  9264. InitNode(nop, pnode);
  9265. pnode->sxUni.pnode1 = pnode1;
  9266. pnode->ichMin = ichMin;
  9267. pnode->ichLim = ichLim;
  9268. return pnode;
  9269. }
  9270. ParseNodePtr Parser::CreateBinNode(OpCode nop, ParseNodePtr pnode1,
  9271. ParseNodePtr pnode2,charcount_t ichMin,charcount_t ichLim)
  9272. {
  9273. Assert(!this->m_deferringAST);
  9274. ParseNodePtr pnode = StaticCreateBinNode(nop, pnode1, pnode2, &m_nodeAllocator);
  9275. Assert(m_pCurrentAstSize != NULL);
  9276. *m_pCurrentAstSize += kcbPnBin;
  9277. pnode->ichMin = ichMin;
  9278. pnode->ichLim = ichLim;
  9279. return pnode;
  9280. }
  9281. ParseNodePtr Parser::CreateTriNode(OpCode nop, ParseNodePtr pnode1,
  9282. ParseNodePtr pnode2, ParseNodePtr pnode3,
  9283. charcount_t ichMin,charcount_t ichLim)
  9284. {
  9285. Assert(!this->m_deferringAST);
  9286. DebugOnly(VerifyNodeSize(nop, kcbPnTri));
  9287. ParseNodePtr pnode = (ParseNodePtr)m_nodeAllocator.Alloc(kcbPnTri);
  9288. Assert(m_pCurrentAstSize != NULL);
  9289. *m_pCurrentAstSize += kcbPnTri;
  9290. InitNode(nop, pnode);
  9291. pnode->sxTri.pnodeNext = NULL;
  9292. pnode->sxTri.pnode1 = pnode1;
  9293. pnode->sxTri.pnode2 = pnode2;
  9294. pnode->sxTri.pnode3 = pnode3;
  9295. pnode->ichMin = ichMin;
  9296. pnode->ichLim = ichLim;
  9297. return pnode;
  9298. }
  9299. bool PnBlock::HasBlockScopedContent() const
  9300. {
  9301. // A block has its own content if a let, const, or function is declared there.
  9302. if (this->pnodeLexVars != nullptr || this->blockType == Parameter)
  9303. {
  9304. return true;
  9305. }
  9306. // The enclosing scopes can contain functions and other things, so walk the list
  9307. // looking specifically for functions.
  9308. for (ParseNodePtr pnode = this->pnodeScopes; pnode;)
  9309. {
  9310. switch (pnode->nop) {
  9311. case knopFncDecl:
  9312. return true;
  9313. case knopBlock:
  9314. pnode = pnode->sxBlock.pnodeNext;
  9315. break;
  9316. case knopCatch:
  9317. pnode = pnode->sxCatch.pnodeNext;
  9318. break;
  9319. case knopWith:
  9320. pnode = pnode->sxWith.pnodeNext;
  9321. break;
  9322. default:
  9323. Assert(UNREACHED);
  9324. return true;
  9325. }
  9326. }
  9327. return false;
  9328. }
  9329. class ByteCodeGenerator;
  9330. // Copy AST; this works mostly on expressions for now
  9331. ParseNode* Parser::CopyPnode(ParseNode *pnode) {
  9332. if (pnode==NULL)
  9333. return NULL;
  9334. switch (pnode->nop) {
  9335. //PTNODE(knopName , "name" ,None ,Pid ,fnopLeaf)
  9336. case knopName: {
  9337. ParseNode* nameNode=CreateNameNode(pnode->sxPid.pid,pnode->ichMin,pnode->ichLim);
  9338. nameNode->sxPid.sym=pnode->sxPid.sym;
  9339. return nameNode;
  9340. }
  9341. //PTNODE(knopInt , "int const" ,None ,Int ,fnopLeaf|fnopConst)
  9342. case knopInt:
  9343. return pnode;
  9344. //PTNODE(knopFlt , "flt const" ,None ,Flt ,fnopLeaf|fnopConst)
  9345. case knopFlt:
  9346. return pnode;
  9347. //PTNODE(knopStr , "str const" ,None ,Pid ,fnopLeaf|fnopConst)
  9348. case knopStr:
  9349. return pnode;
  9350. //PTNODE(knopRegExp , "reg expr" ,None ,Pid ,fnopLeaf|fnopConst)
  9351. case knopRegExp:
  9352. return pnode;
  9353. break;
  9354. //PTNODE(knopThis , "this" ,None ,None ,fnopLeaf)
  9355. case knopThis:
  9356. return CreateNodeT<knopThis>(pnode->ichMin,pnode->ichLim);
  9357. //PTNODE(knopNull , "null" ,Null ,None ,fnopLeaf)
  9358. case knopNull:
  9359. return pnode;
  9360. //PTNODE(knopFalse , "false" ,False ,None ,fnopLeaf)
  9361. case knopFalse:
  9362. return CreateNodeT<knopFalse>(pnode->ichMin,pnode->ichLim);
  9363. break;
  9364. //PTNODE(knopTrue , "true" ,True ,None ,fnopLeaf)
  9365. case knopTrue:
  9366. return CreateNodeT<knopTrue>(pnode->ichMin,pnode->ichLim);
  9367. //PTNODE(knopEmpty , "empty" ,Empty ,None ,fnopLeaf)
  9368. case knopEmpty:
  9369. return CreateNodeT<knopEmpty>(pnode->ichMin,pnode->ichLim);
  9370. // Unary operators.
  9371. //PTNODE(knopNot , "~" ,BitNot ,Uni ,fnopUni)
  9372. //PTNODE(knopNeg , "unary -" ,Neg ,Uni ,fnopUni)
  9373. //PTNODE(knopPos , "unary +" ,Pos ,Uni ,fnopUni)
  9374. //PTNODE(knopLogNot , "!" ,LogNot ,Uni ,fnopUni)
  9375. //PTNODE(knopEllipsis , "..." ,Spread ,Uni , fnopUni)
  9376. //PTNODE(knopDecPost , "-- post" ,Dec ,Uni ,fnopUni|fnopAsg)
  9377. //PTNODE(knopIncPre , "++ pre" ,Inc ,Uni ,fnopUni|fnopAsg)
  9378. //PTNODE(knopDecPre , "-- pre" ,Dec ,Uni ,fnopUni|fnopAsg)
  9379. //PTNODE(knopTypeof , "typeof" ,None ,Uni ,fnopUni)
  9380. //PTNODE(knopVoid , "void" ,Void ,Uni ,fnopUni)
  9381. //PTNODE(knopDelete , "delete" ,None ,Uni ,fnopUni)
  9382. case knopNot:
  9383. case knopNeg:
  9384. case knopPos:
  9385. case knopLogNot:
  9386. case knopEllipsis:
  9387. case knopIncPost:
  9388. case knopDecPost:
  9389. case knopIncPre:
  9390. case knopDecPre:
  9391. case knopTypeof:
  9392. case knopVoid:
  9393. case knopDelete:
  9394. return CreateUniNode(pnode->nop,CopyPnode(pnode->sxUni.pnode1),pnode->ichMin,pnode->ichLim);
  9395. //PTNODE(knopArray , "arr cnst" ,None ,Uni ,fnopUni)
  9396. //PTNODE(knopObject , "obj cnst" ,None ,Uni ,fnopUni)
  9397. case knopArray:
  9398. case knopObject:
  9399. // TODO: need to copy arr
  9400. Assert(false);
  9401. break;
  9402. // Binary operators
  9403. //PTNODE(knopAdd , "+" ,Add ,Bin ,fnopBin)
  9404. //PTNODE(knopSub , "-" ,Sub ,Bin ,fnopBin)
  9405. //PTNODE(knopMul , "*" ,Mul ,Bin ,fnopBin)
  9406. //PTNODE(knopExpo , "**" ,Expo ,Bin ,fnopBin)
  9407. //PTNODE(knopDiv , "/" ,Div ,Bin ,fnopBin)
  9408. //PTNODE(knopMod , "%" ,Mod ,Bin ,fnopBin)
  9409. //PTNODE(knopOr , "|" ,BitOr ,Bin ,fnopBin)
  9410. //PTNODE(knopXor , "^" ,BitXor ,Bin ,fnopBin)
  9411. //PTNODE(knopAnd , "&" ,BitAnd ,Bin ,fnopBin)
  9412. //PTNODE(knopEq , "==" ,EQ ,Bin ,fnopBin|fnopRel)
  9413. //PTNODE(knopNe , "!=" ,NE ,Bin ,fnopBin|fnopRel)
  9414. //PTNODE(knopLt , "<" ,LT ,Bin ,fnopBin|fnopRel)
  9415. //PTNODE(knopLe , "<=" ,LE ,Bin ,fnopBin|fnopRel)
  9416. //PTNODE(knopGe , ">=" ,GE ,Bin ,fnopBin|fnopRel)
  9417. //PTNODE(knopGt , ">" ,GT ,Bin ,fnopBin|fnopRel)
  9418. //PTNODE(knopEqv , "===" ,Eqv ,Bin ,fnopBin|fnopRel)
  9419. //PTNODE(knopIn , "in" ,In ,Bin ,fnopBin|fnopRel)
  9420. //PTNODE(knopInstOf , "instanceof",InstOf ,Bin ,fnopBin|fnopRel)
  9421. //PTNODE(knopNEqv , "!==" ,NEqv ,Bin ,fnopBin|fnopRel)
  9422. //PTNODE(knopComma , "," ,None ,Bin ,fnopBin)
  9423. //PTNODE(knopLogOr , "||" ,None ,Bin ,fnopBin)
  9424. //PTNODE(knopLogAnd , "&&" ,None ,Bin ,fnopBin)
  9425. //PTNODE(knopLsh , "<<" ,Lsh ,Bin ,fnopBin)
  9426. //PTNODE(knopRsh , ">>" ,Rsh ,Bin ,fnopBin)
  9427. //PTNODE(knopRs2 , ">>>" ,Rs2 ,Bin ,fnopBin)
  9428. case knopAdd:
  9429. case knopSub:
  9430. case knopMul:
  9431. case knopExpo:
  9432. case knopDiv:
  9433. case knopMod:
  9434. case knopOr:
  9435. case knopXor:
  9436. case knopAnd:
  9437. case knopEq:
  9438. case knopNe:
  9439. case knopLt:
  9440. case knopLe:
  9441. case knopGe:
  9442. case knopGt:
  9443. case knopEqv:
  9444. case knopIn:
  9445. case knopInstOf:
  9446. case knopNEqv:
  9447. case knopComma:
  9448. case knopLogOr:
  9449. case knopLogAnd:
  9450. case knopLsh:
  9451. case knopRsh:
  9452. case knopRs2:
  9453. //PTNODE(knopAsg , "=" ,None ,Bin ,fnopBin|fnopAsg)
  9454. case knopAsg:
  9455. //PTNODE(knopDot , "." ,None ,Bin ,fnopBin)
  9456. case knopDot:
  9457. //PTNODE(knopAsgAdd , "+=" ,Add ,Bin ,fnopBin|fnopAsg)
  9458. case knopAsgAdd:
  9459. //PTNODE(knopAsgSub , "-=" ,Sub ,Bin ,fnopBin|fnopAsg)
  9460. case knopAsgSub:
  9461. //PTNODE(knopAsgMul , "*=" ,Mul ,Bin ,fnopBin|fnopAsg)
  9462. case knopAsgMul:
  9463. //PTNODE(knopAsgDiv , "/=" ,Div ,Bin ,fnopBin|fnopAsg)
  9464. case knopAsgExpo:
  9465. //PTNODE(knopAsgExpo , "**=" ,Expo ,Bin ,fnopBin|fnopAsg)
  9466. case knopAsgDiv:
  9467. //PTNODE(knopAsgMod , "%=" ,Mod ,Bin ,fnopBin|fnopAsg)
  9468. case knopAsgMod:
  9469. //PTNODE(knopAsgAnd , "&=" ,BitAnd ,Bin ,fnopBin|fnopAsg)
  9470. case knopAsgAnd:
  9471. //PTNODE(knopAsgXor , "^=" ,BitXor ,Bin ,fnopBin|fnopAsg)
  9472. case knopAsgXor:
  9473. //PTNODE(knopAsgOr , "|=" ,BitOr ,Bin ,fnopBin|fnopAsg)
  9474. case knopAsgOr:
  9475. //PTNODE(knopAsgLsh , "<<=" ,Lsh ,Bin ,fnopBin|fnopAsg)
  9476. case knopAsgLsh:
  9477. //PTNODE(knopAsgRsh , ">>=" ,Rsh ,Bin ,fnopBin|fnopAsg)
  9478. case knopAsgRsh:
  9479. //PTNODE(knopAsgRs2 , ">>>=" ,Rs2 ,Bin ,fnopBin|fnopAsg)
  9480. case knopAsgRs2:
  9481. //PTNODE(knopMember , ":" ,None ,Bin ,fnopBin)
  9482. case knopMember:
  9483. case knopMemberShort:
  9484. //PTNODE(knopIndex , "[]" ,None ,Bin ,fnopBin)
  9485. //PTNODE(knopList , "<list>" ,None ,Bin ,fnopNone)
  9486. case knopIndex:
  9487. case knopList:
  9488. return CreateBinNode(pnode->nop,CopyPnode(pnode->sxBin.pnode1),
  9489. CopyPnode(pnode->sxBin.pnode2),pnode->ichMin,pnode->ichLim);
  9490. //PTNODE(knopCall , "()" ,None ,Bin ,fnopBin)
  9491. //PTNODE(knopNew , "new" ,None ,Bin ,fnopBin)
  9492. case knopNew:
  9493. case knopCall:
  9494. return CreateCallNode(pnode->nop,CopyPnode(pnode->sxBin.pnode1),
  9495. CopyPnode(pnode->sxBin.pnode2),pnode->ichMin,pnode->ichLim);
  9496. //PTNODE(knopQmark , "?" ,None ,Tri ,fnopBin)
  9497. case knopQmark:
  9498. return CreateTriNode(pnode->nop,CopyPnode(pnode->sxTri.pnode1),
  9499. CopyPnode(pnode->sxTri.pnode2),CopyPnode(pnode->sxTri.pnode3),
  9500. pnode->ichMin,pnode->ichLim);
  9501. // General nodes.
  9502. //PTNODE(knopVarDecl , "varDcl" ,None ,Var ,fnopNone)
  9503. case knopVarDecl: {
  9504. ParseNode* copyNode=CreateNodeT<knopVarDecl>(pnode->ichMin,pnode->ichLim);
  9505. copyNode->sxVar.pnodeInit=CopyPnode(pnode->sxVar.pnodeInit);
  9506. copyNode->sxVar.sym=pnode->sxVar.sym;
  9507. // TODO: mult-decl
  9508. Assert(pnode->sxVar.pnodeNext==NULL);
  9509. copyNode->sxVar.pnodeNext=NULL;
  9510. return copyNode;
  9511. }
  9512. //PTNODE(knopFncDecl , "fncDcl" ,None ,Fnc ,fnopLeaf)
  9513. //PTNODE(knopProg , "program" ,None ,Fnc ,fnopNone)
  9514. case knopFncDecl:
  9515. case knopProg:
  9516. Assert(false);
  9517. break;
  9518. //PTNODE(knopEndCode , "<endcode>" ,None ,None ,fnopNone)
  9519. case knopEndCode:
  9520. break;
  9521. //PTNODE(knopDebugger , "debugger" ,None ,None ,fnopNone)
  9522. case knopDebugger:
  9523. break;
  9524. //PTNODE(knopFor , "for" ,None ,For ,fnopBreak|fnopContinue)
  9525. case knopFor: {
  9526. ParseNode* copyNode=CreateNodeT<knopFor>(pnode->ichMin,pnode->ichLim);
  9527. copyNode->sxFor.pnodeInverted=NULL;
  9528. copyNode->sxFor.pnodeInit=CopyPnode(pnode->sxFor.pnodeInit);
  9529. copyNode->sxFor.pnodeCond=CopyPnode(pnode->sxFor.pnodeCond);
  9530. copyNode->sxFor.pnodeIncr=CopyPnode(pnode->sxFor.pnodeIncr);
  9531. copyNode->sxFor.pnodeBody=CopyPnode(pnode->sxFor.pnodeBody);
  9532. return copyNode;
  9533. }
  9534. //PTNODE(knopIf , "if" ,None ,If ,fnopNone)
  9535. case knopIf:
  9536. Assert(false);
  9537. break;
  9538. //PTNODE(knopWhile , "while" ,None ,While,fnopBreak|fnopContinue)
  9539. case knopWhile:
  9540. Assert(false);
  9541. break;
  9542. //PTNODE(knopDoWhile , "do-while" ,None ,While,fnopBreak|fnopContinue)
  9543. case knopDoWhile:
  9544. Assert(false);
  9545. break;
  9546. //PTNODE(knopForIn , "for in" ,None ,ForIn,fnopBreak|fnopContinue|fnopCleanup)
  9547. case knopForIn:
  9548. Assert(false);
  9549. break;
  9550. case knopForOf:
  9551. Assert(false);
  9552. break;
  9553. //PTNODE(knopReturn , "return" ,None ,Uni ,fnopNone)
  9554. case knopReturn: {
  9555. ParseNode* copyNode=CreateNodeT<knopReturn>(pnode->ichMin,pnode->ichLim);
  9556. copyNode->sxReturn.pnodeExpr=CopyPnode(pnode->sxReturn.pnodeExpr);
  9557. return copyNode;
  9558. }
  9559. //PTNODE(knopBlock , "{}" ,None ,Block,fnopNone)
  9560. case knopBlock: {
  9561. ParseNode* copyNode=CreateBlockNode(pnode->ichMin,pnode->ichLim,pnode->sxBlock.blockType);
  9562. if (pnode->grfpn & PNodeFlags::fpnSyntheticNode) {
  9563. // fpnSyntheticNode is sometimes set on PnodeBlockType::Regular blocks which
  9564. // CreateBlockNode() will not automatically set for us, so set it here if it's
  9565. // specified on the source node.
  9566. copyNode->grfpn |= PNodeFlags::fpnSyntheticNode;
  9567. }
  9568. copyNode->sxBlock.pnodeStmt=CopyPnode(pnode->sxBlock.pnodeStmt);
  9569. return copyNode;
  9570. }
  9571. //PTNODE(knopWith , "with" ,None ,With ,fnopCleanup)
  9572. case knopWith:
  9573. Assert(false);
  9574. break;
  9575. //PTNODE(knopBreak , "break" ,None ,Jump ,fnopNone)
  9576. case knopBreak:
  9577. Assert(false);
  9578. break;
  9579. //PTNODE(knopContinue , "continue" ,None ,Jump ,fnopNone)
  9580. case knopContinue:
  9581. Assert(false);
  9582. break;
  9583. //PTNODE(knopLabel , "label" ,None ,Label,fnopNone)
  9584. case knopLabel:
  9585. Assert(false);
  9586. break;
  9587. //PTNODE(knopSwitch , "switch" ,None ,Switch,fnopBreak)
  9588. case knopSwitch:
  9589. Assert(false);
  9590. break;
  9591. //PTNODE(knopCase , "case" ,None ,Case ,fnopNone)
  9592. case knopCase:
  9593. Assert(false);
  9594. break;
  9595. //PTNODE(knopTryFinally,"try-finally",None,TryFinally,fnopCleanup)
  9596. case knopTryFinally:
  9597. Assert(false);
  9598. break;
  9599. case knopFinally:
  9600. Assert(false);
  9601. break;
  9602. //PTNODE(knopCatch , "catch" ,None ,Catch,fnopNone)
  9603. case knopCatch:
  9604. Assert(false);
  9605. break;
  9606. //PTNODE(knopTryCatch , "try-catch" ,None ,TryCatch ,fnopCleanup)
  9607. case knopTryCatch:
  9608. Assert(false);
  9609. break;
  9610. //PTNODE(knopTry , "try" ,None ,Try ,fnopCleanup)
  9611. case knopTry:
  9612. Assert(false);
  9613. break;
  9614. //PTNODE(knopThrow , "throw" ,None ,Uni ,fnopNone)
  9615. case knopThrow:
  9616. Assert(false);
  9617. break;
  9618. default:
  9619. Assert(false);
  9620. break;
  9621. }
  9622. return NULL;
  9623. }
  9624. // Returns true when str is string for Nan, Infinity or -Infinity.
  9625. // Does not check for double number value being in NaN/Infinity range.
  9626. // static
  9627. template<bool CheckForNegativeInfinity>
  9628. inline bool Parser::IsNaNOrInfinityLiteral(LPCOLESTR str)
  9629. {
  9630. // Note: wcscmp crashes when one of the parameters is NULL.
  9631. return str &&
  9632. (wcscmp(L"NaN", str) == 0 ||
  9633. wcscmp(L"Infinity", str) == 0 ||
  9634. CheckForNegativeInfinity && wcscmp(L"-Infinity", str) == 0);
  9635. }
  9636. template <bool buildAST>
  9637. ParseNodePtr Parser::ParseSuper(ParseNodePtr pnode, bool fAllowCall)
  9638. {
  9639. ParseNodePtr currentNodeFunc = GetCurrentFunctionNode();
  9640. if (buildAST) {
  9641. pnode = CreateNodeWithScanner<knopSuper>();
  9642. }
  9643. m_pscan->ScanForcingPid();
  9644. switch (m_token.tk)
  9645. {
  9646. case tkDot: // super.prop
  9647. case tkLBrack: // super[foo]
  9648. case tkLParen: // super(args)
  9649. break;
  9650. default:
  9651. Error(ERRInvalidSuper);
  9652. break;
  9653. }
  9654. if (!fAllowCall && (m_token.tk == tkLParen))
  9655. {
  9656. Error(ERRInvalidSuper); // new super() is not allowed
  9657. }
  9658. else if (this->m_parsingSuperRestrictionState == ParsingSuperRestrictionState_SuperCallAndPropertyAllowed)
  9659. {
  9660. // Any super access is good within a class constructor
  9661. }
  9662. else if (this->m_parsingSuperRestrictionState == ParsingSuperRestrictionState_SuperPropertyAllowed)
  9663. {
  9664. // Cannot call super within a class member
  9665. if (m_token.tk == tkLParen)
  9666. {
  9667. Error(ERRInvalidSuper);
  9668. }
  9669. }
  9670. else
  9671. {
  9672. // Anything else is an error
  9673. Error(ERRInvalidSuper);
  9674. }
  9675. currentNodeFunc->sxFnc.SetHasSuperReference(TRUE);
  9676. CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(SuperCount, m_scriptContext);
  9677. return pnode;
  9678. }
  9679. void Parser::AppendToList(ParseNodePtr *node, ParseNodePtr nodeToAppend)
  9680. {
  9681. Assert(nodeToAppend);
  9682. ParseNodePtr* lastPtr = node;
  9683. while ((*lastPtr) && (*lastPtr)->nop == knopList)
  9684. {
  9685. lastPtr = &(*lastPtr)->sxBin.pnode2;
  9686. }
  9687. auto last = (*lastPtr);
  9688. if (last)
  9689. {
  9690. *lastPtr = CreateBinNode(knopList, last, nodeToAppend, last->ichMin, nodeToAppend->ichLim);
  9691. }
  9692. else
  9693. {
  9694. *lastPtr = nodeToAppend;
  9695. }
  9696. }
  9697. ParseNodePtr Parser::ConvertArrayToArrayPattern(ParseNodePtr pnode)
  9698. {
  9699. Assert(pnode->nop == knopArray);
  9700. pnode->nop = knopArrayPattern;
  9701. ForEachItemRefInList(&pnode->sxArrLit.pnode1, [&](ParseNodePtr *itemRef) {
  9702. ParseNodePtr item = *itemRef;
  9703. if (item->nop == knopEllipsis)
  9704. {
  9705. itemRef = &item->sxUni.pnode1;
  9706. item = *itemRef;
  9707. if (!(item->nop == knopName
  9708. || item->nop == knopDot
  9709. || item->nop == knopIndex
  9710. || item->nop == knopArray
  9711. || item->nop == knopObject))
  9712. {
  9713. Error(ERRInvalidAssignmentTarget);
  9714. }
  9715. }
  9716. else if (item->nop == knopAsg)
  9717. {
  9718. itemRef = &item->sxBin.pnode1;
  9719. item = *itemRef;
  9720. }
  9721. if (item->nop == knopArray)
  9722. {
  9723. ConvertArrayToArrayPattern(item);
  9724. }
  9725. else if (item->nop == knopObject)
  9726. {
  9727. *itemRef = ConvertObjectToObjectPattern(item);
  9728. }
  9729. });
  9730. return pnode;
  9731. }
  9732. ParseNodePtr Parser::CreateParamPatternNode(ParseNodePtr pnode1)
  9733. {
  9734. ParseNodePtr paramPatternNode = CreateNode(knopParamPattern, pnode1->ichMin, pnode1->ichLim);
  9735. paramPatternNode->sxParamPattern.pnode1 = pnode1;
  9736. paramPatternNode->sxParamPattern.pnodeNext = nullptr;
  9737. paramPatternNode->sxParamPattern.location = Js::Constants::NoRegister;
  9738. return paramPatternNode;
  9739. }
  9740. ParseNodePtr Parser::ConvertObjectToObjectPattern(ParseNodePtr pnodeMemberList)
  9741. {
  9742. charcount_t ichMin = m_pscan->IchMinTok();
  9743. charcount_t ichLim = m_pscan->IchLimTok();
  9744. ParseNodePtr pnodeMemberNodeList = nullptr;
  9745. if (pnodeMemberList != nullptr && pnodeMemberList->nop == knopObject)
  9746. {
  9747. ichMin = pnodeMemberList->ichMin;
  9748. ichLim = pnodeMemberList->ichLim;
  9749. pnodeMemberList = pnodeMemberList->sxUni.pnode1;
  9750. }
  9751. ForEachItemInList(pnodeMemberList, [&](ParseNodePtr item) {
  9752. ParseNodePtr memberNode = ConvertMemberToMemberPattern(item);
  9753. AppendToList(&pnodeMemberNodeList, memberNode);
  9754. });
  9755. return CreateUniNode(knopObjectPattern, pnodeMemberNodeList, ichMin, ichLim);
  9756. }
  9757. ParseNodePtr Parser::GetRightSideNodeFromPattern(ParseNodePtr pnode)
  9758. {
  9759. Assert(pnode != nullptr);
  9760. ParseNodePtr rightNode = nullptr;
  9761. OpCode op = pnode->nop;
  9762. if (op == knopObject)
  9763. {
  9764. rightNode = ConvertObjectToObjectPattern(pnode);
  9765. }
  9766. else if (op == knopArray)
  9767. {
  9768. rightNode = ConvertArrayToArrayPattern(pnode);
  9769. }
  9770. else
  9771. {
  9772. // we should allow
  9773. // references (name/string/knopDots and knopIndex)
  9774. // Allow assignment operator for initializer
  9775. // rest is syntax error.
  9776. if (!(op == knopName || op == knopStr || op == knopDot || op == knopIndex || op == knopAsg))
  9777. {
  9778. if (m_token.IsOperator())
  9779. {
  9780. Error(ERRDestructNoOper);
  9781. }
  9782. Error(ERRDestructIDRef);
  9783. }
  9784. rightNode = pnode;
  9785. }
  9786. return rightNode;
  9787. }
  9788. ParseNodePtr Parser::ConvertMemberToMemberPattern(ParseNodePtr pnodeMember)
  9789. {
  9790. Assert(pnodeMember->nop == knopMember || pnodeMember->nop == knopMemberShort);
  9791. ParseNodePtr rightNode = GetRightSideNodeFromPattern(pnodeMember->sxBin.pnode2);
  9792. ParseNodePtr resultNode = CreateBinNode(knopObjectPatternMember, pnodeMember->sxBin.pnode1, rightNode);
  9793. resultNode->ichMin = pnodeMember->ichMin;
  9794. resultNode->ichLim = pnodeMember->ichLim;
  9795. return resultNode;
  9796. }
  9797. ParseNodePtr Parser::ConvertToPattern(ParseNodePtr pnode)
  9798. {
  9799. if (pnode != nullptr)
  9800. {
  9801. if (pnode->nop == knopArray)
  9802. {
  9803. ConvertArrayToArrayPattern(pnode);
  9804. }
  9805. else if (pnode->nop == knopObject)
  9806. {
  9807. pnode = ConvertObjectToObjectPattern(pnode);
  9808. }
  9809. }
  9810. return pnode;
  9811. }
  9812. // This essentially be called for verifying the structure of the current tree with satisfying the destructuring grammar.
  9813. void Parser::ParseDestructuredLiteralWithScopeSave(tokens declarationType,
  9814. bool isDecl,
  9815. bool topLevel,
  9816. DestructuringInitializerContext initializerContext/* = DIC_None*/,
  9817. bool allowIn /*= true*/)
  9818. {
  9819. // We are going to parse the text again to validate the current grammar as Destructuring. Saving some scopes and
  9820. // AST related information before the validation parsing and later they will be restored.
  9821. ParseNodePtr pnodeFncSave = m_currentNodeFunc;
  9822. long *pAstSizeSave = m_pCurrentAstSize;
  9823. uint *pNestedCountSave = m_pnestedCount;
  9824. ParseNodePtr *ppnodeScopeSave = m_ppnodeScope;
  9825. ParseNodePtr *ppnodeExprScopeSave = m_ppnodeExprScope;
  9826. ParseNodePtr newTempScope = nullptr;
  9827. m_ppnodeScope = &newTempScope;
  9828. long newTempAstSize = 0;
  9829. m_pCurrentAstSize = &newTempAstSize;
  9830. uint newTempNestedCount = 0;
  9831. m_pnestedCount = &newTempNestedCount;
  9832. m_ppnodeExprScope = nullptr;
  9833. ParseDestructuredLiteral<false>(declarationType, isDecl, topLevel, initializerContext, allowIn);
  9834. m_currentNodeFunc = pnodeFncSave;
  9835. m_pCurrentAstSize = pAstSizeSave;
  9836. m_pnestedCount = pNestedCountSave;
  9837. m_ppnodeScope = ppnodeScopeSave;
  9838. m_ppnodeExprScope = ppnodeExprScopeSave;
  9839. }
  9840. template <bool buildAST>
  9841. ParseNodePtr Parser::ParseDestructuredLiteral(tokens declarationType,
  9842. bool isDecl,
  9843. bool topLevel/* = true*/,
  9844. DestructuringInitializerContext initializerContext/* = DIC_None*/,
  9845. bool allowIn/* = true*/,
  9846. BOOL *forInOfOkay/* = nullptr*/,
  9847. BOOL *nativeForOkay/* = nullptr*/)
  9848. {
  9849. ParseNodePtr pnode = nullptr;
  9850. Assert(IsPossiblePatternStart());
  9851. if (m_token.tk == tkLCurly)
  9852. {
  9853. pnode = ParseDestructuredObjectLiteral<buildAST>(declarationType, isDecl, topLevel);
  9854. }
  9855. else
  9856. {
  9857. pnode = ParseDestructuredArrayLiteral<buildAST>(declarationType, isDecl, topLevel);
  9858. }
  9859. return ParseDestructuredInitializer<buildAST>(pnode, isDecl, topLevel, initializerContext, allowIn, forInOfOkay, nativeForOkay);
  9860. }
  9861. template <bool buildAST>
  9862. ParseNodePtr Parser::ParseDestructuredInitializer(ParseNodePtr lhsNode,
  9863. bool isDecl,
  9864. bool topLevel,
  9865. DestructuringInitializerContext initializerContext,
  9866. bool allowIn,
  9867. BOOL *forInOfOkay,
  9868. BOOL *nativeForOkay)
  9869. {
  9870. m_pscan->Scan();
  9871. if (topLevel && nativeForOkay == nullptr)
  9872. {
  9873. if (initializerContext != DIC_ForceErrorOnInitializer && m_token.tk != tkAsg)
  9874. {
  9875. // e.g. var {x};
  9876. Error(ERRDestructInit);
  9877. }
  9878. else if (initializerContext == DIC_ForceErrorOnInitializer && m_token.tk == tkAsg)
  9879. {
  9880. // e.g. catch([x] = [0])
  9881. Error(ERRDestructNotInit);
  9882. }
  9883. }
  9884. if (m_token.tk != tkAsg || initializerContext == DIC_ShouldNotParseInitializer)
  9885. {
  9886. if (topLevel && nativeForOkay != nullptr)
  9887. {
  9888. // Native loop should have destructuring initializer
  9889. *nativeForOkay = FALSE;
  9890. }
  9891. return lhsNode;
  9892. }
  9893. if (forInOfOkay)
  9894. {
  9895. *forInOfOkay = FALSE;
  9896. }
  9897. m_pscan->Scan();
  9898. ParseNodePtr pnodeDefault = ParseExpr<buildAST>(koplCma, nullptr, allowIn);
  9899. ParseNodePtr pnodeDestructAsg = nullptr;
  9900. if (buildAST)
  9901. {
  9902. Assert(lhsNode != nullptr);
  9903. pnodeDestructAsg = CreateNodeWithScanner<knopAsg>();
  9904. pnodeDestructAsg->sxBin.pnode1 = lhsNode;
  9905. pnodeDestructAsg->sxBin.pnode2 = pnodeDefault;
  9906. pnodeDestructAsg->ichMin = lhsNode->ichMin;
  9907. pnodeDestructAsg->ichLim = pnodeDefault->ichLim;
  9908. }
  9909. return pnodeDestructAsg;
  9910. }
  9911. template <bool buildAST>
  9912. ParseNodePtr Parser::ParseDestructuredObjectLiteral(tokens declarationType, bool isDecl, bool topLevel/* = true*/)
  9913. {
  9914. Assert(m_token.tk == tkLCurly);
  9915. charcount_t ichMin = m_pscan->IchMinTok();
  9916. m_pscan->Scan();
  9917. if (!isDecl)
  9918. {
  9919. declarationType = tkLCurly;
  9920. }
  9921. ParseNodePtr pnodeMemberList = ParseMemberList<buildAST>(nullptr/*pNameHint*/, nullptr/*pHintLength*/, declarationType);
  9922. Assert(m_token.tk == tkRCurly);
  9923. ParseNodePtr objectPatternNode = nullptr;
  9924. if (buildAST)
  9925. {
  9926. charcount_t ichLim = m_pscan->IchLimTok();
  9927. objectPatternNode = CreateUniNode(knopObjectPattern, pnodeMemberList, ichMin, ichLim);
  9928. }
  9929. return objectPatternNode;
  9930. }
  9931. template <bool buildAST>
  9932. ParseNodePtr Parser::ParseDestructuredVarDecl(tokens declarationType, bool isDecl, bool *hasSeenRest, bool topLevel/* = true*/)
  9933. {
  9934. ParseNodePtr pnodeElem = nullptr;
  9935. int parenCount = 0;
  9936. bool seenRest = false;
  9937. while (m_token.tk == tkLParen)
  9938. {
  9939. m_pscan->Scan();
  9940. ++parenCount;
  9941. }
  9942. if (m_token.tk == tkEllipsis)
  9943. {
  9944. // As per ES 2015 : Rest can have left-hand-side-expression when on assignment expression, but under declaration only binding identifier is allowed
  9945. // But spec is going to change for this one to allow LHS-expression both on expression and declaration - so making that happen early.
  9946. seenRest = true;
  9947. m_pscan->Scan();
  9948. while (m_token.tk == tkLParen)
  9949. {
  9950. m_pscan->Scan();
  9951. ++parenCount;
  9952. }
  9953. if (m_token.tk != tkID && m_token.tk != tkSUPER && m_token.tk != tkLCurly && m_token.tk != tkLBrack)
  9954. {
  9955. if (isDecl)
  9956. {
  9957. Error(ERRnoIdent);
  9958. }
  9959. else
  9960. {
  9961. Error(ERRInvalidAssignmentTarget);
  9962. }
  9963. }
  9964. }
  9965. if (IsPossiblePatternStart())
  9966. {
  9967. // Go recursively
  9968. pnodeElem = ParseDestructuredLiteral<buildAST>(declarationType, isDecl, false /*topLevel*/);
  9969. }
  9970. else if (m_token.tk == tkSUPER || m_token.tk == tkID)
  9971. {
  9972. if (isDecl)
  9973. {
  9974. charcount_t ichMin = m_pscan->IchMinTok();
  9975. pnodeElem = ParseVariableDeclaration<buildAST>(declarationType, ichMin
  9976. ,/* fAllowIn */false, /* pfForInOk */nullptr, /* singleDefOnly */true, /* allowInit */!seenRest, false /*topLevelParse*/);
  9977. }
  9978. else
  9979. {
  9980. BOOL fCanAssign;
  9981. IdentToken token;
  9982. // We aren't declaring anything, so scan the ID reference manually.
  9983. pnodeElem = ParseTerm<buildAST>(/* fAllowCall */ m_token.tk != tkSUPER, nullptr /*pNameHint*/, nullptr /*pHintLength*/, nullptr /*pShortNameOffset*/, &token, false,
  9984. &fCanAssign);
  9985. if (!fCanAssign && PHASE_ON1(Js::EarlyReferenceErrorsPhase))
  9986. {
  9987. Error(JSERR_CantAssignTo);
  9988. }
  9989. if (buildAST)
  9990. {
  9991. if (IsStrictMode() && pnodeElem != nullptr && pnodeElem->nop == knopName)
  9992. {
  9993. CheckStrictModeEvalArgumentsUsage(pnodeElem->sxPid.pid);
  9994. }
  9995. }
  9996. else
  9997. {
  9998. if (IsStrictMode() && token.tk == tkID)
  9999. {
  10000. CheckStrictModeEvalArgumentsUsage(token.pid);
  10001. }
  10002. token.tk = tkNone;
  10003. }
  10004. }
  10005. }
  10006. else if (!(m_token.tk == tkComma || m_token.tk == tkRBrack || m_token.tk == tkRCurly))
  10007. {
  10008. if (m_token.IsOperator())
  10009. {
  10010. Error(ERRDestructNoOper);
  10011. }
  10012. Error(ERRDestructIDRef);
  10013. }
  10014. // Swallow RParens before a default expression, if any.
  10015. while (m_token.tk == tkRParen)
  10016. {
  10017. m_pscan->Scan();
  10018. --parenCount;
  10019. }
  10020. if (hasSeenRest != nullptr)
  10021. {
  10022. *hasSeenRest = seenRest;
  10023. }
  10024. if (m_token.tk == tkAsg)
  10025. {
  10026. // Parse the initializer.
  10027. if (seenRest)
  10028. {
  10029. Error(ERRRestWithDefault);
  10030. }
  10031. m_pscan->Scan();
  10032. ParseNodePtr pnodeInit = ParseExpr<buildAST>(koplCma);
  10033. if (buildAST)
  10034. {
  10035. pnodeElem = CreateBinNode(knopAsg, pnodeElem, pnodeInit);
  10036. }
  10037. }
  10038. if (buildAST && seenRest)
  10039. {
  10040. ParseNodePtr pnodeRest = CreateNodeWithScanner<knopEllipsis>();
  10041. pnodeRest->sxUni.pnode1 = pnodeElem;
  10042. pnodeElem = pnodeRest;
  10043. }
  10044. while (m_token.tk == tkRParen)
  10045. {
  10046. m_pscan->Scan();
  10047. --parenCount;
  10048. }
  10049. if (!(m_token.tk == tkComma || m_token.tk == tkRBrack || m_token.tk == tkRCurly))
  10050. {
  10051. if (m_token.IsOperator())
  10052. {
  10053. Error(ERRDestructNoOper);
  10054. }
  10055. Error(ERRsyntax);
  10056. }
  10057. if (parenCount != 0)
  10058. {
  10059. Error(ERRnoRparen);
  10060. }
  10061. return pnodeElem;
  10062. }
  10063. template <bool buildAST>
  10064. ParseNodePtr Parser::ParseDestructuredArrayLiteral(tokens declarationType, bool isDecl, bool topLevel)
  10065. {
  10066. Assert(m_token.tk == tkLBrack);
  10067. charcount_t ichMin = m_pscan->IchMinTok();
  10068. m_pscan->Scan();
  10069. ParseNodePtr pnodeDestructArr = nullptr;
  10070. ParseNodePtr pnodeList = nullptr;
  10071. ParseNodePtr *lastNodeRef = nullptr;
  10072. uint count = 0;
  10073. bool hasMissingValues = false;
  10074. bool seenRest = false;
  10075. while (true)
  10076. {
  10077. if (seenRest) // Rest must be in the last position.
  10078. {
  10079. Error(ERRDestructRestLast);
  10080. }
  10081. ParseNodePtr pnodeElem = ParseDestructuredVarDecl<buildAST>(declarationType, isDecl, &seenRest, topLevel);
  10082. if (buildAST)
  10083. {
  10084. if (pnodeElem == nullptr && buildAST)
  10085. {
  10086. pnodeElem = CreateNodeWithScanner<knopEmpty>();
  10087. hasMissingValues = true;
  10088. }
  10089. AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeElem);
  10090. }
  10091. count++;
  10092. if (m_token.tk == tkRBrack)
  10093. {
  10094. break;
  10095. }
  10096. if (m_token.tk != tkComma)
  10097. {
  10098. Error(ERRDestructNoOper);
  10099. }
  10100. m_pscan->Scan();
  10101. }
  10102. if (buildAST)
  10103. {
  10104. pnodeDestructArr = CreateNodeWithScanner<knopArrayPattern>();
  10105. pnodeDestructArr->sxArrLit.pnode1 = pnodeList;
  10106. pnodeDestructArr->sxArrLit.arrayOfTaggedInts = false;
  10107. pnodeDestructArr->sxArrLit.arrayOfInts = false;
  10108. pnodeDestructArr->sxArrLit.arrayOfNumbers = false;
  10109. pnodeDestructArr->sxArrLit.hasMissingValues = hasMissingValues;
  10110. pnodeDestructArr->sxArrLit.count = count;
  10111. pnodeDestructArr->sxArrLit.spreadCount = seenRest ? 1 : 0;
  10112. pnodeDestructArr->ichMin = ichMin;
  10113. pnodeDestructArr->ichLim = m_pscan->IchLimTok();
  10114. if (pnodeDestructArr->sxArrLit.pnode1)
  10115. {
  10116. this->CheckArguments(pnodeDestructArr->sxArrLit.pnode1);
  10117. }
  10118. }
  10119. return pnodeDestructArr;
  10120. }
  10121. void Parser::CaptureContext(ParseContext *parseContext) const
  10122. {
  10123. parseContext->pszSrc = m_pscan->PchBase();
  10124. parseContext->length = this->m_originalLength;
  10125. parseContext->characterOffset = m_pscan->IchMinTok();
  10126. parseContext->offset = parseContext->characterOffset + m_pscan->m_cMultiUnits;
  10127. parseContext->grfscr = this->m_grfscr;
  10128. parseContext->lineNumber = m_pscan->LineCur();
  10129. parseContext->pnodeProg = this->m_currentNodeProg;
  10130. parseContext->fromExternal = m_pscan->IsFromExternalSource();
  10131. parseContext->strictMode = this->IsStrictMode();
  10132. parseContext->sourceContextInfo = this->m_sourceContextInfo;
  10133. parseContext->currentBlockInfo = this->m_currentBlockInfo;
  10134. parseContext->nextBlockId = this->m_nextBlockId;
  10135. }
  10136. void Parser::RestoreContext(ParseContext *const parseContext)
  10137. {
  10138. m_sourceContextInfo = parseContext->sourceContextInfo;
  10139. m_currentBlockInfo = parseContext->currentBlockInfo;
  10140. m_nextBlockId = parseContext->nextBlockId;
  10141. m_grfscr = parseContext->grfscr;
  10142. m_length = parseContext->length;
  10143. m_pscan->SetText(parseContext->pszSrc, parseContext->offset, parseContext->length, parseContext->characterOffset, parseContext->grfscr, parseContext->lineNumber);
  10144. m_currentNodeProg = parseContext->pnodeProg;
  10145. m_fUseStrictMode = parseContext->strictMode;
  10146. }
  10147. class ByteCodeGenerator;
  10148. #if DBG_DUMP
  10149. #define INDENT_SIZE 2
  10150. void PrintPnodeListWIndent(ParseNode *pnode,int indentAmt);
  10151. void PrintFormalsWIndent(ParseNode *pnode, int indentAmt);
  10152. void Indent(int indentAmt) {
  10153. for (int i=0;i<indentAmt;i++) {
  10154. Output::Print(L" ");
  10155. }
  10156. }
  10157. void PrintScopesWIndent(ParseNode *pnode,int indentAmt) {
  10158. ParseNode *scope = nullptr;
  10159. bool firstOnly = false;
  10160. switch(pnode->nop)
  10161. {
  10162. case knopProg:
  10163. case knopFncDecl: scope = pnode->sxFnc.pnodeScopes; break;
  10164. case knopBlock: scope = pnode->sxBlock.pnodeScopes; break;
  10165. case knopCatch: scope = pnode->sxCatch.pnodeScopes; break;
  10166. case knopWith: scope = pnode->sxWith.pnodeScopes; break;
  10167. case knopSwitch: scope = pnode->sxSwitch.pnodeBlock; firstOnly = true; break;
  10168. case knopFor: scope = pnode->sxFor.pnodeBlock; firstOnly = true; break;
  10169. case knopForIn: scope = pnode->sxForInOrForOf.pnodeBlock; firstOnly = true; break;
  10170. case knopForOf: scope = pnode->sxForInOrForOf.pnodeBlock; firstOnly = true; break;
  10171. }
  10172. if (scope) {
  10173. Indent(indentAmt);
  10174. Output::Print(L"Scopes: ");
  10175. ParseNode *next = nullptr;
  10176. ParseNode *syntheticBlock = nullptr;
  10177. while (scope) {
  10178. switch (scope->nop) {
  10179. case knopFncDecl: Output::Print(L"knopFncDecl"); next = scope->sxFnc.pnodeNext; break;
  10180. case knopBlock: Output::Print(L"knopBlock"); next = scope->sxBlock.pnodeNext; break;
  10181. case knopCatch: Output::Print(L"knopCatch"); next = scope->sxCatch.pnodeNext; break;
  10182. case knopWith: Output::Print(L"knopWith"); next = scope->sxWith.pnodeNext; break;
  10183. default: Output::Print(L"unknown"); break;
  10184. }
  10185. if (firstOnly) {
  10186. next = nullptr;
  10187. syntheticBlock = scope;
  10188. }
  10189. if (scope->grfpn & fpnSyntheticNode) {
  10190. Output::Print(L" synthetic");
  10191. if (scope->nop == knopBlock)
  10192. syntheticBlock = scope;
  10193. }
  10194. Output::Print(L" (%d-%d)", scope->ichMin, scope->ichLim);
  10195. if (next) Output::Print(L", ");
  10196. scope = next;
  10197. }
  10198. Output::Print(L"\n");
  10199. if (syntheticBlock || firstOnly) {
  10200. PrintScopesWIndent(syntheticBlock, indentAmt + INDENT_SIZE);
  10201. }
  10202. }
  10203. }
  10204. void PrintPnodeWIndent(ParseNode *pnode,int indentAmt) {
  10205. if (pnode==NULL)
  10206. return;
  10207. Output::Print(L"[%d, %d): ", pnode->ichMin, pnode->ichLim);
  10208. switch (pnode->nop) {
  10209. //PTNODE(knopName , "name" ,None ,Pid ,fnopLeaf)
  10210. case knopName:
  10211. Indent(indentAmt);
  10212. if (pnode->sxPid.pid!=NULL) {
  10213. Output::Print(L"id: %s\n",pnode->sxPid.pid->Psz());
  10214. }
  10215. else {
  10216. Output::Print(L"name node\n");
  10217. }
  10218. break;
  10219. //PTNODE(knopInt , "int const" ,None ,Int ,fnopLeaf|fnopConst)
  10220. case knopInt:
  10221. Indent(indentAmt);
  10222. Output::Print(L"%d\n",pnode->sxInt.lw);
  10223. break;
  10224. //PTNODE(knopFlt , "flt const" ,None ,Flt ,fnopLeaf|fnopConst)
  10225. case knopFlt:
  10226. Indent(indentAmt);
  10227. Output::Print(L"%lf\n",pnode->sxFlt.dbl);
  10228. break;
  10229. //PTNODE(knopStr , "str const" ,None ,Pid ,fnopLeaf|fnopConst)
  10230. case knopStr:
  10231. Indent(indentAmt);
  10232. Output::Print(L"\"%s\"\n",pnode->sxPid.pid->Psz());
  10233. break;
  10234. //PTNODE(knopRegExp , "reg expr" ,None ,Pid ,fnopLeaf|fnopConst)
  10235. case knopRegExp:
  10236. Indent(indentAmt);
  10237. Output::Print(L"/%x/\n",pnode->sxPid.regexPattern);
  10238. break;
  10239. //PTNODE(knopThis , "this" ,None ,None ,fnopLeaf)
  10240. case knopThis:
  10241. Indent(indentAmt);
  10242. Output::Print(L"this\n");
  10243. break;
  10244. //PTNODE(knopSuper , "super" ,None ,None ,fnopLeaf)
  10245. case knopSuper:
  10246. Indent(indentAmt);
  10247. Output::Print(L"super\n");
  10248. break;
  10249. //PTNODE(knopNewTarget , "new.target" ,None ,None ,fnopLeaf)
  10250. case knopNewTarget:
  10251. Indent(indentAmt);
  10252. Output::Print(L"new.target\n");
  10253. break;
  10254. //PTNODE(knopNull , "null" ,Null ,None ,fnopLeaf)
  10255. case knopNull:
  10256. Indent(indentAmt);
  10257. Output::Print(L"null\n");
  10258. break;
  10259. //PTNODE(knopFalse , "false" ,False ,None ,fnopLeaf)
  10260. case knopFalse:
  10261. Indent(indentAmt);
  10262. Output::Print(L"false\n");
  10263. break;
  10264. //PTNODE(knopTrue , "true" ,True ,None ,fnopLeaf)
  10265. case knopTrue:
  10266. Indent(indentAmt);
  10267. Output::Print(L"true\n");
  10268. break;
  10269. //PTNODE(knopEmpty , "empty" ,Empty ,None ,fnopLeaf)
  10270. case knopEmpty:
  10271. Indent(indentAmt);
  10272. Output::Print(L"empty\n");
  10273. break;
  10274. // Unary operators.
  10275. //PTNODE(knopNot , "~" ,BitNot ,Uni ,fnopUni)
  10276. case knopNot:
  10277. Indent(indentAmt);
  10278. Output::Print(L"~\n");
  10279. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10280. break;
  10281. //PTNODE(knopNeg , "unary -" ,Neg ,Uni ,fnopUni)
  10282. case knopNeg:
  10283. Indent(indentAmt);
  10284. Output::Print(L"U-\n");
  10285. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10286. break;
  10287. //PTNODE(knopPos , "unary +" ,Pos ,Uni ,fnopUni)
  10288. case knopPos:
  10289. Indent(indentAmt);
  10290. Output::Print(L"U+\n");
  10291. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10292. break;
  10293. //PTNODE(knopLogNot , "!" ,LogNot ,Uni ,fnopUni)
  10294. case knopLogNot:
  10295. Indent(indentAmt);
  10296. Output::Print(L"!\n");
  10297. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10298. break;
  10299. //PTNODE(knopEllipsis , "..." ,Spread ,Uni , fnopUni)
  10300. case knopEllipsis:
  10301. Indent(indentAmt);
  10302. Output::Print(L"...<expr>\n");
  10303. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10304. break;
  10305. //PTNODE(knopIncPost , "++ post" ,Inc ,Uni ,fnopUni|fnopAsg)
  10306. case knopIncPost:
  10307. Indent(indentAmt);
  10308. Output::Print(L"<expr>++\n");
  10309. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10310. break;
  10311. //PTNODE(knopDecPost , "-- post" ,Dec ,Uni ,fnopUni|fnopAsg)
  10312. case knopDecPost:
  10313. Indent(indentAmt);
  10314. Output::Print(L"<expr>--\n");
  10315. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10316. break;
  10317. //PTNODE(knopIncPre , "++ pre" ,Inc ,Uni ,fnopUni|fnopAsg)
  10318. case knopIncPre:
  10319. Indent(indentAmt);
  10320. Output::Print(L"++<expr>\n");
  10321. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10322. break;
  10323. //PTNODE(knopDecPre , "-- pre" ,Dec ,Uni ,fnopUni|fnopAsg)
  10324. case knopDecPre:
  10325. Indent(indentAmt);
  10326. Output::Print(L"--<expr>\n");
  10327. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10328. break;
  10329. //PTNODE(knopTypeof , "typeof" ,None ,Uni ,fnopUni)
  10330. case knopTypeof:
  10331. Indent(indentAmt);
  10332. Output::Print(L"typeof\n");
  10333. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10334. break;
  10335. //PTNODE(knopVoid , "void" ,Void ,Uni ,fnopUni)
  10336. case knopVoid:
  10337. Indent(indentAmt);
  10338. Output::Print(L"void\n");
  10339. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10340. break;
  10341. //PTNODE(knopDelete , "delete" ,None ,Uni ,fnopUni)
  10342. case knopDelete:
  10343. Indent(indentAmt);
  10344. Output::Print(L"delete\n");
  10345. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10346. break;
  10347. //PTNODE(knopArray , "arr cnst" ,None ,Uni ,fnopUni)
  10348. case knopArrayPattern:
  10349. Indent(indentAmt);
  10350. Output::Print(L"Array Pattern\n");
  10351. PrintPnodeListWIndent(pnode->sxUni.pnode1, indentAmt + INDENT_SIZE);
  10352. break;
  10353. case knopObjectPattern:
  10354. Indent(indentAmt);
  10355. Output::Print(L"Object Pattern\n");
  10356. PrintPnodeListWIndent(pnode->sxUni.pnode1, indentAmt + INDENT_SIZE);
  10357. break;
  10358. case knopArray:
  10359. Indent(indentAmt);
  10360. Output::Print(L"Array Literal\n");
  10361. PrintPnodeListWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10362. break;
  10363. //PTNODE(knopObject , "obj cnst" ,None ,Uni ,fnopUni)
  10364. case knopObject:
  10365. Indent(indentAmt);
  10366. Output::Print(L"Object Literal\n");
  10367. PrintPnodeListWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10368. break;
  10369. // Binary and Ternary Operators
  10370. //PTNODE(knopAdd , "+" ,Add ,Bin ,fnopBin)
  10371. case knopAdd:
  10372. Indent(indentAmt);
  10373. Output::Print(L"+\n");
  10374. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10375. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10376. break;
  10377. //PTNODE(knopSub , "-" ,Sub ,Bin ,fnopBin)
  10378. case knopSub:
  10379. Indent(indentAmt);
  10380. Output::Print(L"-\n");
  10381. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10382. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10383. break;
  10384. //PTNODE(knopMul , "*" ,Mul ,Bin ,fnopBin)
  10385. case knopMul:
  10386. Indent(indentAmt);
  10387. Output::Print(L"*\n");
  10388. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10389. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10390. break;
  10391. //PTNODE(knopDiv , "/" ,Div ,Bin ,fnopBin)
  10392. case knopExpo:
  10393. Indent(indentAmt);
  10394. Output::Print(L"**\n");
  10395. PrintPnodeWIndent(pnode->sxBin.pnode1, indentAmt + INDENT_SIZE);
  10396. PrintPnodeWIndent(pnode->sxBin.pnode2, indentAmt + INDENT_SIZE);
  10397. break;
  10398. //PTNODE(knopExpo , "**" ,Expo ,Bin ,fnopBin)
  10399. case knopDiv:
  10400. Indent(indentAmt);
  10401. Output::Print(L"/\n");
  10402. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10403. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10404. break;
  10405. //PTNODE(knopMod , "%" ,Mod ,Bin ,fnopBin)
  10406. case knopMod:
  10407. Indent(indentAmt);
  10408. Output::Print(L"%\n");
  10409. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10410. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10411. break;
  10412. //PTNODE(knopOr , "|" ,BitOr ,Bin ,fnopBin)
  10413. case knopOr:
  10414. Indent(indentAmt);
  10415. Output::Print(L"|\n");
  10416. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10417. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10418. break;
  10419. //PTNODE(knopXor , "^" ,BitXor ,Bin ,fnopBin)
  10420. case knopXor:
  10421. Indent(indentAmt);
  10422. Output::Print(L"^\n");
  10423. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10424. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10425. break;
  10426. //PTNODE(knopAnd , "&" ,BitAnd ,Bin ,fnopBin)
  10427. case knopAnd:
  10428. Indent(indentAmt);
  10429. Output::Print(L"&\n");
  10430. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10431. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10432. break;
  10433. //PTNODE(knopEq , "==" ,EQ ,Bin ,fnopBin|fnopRel)
  10434. case knopEq:
  10435. Indent(indentAmt);
  10436. Output::Print(L"==\n");
  10437. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10438. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10439. break;
  10440. //PTNODE(knopNe , "!=" ,NE ,Bin ,fnopBin|fnopRel)
  10441. case knopNe:
  10442. Indent(indentAmt);
  10443. Output::Print(L"!=\n");
  10444. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10445. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10446. break;
  10447. //PTNODE(knopLt , "<" ,LT ,Bin ,fnopBin|fnopRel)
  10448. case knopLt:
  10449. Indent(indentAmt);
  10450. Output::Print(L"<\n");
  10451. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10452. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10453. break;
  10454. //PTNODE(knopLe , "<=" ,LE ,Bin ,fnopBin|fnopRel)
  10455. case knopLe:
  10456. Indent(indentAmt);
  10457. Output::Print(L"<=\n");
  10458. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10459. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10460. break;
  10461. //PTNODE(knopGe , ">=" ,GE ,Bin ,fnopBin|fnopRel)
  10462. case knopGe:
  10463. Indent(indentAmt);
  10464. Output::Print(L">=\n");
  10465. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10466. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10467. break;
  10468. //PTNODE(knopGt , ">" ,GT ,Bin ,fnopBin|fnopRel)
  10469. case knopGt:
  10470. Indent(indentAmt);
  10471. Output::Print(L">\n");
  10472. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10473. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10474. break;
  10475. //PTNODE(knopCall , "()" ,None ,Bin ,fnopBin)
  10476. case knopCall:
  10477. Indent(indentAmt);
  10478. Output::Print(L"Call\n");
  10479. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10480. PrintPnodeListWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10481. break;
  10482. //PTNODE(knopDot , "." ,None ,Bin ,fnopBin)
  10483. case knopDot:
  10484. Indent(indentAmt);
  10485. Output::Print(L".\n");
  10486. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10487. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10488. break;
  10489. //PTNODE(knopAsg , "=" ,None ,Bin ,fnopBin|fnopAsg)
  10490. case knopAsg:
  10491. Indent(indentAmt);
  10492. Output::Print(L"=\n");
  10493. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10494. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10495. break;
  10496. //PTNODE(knopInstOf , "instanceof",InstOf ,Bin ,fnopBin|fnopRel)
  10497. case knopInstOf:
  10498. Indent(indentAmt);
  10499. Output::Print(L"instanceof\n");
  10500. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10501. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10502. break;
  10503. //PTNODE(knopIn , "in" ,In ,Bin ,fnopBin|fnopRel)
  10504. case knopIn:
  10505. Indent(indentAmt);
  10506. Output::Print(L"in\n");
  10507. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10508. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10509. break;
  10510. //PTNODE(knopEqv , "===" ,Eqv ,Bin ,fnopBin|fnopRel)
  10511. case knopEqv:
  10512. Indent(indentAmt);
  10513. Output::Print(L"===\n");
  10514. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10515. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10516. break;
  10517. //PTNODE(knopNEqv , "!==" ,NEqv ,Bin ,fnopBin|fnopRel)
  10518. case knopNEqv:
  10519. Indent(indentAmt);
  10520. Output::Print(L"!==\n");
  10521. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10522. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10523. break;
  10524. //PTNODE(knopComma , "," ,None ,Bin ,fnopBin)
  10525. case knopComma:
  10526. Indent(indentAmt);
  10527. Output::Print(L",\n");
  10528. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10529. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10530. break;
  10531. //PTNODE(knopLogOr , "||" ,None ,Bin ,fnopBin)
  10532. case knopLogOr:
  10533. Indent(indentAmt);
  10534. Output::Print(L"||\n");
  10535. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10536. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10537. break;
  10538. //PTNODE(knopLogAnd , "&&" ,None ,Bin ,fnopBin)
  10539. case knopLogAnd:
  10540. Indent(indentAmt);
  10541. Output::Print(L"&&\n");
  10542. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10543. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10544. break;
  10545. //PTNODE(knopLsh , "<<" ,Lsh ,Bin ,fnopBin)
  10546. case knopLsh:
  10547. Indent(indentAmt);
  10548. Output::Print(L"<<\n");
  10549. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10550. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10551. break;
  10552. //PTNODE(knopRsh , ">>" ,Rsh ,Bin ,fnopBin)
  10553. case knopRsh:
  10554. Indent(indentAmt);
  10555. Output::Print(L">>\n");
  10556. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10557. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10558. break;
  10559. //PTNODE(knopRs2 , ">>>" ,Rs2 ,Bin ,fnopBin)
  10560. case knopRs2:
  10561. Indent(indentAmt);
  10562. Output::Print(L">>>\n");
  10563. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10564. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10565. break;
  10566. //PTNODE(knopNew , "new" ,None ,Bin ,fnopBin)
  10567. case knopNew:
  10568. Indent(indentAmt);
  10569. Output::Print(L"new\n");
  10570. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10571. PrintPnodeListWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10572. break;
  10573. //PTNODE(knopIndex , "[]" ,None ,Bin ,fnopBin)
  10574. case knopIndex:
  10575. Indent(indentAmt);
  10576. Output::Print(L"[]\n");
  10577. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10578. PrintPnodeListWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10579. break;
  10580. //PTNODE(knopQmark , "?" ,None ,Tri ,fnopBin)
  10581. case knopQmark:
  10582. Indent(indentAmt);
  10583. Output::Print(L"?:\n");
  10584. PrintPnodeWIndent(pnode->sxTri.pnode1,indentAmt+INDENT_SIZE);
  10585. PrintPnodeWIndent(pnode->sxTri.pnode2,indentAmt+INDENT_SIZE);
  10586. PrintPnodeWIndent(pnode->sxTri.pnode3,indentAmt+INDENT_SIZE);
  10587. break;
  10588. //PTNODE(knopAsgAdd , "+=" ,Add ,Bin ,fnopBin|fnopAsg)
  10589. case knopAsgAdd:
  10590. Indent(indentAmt);
  10591. Output::Print(L"+=\n");
  10592. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10593. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10594. break;
  10595. //PTNODE(knopAsgSub , "-=" ,Sub ,Bin ,fnopBin|fnopAsg)
  10596. case knopAsgSub:
  10597. Indent(indentAmt);
  10598. Output::Print(L"-=\n");
  10599. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10600. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10601. break;
  10602. //PTNODE(knopAsgMul , "*=" ,Mul ,Bin ,fnopBin|fnopAsg)
  10603. case knopAsgMul:
  10604. Indent(indentAmt);
  10605. Output::Print(L"*=\n");
  10606. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10607. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10608. break;
  10609. //PTNODE(knopAsgDiv , "/=" ,Div ,Bin ,fnopBin|fnopAsg)
  10610. case knopAsgExpo:
  10611. Indent(indentAmt);
  10612. Output::Print(L"**=\n");
  10613. PrintPnodeWIndent(pnode->sxBin.pnode1, indentAmt + INDENT_SIZE);
  10614. PrintPnodeWIndent(pnode->sxBin.pnode2, indentAmt + INDENT_SIZE);
  10615. break;
  10616. //PTNODE(knopAsgExpo , "**=" ,Expo ,Bin ,fnopBin|fnopAsg)
  10617. case knopAsgDiv:
  10618. Indent(indentAmt);
  10619. Output::Print(L"/=\n");
  10620. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10621. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10622. break;
  10623. //PTNODE(knopAsgMod , "%=" ,Mod ,Bin ,fnopBin|fnopAsg)
  10624. case knopAsgMod:
  10625. Indent(indentAmt);
  10626. Output::Print(L"%=\n");
  10627. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10628. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10629. break;
  10630. //PTNODE(knopAsgAnd , "&=" ,BitAnd ,Bin ,fnopBin|fnopAsg)
  10631. case knopAsgAnd:
  10632. Indent(indentAmt);
  10633. Output::Print(L"&=\n");
  10634. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10635. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10636. break;
  10637. //PTNODE(knopAsgXor , "^=" ,BitXor ,Bin ,fnopBin|fnopAsg)
  10638. case knopAsgXor:
  10639. Indent(indentAmt);
  10640. Output::Print(L"^=\n");
  10641. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10642. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10643. break;
  10644. //PTNODE(knopAsgOr , "|=" ,BitOr ,Bin ,fnopBin|fnopAsg)
  10645. case knopAsgOr:
  10646. Indent(indentAmt);
  10647. Output::Print(L"|=\n");
  10648. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10649. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10650. break;
  10651. //PTNODE(knopAsgLsh , "<<=" ,Lsh ,Bin ,fnopBin|fnopAsg)
  10652. case knopAsgLsh:
  10653. Indent(indentAmt);
  10654. Output::Print(L"<<=\n");
  10655. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10656. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10657. break;
  10658. //PTNODE(knopAsgRsh , ">>=" ,Rsh ,Bin ,fnopBin|fnopAsg)
  10659. case knopAsgRsh:
  10660. Indent(indentAmt);
  10661. Output::Print(L">>=\n");
  10662. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10663. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10664. break;
  10665. //PTNODE(knopAsgRs2 , ">>>=" ,Rs2 ,Bin ,fnopBin|fnopAsg)
  10666. case knopAsgRs2:
  10667. Indent(indentAmt);
  10668. Output::Print(L">>>=\n");
  10669. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10670. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10671. break;
  10672. case knopComputedName:
  10673. Indent(indentAmt);
  10674. Output::Print(L"ComputedProperty\n");
  10675. PrintPnodeWIndent(pnode->sxUni.pnode1, indentAmt + INDENT_SIZE);
  10676. break;
  10677. //PTNODE(knopMember , ":" ,None ,Bin ,fnopBin)
  10678. case knopMember:
  10679. case knopMemberShort:
  10680. case knopObjectPatternMember:
  10681. Indent(indentAmt);
  10682. Output::Print(L":\n");
  10683. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt+INDENT_SIZE);
  10684. PrintPnodeWIndent(pnode->sxBin.pnode2,indentAmt+INDENT_SIZE);
  10685. break;
  10686. // General nodes.
  10687. //PTNODE(knopList , "<list>" ,None ,Bin ,fnopNone)
  10688. case knopList:
  10689. Indent(indentAmt);
  10690. Output::Print(L"List\n");
  10691. PrintPnodeListWIndent(pnode,indentAmt+INDENT_SIZE);
  10692. break;
  10693. //PTNODE(knopVarDecl , "varDcl" ,None ,Var ,fnopNone)
  10694. case knopVarDecl:
  10695. Indent(indentAmt);
  10696. Output::Print(L"var %s\n",pnode->sxVar.pid->Psz());
  10697. if (pnode->sxVar.pnodeInit!=NULL)
  10698. PrintPnodeWIndent(pnode->sxVar.pnodeInit,indentAmt+INDENT_SIZE);
  10699. break;
  10700. case knopConstDecl:
  10701. Indent(indentAmt);
  10702. Output::Print(L"const %s\n",pnode->sxVar.pid->Psz());
  10703. if (pnode->sxVar.pnodeInit!=NULL)
  10704. PrintPnodeWIndent(pnode->sxVar.pnodeInit,indentAmt+INDENT_SIZE);
  10705. break;
  10706. case knopLetDecl:
  10707. Indent(indentAmt);
  10708. Output::Print(L"let %s\n",pnode->sxVar.pid->Psz());
  10709. if (pnode->sxVar.pnodeInit!=NULL)
  10710. PrintPnodeWIndent(pnode->sxVar.pnodeInit,indentAmt+INDENT_SIZE);
  10711. break;
  10712. //PTNODE(knopFncDecl , "fncDcl" ,None ,Fnc ,fnopLeaf)
  10713. case knopFncDecl:
  10714. Indent(indentAmt);
  10715. if (pnode->sxFnc.pid!=NULL)
  10716. {
  10717. Output::Print(L"fn decl %d nested %d name %s (%d-%d)\n",pnode->sxFnc.IsDeclaration(),pnode->sxFnc.IsNested(),
  10718. pnode->sxFnc.pid->Psz(), pnode->ichMin, pnode->ichLim);
  10719. }
  10720. else
  10721. {
  10722. Output::Print(L"fn decl %d nested %d anonymous (%d-%d)\n",pnode->sxFnc.IsDeclaration(),pnode->sxFnc.IsNested(),pnode->ichMin,pnode->ichLim);
  10723. }
  10724. PrintScopesWIndent(pnode, indentAmt+INDENT_SIZE);
  10725. PrintFormalsWIndent(pnode->sxFnc.pnodeArgs, indentAmt + INDENT_SIZE);
  10726. PrintPnodeWIndent(pnode->sxFnc.pnodeRest, indentAmt + INDENT_SIZE);
  10727. PrintPnodeWIndent(pnode->sxFnc.pnodeBody, indentAmt + INDENT_SIZE);
  10728. break;
  10729. //PTNODE(knopProg , "program" ,None ,Fnc ,fnopNone)
  10730. case knopProg:
  10731. Indent(indentAmt);
  10732. Output::Print(L"program\n");
  10733. PrintScopesWIndent(pnode, indentAmt+INDENT_SIZE);
  10734. PrintPnodeListWIndent(pnode->sxFnc.pnodeBody,indentAmt+INDENT_SIZE);
  10735. break;
  10736. //PTNODE(knopEndCode , "<endcode>" ,None ,None ,fnopNone)
  10737. case knopEndCode:
  10738. Indent(indentAmt);
  10739. Output::Print(L"<endcode>\n");
  10740. break;
  10741. //PTNODE(knopDebugger , "debugger" ,None ,None ,fnopNone)
  10742. case knopDebugger:
  10743. Indent(indentAmt);
  10744. Output::Print(L"<debugger>\n");
  10745. break;
  10746. //PTNODE(knopFor , "for" ,None ,For ,fnopBreak|fnopContinue)
  10747. case knopFor:
  10748. Indent(indentAmt);
  10749. Output::Print(L"for\n");
  10750. PrintScopesWIndent(pnode, indentAmt+INDENT_SIZE);
  10751. PrintPnodeWIndent(pnode->sxFor.pnodeInit,indentAmt+INDENT_SIZE);
  10752. PrintPnodeWIndent(pnode->sxFor.pnodeCond,indentAmt+INDENT_SIZE);
  10753. PrintPnodeWIndent(pnode->sxFor.pnodeIncr,indentAmt+INDENT_SIZE);
  10754. PrintPnodeWIndent(pnode->sxFor.pnodeBody,indentAmt+INDENT_SIZE);
  10755. break;
  10756. //PTNODE(knopIf , "if" ,None ,If ,fnopNone)
  10757. case knopIf:
  10758. Indent(indentAmt);
  10759. Output::Print(L"if\n");
  10760. PrintPnodeWIndent(pnode->sxIf.pnodeCond,indentAmt+INDENT_SIZE);
  10761. PrintPnodeWIndent(pnode->sxIf.pnodeTrue,indentAmt+INDENT_SIZE);
  10762. if (pnode->sxIf.pnodeFalse!=NULL)
  10763. PrintPnodeWIndent(pnode->sxIf.pnodeFalse,indentAmt+INDENT_SIZE);
  10764. break;
  10765. //PTNODE(knopWhile , "while" ,None ,While,fnopBreak|fnopContinue)
  10766. case knopWhile:
  10767. Indent(indentAmt);
  10768. Output::Print(L"while\n");
  10769. PrintPnodeWIndent(pnode->sxWhile.pnodeCond,indentAmt+INDENT_SIZE);
  10770. PrintPnodeWIndent(pnode->sxWhile.pnodeBody,indentAmt+INDENT_SIZE);
  10771. break;
  10772. //PTNODE(knopDoWhile , "do-while" ,None ,While,fnopBreak|fnopContinue)
  10773. case knopDoWhile:
  10774. Indent(indentAmt);
  10775. Output::Print(L"do\n");
  10776. PrintPnodeWIndent(pnode->sxWhile.pnodeCond,indentAmt+INDENT_SIZE);
  10777. PrintPnodeWIndent(pnode->sxWhile.pnodeBody,indentAmt+INDENT_SIZE);
  10778. break;
  10779. //PTNODE(knopForIn , "for in" ,None ,ForIn,fnopBreak|fnopContinue|fnopCleanup)
  10780. case knopForIn:
  10781. Indent(indentAmt);
  10782. Output::Print(L"forIn\n");
  10783. PrintScopesWIndent(pnode, indentAmt+INDENT_SIZE);
  10784. PrintPnodeWIndent(pnode->sxForInOrForOf.pnodeLval,indentAmt+INDENT_SIZE);
  10785. PrintPnodeWIndent(pnode->sxForInOrForOf.pnodeObj,indentAmt+INDENT_SIZE);
  10786. PrintPnodeWIndent(pnode->sxForInOrForOf.pnodeBody,indentAmt+INDENT_SIZE);
  10787. break;
  10788. case knopForOf:
  10789. Indent(indentAmt);
  10790. Output::Print(L"forOf\n");
  10791. PrintScopesWIndent(pnode, indentAmt+INDENT_SIZE);
  10792. PrintPnodeWIndent(pnode->sxForInOrForOf.pnodeLval,indentAmt+INDENT_SIZE);
  10793. PrintPnodeWIndent(pnode->sxForInOrForOf.pnodeObj,indentAmt+INDENT_SIZE);
  10794. PrintPnodeWIndent(pnode->sxForInOrForOf.pnodeBody,indentAmt+INDENT_SIZE);
  10795. break;
  10796. //PTNODE(knopReturn , "return" ,None ,Uni ,fnopNone)
  10797. case knopReturn:
  10798. Indent(indentAmt);
  10799. Output::Print(L"return\n");
  10800. if (pnode->sxReturn.pnodeExpr!=NULL)
  10801. PrintPnodeWIndent(pnode->sxReturn.pnodeExpr,indentAmt+INDENT_SIZE);
  10802. break;
  10803. //PTNODE(knopBlock , "{}" ,None ,Block,fnopNone)
  10804. case knopBlock:
  10805. Indent(indentAmt);
  10806. Output::Print(L"block ");
  10807. if (pnode->grfpn & fpnSyntheticNode)
  10808. Output::Print(L"synthetic ");
  10809. Output::Print(L"(%d-%d)\n",pnode->ichMin,pnode->ichLim);
  10810. PrintScopesWIndent(pnode, indentAmt+INDENT_SIZE);
  10811. if (pnode->sxBlock.pnodeStmt!=NULL)
  10812. PrintPnodeWIndent(pnode->sxBlock.pnodeStmt,indentAmt+INDENT_SIZE);
  10813. break;
  10814. //PTNODE(knopWith , "with" ,None ,With ,fnopCleanup)
  10815. case knopWith:
  10816. Indent(indentAmt);
  10817. Output::Print(L"with (%d-%d)\n", pnode->ichMin,pnode->ichLim);
  10818. PrintScopesWIndent(pnode, indentAmt+INDENT_SIZE);
  10819. PrintPnodeWIndent(pnode->sxWith.pnodeObj,indentAmt+INDENT_SIZE);
  10820. PrintPnodeWIndent(pnode->sxWith.pnodeBody,indentAmt+INDENT_SIZE);
  10821. break;
  10822. //PTNODE(knopBreak , "break" ,None ,Jump ,fnopNone)
  10823. case knopBreak:
  10824. Indent(indentAmt);
  10825. Output::Print(L"break\n");
  10826. // TODO: some representation of target
  10827. break;
  10828. //PTNODE(knopContinue , "continue" ,None ,Jump ,fnopNone)
  10829. case knopContinue:
  10830. Indent(indentAmt);
  10831. Output::Print(L"continue\n");
  10832. // TODO: some representation of target
  10833. break;
  10834. //PTNODE(knopLabel , "label" ,None ,Label,fnopNone)
  10835. case knopLabel:
  10836. Indent(indentAmt);
  10837. Output::Print(L"label %s",pnode->sxLabel.pid->Psz());
  10838. // TODO: print labeled statement
  10839. break;
  10840. //PTNODE(knopSwitch , "switch" ,None ,Switch,fnopBreak)
  10841. case knopSwitch:
  10842. Indent(indentAmt);
  10843. Output::Print(L"switch\n");
  10844. PrintScopesWIndent(pnode, indentAmt+INDENT_SIZE);
  10845. for (ParseNode *pnodeT = pnode->sxSwitch.pnodeCases; NULL != pnodeT;pnodeT = pnodeT->sxCase.pnodeNext) {
  10846. PrintPnodeWIndent(pnodeT,indentAmt+2);
  10847. }
  10848. break;
  10849. //PTNODE(knopCase , "case" ,None ,Case ,fnopNone)
  10850. case knopCase:
  10851. Indent(indentAmt);
  10852. Output::Print(L"case\n");
  10853. PrintPnodeWIndent(pnode->sxCase.pnodeExpr,indentAmt+INDENT_SIZE);
  10854. PrintPnodeWIndent(pnode->sxCase.pnodeBody,indentAmt+INDENT_SIZE);
  10855. break;
  10856. //PTNODE(knopTryFinally,"try-finally",None,TryFinally,fnopCleanup)
  10857. case knopTryFinally:
  10858. PrintPnodeWIndent(pnode->sxTryFinally.pnodeTry,indentAmt);
  10859. PrintPnodeWIndent(pnode->sxTryFinally.pnodeFinally,indentAmt);
  10860. break;
  10861. case knopFinally:
  10862. Indent(indentAmt);
  10863. Output::Print(L"finally\n");
  10864. PrintPnodeWIndent(pnode->sxFinally.pnodeBody,indentAmt+INDENT_SIZE);
  10865. break;
  10866. //PTNODE(knopCatch , "catch" ,None ,Catch,fnopNone)
  10867. case knopCatch:
  10868. Indent(indentAmt);
  10869. Output::Print(L"catch (%d-%d)\n", pnode->ichMin,pnode->ichLim);
  10870. PrintScopesWIndent(pnode, indentAmt+INDENT_SIZE);
  10871. PrintPnodeWIndent(pnode->sxCatch.pnodeParam,indentAmt+INDENT_SIZE);
  10872. // if (pnode->sxCatch.pnodeGuard!=NULL)
  10873. // PrintPnodeWIndent(pnode->sxCatch.pnodeGuard,indentAmt+INDENT_SIZE);
  10874. PrintPnodeWIndent(pnode->sxCatch.pnodeBody,indentAmt+INDENT_SIZE);
  10875. break;
  10876. //PTNODE(knopTryCatch , "try-catch" ,None ,TryCatch ,fnopCleanup)
  10877. case knopTryCatch:
  10878. PrintPnodeWIndent(pnode->sxTryCatch.pnodeTry,indentAmt);
  10879. PrintPnodeWIndent(pnode->sxTryCatch.pnodeCatch,indentAmt);
  10880. break;
  10881. //PTNODE(knopTry , "try" ,None ,Try ,fnopCleanup)
  10882. case knopTry:
  10883. Indent(indentAmt);
  10884. Output::Print(L"try\n");
  10885. PrintPnodeWIndent(pnode->sxTry.pnodeBody,indentAmt+INDENT_SIZE);
  10886. break;
  10887. //PTNODE(knopThrow , "throw" ,None ,Uni ,fnopNone)
  10888. case knopThrow:
  10889. Indent(indentAmt);
  10890. Output::Print(L"throw\n");
  10891. PrintPnodeWIndent(pnode->sxUni.pnode1,indentAmt+INDENT_SIZE);
  10892. break;
  10893. //PTNODE(knopClassDecl, "classDecl", None , Class, fnopLeaf)
  10894. case knopClassDecl:
  10895. Indent(indentAmt);
  10896. Output::Print(L"class %s", pnode->sxClass.pnodeName->sxVar.pid->Psz());
  10897. if (pnode->sxClass.pnodeExtends != nullptr)
  10898. {
  10899. Output::Print(L" extends ");
  10900. PrintPnodeWIndent(pnode->sxClass.pnodeExtends, 0);
  10901. }
  10902. else {
  10903. Output::Print(L"\n");
  10904. }
  10905. PrintPnodeWIndent(pnode->sxClass.pnodeConstructor, indentAmt + INDENT_SIZE);
  10906. PrintPnodeWIndent(pnode->sxClass.pnodeMembers, indentAmt + INDENT_SIZE);
  10907. PrintPnodeWIndent(pnode->sxClass.pnodeStaticMembers, indentAmt + INDENT_SIZE);
  10908. break;
  10909. case knopStrTemplate:
  10910. Indent(indentAmt);
  10911. Output::Print(L"string template\n");
  10912. PrintPnodeListWIndent(pnode->sxStrTemplate.pnodeSubstitutionExpressions, indentAmt + INDENT_SIZE);
  10913. break;
  10914. case knopYieldStar:
  10915. Indent(indentAmt);
  10916. Output::Print(L"yield*\n");
  10917. PrintPnodeListWIndent(pnode->sxUni.pnode1, indentAmt + INDENT_SIZE);
  10918. break;
  10919. case knopYield:
  10920. case knopYieldLeaf:
  10921. Indent(indentAmt);
  10922. Output::Print(L"yield\n");
  10923. PrintPnodeListWIndent(pnode->sxUni.pnode1, indentAmt + INDENT_SIZE);
  10924. break;
  10925. case knopAwait:
  10926. Indent(indentAmt);
  10927. Output::Print(L"await\n");
  10928. PrintPnodeListWIndent(pnode->sxUni.pnode1, indentAmt + INDENT_SIZE);
  10929. break;
  10930. default:
  10931. Output::Print(L"unhandled pnode op %d\n",pnode->nop);
  10932. break;
  10933. }
  10934. }
  10935. void PrintPnodeListWIndent(ParseNode *pnode,int indentAmt) {
  10936. if (pnode!=NULL) {
  10937. while(pnode->nop==knopList) {
  10938. PrintPnodeWIndent(pnode->sxBin.pnode1,indentAmt);
  10939. pnode = pnode->sxBin.pnode2;
  10940. }
  10941. PrintPnodeWIndent(pnode,indentAmt);
  10942. }
  10943. }
  10944. void PrintFormalsWIndent(ParseNode *pnodeArgs, int indentAmt)
  10945. {
  10946. for (ParseNode *pnode = pnodeArgs; pnode != nullptr; pnode = pnode->GetFormalNext())
  10947. {
  10948. PrintPnodeWIndent(pnode->nop == knopParamPattern ? pnode->sxParamPattern.pnode1 : pnode, indentAmt);
  10949. }
  10950. }
  10951. void PrintPnode(ParseNode *pnode) {
  10952. PrintPnodeWIndent(pnode,0);
  10953. }
  10954. void ParseNode::Dump()
  10955. {
  10956. switch(nop)
  10957. {
  10958. case knopFncDecl:
  10959. case knopProg:
  10960. LPCOLESTR name = Js::Constants::AnonymousFunction;
  10961. if(this->sxFnc.pnodeName)
  10962. {
  10963. name = this->sxFnc.pnodeName->sxVar.pid->Psz();
  10964. }
  10965. Output::Print(L"%s (%d) [%d, %d]:\n", name, this->sxFnc.functionId, this->sxFnc.lineNumber, this->sxFnc.columnNumber);
  10966. Output::Print(L"hasArguments: %s callsEval:%s childCallsEval:%s HasReferenceableBuiltInArguments:%s ArgumentsObjectEscapes:%s HasWith:%s HasThis:%s HasOnlyThis:%s \n",
  10967. IsTrueOrFalse(this->sxFnc.HasHeapArguments()),
  10968. IsTrueOrFalse(this->sxFnc.CallsEval()),
  10969. IsTrueOrFalse(this->sxFnc.ChildCallsEval()),
  10970. IsTrueOrFalse(this->sxFnc.HasReferenceableBuiltInArguments()),
  10971. IsTrueOrFalse(this->sxFnc.GetArgumentsObjectEscapes()),
  10972. IsTrueOrFalse(this->sxFnc.HasWithStmt()),
  10973. IsTrueOrFalse(this->sxFnc.HasThisStmt()),
  10974. IsTrueOrFalse(this->sxFnc.HasOnlyThisStmts()));
  10975. if(this->sxFnc.funcInfo)
  10976. {
  10977. this->sxFnc.funcInfo->Dump();
  10978. }
  10979. break;
  10980. }
  10981. }
  10982. #endif
  10983. DeferredFunctionStub * BuildDeferredStubTree(ParseNode *pnodeFnc, Recycler *recycler)
  10984. {
  10985. Assert(pnodeFnc->nop == knopFncDecl);
  10986. uint nestedCount = pnodeFnc->sxFnc.nestedCount;
  10987. if (nestedCount == 0)
  10988. {
  10989. return nullptr;
  10990. }
  10991. if (pnodeFnc->sxFnc.deferredStub)
  10992. {
  10993. return pnodeFnc->sxFnc.deferredStub;
  10994. }
  10995. DeferredFunctionStub *deferredStubs = RecyclerNewArray(recycler, DeferredFunctionStub, nestedCount);
  10996. uint i = 0;
  10997. ParseNode *pnodeBlock = pnodeFnc->sxFnc.pnodeBodyScope;
  10998. Assert(pnodeBlock != nullptr
  10999. && pnodeBlock->nop == knopBlock
  11000. && (pnodeBlock->sxBlock.blockType == PnodeBlockType::Function
  11001. || pnodeBlock->sxBlock.blockType == PnodeBlockType::Parameter));
  11002. for (ParseNode *pnodeChild = pnodeBlock->sxBlock.pnodeScopes; pnodeChild != nullptr;)
  11003. {
  11004. if (pnodeChild->nop != knopFncDecl)
  11005. {
  11006. // We only expect to find a function body block in a parameter scope block.
  11007. Assert(pnodeChild->nop == knopBlock
  11008. && (pnodeBlock->sxBlock.blockType == PnodeBlockType::Parameter
  11009. || pnodeChild->sxBlock.blockType == PnodeBlockType::Function));
  11010. pnodeChild = pnodeChild->sxBlock.pnodeNext;
  11011. continue;
  11012. }
  11013. Assert(i < nestedCount);
  11014. if (pnodeChild->sxFnc.IsGeneratedDefault())
  11015. {
  11016. ++i;
  11017. pnodeChild = pnodeChild->sxFnc.pnodeNext;
  11018. continue;
  11019. }
  11020. __analysis_assume(i < nestedCount);
  11021. deferredStubs[i].fncFlags = pnodeChild->sxFnc.fncFlags;
  11022. deferredStubs[i].nestedCount = pnodeChild->sxFnc.nestedCount;
  11023. deferredStubs[i].restorePoint = *pnodeChild->sxFnc.pRestorePoint;
  11024. deferredStubs[i].deferredStubs = BuildDeferredStubTree(pnodeChild, recycler);
  11025. #if DEBUG
  11026. deferredStubs[i].ichMin = pnodeChild->ichMin;
  11027. #endif
  11028. ++i;
  11029. pnodeChild = pnodeChild->sxFnc.pnodeNext;
  11030. }
  11031. return deferredStubs;
  11032. }